From 3a2f6646f0a639934c1d958f3d1e72b836c5f25f Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 6 Sep 2023 15:35:37 -0400 Subject: [PATCH] Use CI-CD-Github-Actions for spelling and formatting, add in the bot formatting action, update the CI-CD workflow files. Fix incorrect spelling and formatting on files. (#1083) * Use new version of CI-CD Actions, checkout@v3 instead of checkout@v2 on all jobs * Use cSpell spell check, and use ubuntu-20.04 for formatting check * Add in bot formatting action * Update freertos_demo.yml and freertos_plus_demo.yml files to increase github log readability * Add in a Qemu demo onto the workflows. --- .github/.cSpellWords.txt | 6150 +++++++++++++++ .github/scripts/common/header_checker.py | 2 +- .github/scripts/common/requirements.txt | 24 +- .github/scripts/core_checker.py | 62 +- .github/scripts/qemu_reader.c | 38 + .github/scripts/release-requirements.txt | 27 +- .github/workflows/auto-release.yml | 4 +- .github/workflows/ci.yml | 198 +- .github/workflows/core-checks.yml | 4 +- .github/workflows/formatting.yml | 23 + .github/workflows/freertos_demos.yml | 656 +- .github/workflows/freertos_plus_demos.yml | 1189 ++- .github/workflows/kernel-unit-tests.yml | 6 +- FreeRTOS+TCP.url | 10 +- .../DemoTasks/DefenderDemoExample.c | 2 +- .../Device_Defender_Demo.vcxproj.filters | 2 +- .../Device_Defender_Demo/core_mqtt_config.h | 2 +- .../Device_Defender_Demo/defender_config.h | 2 +- .../Device_Defender_Demo/defender_demo.sln | 2 +- .../Device_Defender_Demo/demo_config.h | 2 +- .../Device_Defender_Demo/main.c | 2 +- .../Device_Defender_Demo/metrics_collector.c | 2 +- .../Device_Defender_Demo/metrics_collector.h | 2 +- .../Device_Defender_Demo/report_builder.c | 94 +- .../Device_Defender_Demo/report_builder.h | 2 +- .../Common/main.c | 2 +- .../DemoTasks/ShadowDemoMainExample.c | 2 +- .../Device_Shadow_Demo.vcxproj.filters | 2 +- .../Device_Shadow_Demo/core_mqtt_config.h | 6 +- .../Device_Shadow_Demo/demo_config.h | 4 +- .../Device_Shadow_Demo/shadow_config.h | 8 +- .../Device_Shadow_Demo/shadow_main_demo.sln | 2 +- .../DemoSetup/demo_config.templ | 2 +- .../DemoSetup/demo_config_empty.templ | 2 +- .../FleetProvisioningDemoExample.c | 20 +- .../core_mqtt_config.h | 2 +- .../demo_config.h | 2 +- .../fleet_provisioning_config.h | 2 +- .../fleet_provisioning_demo.sln | 2 +- .../fleet_provisioning_demo.vcxproj.filters | 2 +- .../Fleet_Provisioning_With_CSR_Demo/main.c | 2 +- .../pkcs11_operations.c | 2 +- .../pkcs11_operations.h | 2 +- .../tinycbor_serializer.c | 2 +- .../tinycbor_serializer.h | 2 +- .../Jobs_Demo/DemoTasks/JobsDemoExample.c | 2 +- .../Jobs_Demo/Jobs_Demo.vcxproj.filters | 2 +- .../Jobs_Demo/core_mqtt_config.h | 6 +- .../Jobs_Demo/demo_config.h | 4 +- .../Jobs_Demo/jobs_demo.sln | 2 +- .../Jobs_Windows_Simulator/Jobs_Demo/main.c | 2 +- .../AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c | 42 +- .../AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.h | 2 +- .../mqtt_pkcs11_demo_helpers.c | 42 +- .../mqtt_pkcs11_demo_helpers.h | 2 +- .../Common/HTTP_Utils/http_demo_utils.c | 6 +- .../Common/HTTP_Utils/http_demo_utils.h | 2 +- .../aws_ota_codesigner_certificate.h | 18 +- .../code_signature_verification.h | 18 +- .../code_signature_verification_mbedtls.c | 340 +- .../Common/Ota_PAL/Win32/ota_pal.c | 79 +- .../Common/Ota_PAL/Win32/ota_pal.h | 20 +- .../subscription_manager.c | 2 +- .../subscription_manager.h | 2 +- .../DemoTasks/OtaOverHttpDemoExample.c | 78 +- .../Ota_Over_Http_Demo.vcxproj | 496 +- .../Ota_Over_Http_Demo.vcxproj.filters | 2 +- .../Ota_Over_Http_Demo/core_mqtt_config.h | 51 +- .../Ota_Over_Http_Demo/demo_config.h | 2 +- .../Ota_Over_Http_Demo/main.c | 2 +- .../Ota_Over_Http_Demo/ota_config.h | 6 +- .../Ota_Over_Http_Demo/ota_over_http_demo.sln | 232 +- .../DemoTasks/OtaOverMqttDemoExample.c | 118 +- .../Ota_Over_Mqtt_Demo.vcxproj.filters | 2 +- .../Ota_Over_Mqtt_Demo/core_mqtt_config.h | 51 +- .../Ota_Over_Mqtt_Demo/demo_config.h | 2 +- .../Ota_Over_Mqtt_Demo/main.c | 2 +- .../Ota_Over_Mqtt_Demo/ota_config.h | 6 +- .../Ota_Over_Mqtt_Demo/ota_over_mqtt_demo.sln | 2 +- ...eeRTOS+TCP_and_FreeRTOS_FAT_in_the_lab.url | 10 +- .../Common/FreeRTOS_TCP_server.c | 757 +- .../FTP/FreeRTOS_FTP_commands.c | 149 +- .../FTP/FreeRTOS_FTP_server.c | 5589 +++++++------- .../HTTP_Server/FreeRTOS_HTTP_commands.c | 163 +- .../HTTP_Server/FreeRTOS_HTTP_server.c | 897 +-- .../Common/Demo_IP_Protocols/NTP/NTPDemo.c | 967 +-- .../Common/Demo_IP_Protocols/NTP/readme.md | 4 +- .../include/FreeRTOS_FTP_commands.h | 269 +- .../include/FreeRTOS_HTTP_commands.h | 135 +- .../include/FreeRTOS_TCP_server.h | 266 +- .../include/FreeRTOS_server_private.h | 386 +- .../Demo_IP_Protocols/include/NTPClient.h | 169 +- .../Demo_IP_Protocols/include/NTPDemo.h | 45 +- .../File-Related-CLI-commands.c | 1082 +-- .../Sample-CLI-commands.c | 986 +-- .../UARTCommandConsole.c | 452 +- .../UDP-Related-CLI-commands.c | 667 +- .../CreateExampleFiles/File-system-demo.c | 636 +- .../CLICommands/CLI-commands.c | 1392 ++-- .../CLICommands/UDPCommandInterpreter.h | 66 +- .../CLICommands/UDPCommandServer.c | 413 +- .../EchoClients/TwoEchoClients.c | 774 +- .../EchoClients/TwoEchoClients.h | 75 +- .../TraceMacros/Example1/DemoIPTrace.c | 299 +- .../TraceMacros/Example1/DemoIPTrace.h | 243 +- .../Common/Logging/windows/Logging_WinSim.c | 153 +- .../freertos_agent_message.c | 2 +- .../freertos_command_pool.c | 4 +- .../include/freertos_agent_message.h | 2 +- .../include/freertos_command_pool.h | 2 +- .../Common/MutualAuthMQTTExample.c | 66 +- .../Common/cellular_platform.c | 2 +- .../Common/cellular_platform.h | 4 +- .../Common/cellular_setup.c | 2 +- .../Common/comm_if_windows.c | 2 +- .../Common/core_mqtt_config.h | 2 +- .../Common/main.c | 2 +- .../cellular_config.h | 2 +- .../demo_config.h | 2 +- .../mqtt_mutual_auth_demo_with_bg96.sln | 172 +- .../mqtt_mutual_auth_demo_with_bg96.vcxproj | 426 +- ...mutual_auth_demo_with_bg96.vcxproj.filters | 454 +- .../cellular_config.h | 2 +- .../demo_config.h | 2 +- .../mqtt_mutual_auth_demo_with_hl7802.sln | 172 +- .../mqtt_mutual_auth_demo_with_hl7802.vcxproj | 428 +- ...tual_auth_demo_with_hl7802.vcxproj.filters | 454 +- .../cellular_config.h | 2 +- .../demo_config.h | 2 +- .../mqtt_mutual_auth_demo_with_sara_r4.sln | 172 +- ...mqtt_mutual_auth_demo_with_sara_r4.vcxproj | 426 +- ...ual_auth_demo_with_sara_r4.vcxproj.filters | 454 +- .../CLI-commands.c | 791 +- .../FreeRTOS_Plus_CLI_with_Trace.sln | 172 +- ...s_CLI_with_Trace_Windows_Simulator.vcxproj | 360 +- ...th_Trace_Windows_Simulator.vcxproj.filters | 166 +- .../READ_ME.url | 10 +- .../Run-time-stats-utils.c | 198 +- .../Trace_Recorder_Configuration/trcConfig.h | 826 +- .../trcKernelPortConfig.h | 30 +- .../trcKernelPortSnapshotConfig.h | 48 +- .../trcSnapshotConfig.h | 756 +- .../UDPCommandServer.c | 439 +- .../WIN32.vcxproj | 324 +- .../WIN32.vcxproj.filters | 200 +- .../main.c | 504 +- .../readme.txt | 14 +- .../ReadMe.txt | 14 +- .../ConfigurationFiles/redconf.c | 35 +- .../ConfigurationFiles/redconf.h | 225 +- .../ConfigurationFiles/redtypes.h | 221 +- .../File-Related-CLI-commands.c | 3129 ++++---- .../File-system-demo.c | 572 +- .../FreeRTOS_Plus_Reliance_Edge_with_CLI.sln | 172 +- ...eeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj | 410 +- ...lus_Reliance_Edge_with_CLI.vcxproj.filters | 352 +- .../Instructions_ReadMe.url | 12 +- .../Run-time-stats-utils.c | 178 +- .../Sample-CLI-commands.c | 777 +- .../UDPCommandServer.c | 455 +- .../main.c | 292 +- .../FreeRTOS-simulator-for-Linux.url | 10 +- .../FreeRTOSConfig.h | 24 +- .../FreeRTOSIPConfig.h | 2 +- .../FreeRTOS_Plus_TCP_Echo_Posix/Makefile | 2 +- .../SimpleTCPEchoServer.c | 12 +- .../TCPEchoClient_SingleTasks.c | 10 +- .../TCPEchoClient_SingleTasks.h | 7 +- .../Trace_Recorder_Configuration/trcConfig.h | 640 +- .../trcKernelPortConfig.h | 24 +- .../trcKernelPortSnapshotConfig.h | 46 +- .../trcSnapshotConfig.h | 490 +- .../code_coverage_additions.c | 10 +- .../FreeRTOS_Plus_TCP_Echo_Posix/console.c | 2 +- .../FreeRTOS_Plus_TCP_Echo_Posix/console.h | 23 +- .../Demo/FreeRTOS_Plus_TCP_Echo_Posix/main.c | 66 +- .../main_networking.c | 47 +- .../runtime_stats_hooks.c | 2 +- .../CMSIS/CMSDK_CM3.h | 1042 ++- .../CMSIS/SMM_MPS2.h | 963 +-- .../CMSIS/cmsis.h | 66 +- .../CMSIS/cmsis_compiler.h | 464 +- .../CMSIS/cmsis_gcc.h | 3563 +++++---- .../CMSIS/cmsis_version.h | 30 +- .../CMSIS/core_cm3.h | 2627 +++---- .../CMSIS/mpu_armv7.h | 436 +- .../FreeRTOSConfig.h | 161 +- .../FreeRTOSIPConfig.h | 395 +- .../TCPEchoClient_SingleTasks.c | 10 +- .../TCPEchoClient_SingleTasks.h | 7 +- .../FreeRTOS_Plus_TCP_Echo_Qemu_mps2/main.c | 64 +- .../main_networking.c | 54 +- .../mps2_m3.ld | 4 +- .../startup.c | 4 +- .../syscalls.c | 47 +- .../IPv6_Multi_WinSim_demo/FreeRTOSConfig.h | 4 +- .../IPv6_Multi_WinSim_demo/FreeRTOSIPConfig.h | 2 +- .../FreeRTOS_Plus_TCP_IPv6_Multi.sln | 2 +- .../IPv6_Multi_WinSim_demo/Logging_WinSim.c | 1106 +-- .../IPv6_Multi_WinSim_demo/ReadMe.md | 6 +- .../TCPEchoClient_SingleTasks.c | 948 +-- .../TCPEchoClient_SingleTasks.h | 76 +- .../UDPEchoClient_SingleTasks.c | 283 +- .../UDPEchoClient_SingleTasks.h | 13 +- .../IPv6_Multi_WinSim_demo/WIN32.vcxproj | 564 +- .../WIN32.vcxproj.filters | 706 +- .../IPv6_Multi_WinSim_demo/main.c | 187 +- .../IPv6_Multi_WinSim_demo/printf-stdarg.c | 2 +- .../common/Logging/include/logging.h | 2 +- .../common/Logging/include/logging_levels.h | 2 +- .../common/Logging/include/logging_stack.h | 2 +- .../common/Logging/windows/Logging_WinSim.c | 1107 +-- .../common/NTP/NTPDemo.c | 89 +- .../common/NTP/include/NTPDemo.h | 2 +- .../common/NTP/include/ntpClient.h | 2 +- .../common/WinPCap/Packet32.h | 36 +- .../common/WinPCap/PacketData.h | 38 +- .../common/WinPCap/Win32-Extensions.h | 4 +- .../common/WinPCap/arch.c | 380 +- .../common/WinPCap/ip6_misc.h | 2 +- .../common/WinPCap/netif.h | 2 +- .../common/WinPCap/pcap/bluetooth.h | 7 +- .../common/WinPCap/pcap/bpf.h | 527 +- .../common/WinPCap/pcap/namedb.h | 71 +- .../common/WinPCap/pcap/pcap.h | 530 +- .../common/WinPCap/pcap/sll.h | 33 +- .../common/WinPCap/pcap/usb.h | 66 +- .../common/WinPCap/pcap/vlan.h | 11 +- .../common/WinPCap/remote-ext.h | 16 +- .../DemoTasks/SimpleTCPEchoServer.c | 493 +- .../DemoTasks/SimpleUDPClientAndServer.c | 780 +- .../DemoTasks/TCPEchoClient_SingleTasks.c | 767 +- .../DemoTasks/include/SimpleTCPEchoServer.h | 143 +- .../include/SimpleUDPClientAndServer.h | 66 +- .../include/TCPEchoClient_SingleTasks.h | 77 +- .../FreeRTOS_Plus_TCP_Minimal.sln | 178 +- .../FreeRTOS_Plus_TCP_Minimal.vcxproj.filters | 2 +- .../ReadMe.txt | 68 +- .../Read_Me_Build_Instructions.url | 12 +- .../main.c | 867 ++- .../tcp_echo_config.h | 2 +- .../DemoTasks/CLI-commands.c | 891 +-- .../DemoTasks/SimpleClientAndServer.c | 531 +- .../DemoTasks/TwoEchoClients.c | 626 +- .../DemoTasks/UDPCommandServer.c | 245 +- .../DemoTasks/include/SimpleClientAndServer.h | 6 +- .../DemoTasks/include/TwoEchoClients.h | 5 +- .../DemoTasks/include/UDPCommandInterpreter.h | 6 +- .../DemoTasks/include/user_settings.h | 20 +- .../FreeRTOS_Plus_UDP_with_CLI.sln | 172 +- .../FreeRTOS_Plus_UDP_with_CLI.vcxproj | 348 +- ...FreeRTOS_Plus_UDP_with_CLI.vcxproj.filters | 118 +- .../README_FIRST.txt | 4 +- .../Run-time-stats-utils.c | 62 +- .../main.c | 119 +- .../ReadMe.txt | 6 +- .../See also FreeRTOS+TCP.url | 10 +- .../FreeRTOS_Plus_WolfSSL.sln | 226 +- ...TOS_Plus_WolfSSL_Windows_Simulator.vcxproj | 710 +- ..._WolfSSL_Windows_Simulator.vcxproj.filters | 776 +- .../READ_ME.url | 10 +- .../SecureTCPClientTask.c | 268 +- .../SecureTCPServerTask.c | 487 +- .../main.c | 179 +- .../user_settings.h | 42 +- .../Common/http_demo_utils.c | 6 +- .../Common/http_demo_utils.h | 2 +- .../coreHTTP_Windows_Simulator/Common/main.c | 3 +- .../Common/presigned_url_generator/README.md | 84 +- .../CoreHTTP_Mutual_Auth.vcxproj.filters | 2 +- .../DemoTasks/MutualAuthHTTPExample.c | 2 +- .../HTTP_Mutual_Auth/demo_config.h | 2 +- .../http_mutual_auth_demo.sln | 2 +- .../CoreHTTP_Plaintext.vcxproj.filters | 2 +- .../DemoTasks/PlainTextHTTPExample.c | 2 +- .../HTTP_Plaintext/demo_config.h | 2 +- .../HTTP_Plaintext/http_plain_text_demo.sln | 2 +- .../CoreHTTP_S3_Download.vcxproj.filters | 2 +- .../DemoTasks/S3DownloadHTTPExample.c | 4 +- .../HTTP_S3_Download/README.md | 26 +- .../HTTP_S3_Download/demo_config.h | 14 +- .../http_s3_download_demo.sln | 2 +- .../HTTP_S3_Download/sigv4_config.h | 2 +- ..._S3_Download_Multithreaded.vcxproj.filters | 2 +- .../S3DownloadMultithreadedHTTPExample.c | 2 +- .../demo_config.h | 2 +- .../http_s3_download_multithreaded_demo.sln | 2 +- .../CoreHTTP_S3_Upload.vcxproj.filters | 2 +- .../DemoTasks/S3UploadHTTPExample.c | 2 +- .../HTTP_S3_Upload/demo_config.h | 2 +- .../HTTP_S3_Upload/http_s3_upload_demo.sln | 2 +- .../Common/core_mqtt_config.h | 5 +- .../coreMQTT_Windows_Simulator/Common/main.c | 2 +- .../DemoTasks/BasicTLSMQTTExample.c | 12 +- .../MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj | 508 +- .../MQTT_Basic_TLS.vcxproj.filters | 232 +- .../MQTT_Basic_TLS/demo_config.h | 4 +- .../MQTT_Basic_TLS/mqtt_basic_tls_demo.sln | 268 +- .../MQTT_Basic_TLS/mqtt_broker_setup.txt | 2 +- .../DemoTasks/KeepAliveMQTTExample.c | 2 +- .../MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj | 444 +- .../MQTT_Keep_Alive.vcxproj.filters | 206 +- .../MQTT_Keep_Alive/demo_config.h | 4 +- .../MQTT_Keep_Alive/mqtt_keep_alive_demo.sln | 268 +- .../DemoTasks/mqtt-agent-task.c | 118 +- .../DemoTasks/simple_sub_pub_demo.c | 2 +- .../MQTT_Multitask/MQTT_Multitask.vcxproj | 396 +- .../MQTT_Multitask.vcxproj.filters | 320 +- .../MQTT_Multitask/demo_config.h | 2 +- .../MQTT_Multitask/mqtt_multitask_demo.sln | 202 +- .../subscription_manager.c | 2 +- .../subscription_manager.h | 2 +- .../DemoTasks/MutualAuthMQTTExample.c | 42 +- .../MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj | 508 +- .../MQTT_Mutual_Auth.vcxproj.filters | 226 +- .../MQTT_Mutual_Auth/demo_config.h | 2 +- .../mqtt_mutual_auth_demo.sln | 268 +- .../DemoTasks/MutualAuthMQTTExample.c | 2 +- .../MQTT_Mutual_Auth_wolfSSL.vcxproj | 730 +- .../MQTT_Mutual_Auth_wolfSSL.vcxproj.filters | 1256 +-- .../README_wolfSSL.md | 366 +- .../MQTT_Mutual_Auth_wolfSSL/demo_config.h | 10 +- .../mqtt_mutual_auth_demo_wolfSSL.sln | 204 +- .../MQTT_Mutual_Auth_wolfSSL/user_settings.h | 13 +- .../DemoTasks/PlaintextMQTTExample.c | 12 +- .../MQTT_Plain_Text/MQTT_Plain_Text.vcxproj | 504 +- .../MQTT_Plain_Text.vcxproj.filters | 208 +- .../MQTT_Plain_Text/demo_config.h | 4 +- .../MQTT_Plain_Text/mqtt_plain_text_demo.sln | 268 +- .../DemoTasks/SerializerMQTTExample.c | 2 +- .../MQTT_Serializer/MQTT_Serializer.vcxproj | 500 +- .../MQTT_Serializer.vcxproj.filters | 196 +- .../MQTT_Serializer/demo_config.h | 4 +- .../MQTT_Serializer/mqtt_serializer_demo.sln | 268 +- .../PKCS11_Mqtt_MutualAuthDemo.c | 2 +- .../README.md | 2 +- .../corePKCS11_MQTT_Mutual_Auth.sln | 2 +- .../corePKCS11_MQTT_Mutual_Auth.vcxproj | 414 +- ...orePKCS11_MQTT_Mutual_Auth.vcxproj.filters | 226 +- .../core_mqtt_config.h | 6 +- .../demo_config.h | 4 +- .../main.c | 3 +- .../CorePKCS11_Demos.sln | 2 +- .../CorePKCS11_Demos.vcxproj.filters | 2 +- .../examples/demo_helpers.c | 2 +- .../examples/demo_helpers.h | 2 +- .../examples/management_and_rng.c | 2 +- .../examples/mechanisms_and_digests.c | 2 +- .../examples/objects.c | 2 +- .../examples/pkcs11_demos.h | 4 +- .../examples/sign_and_verify.c | 2 +- .../Demo/corePKCS11_Windows_Simulator/main.c | 12 +- .../pkcs11_demo_config.h | 2 +- .../SNTPClientTask.c | 20 +- .../SampleAppTask.c | 2 +- .../common_demo_include.h | 2 +- .../coreSNTP_Demo.vcxproj.filters | 2 +- .../core_sntp_config.h | 2 +- .../core_sntp_demo.sln | 2 +- .../coreSNTP_Windows_Simulator/demo_config.h | 2 +- .../Demo/coreSNTP_Windows_Simulator/main.c | 4 +- FreeRTOS-Plus/Demo/readme.txt | 18 +- .../mbedtls_bio_tcp_sockets_wrapper.c | 2 +- .../mbedtls_bio_tcp_sockets_wrapper.h | 2 +- .../network_transport/mbedtls_pk_pkcs11.c | 2 +- .../network_transport/mbedtls_pkcs11.h | 2 +- .../network_transport/mbedtls_rng_pkcs11.c | 2 +- .../include/tcp_sockets_wrapper.h | 2 +- .../ports/cellular/tcp_sockets_wrapper.c | 4 +- .../ports/freertos_plus_tcp/sockets_wrapper.c | 22 +- .../ports/freertos_plus_tcp/sockets_wrapper.h | 4 +- .../freertos_plus_tcp/tcp_sockets_wrapper.c | 22 +- .../network_transport/transport_mbedtls.c | 21 +- .../network_transport/transport_mbedtls.h | 4 +- .../transport_mbedtls_pkcs11.c | 2 +- .../transport_mbedtls_pkcs11.h | 2 +- .../network_transport/transport_plaintext.c | 2 +- .../network_transport/transport_plaintext.h | 4 +- .../network_transport/transport_wolfSSL.c | 2 +- .../network_transport/transport_wolfSSL.h | 6 +- .../Source/Application-Protocols/readme.txt | 4 +- .../Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.c | 781 +- .../Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.h | 249 +- .../Source/FreeRTOS-Plus-CLI/History.txt | 64 +- .../FreeRTOS-Plus-CLI/LICENSE_INFORMATION.txt | 38 +- .../Source/FreeRTOS-Plus-CLI/ReadMe.url | 10 +- .../Source/FreeRTOS-Plus-CLI/readme.txt | 7 +- .../Source/FreeRTOS-Plus-IO/LinkToDemo.url | 10 +- .../Source/FreeRTOS-Plus-IO/readme.txt | 12 +- .../Include/aws_secure_sockets.tzext.h | 280 +- .../Include/aws_wifi.tzext.h | 270 +- .../FreeRTOS-Plus-Trace/Include/trcAssert.h | 288 +- .../FreeRTOS-Plus-Trace/Include/trcCounter.h | 318 +- .../FreeRTOS-Plus-Trace/Include/trcDefines.h | 364 +- .../Include/trcDiagnostics.h | 295 +- .../Include/trcEntryTable.h | 529 +- .../FreeRTOS-Plus-Trace/Include/trcError.h | 198 +- .../FreeRTOS-Plus-Trace/Include/trcEvent.h | 1250 +-- .../Include/trcEventBuffer.h | 270 +- .../Include/trcExtension.h | 195 +- .../Include/trcHardwarePort.h | 1438 ++-- .../FreeRTOS-Plus-Trace/Include/trcHeap.h | 281 +- .../FreeRTOS-Plus-Trace/Include/trcISR.h | 455 +- .../Include/trcInternalEventBuffer.h | 217 +- .../FreeRTOS-Plus-Trace/Include/trcInterval.h | 174 +- .../Include/trcKernelPort.h | 5964 +++++++------- .../Include/trcMultiCoreEventBuffer.h | 292 +- .../FreeRTOS-Plus-Trace/Include/trcObject.h | 426 +- .../FreeRTOS-Plus-Trace/Include/trcPrint.h | 420 +- .../FreeRTOS-Plus-Trace/Include/trcRecorder.h | 3790 ++++----- .../Include/trcStackMonitor.h | 272 +- .../Include/trcStateMachine.h | 160 +- .../Include/trcStaticBuffer.h | 224 +- .../FreeRTOS-Plus-Trace/Include/trcString.h | 153 +- .../FreeRTOS-Plus-Trace/Include/trcTask.h | 491 +- .../Include/trcTimestamp.h | 506 +- .../FreeRTOS-Plus-Trace/Include/trcTypes.h | 138 +- .../FreeRTOS-Plus-Trace/Include/trcUtility.h | 102 +- .../Source/FreeRTOS-Plus-Trace/LICENSE.md | 402 +- .../Source/FreeRTOS-Plus-Trace/LICENSE.spdx | 18 +- .../Source/FreeRTOS-Plus-Trace/README.md | 10 +- .../Source/FreeRTOS-Plus-Trace/ReadMe.url | 10 +- .../FreeRTOS-Plus-Trace/config/trcConfig.h | 640 +- .../config/trcKernelPortConfig.h | 232 +- .../config/trcKernelPortSnapshotConfig.h | 138 +- .../config/trcKernelPortStreamingConfig.h | 48 +- .../config/trcSnapshotConfig.h | 490 +- .../config/trcStreamingConfig.h | 102 +- .../TraceRecorderInit/TraceRecorderInit.cpp | 110 +- .../include/TraceRecorderInit.h | 76 +- .../extras/TraceRecorderInit/readme.txt | 60 +- .../AFR_WIFI_LOCAL/Readme-Streamport.txt | 42 +- .../AFR_WIFI_LOCAL/include/trcStreamPort.h | 258 +- .../AFR_WIFI_LOCAL/trcStreamPort.c | 320 +- .../Keil-uVision-Tracealyzer-ITM-Exporter.ini | 110 +- .../streamports/ARM_ITM/Readme-ARM_ITM.txt | 68 +- .../ARM_ITM/config/trcStreamPortConfig.h | 70 +- .../ARM_ITM/include/trcStreamPort.h | 230 +- .../streamports/ARM_ITM/trcStreamPort.c | 326 +- .../streamports/File/Readme-Streamport.txt | 36 +- .../File/config/trcStreamPortConfig.h | 78 +- .../streamports/File/include/trcStreamPort.h | 168 +- .../streamports/File/trcStreamPort.c | 165 +- .../Jlink_RTT/Readme-Streamport.txt | 42 +- .../streamports/Jlink_RTT/SEGGER_RTT.c | 3149 ++++---- .../Jlink_RTT/config/trcStreamPortConfig.h | 246 +- .../Jlink_RTT/include/SEGGER_RTT.h | 451 +- .../Jlink_RTT/include/SEGGER_RTT_Conf.h | 542 +- .../Jlink_RTT/include/trcStreamPort.h | 286 +- .../streamports/Jlink_RTT/trcStreamPort.c | 129 +- .../RingBuffer/Readme-Streamport.txt | 36 +- .../RingBuffer/config/trcStreamPortConfig.h | 120 +- .../RingBuffer/include/trcStreamPort.h | 404 +- .../streamports/RingBuffer/trcStreamPort.c | 264 +- .../STM32_USB_CDC/Readme-Streamport.txt | 186 +- .../config/trcStreamPortConfig.h | 78 +- .../STM32_USB_CDC/include/trcStreamPort.h | 224 +- .../streamports/STM32_USB_CDC/trcStreamPort.c | 309 +- .../streamports/TCPIP/Readme-Streamport.txt | 98 +- .../TCPIP/config/trcStreamPortConfig.h | 82 +- .../streamports/TCPIP/include/trcStreamPort.h | 153 +- .../streamports/TCPIP/trcStreamPort.c | 440 +- .../TCPIP_Win32/Readme-Streamport.txt | 74 +- .../TCPIP_Win32/config/trcStreamPortConfig.h | 82 +- .../TCPIP_Win32/include/trcStreamPort.h | 166 +- .../streamports/TCPIP_Win32/trcStreamPort.c | 497 +- .../XMOS_xScope/config/trcStreamPortConfig.h | 70 +- .../XMOS_xScope/include/trcStreamPort.h | 267 +- .../streamports/XMOS_xScope/trcStreamPort.c | 211 +- .../Source/FreeRTOS-Plus-Trace/trcAssert.c | 256 +- .../Source/FreeRTOS-Plus-Trace/trcCounter.c | 318 +- .../FreeRTOS-Plus-Trace/trcDiagnostics.c | 337 +- .../FreeRTOS-Plus-Trace/trcEntryTable.c | 874 +-- .../Source/FreeRTOS-Plus-Trace/trcError.c | 693 +- .../Source/FreeRTOS-Plus-Trace/trcEvent.c | 839 +- .../FreeRTOS-Plus-Trace/trcEventBuffer.c | 516 +- .../Source/FreeRTOS-Plus-Trace/trcExtension.c | 207 +- .../FreeRTOS-Plus-Trace/trcHardwarePort.c | 284 +- .../Source/FreeRTOS-Plus-Trace/trcHeap.c | 333 +- .../Source/FreeRTOS-Plus-Trace/trcISR.c | 556 +- .../trcInternalEventBuffer.c | 153 +- .../Source/FreeRTOS-Plus-Trace/trcInterval.c | 168 +- .../FreeRTOS-Plus-Trace/trcKernelPort.c | 1338 ++-- .../trcMultiCoreEventBuffer.c | 229 +- .../Source/FreeRTOS-Plus-Trace/trcObject.c | 731 +- .../Source/FreeRTOS-Plus-Trace/trcPrint.c | 644 +- .../FreeRTOS-Plus-Trace/trcSnapshotRecorder.c | 6822 +++++++++-------- .../FreeRTOS-Plus-Trace/trcStackMonitor.c | 438 +- .../FreeRTOS-Plus-Trace/trcStateMachine.c | 202 +- .../FreeRTOS-Plus-Trace/trcStaticBuffer.c | 114 +- .../trcStreamingRecorder.c | 1206 +-- .../Source/FreeRTOS-Plus-Trace/trcString.c | 153 +- .../Source/FreeRTOS-Plus-Trace/trcTask.c | 391 +- .../Source/FreeRTOS-Plus-Trace/trcTimestamp.c | 353 +- .../Reliance-Edge/core/driver/blockio.c | 285 +- .../Source/Reliance-Edge/core/driver/buffer.c | 1516 ++-- .../Source/Reliance-Edge/core/driver/core.c | 3859 +++++----- .../Source/Reliance-Edge/core/driver/dir.c | 1924 ++--- .../Source/Reliance-Edge/core/driver/format.c | 475 +- .../Source/Reliance-Edge/core/driver/imap.c | 697 +- .../Reliance-Edge/core/driver/imapextern.c | 631 +- .../Reliance-Edge/core/driver/imapinline.c | 266 +- .../Source/Reliance-Edge/core/driver/inode.c | 2247 +++--- .../Reliance-Edge/core/driver/inodedata.c | 3853 +++++----- .../Source/Reliance-Edge/core/driver/volume.c | 1082 +-- .../Reliance-Edge/core/include/redcore.h | 570 +- .../Reliance-Edge/core/include/redcoremacs.h | 185 +- .../Reliance-Edge/core/include/redcorevol.h | 193 +- .../Reliance-Edge/core/include/rednodes.h | 392 +- .../Source/Reliance-Edge/doc/coding_style.txt | 778 +- .../Source/Reliance-Edge/doc/release_notes.md | 4 +- FreeRTOS-Plus/Source/Reliance-Edge/fse/fse.c | 1376 ++-- .../Source/Reliance-Edge/include/redapimacs.h | 225 +- .../Reliance-Edge/include/redconfigchk.h | 434 +- .../Source/Reliance-Edge/include/redcoreapi.h | 218 +- .../Reliance-Edge/include/reddeviations.h | 450 +- .../Source/Reliance-Edge/include/rederrno.h | 229 +- .../Source/Reliance-Edge/include/redexclude.h | 107 +- .../Source/Reliance-Edge/include/redfs.h | 93 +- .../Source/Reliance-Edge/include/redfse.h | 224 +- .../Source/Reliance-Edge/include/redgetopt.h | 161 +- .../Source/Reliance-Edge/include/redmacs.h | 207 +- .../Source/Reliance-Edge/include/redmisc.h | 97 +- .../Source/Reliance-Edge/include/redosserv.h | 182 +- .../Source/Reliance-Edge/include/redpath.h | 62 +- .../Source/Reliance-Edge/include/redposix.h | 408 +- .../Source/Reliance-Edge/include/redstat.h | 189 +- .../Source/Reliance-Edge/include/redtests.h | 446 +- .../Reliance-Edge/include/redtestutils.h | 176 +- .../Source/Reliance-Edge/include/redtoolcmn.h | 75 +- .../Source/Reliance-Edge/include/redtools.h | 265 +- .../Source/Reliance-Edge/include/redutils.h | 161 +- .../Source/Reliance-Edge/include/redver.h | 133 +- .../Source/Reliance-Edge/include/redvolume.h | 181 +- .../os/freertos/include/redosdeviations.h | 405 +- .../os/freertos/include/redostypes.h | 85 +- .../os/freertos/services/osassert.c | 84 +- .../os/freertos/services/osbdev.c | 2533 +++--- .../os/freertos/services/osclock.c | 159 +- .../os/freertos/services/osmutex.c | 205 +- .../os/freertos/services/osoutput.c | 140 +- .../os/freertos/services/ostask.c | 137 +- .../os/freertos/services/ostimestamp.c | 218 +- .../Source/Reliance-Edge/posix/path.c | 893 ++- .../Source/Reliance-Edge/posix/posix.c | 6203 +++++++-------- .../Reliance-Edge/tests/posix/fsstress.c | 4301 ++++++----- .../tests/posix/redposixcompat.h | 304 +- .../Source/Reliance-Edge/tests/util/atoi.c | 479 +- .../Source/Reliance-Edge/tests/util/math.c | 688 +- .../Source/Reliance-Edge/tests/util/printf.c | 1517 ++-- .../Source/Reliance-Edge/tests/util/rand.c | 196 +- .../Source/Reliance-Edge/toolcmn/getopt.c | 1306 ++-- .../Source/Reliance-Edge/toolcmn/toolcmn.c | 201 +- .../Source/Reliance-Edge/util/bitmap.c | 200 +- FreeRTOS-Plus/Source/Reliance-Edge/util/crc.c | 1193 ++- .../Source/Reliance-Edge/util/endian.c | 162 +- .../Source/Reliance-Edge/util/memory.c | 607 +- .../Source/Reliance-Edge/util/namelen.c | 122 +- .../Source/Reliance-Edge/util/sign.c | 125 +- .../Source/Reliance-Edge/util/string.c | 660 +- .../Source/Utilities/logging/logging.h | 7 +- .../Source/Utilities/logging/logging_levels.h | 4 +- .../Source/Utilities/logging/logging_stack.h | 22 +- FreeRTOS-Plus/Source/WebDocs.url | 10 +- .../Integration/Config/FreeRTOSConfig.h | 2 +- .../Integration/Config/FreeRTOSIPConfig.h | 2 +- ...reeRTOS-Cellular-Interface-Integration.sln | 2 +- .../freertos_tcp_test_access_declare.h | 2 +- .../freertos_tcp_test_access_dns_define.h | 2 +- .../freertos_tcp_test_access_tcp_define.h | 2 +- .../Test_code/Test_Cases/test_freertos_tcp.c | 2 +- .../Test_code/Test_Runner/test_runner.c | 2 +- .../Test_code/Test_Runner/test_runner.h | 2 +- .../Test_Runner/test_runner_config.h | 2 +- .../Integration/Test_code/test_cellular_api.c | 5640 +++++++------- .../Integration/Test_code/test_config.h | 170 +- .../Integration/WinPCap/Packet32.h | 42 +- .../Integration/WinPCap/PacketData.h | 72 +- .../Integration/WinPCap/Win32-Extensions.h | 10 +- .../Integration/WinPCap/arch.c | 10 +- .../Integration/WinPCap/netif.h | 2 +- .../Integration/WinPCap/pcap/bluetooth.h | 11 +- .../Integration/WinPCap/pcap/bpf.h | 529 +- .../Integration/WinPCap/pcap/namedb.h | 71 +- .../Integration/WinPCap/pcap/pcap.h | 530 +- .../Integration/WinPCap/pcap/sll.h | 33 +- .../Integration/WinPCap/pcap/usb.h | 70 +- .../Integration/WinPCap/pcap/vlan.h | 11 +- .../Integration/WinPCap/remote-ext.h | 12 +- .../Integration/cellular_config.h | 2 +- .../Integration/cellular_platform.c | 2 +- .../Integration/cellular_platform.h | 4 +- .../Integration/comm_if_windows.c | 2 +- .../Integration/main.c | 6 +- .../Config/FreeRTOSConfig.h | 272 +- .../Config/FreeRTOSIPConfig.h | 383 +- .../Full-TCP-Networkless.sln | 2 +- .../Full-TCP-Networkless/ReadMe.txt | 2 +- .../freertos_tcp_test_access_declare.h | 7 +- .../freertos_tcp_test_access_dns_define.h | 7 +- .../freertos_tcp_test_access_tcp_define.h | 7 +- .../Test_code/Test_Cases/test_freertos_tcp.c | 23 +- .../Test_code/Test_Runner/test_runner.c | 65 +- .../Test_code/Test_Runner/test_runner.h | 47 +- .../Test_Runner/test_runner_config.h | 42 +- .../Full-TCP-Networkless/WinPCap/Packet32.h | 559 +- .../Full-TCP-Networkless/WinPCap/PacketData.h | 502 +- .../WinPCap/Win32-Extensions.h | 119 +- .../Full-TCP-Networkless/WinPCap/arch.c | 382 +- .../Full-TCP-Networkless/WinPCap/bittypes.h | 154 +- .../Full-TCP-Networkless/WinPCap/ip6_misc.h | 186 +- .../Full-TCP-Networkless/WinPCap/netif.h | 16 +- .../Full-TCP-Networkless/WinPCap/pcap-bpf.h | 2 +- .../WinPCap/pcap-stdinc.h | 58 +- .../WinPCap/pcap/bluetooth.h | 11 +- .../Full-TCP-Networkless/WinPCap/pcap/bpf.h | 529 +- .../WinPCap/pcap/namedb.h | 71 +- .../Full-TCP-Networkless/WinPCap/pcap/pcap.h | 530 +- .../Full-TCP-Networkless/WinPCap/pcap/sll.h | 33 +- .../Full-TCP-Networkless/WinPCap/pcap/usb.h | 70 +- .../Full-TCP-Networkless/WinPCap/pcap/vlan.h | 11 +- .../Full-TCP-Networkless/WinPCap/remote-ext.h | 692 +- .../Integration/Full-TCP-Networkless/main.c | 7 +- .../Full-TCP-Suite/Config/FreeRTOSConfig.h | 144 +- .../Full-TCP-Suite/Config/FreeRTOSIPConfig.h | 349 +- .../Full-TCP-Suite/Full-TCP-Suite.sln | 2 +- .../Logging/run-time-stats-utils.c | 17 +- .../Integration/Full-TCP-Suite/ReadMe.txt | 10 +- .../Test_Cases/include/application_version.h | 5 +- .../Test_Cases/include/clientcredential.h | 49 +- .../Test_Cases/include/config_common.h | 5 +- .../Test_Cases/include/test_framework.h | 5 +- .../Test_Cases/include/test_runner.h | 5 +- .../Test_Code/Test_Cases/include/test_tcp.h | 29 +- .../Test_Cases/include/test_tcp_config.h | 26 +- .../Test_Code/Test_Cases/include/test_utils.h | 5 +- .../Test_Cases/include/unity_config.h | 5 +- .../Test_Code/Test_Cases/test.c | 5 +- .../Test_Code/Test_Cases/test_framework.c | 5 +- .../Test_Code/Test_Cases/test_freertos.c | 5 +- .../Test_Code/Test_Cases/test_tcp.c | 205 +- .../Test_Code/Test_Runner/test_runner.c | 9 +- .../Test_Runner/test_runner_config.h | 40 +- .../Full-TCP-Suite/WinPCap/Packet32.h | 559 +- .../Full-TCP-Suite/WinPCap/PacketData.h | 502 +- .../Full-TCP-Suite/WinPCap/Win32-Extensions.h | 119 +- .../Integration/Full-TCP-Suite/WinPCap/arch.c | 382 +- .../Full-TCP-Suite/WinPCap/bittypes.h | 154 +- .../Full-TCP-Suite/WinPCap/ip6_misc.h | 186 +- .../Full-TCP-Suite/WinPCap/netif.h | 16 +- .../Full-TCP-Suite/WinPCap/pcap-bpf.h | 2 +- .../Full-TCP-Suite/WinPCap/pcap-stdinc.h | 58 +- .../Full-TCP-Suite/WinPCap/pcap/bluetooth.h | 11 +- .../Full-TCP-Suite/WinPCap/pcap/bpf.h | 529 +- .../Full-TCP-Suite/WinPCap/pcap/namedb.h | 71 +- .../Full-TCP-Suite/WinPCap/pcap/pcap.h | 530 +- .../Full-TCP-Suite/WinPCap/pcap/sll.h | 33 +- .../Full-TCP-Suite/WinPCap/pcap/usb.h | 70 +- .../Full-TCP-Suite/WinPCap/pcap/vlan.h | 11 +- .../Full-TCP-Suite/WinPCap/remote-ext.h | 692 +- .../Integration/Full-TCP-Suite/main.c | 7 +- .../ThirdParty/winpcap/include/Packet32.h | 559 +- .../winpcap/include/Win32-Extensions.h | 119 +- .../ThirdParty/winpcap/include/bittypes.h | 154 +- .../ThirdParty/winpcap/include/ip6_misc.h | 186 +- .../ThirdParty/winpcap/include/pcap-bpf.h | 2 +- .../ThirdParty/winpcap/include/pcap-stdinc.h | 58 +- .../winpcap/include/pcap/bluetooth.h | 11 +- .../ThirdParty/winpcap/include/pcap/bpf.h | 529 +- .../ThirdParty/winpcap/include/pcap/namedb.h | 71 +- .../ThirdParty/winpcap/include/pcap/pcap.h | 530 +- .../ThirdParty/winpcap/include/pcap/sll.h | 33 +- .../ThirdParty/winpcap/include/pcap/usb.h | 70 +- .../ThirdParty/winpcap/include/pcap/vlan.h | 11 +- .../ThirdParty/winpcap/include/remote-ext.h | 692 +- .../FreeRTOS+TCP/FreeRTOS+TCP.vcxproj | 3784 ++++----- .../FreeRTOS+TCP/FreeRTOS+TCP.vcxproj.filters | 1882 ++--- .../FreeRTOS+TCP/FreeRTOSIPConfig.h | 76 +- .../FreeRTOS+TCP/NetworkInterface_WinPCap.c | 20 +- .../FreeRTOS+TCP/libslirp-version.h | 30 +- .../FreeRTOS+TCP/plus_tcp_hooks_winsim.c | 68 +- .../FreeRTOS-Kernel.vcxproj.filters | 2 +- .../FreeRTOS-Kernel/FreeRTOSConfig.h | 26 +- .../FreeRTOS-Kernel/freertos_hooks_winsim.c | 86 +- .../FreeRTOS-Kernel/runtime_stats_winsim.c | 28 +- .../FreeRTOS_Plus_Libs.sln | 2 +- .../Logging/Logging.vcxproj.filters | 2 +- .../MbedTLS/MbedTLS.vcxproj.filters | 2 +- .../MbedTLS/mbedtls_config_v3.2.1.h | 423 +- .../MbedTLS/mbedtls_freertos_port.c | 156 +- .../MbedTLS/mbedtls_freertos_port.h | 6 +- .../MbedTLS/threading_alt.h | 2 +- .../coreHTTP/coreHTTP.vcxproj.filters | 2 +- .../coreHTTP/core_http_config.h | 2 +- .../corePKCS11/corePKCS11.vcxproj.filters | 2 +- .../corePKCS11/core_pkcs11_config.h | 4 +- .../Demo/Common/ARMv8M/mpu_demo/mpu_demo.c | 694 +- .../Demo/Common/ARMv8M/mpu_demo/mpu_demo.h | 88 +- .../GCC/ARM_CM23/non_secure/reg_test_asm.c | 2 +- .../GCC/ARM_CM23/non_secure/reg_test_asm.h | 2 +- .../GCC/ARM_CM23/secure/secure_reg_test_asm.c | 2 +- .../GCC/ARM_CM23/secure/secure_reg_test_asm.h | 2 +- .../GCC/ARM_CM33/non_secure/reg_test_asm.c | 2 +- .../GCC/ARM_CM33/non_secure/reg_test_asm.h | 2 +- .../GCC/ARM_CM33/secure/secure_reg_test_asm.c | 2 +- .../GCC/ARM_CM33/secure/secure_reg_test_asm.h | 2 +- .../IAR/ARM_CM23/non_secure/reg_test_asm.h | 2 +- .../IAR/ARM_CM23/non_secure/reg_test_asm.s | 2 +- .../IAR/ARM_CM23/secure/secure_reg_test.c | 2 +- .../IAR/ARM_CM23/secure/secure_reg_test_asm.h | 2 +- .../IAR/ARM_CM23/secure/secure_reg_test_asm.s | 2 +- .../IAR/ARM_CM33/non_secure/reg_test_asm.h | 2 +- .../IAR/ARM_CM33/non_secure/reg_test_asm.s | 2 +- .../IAR/ARM_CM33/secure/secure_reg_test.c | 2 +- .../IAR/ARM_CM33/secure/secure_reg_test_asm.h | 2 +- .../IAR/ARM_CM33/secure/secure_reg_test_asm.s | 2 +- .../Common/ARMv8M/tz_demo/nsc_functions.c | 116 +- .../Common/ARMv8M/tz_demo/nsc_functions.h | 100 +- FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.c | 266 +- FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.h | 88 +- FreeRTOS/Demo/Common/Full/BlockQ.c | 614 +- FreeRTOS/Demo/Common/Full/PollQ.c | 442 +- FreeRTOS/Demo/Common/Full/comtest.c | 700 +- FreeRTOS/Demo/Common/Full/death.c | 404 +- FreeRTOS/Demo/Common/Full/dynamic.c | 1148 +-- FreeRTOS/Demo/Common/Full/events.c | 736 +- FreeRTOS/Demo/Common/Full/flash.c | 252 +- FreeRTOS/Demo/Common/Full/flop.c | 658 +- FreeRTOS/Demo/Common/Full/integer.c | 650 +- FreeRTOS/Demo/Common/Full/print.c | 206 +- FreeRTOS/Demo/Common/Full/semtest.c | 570 +- FreeRTOS/Demo/Common/Minimal/AbortDelay.c | 1598 ++-- FreeRTOS/Demo/Common/Minimal/BlockQ.c | 612 +- .../Demo/Common/Minimal/EventGroupsDemo.c | 2116 ++--- FreeRTOS/Demo/Common/Minimal/GenQTest.c | 2078 ++--- FreeRTOS/Demo/Common/Minimal/IntQueue.c | 1482 ++-- FreeRTOS/Demo/Common/Minimal/IntSemTest.c | 1060 +-- .../Demo/Common/Minimal/MessageBufferAMP.c | 656 +- .../Demo/Common/Minimal/MessageBufferDemo.c | 1942 ++--- FreeRTOS/Demo/Common/Minimal/PollQ.c | 444 +- FreeRTOS/Demo/Common/Minimal/QPeek.c | 880 +-- FreeRTOS/Demo/Common/Minimal/QueueOverwrite.c | 470 +- FreeRTOS/Demo/Common/Minimal/QueueSet.c | 2320 +++--- .../Demo/Common/Minimal/QueueSetPolling.c | 364 +- .../Demo/Common/Minimal/StaticAllocation.c | 2226 +++--- .../Demo/Common/Minimal/StreamBufferDemo.c | 2494 +++--- .../Common/Minimal/StreamBufferInterrupt.c | 456 +- FreeRTOS/Demo/Common/Minimal/TaskNotify.c | 1440 ++-- .../Demo/Common/Minimal/TaskNotifyArray.c | 6 +- FreeRTOS/Demo/Common/Minimal/TimerDemo.c | 2448 +++--- FreeRTOS/Demo/Common/Minimal/blocktim.c | 6 +- FreeRTOS/Demo/Common/Minimal/comtest.c | 530 +- .../Demo/Common/Minimal/comtest_strings.c | 632 +- FreeRTOS/Demo/Common/Minimal/countsem.c | 580 +- FreeRTOS/Demo/Common/Minimal/crflash.c | 436 +- FreeRTOS/Demo/Common/Minimal/crhook.c | 472 +- FreeRTOS/Demo/Common/Minimal/death.c | 400 +- FreeRTOS/Demo/Common/Minimal/dynamic.c | 976 +-- FreeRTOS/Demo/Common/Minimal/flash.c | 234 +- FreeRTOS/Demo/Common/Minimal/flash_timer.c | 190 +- FreeRTOS/Demo/Common/Minimal/flop.c | 692 +- FreeRTOS/Demo/Common/Minimal/integer.c | 322 +- FreeRTOS/Demo/Common/Minimal/readme.txt | 2 +- FreeRTOS/Demo/Common/Minimal/recmutex.c | 822 +- FreeRTOS/Demo/Common/Minimal/semtest.c | 542 +- FreeRTOS/Demo/Common/Minimal/sp_flop.c | 648 +- FreeRTOS/Demo/Common/ReadMe.txt | 26 +- FreeRTOS/Demo/Common/include/AbortDelay.h | 66 +- FreeRTOS/Demo/Common/include/BlockQ.h | 66 +- .../Demo/Common/include/EventGroupsDemo.h | 84 +- FreeRTOS/Demo/Common/include/GenQTest.h | 68 +- FreeRTOS/Demo/Common/include/IntQueue.h | 70 +- FreeRTOS/Demo/Common/include/IntSemTest.h | 68 +- .../Demo/Common/include/MessageBufferAMP.h | 68 +- .../Demo/Common/include/MessageBufferDemo.h | 66 +- FreeRTOS/Demo/Common/include/PollQ.h | 66 +- FreeRTOS/Demo/Common/include/QPeek.h | 66 +- FreeRTOS/Demo/Common/include/QueueOverwrite.h | 68 +- FreeRTOS/Demo/Common/include/QueueSet.h | 68 +- .../Demo/Common/include/QueueSetPolling.h | 68 +- .../Demo/Common/include/StaticAllocation.h | 66 +- .../Demo/Common/include/StreamBufferDemo.h | 68 +- .../Common/include/StreamBufferInterrupt.h | 68 +- FreeRTOS/Demo/Common/include/TaskNotify.h | 68 +- .../Demo/Common/include/TaskNotifyArray.h | 2 +- FreeRTOS/Demo/Common/include/TimerDemo.h | 86 +- FreeRTOS/Demo/Common/include/blocktim.h | 66 +- FreeRTOS/Demo/Common/include/comtest.h | 78 +- FreeRTOS/Demo/Common/include/comtest2.h | 70 +- .../Demo/Common/include/comtest_strings.h | 70 +- FreeRTOS/Demo/Common/include/countsem.h | 66 +- FreeRTOS/Demo/Common/include/crflash.h | 90 +- FreeRTOS/Demo/Common/include/crhook.h | 82 +- FreeRTOS/Demo/Common/include/death.h | 66 +- FreeRTOS/Demo/Common/include/dynamic.h | 66 +- FreeRTOS/Demo/Common/include/fileIO.h | 70 +- FreeRTOS/Demo/Common/include/flash.h | 64 +- FreeRTOS/Demo/Common/include/flash_timer.h | 80 +- FreeRTOS/Demo/Common/include/flop.h | 66 +- FreeRTOS/Demo/Common/include/integer.h | 66 +- FreeRTOS/Demo/Common/include/mevents.h | 66 +- FreeRTOS/Demo/Common/include/partest.h | 74 +- FreeRTOS/Demo/Common/include/print.h | 68 +- FreeRTOS/Demo/Common/include/recmutex.h | 66 +- FreeRTOS/Demo/Common/include/semtest.h | 66 +- FreeRTOS/Demo/Common/include/serial.h | 216 +- FreeRTOS/License/license.txt | 74 +- FreeRTOS/Test/CBMC/README.md | 2 +- ...reertos_ip_verification_access_ip_define.h | 26 + ...ertos_tcp_verification_access_tcp_define.h | 26 + FreeRTOS/Test/CBMC/include/cbmc.h | 26 + FreeRTOS/Test/CBMC/include/portmacro.h | 2 +- FreeRTOS/Test/CBMC/include/queue_init.h | 26 + FreeRTOS/Test/CBMC/include/tasksStubs.h | 26 + FreeRTOS/Test/CBMC/patches/FreeRTOSConfig.h | 2 +- FreeRTOS/Test/CBMC/patches/FreeRTOSIPConfig.h | 5 +- FreeRTOS/Test/CBMC/patches/compute_patch.py | 2 +- .../Test/CBMC/patches/patches_constants.py | 2 +- FreeRTOS/Test/CBMC/patches/unpatch.py | 2 +- .../CBMC/proofs/CBMCStubLibrary/tasksStubs.c | 26 + .../Makefile.json | 2 +- .../QueueCreateCountingSemaphore_harness.c | 38 +- .../Makefile.json | 2 +- ...eueCreateCountingSemaphoreStatic_harness.c | 38 +- .../README.md | 2 +- .../Queue/QueueCreateMutex/Makefile.json | 2 +- .../QueueCreateMutex_harness.c | 38 +- .../QueueCreateMutexStatic/Makefile.json | 2 +- .../QueueCreateMutexStatic_harness.c | 38 +- .../QueueGenericCreate/Configurations.json | 2 +- .../QueueGenericCreate_harness.c | 38 +- .../Configurations.json | 2 +- .../QueueGenericCreateStatic_harness.c | 38 +- .../Queue/QueueGenericReset/Makefile.json | 2 +- .../QueueGenericReset_harness.c | 38 +- .../QueueGenericSend/Configurations.json | 2 +- .../QueueGenericSend_harness.c | 40 +- .../Configurations.json | 2 +- .../QueueGenericSendFromISR_harness.c | 38 +- .../Queue/QueueGetMutexHolder/Makefile.json | 2 +- .../QueueGetMutexHolder_harness.c | 38 +- .../QueueGetMutexHolderFromISR/Makefile.json | 2 +- .../QueueGetMutexHolderFromISR_harness.c | 38 +- .../QueueGiveFromISR/Configurations.json | 2 +- .../QueueGiveFromISR_harness.c | 38 +- .../QueueGiveMutexRecursive/Makefile.json | 2 +- .../QueueGiveMutexRecursive_harness.c | 38 +- .../Queue/QueueMessagesWaiting/Makefile.json | 2 +- .../QueueMessagesWaiting_harness.c | 38 +- .../Queue/QueueMessagesWaiting/README.md | 2 +- .../CBMC/proofs/Queue/QueuePeek/Makefile.json | 2 +- .../Queue/QueuePeek/QueuePeek_harness.c | 38 +- .../proofs/Queue/QueueReceive/Makefile.json | 2 +- .../Queue/QueueReceive/QueueReceive_harness.c | 38 +- .../Queue/QueueReceiveFromISR/Makefile.json | 2 +- .../QueueReceiveFromISR_harness.c | 38 +- .../Queue/QueueSemaphoreTake/Makefile.json | 2 +- .../QueueSemaphoreTake_harness.c | 38 +- .../Queue/QueueSpacesAvailable/Makefile.json | 2 +- .../QueueSpacesAvailable_harness.c | 38 +- .../QueueTakeMutexRecursive/Makefile.json | 2 +- .../QueueTakeMutexRecursive_harness.c | 38 +- .../prvCopyDataToQueue/Configurations.json | 2 +- .../proofs/Queue/prvCopyDataToQueue/README.md | 2 +- .../prvCopyDataToQueue_harness.c | 38 +- .../Configurations.json | 2 +- .../prvNotifyQueueSetContainer/README.md | 4 +- .../prvNotifyQueueSetContainer_harness.c | 38 +- .../Queue/prvUnlockQueue/Configurations.json | 2 +- .../prvUnlockQueue/prvUnlockQueue_harness.c | 38 +- .../Task/TaskCheckForTimeOut/Makefile.json | 2 +- .../TaskCheckForTimeOut_harness.c | 38 +- .../tasks_test_access_functions.h | 38 +- .../CBMC/proofs/Task/TaskCreate/Makefile.json | 2 +- .../Task/TaskCreate/TaskCreate_harness.c | 2 +- .../TaskCreate/tasks_test_access_functions.h | 38 +- .../proofs/Task/TaskDelay/Configurations.json | 2 +- .../proofs/Task/TaskDelay/TaskDelay_harness.c | 38 +- .../TaskDelay/tasks_test_access_functions.h | 38 +- .../CBMC/proofs/Task/TaskDelete/Makefile.json | 2 +- .../Task/TaskDelete/TaskDelete_harness.c | 38 +- .../TaskDelete/tasks_test_access_functions.h | 38 +- .../TaskGetCurrentTaskHandle/Makefile.json | 2 +- .../TaskGetCurrentTaskHandle_harness.c | 38 +- .../tasks_test_access_functions.h | 38 +- .../Task/TaskGetSchedulerState/Makefile.json | 2 +- .../TaskGetSchedulerState_harness.c | 38 +- .../tasks_test_access_functions.h | 38 +- .../Task/TaskGetTaskNumber/Makefile.json | 2 +- .../TaskGetTaskNumber_harness.c | 38 +- .../tasks_test_access_functions.h | 38 +- .../Task/TaskGetTickCount/Makefile.json | 2 +- .../TaskGetTickCount_harness.c | 38 +- .../TaskIncrementTick/Configurations.json | 2 +- .../TaskIncrementTick_harness.c | 38 +- .../tasks_test_access_functions.h | 2 +- .../proofs/Task/TaskPrioritySet/Makefile.json | 2 +- .../TaskPrioritySet/TaskPrioritySet_harness.c | 38 +- .../tasks_test_access_functions.h | 38 +- .../Task/TaskResumeAll/Configurations.json | 2 +- .../TaskResumeAll/TaskResumeAll_harness.c | 38 +- .../tasks_test_access_functions.h | 38 +- .../Task/TaskSetTimeOutState/Makefile.json | 2 +- .../TaskSetTimeOutState_harness.c | 38 +- .../Task/TaskStartScheduler/Makefile.json | 2 +- .../TaskStartScheduler_harness.c | 38 +- .../tasks_test_access_functions.h | 2 +- .../proofs/Task/TaskSuspendAll/Makefile.json | 2 +- .../TaskSuspendAll/TaskSuspendAll_harness.c | 38 +- .../Task/TaskSwitchContext/Makefile.json | 2 +- .../TaskSwitchContext_harness.c | 38 +- .../tasks_test_access_functions.h | 38 +- .../Test/CBMC/proofs/make_cbmc_batch_files.py | 2 +- .../Test/CBMC/proofs/make_common_makefile.py | 2 +- .../proofs/make_configuration_directories.py | 2 +- .../Test/CBMC/proofs/make_proof_makefiles.py | 2 +- .../Test/CBMC/proofs/make_remove_makefiles.py | 2 +- .../CBMC/proofs/make_type_header_files.py | 2 +- FreeRTOS/Test/CBMC/proofs/prepare.py | 2 +- .../CBMC/proofs/utility/memory_assignments.c | 26 + FreeRTOS/Test/CMock/config/FreeRTOSConfig.h | 2 +- FreeRTOS/Test/CMock/config/fake_assert.h | 2 +- FreeRTOS/Test/CMock/config/fake_port.h | 2 +- FreeRTOS/Test/CMock/config/portmacro.h | 2 +- FreeRTOS/Test/CMock/event_groups/Makefile | 4 +- .../CMock/event_groups/event_groups_utest.c | 2 +- .../Test/CMock/event_groups/list_macros.h | 2 +- FreeRTOS/Test/CMock/list/Makefile | 4 +- FreeRTOS/Test/CMock/list/list_utest.c | 4 +- .../message_buffer/message_buffer/Makefile | 4 +- .../message_buffer/message_buffer_utest.c | 2 +- .../size_mismatch/FreeRTOSConfig.h | 2 +- .../message_buffer/size_mismatch/Makefile | 4 +- .../size_mismatch/message_buffer_utest.c | 2 +- .../Test/CMock/queue/dynamic/FreeRTOSConfig.h | 2 +- FreeRTOS/Test/CMock/queue/dynamic/Makefile | 4 +- .../Test/CMock/queue/generic/FreeRTOSConfig.h | 2 +- FreeRTOS/Test/CMock/queue/generic/Makefile | 4 +- .../generic/queue_create_dynamic_utest.c | 6 +- .../queue/generic/queue_create_static_utest.c | 4 +- .../generic/queue_delete_dynamic_utest.c | 2 +- .../queue/generic/queue_delete_static_utest.c | 8 +- .../generic/queue_get_static_buffers_utest.c | 2 +- .../generic/queue_receive_blocking_utest.c | 2 +- .../generic/queue_receive_nonblocking_utest.c | 2 +- .../CMock/queue/generic/queue_reset_utest.c | 2 +- .../queue/generic/queue_send_blocking_utest.c | 2 +- .../generic/queue_send_nonblocking_utest.c | 10 +- .../CMock/queue/generic/queue_status_utest.c | 2 +- .../Test/CMock/queue/queue_utest_common.c | 2 +- .../Test/CMock/queue/queue_utest_common.h | 6 +- .../CMock/queue/semaphore/FreeRTOSConfig.h | 2 +- FreeRTOS/Test/CMock/queue/semaphore/Makefile | 4 +- .../queue/semaphore/binary_semaphore_utest.c | 4 +- .../semaphore/counting_semaphore_utest.c | 6 +- .../Test/CMock/queue/semaphore/mutex_utest.c | 4 +- .../queue/semaphore/recursive_mutex_utest.c | 2 +- .../queue/semaphore/semaphore_common_utest.c | 2 +- .../queue/semaphore/semaphore_create_utest.c | 2 +- .../semaphore_get_static_buffer_utest.c | 2 +- .../Test/CMock/queue/sets/FreeRTOSConfig.h | 2 +- FreeRTOS/Test/CMock/queue/sets/Makefile | 4 +- .../CMock/queue/sets/queue_in_set_utest.c | 4 +- .../Test/CMock/queue/sets/queue_set_utest.c | 2 +- .../sets/queue_unlock_cascaded_set_utest.c | 2 +- .../CMock/queue/sets/semaphore_in_set_utest.c | 4 +- .../Test/CMock/queue/static/FreeRTOSConfig.h | 2 +- FreeRTOS/Test/CMock/queue/static/Makefile | 4 +- FreeRTOS/Test/CMock/queue/td_port.c | 2 +- FreeRTOS/Test/CMock/queue/td_task.c | 2 +- .../Test/CMock/queue/tracing/FreeRTOSConfig.h | 2 +- FreeRTOS/Test/CMock/queue/tracing/Makefile | 4 +- .../queue/tracing/queue_registry_utest.c | 2 +- .../CMock/queue/tracing/queue_trace_utest.c | 2 +- .../CMock/stream_buffer/api/FreeRTOSConfig.h | 2 +- .../Test/CMock/stream_buffer/api/Makefile | 4 +- .../api/stream_buffer_api_utest.c | 8 +- .../stream_buffer/callback/FreeRTOSConfig.h | 2 +- .../CMock/stream_buffer/callback/Makefile | 4 +- .../callback/stream_buffer_callback_utest.c | 4 +- FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h | 2 +- FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h | 2 +- FreeRTOS/Test/CMock/tasks/global_vars.h | 24 +- FreeRTOS/Test/CMock/tasks/list_macros.h | 2 +- FreeRTOS/Test/CMock/tasks/tasks_1_utest.c | 64 +- FreeRTOS/Test/CMock/tasks/tasks_2_utest.c | 18 +- FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h | 2 +- .../CMock/timers/FreeRTOSConfig_dynamic.h | 2 +- FreeRTOS/Test/CMock/timers/global_vars.h | 2 +- FreeRTOS/Test/CMock/timers/list_macros.h | 2 +- FreeRTOS/Test/CMock/timers/timers_1_utest.c | 38 +- .../Test/CMock/timers/timers_dynamic_utest.c | 2 +- FreeRTOS/Test/CMock/tools/callgraph.py | 2 +- FreeRTOS/Test/CMock/tools/filtercov.py | 2 +- .../Test/Target/boards/pico/FreeRTOSConfig.h | 2 +- FreeRTOS/Test/Target/boards/pico/main.c | 246 +- .../multiple_tasks_running_test_runner.c | 152 +- .../multiple_tasks_running.c | 2 +- .../smp/multiple_tasks_running/test_config.h | 2 +- .../Target/tests/smp/template/test_config.h | 2 +- .../Target/tests/smp/template/test_name.c | 2 +- .../Test/VeriFast/include/proof/common.gh | 2 +- FreeRTOS/Test/VeriFast/include/proof/list.h | 2 +- FreeRTOS/Test/VeriFast/include/proof/queue.h | 2 +- .../VeriFast/include/proof/queuecontracts.h | 2 +- .../Test/VeriFast/list/listLIST_IS_EMPTY.c | 2 +- FreeRTOS/Test/VeriFast/list/uxListRemove.c | 2 +- FreeRTOS/Test/VeriFast/list/vListInitialise.c | 2 +- .../Test/VeriFast/list/vListInitialiseItem.c | 2 +- FreeRTOS/Test/VeriFast/list/vListInsert.c | 2 +- FreeRTOS/Test/VeriFast/list/vListInsertEnd.c | 2 +- FreeRTOS/Test/VeriFast/queue/create.c | 2 +- .../VeriFast/queue/prvCopyDataFromQueue.c | 2 +- .../Test/VeriFast/queue/prvCopyDataToQueue.c | 2 +- .../Test/VeriFast/queue/prvIsQueueEmpty.c | 2 +- FreeRTOS/Test/VeriFast/queue/prvIsQueueFull.c | 2 +- FreeRTOS/Test/VeriFast/queue/prvLockQueue.c | 2 +- FreeRTOS/Test/VeriFast/queue/prvUnlockQueue.c | 2 +- .../VeriFast/queue/uxQueueMessagesWaiting.c | 2 +- .../VeriFast/queue/uxQueueSpacesAvailable.c | 2 +- FreeRTOS/Test/VeriFast/queue/vQueueDelete.c | 2 +- .../Test/VeriFast/queue/xQueueGenericSend.c | 2 +- .../VeriFast/queue/xQueueGenericSendFromISR.c | 2 +- .../queue/xQueueIsQueueEmptyFromISR.c | 2 +- .../VeriFast/queue/xQueueIsQueueFullFromISR.c | 2 +- FreeRTOS/Test/VeriFast/queue/xQueuePeek.c | 2 +- .../Test/VeriFast/queue/xQueuePeekFromISR.c | 2 +- FreeRTOS/Test/VeriFast/queue/xQueueReceive.c | 2 +- .../VeriFast/queue/xQueueReceiveFromISR.c | 2 +- ...nks_to_doc_pages_for_the_demo_projects.url | 10 +- History.txt | 5788 +++++++------- Quick_Start_Guide.url | 10 +- cspell.config.yaml | 31 + lexicon.txt | 3845 ---------- manifest.yml | 15 +- .../CertificateConfigurator.html | 2 +- 1036 files changed, 134568 insertions(+), 127281 deletions(-) create mode 100644 .github/.cSpellWords.txt create mode 100644 .github/scripts/qemu_reader.c create mode 100644 .github/workflows/formatting.yml mode change 100755 => 100644 FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/CMSDK_CM3.h mode change 100755 => 100644 FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/FreeRTOSConfig.h mode change 100755 => 100644 FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/TCPEchoClient_SingleTasks.c create mode 100644 cspell.config.yaml delete mode 100644 lexicon.txt diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt new file mode 100644 index 000000000..c7fbf1e90 --- /dev/null +++ b/.github/.cSpellWords.txt @@ -0,0 +1,6150 @@ + +A +AADLENR +AAIC +AASR +AAVR +ABCDEFGHIJKLM +ABCDEFGHIJKLMNOPQRSTUVWXY +ABCDEFGHIJKLMNOPQRSTUVWYXZ +ABCSE +ABEF +ABETRG +ABOR +ABRQ +ABRT +ABRTB +ABRTE +ABRTL +ABSR +ABTO +ABTSZ +ACBLD +ACCAH +ACCAL +ACCAU +ACCBH +ACCBL +ACCBU +ACCOMPRESSION +ACCOOKIE +ACCWKEN +ACEN +ACESBLE +ACESR +ACFBSY +ACIN +ACKCICHAP +ACKCICHAR +ACKCILONG +ACKCILQR +ACKCISHORT +ACKER +ACLK +ACMD +ACMDCRC +ACMDEND +ACMDIDX +ACMDTEO +ACMEN +ACNAME +ACNS +ACON +ACPA +ACPC +ACPR +ACPU +ACSYS +ACTCMPAD +ACTCMPAU +ACTCMPBD +ACTCMPBU +ACTLR +ACTSS +ADCL +ADCP +ADCR +ADDAR +ADDCICHAP +ADDCICHAR +ADDCILONG +ADDCILQR +ADDEN +ADDR +ADDRH +ADDRL +ADGCEXCR +ADGCTRGR +ADGDR +ADGINTEN +ADHLMT +ADINT +ADINTEN +ADLLMT +ADLST +ADMA +ADOFS +ADON +ADRACK +ADRIVER +ADRSLT +ADSMS +ADTRADF +ADTRAUF +ADTRBDF +ADTRBUF +ADTRG +ADZCC +ADZCSTAT +AEEVT +AEIE +AERR +AESCCM +AESCMAC +AESNI +AESR +AFECR +AFIO +AFIR +AFMR +AFQP +AFSEL +AFSR +AHBENR +AHBPERIPH +AICREDIR +AICREDIRKEY +AIFADC +AIRC +AIRCR +AISE +AKIAIOSFODNN +ALDOM +ALDOW +ALDOY +ALGRTHM +ALHOUR +ALIE +ALLO +ALMIEN +ALMIN +ALMON +ALMV +ALOS +ALPHAR +ALRH +ALRL +ALSEC +ALYEAR +AMASK +AMBA +AMISC +AMRDOM +AMRDOY +AMRHOUR +AMRMIN +AMRMON +AMRSEC +AMRYEAR +AMSEL +AMUL +ANACH +ANAR +ANARBMCR +ANCEN +ANDC +ANDCCR +ANEG +ANEGA +ANEGC +ANEGCAPABLE +ANEGCOMP +ANEGCOMPLETE +ANEGF +ANENABLE +ANER +ANLPAR +ANLPNPAR +ANLPR +ANNPR +ANRESTART +ANSC +APBAHB +APCH +APCS +APIC +APINT +APLL +APMC +APOL +APPE +APPLIC +APROCFREQ +APSR +ARCCOEF +ARCDISPON +ARCHW +ARCON +ARCST +ARCVS +ARCVW +ARGR +ARIS +ARMA +ARMC +ARMCM +ARMEB +ARMR +ARMVFP +ARPE +ARPNR +ASCAFBH +ASCAFBL +ASCARBH +ASCARBL +ASCBFAH +ASCBFAL +ASCBRAH +ASCBRAL +ASCD +ASELCA +ASELCB +ASELCC +ASELCD +ASELCE +ASELCF +ASELCG +ASELCH +ASEN +ASET +ASGTRGAF +ASGTRGAR +ASGTRGBF +ASGTRGBR +ASGTRGCF +ASGTRGCR +ASGTRGDF +ASGTRGDR +ASPR +ASTE +ASTRINGZ +ASWTRG +ASYCINTR +ASYMM +ASYNCWKPENA +ATBID +ATCM +ATMEGA +ATMEL +ATPASTE +ATRAC +ATREADY +ATSAM +ATSAME +ATSHA +ATTL +ATUC +ATUCL +ATVALID +ATXMEGA +ATcmd +AUTOCL +AUTOIP +AUTONEGO +AUTORQ +AVBUF +AVRDX +AVRGNG +AWDCH +AWDEN +AWDENJ +AWDSGL +AXIMONITOR +AXIPMON +Aalok +Abeni +Aizca +Alexey +Ambrisko +Armv +Asyn +Ateml +Atmel +Autonego +Ayjrf +B +BABR +BABT +BADPREAMBEN +BANDL +BANKMD +BANKSWP +BASECLKF +BBGAIN +BBLK +BBOOL +BBOOST +BBSY +BCEN +BCERRE +BCERRI +BCERRIC +BCERRIS +BCFR +BCFT +BCKASTP +BCKP +BCLK +BCNT +BCNTCP +BCON +BCONFIG +BCONSTANT +BCONTROL +BCPB +BCPC +BCTRL +BCUT +BDCR +BDEV +BDEVTEST +BDEVTESTPARAM +BDFA +BDIA +BDPR +BDRST +BDTR +BEEVT +BEIC +BEIE +BEIM +BERIS +BERR +BESR +BFAR +BFARV +BFHFNMIGN +BFRX +BFSR +BFTX +BGAIN +BGCR +BGGAIN +BGHSIZE +BGLOAD +BGMON +BGPERI +BGRX +BGSYNC +BGVSIZE +BHILL +BIDIOE +BIDLE +BIPLR +BISR +BIST +BITSE +BKCHGINT +BKPT +BLENGTH +BLKE +BLKGE +BLKR +BLUEX +BMSR +BODDET +BODEN +BODIEN +BODRSTEN +BODRSTS +BODSTS +BODTH +BODWS +BOFFMSK +BOFST +BOOTAE +BOOTCR +BORF +BORIM +BORIOR +BORMIS +BORRIS +BORWT +BPDG +BRDRDY +BRGAIN +BRGR +BRPE +BRPR +BRSRCCLK +BRTB +BRTG +BRTR +BSCAFBH +BSCAFBL +BSCARBH +BSCARBL +BSCBFAH +BSCBFAL +BSCBRAH +BSCBRAL +BSELCA +BSELCB +BSELCC +BSELCD +BSELCE +BSELCF +BSELCG +BSELCH +BSFA +BSGTRGAF +BSGTRGAR +BSGTRGBF +BSGTRGBR +BSGTRGCF +BSGTRGCR +BSGTRGDF +BSGTRGDR +BSIA +BSLOPE +BSOFF +BSPI +BSRR +BSTATUS +BSTKE +BSTR +BSTW +BSWTRG +BSYENUM +BSYWR +BTABLE +BTCM +BTCR +BTSCR +BTSR +BTYP +BUFEXH +BUFFNA +BUFFRABLE +BUFNA +BUFWREN +BUMEN +BUSA +BUSFAULTSR +BUSP +BUSTKE +BUSW +BWRRDY +BWTR +Bbuild +Bernd +Bfail +Bfails +Bgkqhki +Bgza +Bhargavan +Biagioni +Biplr +Blox +Bufferx +C +CACE +CACHEDTY +CACHEP +CACR +CAECINT +CAEIM +CAERIS +CAEVT +CALCR +CALIB +CALIBRTN +CALN +CALP +CAMCINT +CAMEN +CAMIM +CAMR +CAMRIS +CANEN +CANMCR +CANMSR +CANPS +CANRX +CANTX +CAPAB +CARRIERSENCE +CASR +CASTAGNOLI +CATM +CBECINT +CBEIE +CBEIF +CBEIM +CBERIS +CBFF +CBGGAIN +CBIO +CBMC +CBMCINT +CBMIM +CBMMIS +CBMR +CBMRIS +CBOFST +CBOR +CBRGAIN +CBSCR +CBSISQA +CBSISQB +CCDMA +CCDS +CCER +CCHR +CCID +CCIE +CCIF +CCIR +CCIRERR +CCLK +CCLR +CCMP +CCMR +CCNT +CCNTR +CCOUNT +CCPN +CCPR +CCRCFAIL +CCRE +CCRX +CCTL +CDADC +CDBA +CDCFM +CDDMA +CDEE +CDFEC +CDGPIO +CDGPT +CDINTC +CDMINIBUS +CDPIT +CDPORTS +CDPWM +CDQSPI +CDRIVER +CDSTDIB +CDTMR +CDTY +CDTYR +CDTYUPDR +CDUART +CDUP +CDUS +CDUSB +CEATA +CEATAEND +CEATAIT +CECR +CEDRXS +CEIB +CENB +CENFX +CENTX +CEREG +CEXCEPTION +CFBS +CFCE +CFCS +CFGPP +CFGR +CFLUFX +CFLUTX +CFMCLKD +CFMDACC +CFMMCR +CFMSACC +CFMSACCcarm +CFRC +CFRNW +CFRZ +CFSR +CFUN +CG +CGCR +CGMI +CGMM +CGMR +CGP +CGSN +CHANN +CHBUF +CHCTL +CHDIV +CHDR +CHECKSUMOFFLAOD +CHGEOCIN +CHKDSK +CHLEN +CHNB +CHNCFG +CHNL +CHNLS +CHRL +CHSR +CICR +CIIR +CIMI +CINODE +CINS +CINT +CINV +CIPALR +CIPR +CISR +CIWR +CKAF +CKDIS +CKDIV +CKEN +CKEY +CKGR +CKHSUMS +CKKB +CKKG +CKKR +CKLO +CKNEN +CKON +CKOSCSEL +CKPLL +CKPOL +CKPS +CKRDY +CKRTC +CKRTCOK +CKRTCSEL +CKSEL +CKSYS +CKTIM +CKUSB +CKUSBSEL +CLCD +CLDIV +CLENR +CLIM +CLK +CLKA +CLKB +CLKCR +CLKEN +CLKGSEL +CLKI +CLKP +CLKPR +CLKPS +CLKRQ +CLKS +CLKSR +CLKSTA +CLKVCLR +CLMIS +CLNF +CLRAN +CLRAS +CLRB +CLRDD +CLRDT +CLREX +CLRF +CLRH +CLRIS +CLRL +CLRNQ +CLRPERR +CLRPSW +CLRQS +CLRTA +CLRTC +CLRTE +CLRTF +CLRTG +CLRTH +CLRTI +CLRTJ +CLRTSTAT +CLRUA +CLRUB +CLRUC +CLRWP +CLRZCAL +CLTTO +CLUTFORM +CLUTINT +CMAC +CMAR +CMCNT +CMCON +CMCOR +CMCR +CMDC +CMDCCEN +CMDICEN +CMDINHC +CMDINHD +CMDLL +CMDNB +CMDRDY +CMDTEO +CMIE +CMNWP +CMOCK +CMOS +CMPAIE +CMPAUPD +CMPB +CMPBIE +CMPBUPD +CMPEN +CMPR +CMSDK +CMSE +CMSIS +CMSK +CMSTR +CMTY +CMTYP +CMock +CNBTR +CNDA +CNDTR +CNTALOAD +CNTAMAX +CNTBLOAD +CNTE +CNTH +CNVP +CODAN +CODR +COEVT +COL +COLEN +COLR +COMPA +COMPB +COMPBE +COMPC +COMPE +COMT +CONFG +CONTB +CONTG +CONTROLC +CORHR +CORTEXR +CORTUS +COSR +COTHR +COVFS +CPACR +CPALR +CPAR +CPAS +CPBS +CPCBUF +CPCCACHE +CPCDIS +CPCPRIV +CPCS +CPCSTOP +CPCTRG +CPDI +CPHA +CPIN +CPINREADY +CPIV +CPRD +CPRDR +CPRDUPDR +CPRE +CPSDVSR +CPSM +CPSR +CPTQP +CPTWK +CPUID +CRBGAIN +CRCB +CRCCU +CRCER +CRCPR +CRCS +CREM +CRGFLG +CRGGAIN +CRGINT +CROFF +CROFST +CRRGAIN +CRSDV +CRSM +CRSR +CRTV +CRVAL +CRXDSA +CRYOSC +CRYP +CSAAT +CSAR +CSCAFBH +CSCAFBL +CSCARBH +CSCARBL +CSCBFAH +CSCBFAL +CSCBRAH +CSCBRAL +CSDK +CSEL +CSELCA +CSELCB +CSELCC +CSELCD +CSELCE +CSELCF +CSELCG +CSELCH +CSEN +CSERR +CSFTRST +CSGTRGAF +CSGTRGAR +CSGTRGBF +CSGTRGBR +CSGTRGCF +CSGTRGCR +CSGTRGDF +CSGTRGDR +CSINDICATE +CSIV +CSMC +CSMR +CSNAAT +CSNET +CSPR +CSPSR +CSRH +CSRL +CSRS +CSSON +CSTRT +CSTS +CSUDMA +CSUS +CTCR +CTCRST +CTRLA +CTRR +CTSIC +CTST +CTSX +CTTEST +CUBC +CUPD +CUPDR +CURBK +CWCR +CWGR +CWRI +CWSR +CWTA +CWTAVAL +CWTIF +CWUF +CYGNAL +Cbmc +Centralised +Chth +Cmock +Cndc +Cnpb +Cnpbfi +Coverity +Cp +Cplt +Cpsif +Cpsms +Crccu +Cristian +Crypotki +Ctrlb +Cuiz +D +DAASW +DAASWCR +DACC +DACCVIOL +DACL +DADR +DAIF +DAIFCLR +DAIFSET +DAOV +DASA +DATAA +DATAB +DATAIC +DATAL +DATAM +DATAR +DATARIS +DATATGL +DATATX +DATAVMATCH +DATAW +DATAX +DATNB +DATRDY +DATTEO +DBCKEND +DBCTL +DBCTLUPD +DBGC +DBGMCU +DBGU +DBLI +DBOARD +DBPUC +DBRISE +DBRISEUPD +DBRTECA +DBRTECB +DBWE +DCDIC +DCDR +DCDX +DCFGR +DCGC +DCHP +DCINVA +DCLK +DCMAKE +DCME +DCMF +DCMOCK +DCMR +DCOE +DCOMPILER +DCOUNT +DCOUNTER +DCPF +DCRCC +DCRCE +DCRCFAIL +DCRDR +DCRS +DCRSR +DCSIZ +DCTRL +DCTS +DDCD +DDCM +DDISABLE +DDLBYPMODE +DDONE +DDPI +DDRAN +DDRAS +DDRBUMCR +DDRC +DDRCPSU +DDRCS +DDRD +DDRDD +DDRE +DDRIVER +DDRNQ +DDRP +DDRPHY +DDRQS +DDRT +DDRTA +DDRTC +DDRTE +DDRTF +DDRTG +DDRTH +DDRTI +DDRTJ +DDRUA +DDRUB +DDRUC +DDSP +DDSR +DDSS +DDVDH +DDisable +DEAS +DEBUGEN +DEBUGF +DECNT +DECURRH +DECURRL +DEFFERRALCHECK +DEFMSTR +DEMCR +DERR +DESB +DESIZE +DESTH +DESTL +DEV +DEVAD +DEVDMANXTDSC +DEVEPTICR +DEVEPTIDR +DEVEPTIER +DEVEPTISR +DEVFNUM +DEVICR +DEVIDR +DEVIER +DEVISR +DFPU +DFREERTOS +DFRF +DFSR +DHCSR +DHLCK +DIBN +DIBP +DICR +DIDI +DIER +DIFSR +DINC +DIRH +DIRL +DISCNPERIOD +DISD +DISFPCA +DISMCYCINT +DISNYET +DISOOFP +DISTCPEF +DIVB +DIVH +DIVIDEBY +DIVIDEDBY +DIVL +DIVLD +DLAB +DLFWRDIS +DLHS +DLIR +DLIRCLR +DLIREN +DLISTST +DLKR +DLSTACT +DLYBCS +DLYBCT +DLYBS +DLYI +DMAARBITRATION +DMAB +DMABD +DMABMR +DMAC +DMACCARBR +DMACCARDR +DMACCARXBR +DMACCATBR +DMACCATDR +DMACCATXBR +DMACCR +DMACH +DMACHANS +DMACHDR +DMACHER +DMACHRDR +DMACHTBAR +DMACHTDR +DMACIER +DMACR +DMACRCR +DMACRDLAR +DMACRDRLR +DMACRDTPR +DMACRIWTR +DMACRXCR +DMACRXDLAR +DMACRXDTPR +DMACRXIWTR +DMACRXRLR +DMACSR +DMACTCR +DMACTDLAR +DMACTDRLR +DMACTDTPR +DMACTXCR +DMACTXDLAR +DMACTXRLR +DMADL +DMAE +DMAEOE +DMAIDR +DMAIER +DMAISR +DMAIT +DMAMFBOCR +DMAMR +DMANXTDSC +DMAOMR +DMAPTPRXDESC +DMAPTPTXDESC +DMAR +DMARDLAR +DMAREQC +DMARPDR +DMARSWTR +DMARXDESC +DMARXNDESCRF +DMARXNDESCWBF +DMASBMR +DMASR +DMATDLAR +DMATPDR +DMATXCDESC +DMATXDESC +DMATXNDESCWBF +DNDA +DNDEBUG +DNFB +DNVLAN +DOCOUNT +DOENDH +DOENDL +DOHIE +DOHIGH +DOIE +DOLOW +DOSTARTH +DOSTARTL +DOUT +DPDMA +DPER +DPFPU +DPIT +DPLB +DPLL +DPLX +DPOPM +DPPSR +DPSEL +DPSM +DPSW +DPUSHM +DRBS +DRCR +DRDLAT +DRDY +DREQ +DRESP +DRESULT +DRFCS +DRHIT +DRIM +DRISC +DRNG +DRPT +DRQFR +DRQFT +DRRIS +DRXD +DSBLCLKGTNG +DSCAFBH +DSCAFBL +DSCARBH +DSCARBL +DSCBFAH +DSCBFAL +DSCBRAH +DSCBRAL +DSCHG +DSCK +DSELCA +DSELCB +DSELCE +DSELCF +DSELCH +DSETLAT +DSGTRGAF +DSGTRGAR +DSGTRGBF +DSGTRGBR +DSGTRGCF +DSGTRGCR +DSGTRGDF +DSGTRGDR +DSLPCLKCFG +DSLPE +DSNACK +DSOC +DSPCLK +DSPCLKFREQ +DSPDC +DSPIC +DSPPRESET +DSRIC +DSRX +DSSC +DSTATUS +DSTCE +DSTCM +DSVC +DSWPAG +DSYSTEM +DTCADIBI +DTCIBR +DTCM +DTCN +DTCOR +DTCR +DTCSQE +DTDIR +DTGLE +DTIM +DTIMER +DTIN +DTIP +DTMODE +DTMR +DTOE +DTOUT +DTPMXTMR +DTREN +DTRR +DTUPDR +DTWE +DTXD +DTXMR +DUALF +DUID +DUNIT +DUNITY +DUPL +DUPLEXM +DVAR +DVDR +DVENDOR +DVLAN +DWHIT +DWIDTH +DWITH +DWRLAT +DWTENA +DZPQ +Ddrphy +Deglitchers +Deydw +Dimitri +Doesnt +Drbg +Dsppreset +Dstn +Dyty +E +EABI +EADTAL +EBERR +EBTLADA +EBTLADB +EBTLCA +EBTLCB +EBTLDVD +EBTLDVU +EBTLPR +ECCCR +ECCEN +ECCPR +ECCR +ECCSR +ECFGR +ECIT +ECKEN +ECKEY +ECLOSED +ECMD +ECONN +ECORR +ECRS +ECRSDV +ECRSFD +ECSD +EDBGRQ +EDCR +EDFE +EDID +EDMAC +EDRX +EDRXS +EEARH +EEARL +EECR +EECS +EEDI +EEDO +EEDR +EEPCR +EEPFCLK +EEPROM +EESK +EEVT +EEVTEDG +EEXT +EFFF +EFHPLM +EFRHD +EFRN +EFRS +EFRSH +EFRSL +EFTN +EFTP +EFTSH +EFTSL +EFUBAR +EFUSE +EHPD +EHPDIE +EIGEN +EIGRP +EIGTH +EIMR +EINT +EIPC +EIPG +EIPSW +EISTER +EISTR +EITCNT +EITLA +EITLB +EITLC +EITLD +EITLE +EITLF +EITLU +EITLV +EIVTC +EIVTT +EKHX +ELER +ELOR +EMACB +EMACPS +EMDC +EMDIO +EMICTRL +EMIO +EMPT +EMRBR +EMSG +EMUX +ENABL +ENARP +ENBSTOP +ENCMDCOMPL +ENDAD +ENDIANON +ENDIT +ENDOFRSM +ENDPT +ENDQP +ENDRX +ENDTX +ENDUAL +ENETRG +ENGC +ENHRXDESC +ENHTXDESC +ENIB +ENMFILE +ENOPKTS +ENPBPR +ENPEC +ENRXP +ENSRBADFAMILY +ENSRBADNAME +ENSRBADQUERY +ENSRBADRESP +ENSRCNAMELOOP +ENSRDESTRUCTION +ENSRFILE +ENSRFORMERR +ENSRNODATA +ENSRNOMEM +ENSRNOTIMP +ENSROF +ENSRQUERYDOMAINTOOLONG +ENSRREFUSED +ENSRSERVFAIL +ENTXP +ENUIR +ENUIRCLR +ENUIREN +EOICR +EORSM +EORSME +EORSMEC +EORSMS +EORST +EORSTC +EORSTE +EORSTEC +EORSTES +EOSI +EOSIE +EPASS +EPCIM +EPCISC +EPCRIS +EPDATA +EPDD +EPDDR +EPDISC +EPDR +EPEDS +EPEN +EPENDE +EPFR +EPHY +EPIDX +EPIE +EPIER +EPINT +EPORT +EPPA +EPPAR +EPPD +EPPDR +EPTCLRSTA +EPTCTLENB +EPTSETSTA +EPTSTA +EPTYPE +EPVF +EPWUE +EQCFG +EQIC +EQIF +EQMK +ERCAP +ERDRR +ERDSR +ERDWR +EREFCK +ERRA +ERRIDR +ERRISR +ERRMSK +ERRWRN +ERSTL +ERXCK +ERXDV +ERXER +ESMA +ESPA +ESRC +ESTAT +ESTATUS +ESVLAN +ETHE +ETHERC +ETHMACRX +ETHMACTX +ETIE +ETRCS +ETRF +ETRGEDG +ETRGS +ETSDR +ETXCK +ETXEN +ETXER +EUSP +EUST +EVBA +EVCEN +EVCOUNTER +EVCR +EVNTSTAR +EVNTSTOP +EWARM +EWARN +EWAVR +EWGF +EWPL +EWRL +EWRX +EWUP +EXCC +EXCOL +EXDEF +EXEDG +EXID +EXINT +EXRAMECAD +EXRAMMODE +EXRAMPRCR +EXTD +EXTDW +EXTI +EXTICR +EXTID +EXTOSC +EXTR +EXTRF +EXTRNL +EXTRSM +EXTW +EZPORT +Eccpr +Ecjuve +Edid +Edlinger +Edrx +Elektronika +Espeche +Espressif +Ettinger +Evnt +Exti +Exxx +F +FAAOCAQE +FADD +FARG +FASTWKUP +FATFS +FATSL +FAWMON +FBCLK +FBCS +FBDIV +FBEE +FBEIE +FBES +FBLDO +FBRD +FCAN +FCBBPA +FCHWR +FCIM +FCKR +FCLK +FCLWR +FCMD +FCMDE +FCMISC +FCOWR +FCRIS +FCSCR +FCSE +FDEN +FDIV +FDXFC +FECF +FEDPICC +FEIC +FEIM +FEMIS +FEMPT +FERIS +FERR +FESETERR +FESR +FFCR +FFDHE +FFDR +FFER +FFSR +FFULL +FGHIJKLMNOPQRSTUVWXYZ +FIDI +FIER +FIFOEN +FIFOIRQ +FILTR +FIPR +FIRSTRD +FIRSTWR +FLASH +FLASHPR +FLASHSZ +FLIST +FLITF +FLMRD +FLMSK +FLSH +FMCN +FMER +FMIS +FMPPE +FMPRE +FMRXNE +FMULTCLK +FMXR +FNTR +FNUM +FOLVA +FOLVB +FOOB +FOOBA +FOOBDA +FORCEFS +FORCEH +FORWARDALLEXCEPTPA +FOSC +FOVM +FOVR +FPCCR +FPCSR +FPEC +FPER +FPGAIO +FPOL +FPSW +FPUL +FRACN +FRACR +FRAMERX +FRATIO +FRBR +FRCESTALL +FRCRSTOUT +FRDM +FRDY +FREEN +FRMERR +FRMFILTER +FRMT +FROMISR +FRQAT +FRQBT +FRSR +FRTSC +FRZACK +FRZCLK +FSDCLK +FSDEN +FSDEV +FSEDGE +FSEOF +FSEOFG +FSESTRESSPARAM +FSETESTPARAM +FSIO +FSIOTEST +FSIOTESTPARAM +FSLEN +FSMC +FSOS +FSR +FSSTRESS +FSSTRESSPARAM +FSUACR +FTCP +FTEOCLK +FTSR +FUDUP +FUGF +FULLDPLX +FULLDUPLX +FVALUE +FWKUP +FWUP +FWUPDBC +FWUPEN +FWUPIS +FWUPS +FWUT +FXXX +Falseb +Ferreira +Fithb +Flsh +Freqhz +Frieder +Ftesting +G +GACC +GALR +GAMBLUT +GAMGAREA +GAMGVEN +GAMON +GAMRAREA +GAMRLUT +GAMRVEN +GAMSW +GARP +GASENB +GATEACCTLCLK +GATEACDDRCLK +GATEACRDCLK +GBGAIN +GBLHIBERNATIONEN +GBOFST +GBPS +GBUSERRADDR +GCACC +GCAL +GCFG +GCKCSS +GCMHR +GCONSTANT +GCTRL +GDBGFIFOSPACE +GDBGLTSSM +GDMA +GDOF +GDON +GENAUPD +GENB +GENBUPD +GETD +GEVNTADRHI +GEVNTADRLO +GEVNTSIZ +GGGAIN +GGHU +GGPIO +GHASH +GHASHR +GHWPARAMS +GIEH +GIEL +GIGE +GIRQ +GLBLUCAST +GLBSTATE +GLCONF +GMACSA +GMII +GMSK +GNURX +GOSLEEP +GOVRE +GPACR +GPBR +GPBRON +GPBRS +GPCS +GPIO +GPIOA +GPIOB +GPIOC +GPIOD +GPIOE +GPIOF +GPIOG +GPIOH +GPIOHSCTL +GPIOPS +GPNVM +GPRTBIMAP +GPRV +GPSL +GPSLCE +GPTA +GPTC +GPTCFORC +GPTDDR +GPTEN +GPTIE +GPTM +GPTOC +GPTPACNT +GPTPACTL +GPTPAFLG +GPTPR +GPTTOV +GRAPHX +GRCDISPON +GRCE +GRCHS +GRCHW +GRCVS +GRCVW +GREENX +GRGAIN +GROFST +GRPABH +GRPABL +GRWR +GRWS +GRXER +GSLOPE +GSNPSID +GSWF +GSWR +GSWS +GSWUTR +GTADSMR +GTAGEN +GTBFT +GTCLR +GTCSR +GTDNSR +GTEITC +GTEITLB +GTEITLI +GTICASR +GTICBSR +GTPR +GTPSR +GTSECR +GTSECSR +GTSFREQ +GTSSR +GTSTP +GTUDDTYC +GTUPSR +GTYPE +GUCTL +GWAC +Gaëtan +Gcbs +Genrator +Gherghina +Giveup +Gnomovision +Grec +Guanhua +H +HANDCSR +HASE +HASHDRBG +HASHH +HASHL +HAVEGE +HBERR +HBLANK +HBORDER +HCCA +HCKER +HCLK +HCLOCK +HCOUNT +HCRYPTPROV +HDFC +HDMIA +HDMIB +HDPP +HDRXEN +HDTO +HECC +HFAULT +HFNMIENA +HFPORCH +HFSR +HIMAXID +HIRD +HISI +HISP +HKDF +HLFCYA +HLMT +HLMTI +HLMTIE +HMATRIX +HMDL +HNPERRE +HNPERRI +HNPERRIC +HNPERRIS +HOLDPRESCTCS +HOSTCS +HOSTCSID +HOSTW +HOSTWR +HPCV +HPDC +HPLMN +HPOL +HPOLARITY +HPOUTR +HPOUTRZC +HPRE +HPRESC +HPTR +HRBAP +HRDAP +HRES +HRESP +HRESPNOK +HSDIS +HSDPA +HSDPAHSUPA +HSDRAMC +HSEBYP +HSEN +HSEON +HSERDY +HSHA +HSHK +HSION +HSIRDY +HSITRIM +HSMC +HSMCCS +HSMCPMECC +HSMCREM +HSMODE +HSPDPRESET +HSREN +HSSEL +HSSUP +HSTDMANXTDSC +HSTFNUM +HSTICR +HSTIDR +HSTISR +HSTM +HSTPIPICR +HSTPIPIDR +HSTPIPINRQ +HSTPIPISR +HSUPA +HSYNC +HTBAP +HTDAP +HUNIQUE +HWADDRHINT +HWFC +HWHSH +HWORD +HWPARAMS +HWRD +HWREG +HWREGB +HWREGBITB +HWREGBITH +HWREGBITW +HWREGH +HWTYPE +HWVER +HYST +Hach +Hend +Hitach +Hplmn +Hpxdr +Hresp +Hsmc +I +IABR +IACCVIOL +IACK +IACKLPR +IACR +IADHR +IADLR +IADR +IADRSZ +IAID +IALR +IAPD +IAUR +IBCTLCH +IBCTLDACCORE +IBEC +IBECV +IBRD +IBUS +IBUSERR +IC +ICAIE +ICAP +ICAR +ICBIE +ICBR +ICCAVR +ICCBPR +ICCEOIR +ICCIAR +ICCICAR +ICCPMR +ICCR +ICCRPR +ICCRX +ICDIS +ICDIV +ICDS +ICEN +ICER +ICERST +ICFA +ICFB +ICFILTER +ICINVA +ICMLL +ICMPN +ICOC +ICPC +ICPR +ICPSC +ICSEL +ICSIZ +ICSR +ICSWRST +ICTR +IDCM +IDCR +IDDUID +IDFILTER +IDHW +IDIE +IDMASK +IDMON +IDMSK +IDPI +IDRPQ +IDRPQs +IDSEL +IDSP +IDTE +IDTI +IDTIC +IDTIS +IECR +IEDGA +IEDGB +IEHOST +IERPQ +IERR +IFARB +IFCMSK +IFCRQ +IFDA +IFDB +IFDR +IFER +IFLASH +IFLOCAL +IFLS +IFMSK +IFREMOTE +IFSR +IHCE +IHLCK +IICPS +IIEN +ILGCOMERR +ILKR +ILPDVSR +ILPR +IMCKFS +IMCKMODE +IMCR +IMDOM +IMDOW +IMDOY +IMEI +IMGBLDPARAM +IMHOUR +IMMIN +IMMON +IMPRE +IMPRECISERR +IMRH +IMRL +IMRPQ +IMSC +IMSCR +IMSEC +IMSI +IMYEAR +INACK +INACT +INAK +INCON +INCRX +INCTX +INDF +INDI +INDIS +INITFSMBYP +INITU +INMODE +INOD +INORDER +INPKT +INPOL +INRQ +INTCLKEN +INTCLKS +INTCMPAD +INTCMPAU +INTCMPBD +INTCMPBU +INTD +INTE +INTEGTESTEN +INTEN +INTENCLR +INTENSET +INTFRC +INTFRCH +INTFRCL +INTID +INTIT +INTOE +INTPMR +INTPND +INTPWM +INTQ +INTRNL +INTSR +INTTM +INVA +INVB +INVD +INVI +INVON +INVPC +IOCE +IOCF +IOCLR +IODEFINE +IODIR +IOFIM +IOFMIS +IOFRIS +IOLB +IOPIN +IOPLL +IORD +IORLW +IOSC +IOSCDIS +IOSCVER +IOSET +IOSPCMD +IOUSLCR +IOWAITDIS +IOWAITEN +IPALR +IPCB +IPCE +IPCO +IPCP +IPDSTRETCH +IPEN +IPGS +IPGSEN +IPHDR +IPHE +IPIF +IPLB +IPLLMNR +IPNAME +IPPE +IPPT +IPRH +IPRL +IPRX +IPSBMT +IPSR +IPTCP +IPUDP +IPUPD +IPUT +IRAM +IREGION +IRET +IRLR +IROM +IRQCTL +IRQEN +IRQOUT +IRXER +IRXFCS +ISCK +ISDVI +ISEL +ISER +ISHEXDIGIT +ISHEXDIGITL +ISHEXDIGITU +ISLAN +ISLR +ISOC +ISOUP +ISPR +ISR's +ISRAM +ISRPENDING +ISRPQ +ISRPREEMPT +ISRR +ISRS +ISRTICK +ISTR +ITATBCTR +ITCR +ITCTRL +ITDT +ITEN +ITERR +ITIF +ITIP +ITMC +ITMENA +ITMK +ITOP +IVLTV +IVTIR +IWDG +IWDGRST +Imgbld +Imsi +Itapdly +J +JABBR +JAUTO +JDISCEN +JECH +JEOC +JEXTSEL +JEXTTRIG +JFCH +JFRAME +JITP +JITR +JJJJJJJK +JJJJJJJKKKKKKK +JJJJKKKK +JJKKJJKK +JKJKJKJK +JKKKKKKK +JNCH +JOFR +JSQR +JSWSTRT +JTAG +JTRST +JTVIC +João +Jundrovska +K +KBYP +KByte +KEEPON +KEYEN +KEYR +KEYW +KEYWR +KIDR +KIMR +KKPR +KKRR +KRCR +KRDY +Kamil +Karliner +Karthikeyan +Kbyte +Kcdef +Kced +Keepon +Krutmann +Kutr +L +LAPIC +LASTRD +LASTWR +LBACK +LBASE +LBRERROR +LBUF +LCARR +LCCHG +LCCWR +LCDC +LCDEDG +LCDR +LCDX +LCKD +LCKR +LCOL +LCRH +LCSR +LCTMR +LD +LDAB +LDAEX +LDAEXB +LDAEXH +LDAH +LDATA +LDBDIS +LDBSTOP +LDMFD +LDNXT +LDOARST +LDOIM +LDOMIS +LDONE +LDOPCTL +LDORIS +LDR +LDRA +LDRAS +LDRBS +LDRBT +LDREX +LDREXB +LDREXH +LDREXW +LDRHT +LDRNE +LDRT +LDST +LEDCR +LEDCRR +LEDS +LENCICBCP +LENCICHAP +LENCILONG +LENCILQR +LENTGH +LFER +LFERD +LFFE +LFHF +LFPS +LGRRS +LIACK +LIBSLIRP +LINBE +LINBK +LINBLS +LINCD +LINCE +LINFP +LINHTE +LINID +LINIPE +LINISFE +LINKCC +LINKR +LINSNRE +LJMP +LLHTTP +LLIO +LLMNR +LLMNRDNS +LLMNRI +LLMT +LLMTI +LLMTIE +LMPD +LMUTE +LNNUM +LNOFF +LOCEN +LOCKA +LOCKB +LOCKIE +LOCKUPRST +LOCRE +LOGD +LOGEN +LOLRE +LOOPBK +LOOPIF +LOPW +LOVRS +LOWBATEN +LOWTHRES +LP +LPACK +LPADAPTER +LPANEGA +LPBCK +LPBK +LPCB +LPCM +LPCR +LPDBC +LPDBCEN +LPDM +LPDONE +LPDR +LPDS +LPDWORD +LPEN +LPICR +LPIIE +LPMACK +LPMC +LPMD +LPNPA +LPOSC +LPOSCEN +LPOWFI +LPPACKET +LPPARAM +LPRWFI +LPTHREAD +LPWORD +LPWR +LPWRRST +LQOSEN +LRCK +LRCKP +LRCLK +LRCONT +LSBF +LSBTIR +LSCHG +LSDEV +LSEBYP +LSEOF +LSEOFG +LSEON +LSERDY +LSFTRST +LSION +LSIRDY +LSPEN +LSPENS +LSTATUS +LSUCNT +LSUEVTENA +LUBUFF +LUMA +LUYADD +LVDE +LVDF +LVDIE +LVDRE +LVDSE +LVECTORP +LVSTF +LVSTI +LVXADDF +LVXADDI +LVYADDF +LVYADDI +LVYXADDF +LWRD +Lauterbach +Lebel +Libslirp +Lkec +Lpback +Lpbck +M +MABT +MACA +MACAHR +MACB +MACCR +MACECR +MACFCR +MACHT +MACHTLR +MACISR +MACIT +MACL +MACMDIOAR +MACMDIODR +MACMIIAR +MACMIIDR +MACPCSR +MACPMTCSR +MACRFCR +MACRWKPFR +MACRWUFFR +MACSR +MACTFCR +MACVLANTR +MACWTR +MADD +MADRM +MAHTR +MAINF +MAINRDY +MAIR +MAMCR +MAMPCE +MAN +MANAG +MANCVALID +MAPD +MAPR +MARH +MARM +MASKH +MASKL +MAXBLKL +MAXFS +MAXFSSIZE +MAXMB +MAXRTX +MAXS +MBCR +MBED +MBEDTLSSL +MBFLAG +MBIR +MBISTJTAG +MBKEN +MBOOST +MBOX +MBSR +MBYP +MCACK +MCASTHASHEN +MCCDA +MCCDB +MCCK +MCCTRL +MCDA +MCDB +MCDIS +MCDIV +MCEN +MCFG +MCFHP +MCFR +MCICK +MCID +MCIEN +MCKA +MCKB +MCKO +MCKR +MCKRDY +MCLK +MCNO +MCNTR +MCOL +MCONTROL +MCOP +MCOS +MCSEL +MCSR +MCSWRST +MCU +MCUCR +MCUT +MCXLOGEN +MDCON +MDDI +MDDR +MDEN +MDER +MDII +MDINT +MDINTM +MDIO +MDIR +MDIS +MDIV +MDIVR +MDIX +MDLC +MDNS +MDRX +MDSR +MDTM +MDTX +MEDEMSR +MEM +MEMA +MEMFAULTSR +MEMP +MERASE +MFCR +MFID +MFPH +MFPL +MFPS +MFRX +MFTX +MGKPKTEN +MGKPRCVD +MGMNT +MGTRAVCC +MGTRAVTT +MIBC +MIC +MICR +MIDE +MIIAR +MIIMCTL +MIIMDAT +MIKROC +MIMR +MIMXRT +MINC +MISR +MISRA +MLAN +MMAR +MMARV +MMCCR +MMCIT +MMCR +MMCRFAECR +MMCRFAER +MMCRFCECR +MMCRGUFCR +MMCRIMR +MMCRIR +MMCS +MMCT +MMCTGFCR +MMCTGFMSCCR +MMCTGFSCCR +MMCTIMR +MMCTIR +MMCTS +MMERR +MMFAR +MMFR +MMFSR +MMIO +MMIS +MMMCRS +MMSYSERR +MNUM +MNXIA +MODEMCR +MODEMSR +MOFF +MOFIM +MOFMIS +MOFRIS +MOSC +MOSCCTL +MOSCDIS +MOSCEL +MOSCFAIL +MOSCPUPIM +MOSCPUPMIS +MOSCPUPRIS +MOSCRCF +MOSCS +MOSCVER +MOSI +MOTO +MOVF +MOVFF +MOVWF +MPARK +MPCORE +MPLAB +MPLL +MPOL +MPUCTRL +MQTT +MRCC +MRDY +MREAD +MREV +MRIS +MRRU +MRTR +MRXD +MSBF +MSDIS +MSEL +MSEN +MSI +MSOF +MSOFC +MSOFE +MSOFEC +MSOFES +MSOFS +MSPDEINIT +MSPINIT +MSPLIM +MSTA +MSTATUS +MSTKE +MSTP +MSTPA +MSTPCR +MSTPCRA +MSTPCRC +MSTR +MSTREN +MTCR +MTHREAD +MTIHEN +MTIOA +MTIOB +MTLRQOMR +MTLTQOMR +MTPR +MTXD +MULA +MULB +MUNSTKERR +MUPD +MUSTKE +MVFACGU +MVFACHI +MVFACLO +MVFACMI +MVFC +MVREG +MVTACGU +MVTACHI +MVTACLO +MVTC +MVTIPL +MXTD +MZEF +Mang +Maych +Mbits +Menie +Merkle +Metaharmoniks +Micrium +Mikro +Misra +Mockv +Mockx +Modif +Mosquitto +N +NACKEN +NAIAID +NAIS +NAKCICHAP +NAKCICHAR +NAKCILONG +NAKCILQR +NAKCISHORT +NAKEDEC +NAKIN +NAKLMT +NAKTO +NANDCS +NBDGM +NBIOT +NBKPR +NBKRL +NBLOCKS +NBNS +NCARR +NCFGR +NCKD +NCKDF +NCKDIE +NCLASSES +NCONFIG +NCPDT +NCPHA +NCSPULSERD +NCSPULSEWR +NCSSETUPRD +NCSSETUPWR +NDATAL +NDCACHE +NDEN +NDIS +NDISWAN +NEBP +NEVENTGROUP +NEWQP +NEWTX +NFCSA +NFCSB +NFIQ +NFRX +NFTX +NGYY +NIEN +NIOSII +NIRQ +NISE +NISR +NISTP +NISTR +NLGFX +NLST +NLVID +NMESSAGEBUFFER +NMUTEX +NOCAPTURE +NOCP +NOCPERR +NOCRC +NOCYCCNT +NODIVCLK +NOEXTTRIG +NOGIC +NONBASETHRDENA +NONOVR +NOPEN +NOPIDEVAD +NOPRFCNT +NORON +NORSRAM +NOSTRETCH +NOTRCPKT +NOTRDY +NOTSDMA +NPARITY +NPCS +NPEC +NPFIM +NPMODE +NQUEUE +NRDCYCLE +NRDPULSE +NRDSETUP +NRESET +NRGB +NRSTL +NRZVALID +NSACR +NSAIC +NSEMAPHORE +NSEN +NSFPU +NSPE +NSSR +NSTREAMBUFFER +NTASK +NTIMER +NTRI +NTRST +NUMH +NUML +NVAPR +NVDSIZ +NVIC +NVIEW +NVPSIZ +NVPTYP +NVWPAR +NWAIT +NWAITM +NWAYTEST +NWCFG +NWCTRL +NWDA +NWECYCLE +NWEPULSE +NWESETUP +NXP's +NYET +Nabto +Ndis +Ndzbbpmap +Netif +Nett +Nfontname +Ngan +Nios +Nmap +Npcap +Nullpuc +Nullpx +Nuvoton +Nxxx +Nxxxx +O +OABHF +OABLF +OADF +OADTY +OADTYF +OADTYR +OBCR +OBDF +OBDTY +OBDTYF +OBDTYR +OCAE +OCAIE +OCAR +OCBE +OCBIE +OCBR +OCFA +OCFAST +OCFB +OCFG +OCHR +OCLR +OCMP +OCMR +OCOEN +OCOSC +OCPRELOAD +OCTL +OCTRXH +OCTRXL +ODAT +ODATAR +ODSR +OEIC +OEIM +OEMIS +OERIS +OEVT +OEVTEN +OFFSSTRT +OFOC +OFRX +OFSM +OLER +OLOR +OLVLA +OLVLB +OMFC +OMOD +OMSOR +OMSSR +ONEMS +ONREAD +OOSEQ +OPAD +OPDCMD +OPMOD +OPMODE +OPTER +OPTIM +OPTIMISED +OPTKEYR +OPTPG +ORCCR +ORDERD +ORHI +ORLO +ORRI +OSAPITESTPARAM +OSCACDL +OSCADJ +OSCBYPASS +OSCCLK +OSCDIV +OSCEN +OSCOFF +OSCOUNT +OSCSEL +OSCSRC +OSCUPDH +OSCUPDL +OSIS +OSMC +OSSR +OSSUPDH +OSSUPDL +OSTC +OSTICK +OSTPE +OSTPF +OSTS +OTERR +OTGPADE +OTHI +OTLO +OUTA +OUTEN +OUTENCLR +OUTENSET +OVERFIEC +OVERUN +OVFLOW +OVFLW +OVLY +OVRCTRL +OVRE +OVRES +OVRIDR +OVRIER +OVRIMR +OVRISR +OVRNEXT +OVRUN +OWATCOM +OWDR +OWER +OWSR +Optiga +Otapdlysel +Outx +P +PACLK +PACNT +PACR +PADEN +PADFCFG +PADI +PADO +PADR +PAGEN +PAIF +PAKE +PALR +PAMOD +PAOVF +PAOVI +PARTNO +PASR +PATT +PAUR +PBKEN +PBORCTL +PCAD +PCAN +PCDR +PCEN +PCER +PCFDS +PCGE +PCHAR +PCIDR +PCIER +PCIMR +PCISR +PCKA +PCKB +PCKR +PCKT +PCLATH +PCLATU +PCLK +PCLKEN +PCLKSEL +PCMR +PCMSYNC +PCNTR +PCOMPRESSION +PCON +PCONP +PCPWM +PCRHR +PCRTC +PCSBP +PCSPI +PCSR +PCTIM +PCUART +PCXI +PDCEN +PDCFBYTE +PDCMODE +PDCOFF +PDCPADV +PDCS +PDDPAR +PDDS +PDECF +PDELAYREQ +PDELAYRESP +PDELAYRESPFOLLOWUP +PDIAID +PDISHDMAC +PDIVR +PDOWN +PDREQ +PDRESP +PDRESPFUP +PDRQFR +PDRQFT +PDRSFR +PDRSFT +PDSM +PDSR +PECEN +PECRQ +PEDGE +PEFRN +PEFRS +PEFRSH +PEFRSL +PEFTN +PEFTS +PEFTSH +PEFTSL +PEIC +PEIE +PEIM +PEMIS +PENDBC +PENDET +PENDSTCLR +PENDSV +PENDSVACT +PENDSVCLEAR +PENDSVCLR +PENDSVSET +PENSVCLEAR +PERCEPIO +PERFTRG +PERIODH +PERIODL +PERIPH +PEXCEPTION +PFBD +PFCH +PFLTACT +PFLTAEN +PFLTEN +PFLTSEN +PFNZ +PFRE +PFREEZEC +PFRX +PFRZ +PFTR +PFTX +PGCR +PGERR +PGMD +PGMEN +PHYA +PHYCR +PHYFRST +PHYID +PHYIE +PHYINTM +PHYRR +PIARC +PIBRB +PICNT +PICOLIBC +PIDE +PIDEVAD +PIDF +PIEN +PIIR +PIMR +PINB +PINC +PIND +PINH +PINL +PIOA +PIOB +PIOC +PISR +PITC +PITEN +PITIEN +PIVR +PKHBT +PKHTB +PKTIO +PLIB +PLLA +PLLACOUNT +PLLAR +PLLB +PLLBPL +PLLBR +PLLC +PLLE +PLLEN +PLLFIM +PLLFRIS +PLLFSMBYP +PLLLIM +PLLLMIS +PLLLRIS +PLLON +PLLR +PLLRDY +PLLXTPRE +PLONG +PMECR +PMEN +PMGCR +PMIC +PMISC +PMRKEY +PMSA +PMTIE +PMTIM +PMTS +PMUCTRL +PNDSV +PNQPAR +POBCTRL +POEGGA +POEGGB +POEGGC +POEGGD +POPNE +POPR +POPW +POR +PORF +PORRST +PORT +PORTA +PORTAN +PORTAS +PORTC +PORTD +PORTDD +PORTEN +PORTH +PORTNQ +PORTQS +PORTT +PORTTA +PORTTC +PORTTE +PORTTF +PORTTG +PORTTH +PORTTI +PORTTJ +PORTUA +PORTUB +PORTUC +POSCSR +POWCR +POWERUP +PPACKET +PPLLEN +PPMRC +PPMRH +PPMRL +PPMRS +PPOL +PPRE +PPRES +PPSR +PPUDR +PPUER +PPUSR +PQSPAR +PRADC +PRAS +PRCR +PRDEP +PRDIV +PRDY +PREA +PREAMB +PREB +PRESC +PRFMT +PRFTBS +PRIA +PRIS +PRIVDEFEN +PRKLAST +PRLH +PRLL +PRMS +PROCDLY +PRODH +PRODL +PROGE +PRPTC +PRSET +PRSPI +PRST +PRTCAP +PRTCAPDIR +PRTIM +PRTNO +PRTWI +PRTY +PSAUX +PSBATT +PSCAFBH +PSCAFBL +PSCARBH +PSCARBL +PSCBFAH +PSCBFAL +PSCBRAH +PSCBRAL +PSCCR +PSCCSR +PSCCTLR +PSCCTUR +PSCIMR +PSCMR +PSCNTR +PSCOPSET +PSCRB +PSCSICR +PSCSR +PSCTB +PSCTFAR +PSDDR +PSDDRPLL +PSEL +PSELCA +PSELCB +PSELCC +PSELCD +PSELCE +PSELCF +PSELCG +PSELCH +PSEP +PSGT +PSGTRGAF +PSGTRGAR +PSGTRGBF +PSGTRGBR +PSGTRGCF +PSGTRGCR +PSGTRGDF +PSGTRGDR +PSINTFP +PSINTLP +PSIO +PSLL +PSMAD +PSMCS +PSMCT +PSMDP +PSME +PSMHT +PSMR +PSMSettings +PSPLIM +PSPLL +PSRAM +PSRR +PSSI +PSTDBY +PSTS +PSVPAG +PSWAI +PSWRES +PTCPAR +PTCR +PTFPAR +PTINVALID +PTJPAR +PTLON +PTNEN +PTNSRCL +PTPFT +PTPMT +PTPP +PTPSSIR +PTPTSAR +PTPTSHR +PTPTSHUR +PTPTSLR +PTPTSLUR +PTPTTHR +PTPTTLR +PTPV +PTSR +PTSTR +PUDELAY +PULLD +PULLHILO +PUON +PUPT +PUSHNE +PUSHW +PVALEN +PVDE +PVDO +PVIE +PVIOL +PWAN +PWM +PWMC +PWMCAE +PWMCNT +PWMCTL +PWMDIV +PWMDTY +PWME +PWMEFLT +PWMENA +PWMESYNC +PWMFAULT +PWMI +PWMIR +PWMLER +PWMMCR +PWMMR +PWMO +PWMPC +PWMPCR +PWMPER +PWMPOL +PWMPR +PWMPRCLK +PWMSCLA +PWMSCLB +PWMSDN +PWMSEL +PWMTC +PWMTCR +PWMTYP +PWRCLK +PWRCLKN +PWRCLKP +PWRCLKPN +PWRCR +PWRCTRL +PWRDN +PWRDNPHY +PWRDNSCALE +PWRDWN +PWROPT +PWRSAV +PWSDIS +PWSDIV +PWSEN +Pedersen +Perc +Percepio +Picolibc +Picovolts +Pjiyp +Pkio +Pktio +Plmn +Pnpyim +Ppointer +Prioritised +Prokic +Psbatt +Psddrpll +Psgt +Pspll +Psreg +Pulpino +Q +QADD +QASX +QCCID +QCFG +QDLYR +QDPMC +QIND +QIOPEN +QIRD +QIURC +QP +QPSMS +QSAX +QSIMSTAT +QSPI +QSPIPSU +QSUB +Quectel +Qvpwa +Qwxh +R +RADJ +RAMPZ +RAMWU +RANEG +RASR +RAWRMDIS +RBAR +RBFALL +RBGAIN +RBIE +RBIT +RBOF +RBQB +RBQBAPQ +RBQG +RBQP +RBRISE +RBSRPQ +RBSY +RBSZ +RBUE +RBUIE +RBUS +RCALL +RCAP +RCCPSR +RCCR +RCCU +RCGC +RCIF +RCLK +RCMR +RCOMP +RCON +RCONSTANT +RCOUNT +RCRCE +RCSEL +RCTL +RCUC +RCVT +RCYC +RDAH +RDES +RDFMT +RDFS +RDHR +RDIE +RDIRE +RDLATENCY +RDLR +RDMODE +RDPROOF +RDPRT +RDPT +RDRF +RDSME +RDTR +RDUIEN +RDUIF +RDWUE +RDYY +READSR +RECR +RECV +REDFS +REDFSE +REDOSSERV +REDX +REDY +REENT +REGA +REGADR +REGCR +REGRDY +REJCICBCP +REJCICHAP +REJCILONG +REJCILQR +REJCISHORT +RELD +REMTE +RENABLE +RENB +RENDE +RENTRY +REQ +RERR +RERRCOUNTER +RESEN +RESETOP +RESETPS +RESVD +RESVDBIT +RETP +RETTO +RETTOBASE +RETUNETMR +REVB +REVC +REVID +REVSH +REWAKEUP +RFAE +RFAEC +RFAECR +RFAEM +RFAES +RFAULT +RFCE +RFCEC +RFCECR +RFCEM +RFCES +RFEIA +RFMR +RFOM +RFSH +RFSR +RGAIN +RGBX +RGGAIN +RGMII +RGMIICON +RGMIICTL +RGMIIDCTL +RGUF +RGUFC +RGUFCR +RGUFM +RGUFS +RIIC +RIMR +RINDE +RINMUTE +RIPL +RISR +RJFML +RLAR +RLCE +RLEEN +RLEPIXW +RLES +RLEX +RLOAD +RMCTL +RMDIS +RMDS +RMEN +RMII +RMIIEN +RMIIMII +RMTE +RMTEN +RMUTE +RMVER +RMWKUP +RMWUPE +RNCR +RNFR +RNGA +RNGABCINVA +RNGCR +RNGER +RNGSR +RNPR +RNTO +ROCR +RODATA +ROFF +ROFST +ROHS +ROIE +ROLEEXI +ROLEEXIC +ROLEEXIS +RORIC +RORIM +RORMIS +RORRIS +ROUSSET +ROVR +ROWEN +RPBL +RPCAP +RPLL +RPSF +RPSIE +RPSS +RQPKTCOUNT +RRDPSR +RREQ +RRGAIN +RSAES +RSAR +RSAS +RSASSA +RSCA +RSEG +RSERVED +RSHR +RSLCX +RSLOPE +RSMINPR +RSPR +RSRP +RSRQ +RSTA +RSTC +RSTEN +RSTEP +RSTIT +RSTN +RSTNACK +RSTR +RSTRX +RSTSTA +RSTTX +RSTW +RTACT +RTAR +RTCALF +RTCC +RTCCINT +RTCCR +RTCDF +RTCDR +RTCEN +RTCGOCL +RTCGOCNT +RTCGOCU +RTCIENR +RTCIM +RTCISR +RTCLD +RTCM +RTCPSU +RTCRIS +RTCSC +RTCT +RTCWEN +RTCWK +RTCWKEN +RTIC +RTIE +RTIF +RTIFRC +RTIM +RTIUDCP +RTMIS +RTMR +RTOE +RTOR +RTPR +RTRIS +RTSAS +RTSEN +RTSH +RTSL +RTSR +RTTAL +RTTC +RTTEN +RTTWK +RTTWKEN +RTVR +RVDS +RVMF +RWCMD +RWKFILTRST +RWKPFE +RWKPKTEN +RWKPRCVD +RWMOD +RWSTART +RWSTOP +RWTE +RWTIE +RWTS +RXACT +RXAK +RXALGNERPIM +RXALGNERR +RXALIGNCNT +RXBD +RXBEIEN +RXBEIF +RXBF +RXBMS +RXBP +RXBQBA +RXBRK +RXBROADCNT +RXBS +RXBUF +RXBUFF +RXBUFNB +RXBUFO +RXBYTECNT +RXCC +RXCHAR +RXCHKSUMEN +RXCHR +RXCK +RXCLK +RXCNT +RXCOEN +RXCOUNT +RXCR +RXCRCERPIM +RXCRCERR +RXCRCR +RXCSRH +RXCTR +RXDAVL +RXDBCTR +RXDESC +RXDIS +RXDMA +RXDMABURSTLENGTH +RXDMAE +RXDMON +RXDPKTBUFDIS +RXDSA +RXDTTR +RXDV +RXECHAR +RXECTR +RXEN +RXENA +RXER +RXERCR +RXERM +RXERR +RXFCLR +RXFCSCNT +RXFCTFC +RXFD +RXFDPR +RXFE +RXFEF +RXFF +RXFFF +RXFHBCR +RXFHSR +RXFIFOADD +RXFIFOCOUNTER +RXFIFOE +RXFIFOF +RXFIFOHF +RXFIFOSZ +RXFL +RXFLL +RXFPTEF +RXFTHF +RXFTHRES +RXFUNCADDR +RXFWIR +RXFWMFLL +RXGD +RXGDIEN +RXGMASK +RXHUBADDR +RXHUBPORT +RXIC +RXIDLEV +RXIE +RXIEN +RXIM +RXIN +RXINT +RXINTERRUPT +RXINTERVAL +RXINTM +RXIPCCNT +RXIRQ +RXIRQEN +RXIS +RXJABCNT +RXLENGTHCNT +RXLOOP +RXLPITRC +RXLPITRCIM +RXLPIUSC +RXLPIUSCIM +RXLPWKEN +RXMAXP +RXMIS +RXMONO +RXMULTICNT +RXNANOSEC +RXNCTR +RXNE +RXNEMP +RXNPTR +RXOFFS +RXOFLW +RXOK +RXON +RXOR +RXORCH +RXORCNT +RXORIRQ +RXORIRQEN +RXOVERR +RXOVERWRITE +RXOVR +RXOVRCNT +RXPAUSECNT +RXPOLLING +RXPRIORTX +RXPTR +RXQCR +RXRDY +RXRDYC +RXRDYM +RXRER +RXRESERRCNT +RXRIS +RXRSM +RXRST +RXRTS +RXSD +RXSE +RXSEC +RXSETUP +RXSR +RXST +RXSTALLDEC +RXSTSIE +RXSUSP +RXSYMBCNT +RXSYN +RXSYNH +RXTCPCCNT +RXTEN +RXTO +RXTX +RXTYPE +RXUBR +RXUCASTG +RXUCGPIM +RXUDPCCNT +RXUFLW +RXUNDRCNT +RXWIR +RXWLVL +RXWM +RXWRN +Rajbw +Rationalised +Raynald +Realtek +Remte +Renesas +Rfbo +Rndv +Rssi +Rsvd +Rxed +S +SACKP +SAIF +SAMB +SAMT +SARC +SARM +SARWATE +SASX +SBDAD +SBDAE +SBDCD +SBDCE +SBDDD +SBDDE +SBDPD +SBDPE +SBPR +SBYCR +SCALEA +SCALEB +SCALL +SCBR +SCDBUS +SCDR +SCDSEL +SCER +SCFGR +SCGC +SCIFSR +SCLH +SCLK +SCLL +SCLMD +SCLWS +SCLWSDIS +SCNTR +SCNTRS +SCOL +SCOUNT +SCSR +SCSV +SDBPWR +SDCC +SDCLKDRV +SDCLKEN +SDCLKFSEL +SDCR +SDIDCOUNT +SDIN +SDIO +SDIOEN +SDIOIRQA +SDIOIRQB +SDIOIRQC +SDIOIRQD +SDIOIT +SDIOSUSPEND +SDMA +SDMM +SDNEN +SDOUT +SDPS +SDRAMC +SDTV +SDXC +SECEV +SECP +SECU +SEGGER +SENDA +SEQR +SESREQ +SESSVLD +SETAN +SETAS +SETB +SETDD +SETEN +SETENDC +SETNQ +SETPSW +SETQS +SETR +SETTA +SETTE +SETTF +SETTG +SETTH +SETTI +SETTJ +SETUA +SETUB +SETUC +SEVONPEND +SFRBU +SFRC +SFTRST +SGMII +SH +SHADD +SHASX +SHCR +SHCSR +SHDW +SHDWEOF +SHLL +SHLR +SHMR +SHPR +SHSAX +SHSR +SHSUB +SHTIM +SICR +SIFIVE +SIGV +SIMR +SIOU +SIPL +SLAKI +SLBDIS +SLCKSEL +SLCR +SLCT +SLEWCTL +SLICEBY +SLIPIF +SLOTC +SLOTD +SMBDAM +SMBEN +SMBHHM +SMBTR +SMBUS +SMCR +SMDA +SMEMCPY +SMHH +SMIS +SMLAD +SMLADX +SMLALD +SMLSD +SMLSDX +SMLSLD +SMLSLDX +SMMLA +SMMU +SMNT +SMODE +SMPP +SMPR +SMUAD +SMUADX +SMUSD +SMUSDX +SNAPH +SNAPL +SNGLCOLLCNT +SNTP +SOBURST +SOCURRH +SOCURRL +SODR +SOFC +SOFCTLOAD +SOFE +SOFEC +SOFES +SOFITPSYNC +SOFS +SOFTIRQ +SOIC +SOSIZE +SOURCEH +SOURCEL +SPBYT +SPCCR +SPCK +SPCMD +SPCR +SPDR +SPEEDEN +SPEEDSL +SPEN +SPIE +SPIEN +SPIF +SPIFE +SPINT +SPNIDEN +SPPR +SPRNG +SPSEL +SPSR +SPTCR +SPTOR +SPTSR +SPUI +SQEI +SQTFRL +SRAMSZ +SRCA +SRCMP +SRCR +SRDBL +SREG +SRESEN +SREVISION +SRIS +SRPE +SRPI +SRPIC +SRPIS +SRSDB +SRST +SRTP +SRTSM +SSAR +SSAT +SSAX +SSBY +SSCAFBH +SSCAFBL +SSCARBH +SSCARBL +SSCBFAH +SSCBFAL +SSCBRAH +SSCBRAL +SSCTL +SSELCA +SSELCB +SSELCE +SSELCF +SSELCH +SSFIFO +SSGTRGAF +SSGTRGAR +SSGTRGBF +SSGTRGBR +SSGTRGCF +SSGTRGCR +SSGTRGDF +SSGTRGDR +SSIR +SSKEY +SSLV +SSMUX +SSNHF +SSOE +SSPCLKOUT +SSPCPSR +SSPCR +SSPDMACR +SSPDR +SSPICR +SSPMIS +SSPRI +SSPRIS +SSPRORINTR +SSPRTINTR +SSPRXINTR +SSPSR +SSPTXINTR +SSTD +STAC +STALLEN +STARTRIS +STARTTX +STBITERR +STBY +STCLR +STDB +STDBY +STICKCALVR +STICKCSR +STICKCVR +STICKRVR +STICKTENMS +STILM +STKALIGN +STKERR +STKPTR +STL +STLB +STLEX +STLEXB +STLEXH +STLH +STMICROELECTRONICS +STMODE +STMON +STOCH +STOCHPOSIXPARAM +STOE +STOIS +STOPF +STOPIC +STOPIM +STOPRIS +STOU +STPBGR +STPMD +STPNS +STPWP +STRBT +STREXB +STREXH +STREXW +STRHT +STRT +STRWP +STSS +STSSI +STTBRK +STTDLY +STTOUT +STTT +STTTO +SUB +SUPPR +SUPV +SUSPD +SUSPE +SUSPEC +SUSPES +SUSPND +SUSPS +SVACC +SVCA +SVDIS +SVLAN +SVMST +SWAPW +SWBOOT +SWEN +SWHSH +SWIACK +SWIER +SWINR +SWINT +SWINTR +SWIR +SWIT +SWMATCH +SWMR +SWOENA +SWREQ +SWRES +SWRESET +SWRST +SWRSTALL +SWRSTCMD +SWRSTDAT +SWSEN +SWSTRT +SWTRG +SWTRIG +SWTRIGR +SX +SXTAB +SXTB +SYBYPSR +SYMM +SYNCA +SYNCB +SYNCR +SYNMAXRTX +SYNSR +SYSC +SYSMONPSU +Sdmmc +Shengchao +Simons +Slirp +Snnn +Sntp +Sqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +Stellaris +Sten +Stoch +Streamx +Stub +Stubpuc +StubpucStuby +Stubuc +Stubux +Stubv +Stubx +Stuby +Submoduling +Sutzy +T +TAAMS +TACCR +TACCTL +TACLR +TACMR +TACTL +TACYC +TAEN +TAEVENT +TAGR +TAILR +TAILRH +TAILRL +TAMATCHR +TAMR +TAMRH +TAMRL +TAOTE +TAPMR +TAPR +TAPSMR +TAPSR +TAPWML +TARH +TARL +TASTALL +TATOCINT +TATOIM +TATOMIS +TATORIS +TBAMS +TBCMR +TBCTRL +TBEN +TBEVENT +TBFR +TBFT +TBILR +TBILRL +TBLPTRH +TBLPTRL +TBLPTRU +TBLPTRUH +TBLPTRUL +TBMATCHR +TBMR +TBMRL +TBOOST +TBOTE +TBPMR +TBPR +TBPSMR +TBPSR +TBPWML +TBQB +TBQBAPQ +TBQP +TBRL +TBSY +TBTOCINT +TBTOIM +TBTOMIS +TBTORIS +TBUE +TBUIE +TBUS +TCCR +TCKER +TCKPS +TCLK +TCLR +TCMR +TCMSSV +TCNT +TCOMP +TCONDE +TCONSTHA +TCONSTHB +TCONSTVA +TCONSTVB +TCONTIM +TCRE +TCSEL +TCSR +TCTL +TCUT +TDAR +TDES +TDESMOD +TDFEN +TDHR +TDLR +TDMFS +TDMI +TDMLJ +TDRE +TDSC +TDTR +TEAKCFG +TEMT +TENMS +TEOCLKF +TEOCLKU +TEOF +TESTFS +TESTJ +TESTK +TESTR +TESTSE +TESTSENDZLP +TEXCLADDR +TEXCLDATA +TEXCLOFST +TEXCLPX +TEXCLPY +TEXCLUT +TEXENA +TEXFILTX +TEXFILTY +TEXMSK +TEXUMSK +TEXVMSK +TFCE +TFFCA +TFLG +TFMR +TFWR +TGFC +TGFCR +TGFM +TGFMSC +TGFMSCC +TGFMSCCR +TGFMSCM +TGFMSCS +TGFS +TGFSC +TGFSCC +TGFSCCR +TGFSCM +TGFSCS +TGRA +THALT +THLD +THMASK +THMAX +THRES +TIAO +TICKISR +TIDM +TILDA +TIMFRZ +TIMI +TIMRPRE +TIMRTOT +TIMSK +TIOA +TIOB +TISUBN +TIXCLK +TJTIE +TJTS +TLDA +TLOWM +TLOWS +TMCSR +TMDS +TMIF +TMKAEN +TMKAIF +TMKAMK +TMLB +TMMK +TMODE +TMPR +TMRLR +TMXBFR +TNAMS +TNCMR +TNCR +TNFUL +TNMR +TNPMR +TNPR +TNPSMR +TNPSR +TNTMR +TOCLK +TOGGLESQ +TORST +TOSU +TOVF +TOVR +TPAL +TPASTE +TPBL +TPCS +TPFCP +TPFR +TPIE +TPIU +TPSF +TPSIE +TPSS +TPTR +TRACELCP +TRAPA +TRARECLENGTH +TRAS +TRCD +TRCMD +TRCMPAD +TRCMPAU +TRCMPBD +TRCMPBU +TRCNTLOAD +TRCNTZERO +TRCR +TRDIR +TRDLAT +TREFPRD +TREMOTE +TREQ +TRER +TRFC +TRGEN +TRGI +TRGMOD +TRGPER +TRGPSC +TRGR +TRGSEL +TRGTULST +TRIS +TRISE +TRNG +TRTYP +TSADC +TSALMIEN +TSARU +TSAV +TSCALIB +TSCTL +TSEN +TSENA +TSFCU +TSHLD +TSHR +TSHUR +TSIE +TSIEN +TSITE +TSLR +TSLUR +TSMODE +TSMR +TSON +TSPD +TSSC +TSSCTIM +TSSN +TSSS +TSSTI +TSSTU +TSTCNTA +TSTCNTB +TSTIM +TSTJ +TSTK +TSTP +TSTPCKT +TSTR +TSTS +TSUPNS +TSUS +TSUSS +TSYNC +TTCPS +TTGR +TTHR +TTLR +TTRIG +TTSAS +TTSE +TTSEN +TTSH +TTSL +TTSS +TUIE +TUND +TUNDR +TUNIGCOUNT +TUNINGSDR +TWCK +TWRLAT +TXACT +TXAK +TXBCCNT +TXBD +TXBEIEN +TXBEIF +TXBF +TXBFLL +TXBQBA +TXBUF +TXBUFE +TXBUFF +TXBUFNB +TXCACHE +TXCHR +TXCLK +TXCOEN +TXCOMP +TXCOMPL +TXCP +TXCPIEN +TXCR +TXCRCR +TXCSENSECNT +TXCSRH +TXCSRL +TXCTR +TXCTS +TXDATA +TXDAVL +TXDEFERCNT +TXDESC +TXDIS +TXDMA +TXDMABURSTLENGTH +TXDMAE +TXDPKTBUFDIS +TXDSA +TXECTR +TXEMPM +TXEMPTY +TXEN +TXENA +TXER +TXERM +TXERR +TXFCLR +TXFD +TXFDEF +TXFDPR +TXFE +TXFEF +TXFEMP +TXFF +TXFFF +TXFIFOADD +TXFIFOE +TXFIFOF +TXFIFOHE +TXFIFONOT +TXFIFOSZ +TXFL +TXFLL +TXFLOCK +TXFPTEF +TXFSTADDR +TXFTHF +TXFTHRES +TXFULL +TXFUNCADDR +TXFWMEMP +TXGO +TXGPKTIM +TXHIM +TXHPB +TXHUBADDR +TXHUBPORT +TXIC +TXIE +TXIEN +TXIF +TXIM +TXINTERVAL +TXIRQ +TXIRQEN +TXIS +TXKL +TXLPITRC +TXLPITRCIM +TXLPIUSC +TXLPIUSCIM +TXMAXP +TXMCCNT +TXMCOLGPIM +TXMIS +TXMODE +TXMONO +TXMULTCOLG +TXNANOSEC +TXNTFSR +TXOK +TXON +TXOR +TXORIRQ +TXORIRQEN +TXPAUSECNT +TXPBMS +TXPBPF +TXPF +TXPKTG +TXPKTRDY +TXPOLL +TXPR +TXQBASE +TXQCR +TXRDY +TXRDYM +TXRIS +TXRQ +TXRQST +TXRST +TXRTS +TXSAME +TXSCOLGPIM +TXSE +TXSEC +TXSNGLCOLG +TXSR +TXST +TXSTSIE +TXSUSPEND +TXSYN +TXSYNH +TXTEN +TXTH +TXTYPE +TXUBR +TXUNDERR +TXUNR +TXUR +TXURCH +TXURUNCNT +TXVC +TXVDIS +TXWLVL +TXWM +TXWRN +TXZQPF +TZCTRLTASK +TZEXT +Tapdly +Tdiv +Telus +Thakkar +Thwgv +Tmds +Tpng +Tracealyzer +Tremote +Tslow +Twid +Txed +Txmega +U +UACR +UADD +UALGO +UARTN +UARTOVF +UARTPS +UARTRX +UARTTX +UASR +UASX +UBRRH +UBRRL +UCKER +UCSR +UCSRB +UCSRC +UCTS +UDBL +UDCP +UDIS +UDMA +UDPCK +UDPE +UDPHSDMA +UDPHSEPT +UDPM +UDPV +UDRE +UFCLR +UFDTC +UFINTEN +UFRX +UFSR +UFST +UH +UHADD +UHASX +UHSAX +UHSUB +UIDE +UIHASH +UIHVAL +UIMOD +UIMR +UIPCR +UISR +UL +ULINK +UNACKED +UNALIGN +UNCHG +UNDES +UNDRN +UNIONAB +UNIONCD +UNKN +UNRE +UNSEC +UNSTKERR +UNSUB +UNSUBACK +UOTGCLK +UOTGHSDEVDMA +UOTGHSHSTDMA +UPAPCS +UPAPDEBUG +UPAPSS +UPCR +UPFD +UPPRO +UPRSM +UPRSMC +UPRSME +UPRSMEC +UPRSMS +UPSTR +UPVUPDAL +UQ +UQADD +UQASX +UQSAX +UQSUB +URAD +URAT +URSTEN +URSTIEN +URSTS +URTS +URUN +URXD +US +USAD +USADA +USART +USAT +USAX +USBAT +USBCK +USBD +USBE +USBEN +USBHP +USBISR +USBL +USBLP +USBPLLLIM +USBPLLLMIS +USBPLLLRIS +USBPSU +USBPWRDN +USCAFBH +USCAFBL +USCARBH +USCARBL +USCBFAH +USCBFAL +USCBRAH +USCBRAL +USCH +USDCLKFSEL +USELCA +USELCB +USELCE +USELCF +USELCH +USEND +USEPWMDIV +USEQ +USGA +USGFAULTSR +USGTRGAF +USGTRGAR +USGTRGBF +USGTRGBR +USGTRGCF +USGTRGCR +USGTRGDF +USGTRGDR +USPRG +USRIO +USTCR +UTRAN +UTXD +UX +UXTAB +UXTB +UYVY +Udphs +Uijcfxv +Usart +V +VABORT +VAUX +VBERRE +VBERRI +VBERRIC +VBERRIS +VBHIGH +VBLANK +VBLOW +VBORDER +VBUS +VBUSCHG +VBUSD +VBUSDIS +VBUSE +VBUSERR +VBUSHWC +VBUSPO +VBUSRQ +VBUSRQC +VBUSRQS +VBUSTE +VBUSTI +VBUSTIC +VBUSTIS +VBUSVLD +VCATCH +VCCAMS +VCCAUX +VCCBRAM +VCCCORE +VCCINT +VCOMG +VCOUNT +VDDBU +VDDCORE +VDSIZ +VDTO +VECT +VECTACTIVE +VECTCLRACTIVE +VECTPENDING +VECTRESET +VECTTBL +VELEN +VERIFAST +VESA +VFALL +VFPORCH +VFPOV +VICFIQ +VICIRQ +VICITCR +VICITIP +VICITOP +VJMODE +VLANE +VLANP +VLANTC +VLANTI +VLTV +VMRS +VMSR +VMSRNE +VOLC +VOUT +VPBDIV +VPLEN +VPLL +VPOL +VPOLARITY +VPOPNE +VPOSCLR +VPOSDTC +VPOSINTEN +VPUSHNE +VPVN +VREFH +VREFL +VREFN +VREFP +VREGCR +VRES +VRISE +VROK +VRPM +VRRSTEN +VRRSTS +VSDB +VSYNC +VTIR +VTOFFR +VTOR +VUPD +VZWINTERNETVZWINTERNETVZWINTERNETVZWINTERNETVZWINTERNETVZWINTERN +Vactive +Vajgc +Vaux +Vccams +Vccaux +Vccbram +Vccint +Vref +Vrefn +Vrefp +Vrtc +Vwng +W +WAITONREQ +WAKEON +WAKEUPEC +WAVESEL +WBDIS +WBIE +WCDMA +WCEF +WCEFB +WCEFE +WCOL +WCYC +WDCLKS +WDCR +WDDBGHLT +WDDIS +WDEN +WDERR +WDFEED +WDFIEN +WDGR +WDGT +WDIDLEHLT +WDINT +WDMOD +WDMR +WDOG +WDOGRESETREQ +WDOVF +WDRESET +WDRF +WDRPROC +WDRSTEN +WDRSTT +WDRV +WDSR +WDTC +WDTMIS +WDTOF +WDTPS +WDTRIS +WDTV +WDUNF +WERR +WESTAT +WFCR +WFFRPR +WHITEX +WIZC +WKFRAME +WKMODE +WKPF +WKUI +WKUPDBC +WKUPEN +WKUPT +WMRK +WOLIEN +WPEN +WPKEY +WPMR +WPSR +WPVS +WPVSRC +WRAH +WRALPHA +WRDBT +WREG +WRFMT +WRKEY +WRLATENCY +WRNRD +WRPR +WRPROOF +WRPROT +WRPRTERR +WRRD +WRTO +WSADATA +WSOPT +WSXGA +WTACT +WTCON +WTID +WUCSR +WUFF +WUFFRPR +WUFR +WUIE +WUXGA +WWDG +WWDGRST +Watchdogx +Wcolor +Wconversion +Werror +Weverything +Wextra +Wpacked +Wpedantic +Wpragma +Wsign +Wunused +X +XADD +XAPM +XAXIPMON +XBLANK +XCANPS +XCOL +XCOREAI +XCSUDMA +XDDRCPSU +XDMA +XDMAC +XDMACCHID +XDMAD +XDOWN +XDPDMA +XDPSSU +XEMACPS +XERROR +XEXC +XFPORCH +XGPIOPS +XHCI +XIMGSIZE +XIPIPS +XIPIPSU +XLFAUQG +XLPM +XMEGA +XMEGAB +XMOS +XMPU +XPAR +XPBL +XPLAIN +XPOS +XPOSR +XPPU +XPROT +XPSR +XQSPIPSU +XRAM +XRDY +XRESETPS +XRTCPSU +XSCUGIC +XSLEEP +XSPIPS +XSPW +XSYSMON +XTALSEL +XTDIV +XTEA +XTEN +XTENSA +XTRNL +XTTCPS +XUARTPS +XUSBPSU +XVIDC +XWDTPS +XZDMA +Xchannel +Xclock +Xdma +Xdmac +Xdmad +Xedge +Xfred +Xlevel +Xlpm +Xlpr +Xmode +Xnandps +Xoperation +Xplain +Xplorer +Xprescaler +Xpulse +Xsdps +Y +YA +YADD +YBGAIN +YCRCB +YCRCBA +YDOWN +YERROR +YGGAIN +YOFF +YOFST +YONLY +YPOS +YPOSR +YRDY +YRGAIN +YSCALE +YSET +YUVA +YUVX +YUYV +YYYYMMDD'T'HHMMSS'Z' +Yoyodyne +Z +ZCIE +ZDMA +ZEROIZE +ZEROPAUSETX +ZQPD +Zapv +Zimperium +Zosi +Zync +Zynq +a +aaddrlenlen +abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu +abcdefghijk +abcdefghijklmno +abcdefghijklmnopqrstuvwxyzabcdefghijklmnopq +abcdefghijklmnopqrstuvwyxz +acceptedklmno +accesspolicyfors +accomp +accwken +acinstat +ackci +acki +ackno +acpa +acpc +addci +addi +addif +addiu +adge +aeevt +aesni +alldevs +ambig +amet +amsdu +andi +apch +arasikere +arpa +arpq +arpqc +aswtrg +atlib +atomatic +atxmega +bcpb +bcpc +bdring +beevt +beginthreadex +behavioural +bfextu +bfield +bgcr +bics +bkpt +blckg +blckq +bmcr +boto +brctl +breq +brhi +brne +bswtrg +cacr +capitalisation +carm +cbmc +cbor +cborvalue +ccir +ccount +cflow +cgreg +channelx +chgeocin +chjdsvchjdvhjcdhjsckhdsvchdks +cichar +cid +cilen +ckrdy +cksel +clki +clrex +cmac +cmet +cmock +cmot +cmpa +cmpx +cntr +coalescences +codecov +comms +converttounixtime +coremqtt +cortexa +coverity +covfs +cpas +cpbs +cpcdis +cpcstop +cpsid +cpsie +creg +crflash +crhook +croutine +csrci +csrr +csrs +csrw +ctest +cxsf +dagc +daif +dbgmcu +decf +decfsz +defaultip +deinitializing +demultiplexing +dfcc +dfep +dgst +dhwaddr +dialup +dicr +dioattr +dirid +dmarxdesclist +dmatxdesclist +dnsa +dnsq +doproc +dspclk +eabil +ebff +ebss +ecall +ecdh +ecjpake +ectrk +ectrl +eesr +eevt +eevtedg +efep +eidrx +emacps +emacpsif +emacro +emption +empts +endm +endr +enetrg +epage +epdisc +eqcfg +equidistribution +eret +ethernetif +etrgs +evba +evopopv +evpopov +expandnl +expc +exti +fcolor +fdiagnostics +fdiv +fent +fents +fepp +ffconfig +ffee +ffnn +fifos +firewalld +flac +flist +flpp +fninit +fnsave +fpdemo +fpol +fracr +fracs +frms +fsanitize +fsmc +fsyncs +fwait +fxxx +gapb +genq +getpacketid +getvect +getx +gferc +gfers +ggdb +gjfhjxgxghsgfdwfdfdfdffhfdhdhfhdfhd +glcdc +gmac +gotos +gpfn +gpio +gpiomap +gplp +gptimer +gptw +gstate +hactive +havege +hblank +hclk +hein +hfreq +hkdf +hpol +hres +hsbdiv +hsbsel +htot +htotal +hwaddr +hwdst +hwlen +hwsrc +hwtc +iadd +ib +ibcommon +ibfse +iblinux +ibposix +ibwin +iccid +ierc +iers +ifentry +ifindiscards +ifrc +ifspecific +ilist +ilistlen +imajeff +imei +incon +inconsolata +indat +indet +indis +inpw +intg +intpmr +intx +ipdst +iperf +ipfragfails +iphl +ipntomentry +ipntomtable +ipntomtree +ipoff +iprte +iprteentry +iprtetable +iprtetree +ipsr +ipsrc +iret +irqs +isrstack +issocketconnected +iswrite +isystem +itmask +ittt +jcdubois +jobz +jscott +jscotts +karkhaz +kbhit +kbytes +kennethreitz +lcatch +lcdx +lcov +lcovhtml +ld +ldaa +ldab +ldaex +ldaexb +ldaexh +ldah +lddpc +ldistance +ldmdb +ldmia +ldmts +ldr +ldras +ldrb +ldrbs +ldrbt +ldrex +ldrexb +ldrexh +ldrht +ldrt +ldsr +lfhf +lfree +libsdmmc +libslirp +lidt +litani +llhttp +llreg +lmmnr +lmnopqrstuvw +loopcntr +lovrs +lowiq +lpcm +lpcount +lpdbc +lpdbcen +lpend +lpstart +lpthread +lptr +lsls +ltorg +ltry +lums +lusecs +lxip +macaddrhr +macaddrlr +maxiosz +maxnpacks +mbar +mbed +mbedcrypto +mbox +mbsanity +mcause +mcctrl +mcsc +mcsel +mem +memp +menie +mepc +mevents +mfdr +mfear +mfedr +mfesr +mffsr +mfgpr +mfhi +mflo +mfloat +mfmsr +mfpu +mfspr +mfsr +mhartid +miguelfreitas +miniosz +misra +mlan +mlkzxncvlknlkanlkqwlerknlasdflkzxcnvklnlksqwerasdfklqwenrklnfsad +mmubar +mnext +moscrcf +movea +movem +moveq +movhi +movia +movlb +movlw +movne +movs +movw +movx +mpcr +mqdes +mqttexample +mqttstatus +mqueue +mret +mrru +mrseq +mrsne +mspgcc +msplim +msreq +mstatus +mstroff +mtdr +mthi +mtlo +mtsr +mydevice +myethaddr +mynet +mypy +mzef +n +nakci +nakp +nblocks +ncat +ncycle +ndis +netifapi +netto +newid +nfltmsk +nmake +nnext +nnonopts +noarg +noassert +nocrypt +noheap +noint +nopts +nostdint +notifyzz +npacket +npcb +nprev +nscb +nsfptr +nslots +nstat +nsyslevmsk +nsysmode +nsysstat +ntddndis +ntomentry +numaker +nwrites +nwscanseq +nzcv +ocstr +ocstrlen +ocstrncpy +oderc +odmerc +ofsm +oldid +onext +onse +opad +opdesc +opfnc +opno +oprev +optimisations +optimise +optimised +optimiser +opty +orrs +osal +oscctrl +oscsel +osstatus +otaexample +otahttppage +otahttpsectionoverview +otamqttpage +otamqttsectionoverview +otaosfipage +otaosfisectionoverview +otapalpage +otapalsectionoverview +outpw +ovpset +ovres +pacap +panonopt +parid +pasdfghwsshasdfghjk +pbadiv +pbasel +pbbdiv +pbbsel +pbuff +pbuffer +pbufs +pcertificate +pclienttoken +pcomp +pcrc +pdecode +pdpdeact +percepio +periph +pfep +pfhandler +phandler +phandlerxzvf +phelter +phyksz +pico +picolibc +picovolts +pino +pkhbt +pkhtb +pkio +pkparse +pktios +pktp +pkwrite +plantuml +plength +pllosc +plmn +pmgi +poeg +pointee +pollq +popa +popd +popm +popx +portcomn +portex +portisr +portq +poscsr +pparam +ppkt +ppsz +ppublic +ppuc +ppux +printi +printll +prset +prst +prtmacro +ps +psha +psif +psplim +psps +ptcb +puapar +pubin +puerc +puers +pusha +pushd +pushf +pushm +pushx +pycparser +pylint +pytest +pyyaml +qadd +qasx +qdaudio +qdpmc +qpeek +qsax +qsub +rahul +randomisation +randomiser +raspberrypi +rauthack +rauthnak +rauthreq +rbit +rccr +rconfack +rconfnakrej +rconfreq +rcuc +rdcycle +rddsp +readb +readhw +reall +recmu +recognises +reent +refactorization +rejci +rejectedzz +rejp +reqci +resetci +resetrx +resynced +reta +reti +revsh +rgmii +riscv +rovr +rsar +rslcx +rsrp +rsrq +rtcwken +rtermack +rtermreq +rtpct +rttwken +rxbuffer +rxdata +rxfifo +rxif +rxlpwken +rxstate +sasx +sauthreq +sayyadumar +scdc +scopeid +scsv +scugic +sdata +sdgfdfgdshfgsjdhfdhfkhdkfhjdgfgdfgdfg +sdir +sdmmc +sdvfdvfhdvfhvdhfvdsfdsgfgdsjfgjdsfqwertyuio +searcht +secmbar +segger +segm +seqnr +setvect +sfdghfdfahgsdhfgjsgfjkgfsdgkdgfdjkgdggdjfsjkgjksgkj +sguic +sh +shadd +shasx +shdwc +shsax +shsub +shval +sifaddr +sifdefaultroute +sifdown +sifnpmode +sifup +sifvjcomp +sigv +sinclude +sinit +sinr +sizet +slclk +slipif +smlad +smladx +smlald +smlaldx +smlsd +smlsdx +smlsld +smlsldx +smmla +sms +smsc +smuad +smuadx +smusd +smusdx +snaph +snapl +sntp +sovr +spid +spniden +sresp +srtp +ssat +ssax +ssie +ssnhf +ssrf +ssynchronous +staa +stamand +stdsp +sten +stl +stlb +stlex +stlexb +stlexh +stlh +stmdb +stmia +strbt +strcmpi +strexb +strexh +strht +stringz +strn +strnn +strt +stsr +sub +suba +submoduled +svcne +svlcx +sx +sxtab +sxtb +synchronise +synchronised +synchronising +sysdesr +taskr +tcclks +tcpoutrsts +temac +tempcntr +testfs +thingz +timrdat +timrpre +timrtot +tinycbor +tmcsr +tmds +tmout +topk +totalappdescnbr +tottimo +tpid +tresh +tstfsz +txbuffer +txcmd +txdescs +txfifo +txmir +txmit +txqueuelen +txrx +u +uadd +uasx +ublock +ublox +uchars +ucprefix +udpinerrors +udpnoports +uechannel +uh +uhadd +uhasx +uhsax +uhsub +ul +unconfigure +uncrustify +unhashed +unifdef +uninitialised +uninitializing +unsubscriptions +unsuspended +unsuspends +unwindings +uq +uqadd +uqasx +uqsax +uqsub +us +usad +usada +usat +usax +usbat +utest +utilised +utilises +utilising +utrhf +utrhfgdghfg +ux +uxindex +uxsource +uxtab +uxtb +vactive +vblank +vcmp +vdhcp +vdnssearch +vect +verifast +vfide +vfpcc +vfreq +vidc +vidfrmt +vint +virbr +visualisation +vldmdbeq +vldmia +vldmiaeq +vmode +vmov +vnetmask +vnetwork +vout +vpol +vpop +vport +vpush +vregcr +vres +vstmdbeq +vstmiaeq +vsys +vtot +vtotal +vuint +wakeon +wakeonxzvf +wavsel +wbwdisable +wdebug +wdtcon +winmm +wkupdbc +wlanif +wmlog +wmprintf +wnqj +wrdata +wrdsp +writeb +writehw +wuir +x +xavbuf +xaxiemacif +xchjsd +xdma +xdmac +xdmad +xeek +xemac +xemacps +xemacpsp +xfindobjectwithlabelandclass +xfscompat +xgetslotlist +xheader +xinitializepkcs +xlarge +xlength +xlltemacp +xmega +xparameters +xpendedticks +xplain +xprev +xqueue +xscope +xslope +xsysmon +xsysmonpsu +xtal +xtask +xtea +xtimer +xtopology +xtopologyp +xvidc +xzvf +y +ymxchykldfghiwbdcjhjdddkkgddsdhshdkshdhsskgfkjgfggc +yslope +zeroize +zipperowiec +zynqmp diff --git a/.github/scripts/common/header_checker.py b/.github/scripts/common/header_checker.py index 0bf3a6dbc..57a5c2dcd 100755 --- a/.github/scripts/common/header_checker.py +++ b/.github/scripts/common/header_checker.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # /* # * FreeRTOS V202212.00 -# * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # * # * Permission is hereby granted, free of charge, to any person obtaining a copy of # * this software and associated documentation files (the "Software"), to deal in diff --git a/.github/scripts/common/requirements.txt b/.github/scripts/common/requirements.txt index 51999d0e1..b5722b846 100644 --- a/.github/scripts/common/requirements.txt +++ b/.github/scripts/common/requirements.txt @@ -1,14 +1,14 @@ -certifi==2023.7.22 -chardet==4.0.0 +Deprecated +GitPython +PyGithub +PyJWT +PyYAML +certifi +chardet colorama -Deprecated==1.2.10 -gitdb==4.0.5 -GitPython==3.1.32 -idna==2.10 -PyGithub==1.55 -PyJWT==2.4.0 -PyYAML==5.4 +gitdb +idna requests -smmap==3.0.4 -urllib3==1.26.5 -wrapt==1.12.1 +smmap +urllib3 +wrapt diff --git a/.github/scripts/core_checker.py b/.github/scripts/core_checker.py index d17939230..167fec992 100755 --- a/.github/scripts/core_checker.py +++ b/.github/scripts/core_checker.py @@ -119,6 +119,7 @@ FREERTOS_IGNORED_EXTENSIONS = [ '.ipcf', '.ise', '.jlink', + '.js', '.json', '.la', '.launch', @@ -172,6 +173,7 @@ FREERTOS_IGNORED_EXTENSIONS = [ '.pl', '.plg', '.png', + '.props', '.prc', '.pref', '.prefs', @@ -216,6 +218,7 @@ FREERTOS_IGNORED_EXTENSIONS = [ '.tags', '.tcl', '.tdt', + '.templ', '.template', '.tgt', '.tps', @@ -250,14 +253,12 @@ FREERTOS_IGNORED_EXTENSIONS = [ '.xmsgs', '.xsl', '.yml', - '.md', '.zip' ] FREERTOS_IGNORED_PATTERNS = [ r'.*\.git.*', r'.*mbedtls_config\.h.*', - r'.*mbedtls_config\.h.*', r'.*CMSIS.*', r'.*/Nordic_Code/*', r'.*/Nuvoton_Code/*', @@ -275,8 +276,40 @@ FREERTOS_IGNORED_PATTERNS = [ r'.*/trcKernelPortSnapshotConfig\.h.*', r'.*/MicroZed_hw_platform.*', r'.*/ThirdParty/.*', - r'FreeRTOS\-Plus/Demo/Common/WinPCap/.*', - r'FreeRTOS\-Plus/Source/FreeRTOS-Plus-Trace/.*', + r'.*/WinPCap/.*', + r'.*/DRIVERS/.*', + r'.*/FreeRTOS-Plus-Trace/.*', + r'.*/Reliance-Edge/.*', + r'.*/HCS12_CodeWarrior_banked/.*', + r'.*/ARM7_STR75x_GCC/.*', + r'.*/ARM7_STR75x_IAR/.*', + r'.*/lwip-1.4.0/.*', + r'.*/lwip-1.1.0/.*', + r'.*/MSP430X_MSP430F5438_CCS/.*', + r'.*/Atmel/.*', + r'.*/drivers/.*', + r'.*/lwIP/.*', + r'.*/ARM7_AT91FR40008_GCC/.*', + r'.*/ARM7_AT91SAM7S64_IAR/.*', + r'.*/ARM7_LPC2106_GCC/.*', + r'.*/CORTEX_A9_Cyclone_V_SoC_DK/.*', + r'.*/CORTEX_A9_Zynq_ZC702/.*', + r'.*/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles//.*', + r'.*/ARM7_AT91FR40008_GCC/.*', + r'.*/ARM7_STR71x_IAR/.*', + r'FreeRTOS/Demo/HCS12_GCC_banked/.*', + r'FreeRTOS/Demo/CORTEX_LM3S102_GCC/hw_include/.*', + r'FreeRTOS/Demo/CORTEX_LM3S102_GCC/hw_include/.*', + r'FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/include/.*', + r'FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/.*', + r'FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/.*', + r'FreeRTOS/Demo/AVR_ATMega4809_Atmel_Studio/RTOSDemo/.*', + r'FreeRTOS/Demo/AVR32_UC3/.*', + r'FreeRTOS/Demo/ARM7_STR75x_GCC/STLibrary/inc/.*', + r'FreeRTOS/Demo/ARM7_STR75x_IAR/STLibrary/inc/.*', + r'FreeRTOS/Demo/CORTEX_R4F_RZ_T_GCC_IAR/System/GCC/inc/.*', + r'FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/AtmelFiles/drivers/misc/.*', + r'FreeRTOS/Demo/CORTEX_ATSAM3X_Atmel_Studio/src/.*', r'FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/.*', r'FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/.*', r'FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/.*', @@ -291,6 +324,7 @@ FREERTOS_IGNORED_PATTERNS = [ ] FREERTOS_IGNORED_FILES = [ + 'cspell.config.yaml', '.cproject', '.project', 'fyi-another-way-to-ignore-file.txt', @@ -310,12 +344,28 @@ FREERTOS_IGNORED_FILES = [ 'reg_test.S', 'gdbinit', 'libslirp-version.h', + 'LPC21xx.h', + 'lpc221x.h', + 'winbase.h', + 'windows.h', + 'direct.h', + 'stm32f10x_conf.h', + 'lwipopts.h', + 'lwipopts.h', + 'xil_assert.h', + 'alt_i2c.h', + 'alt_clkmgr.h', + 'hal_lcd.c', + 'adc.h', + 'redconf.c', + 'redconf.h', + 'redtypes.h', ] FREERTOS_HEADER = [ '/*\n', ' * FreeRTOS V202212.00\n', - ' * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n', + ' * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n', ' *\n', ' * Permission is hereby granted, free of charge, to any person obtaining a copy of\n', ' * this software and associated documentation files (the "Software"), to deal in\n', @@ -340,7 +390,7 @@ FREERTOS_HEADER = [ ' */\n', ] -FREERTOS_COPYRIGHT_REGEX = r"^( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$" +FREERTOS_COPYRIGHT_REGEX = r"^( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$" def main(): parser = HeaderChecker.configArgParser() diff --git a/.github/scripts/qemu_reader.c b/.github/scripts/qemu_reader.c new file mode 100644 index 000000000..23095ba0a --- /dev/null +++ b/.github/scripts/qemu_reader.c @@ -0,0 +1,38 @@ +#include +#include + +int main( int argc, char * argv[] ) +{ + setvbuf( stdout, NULL, _IONBF, 0 ); + FILE * fp; + char path[ 256 ]; + char cmd[ 256 ]; + + /* Open the command for reading. */ + fp = popen("find . -name RTOSDemo.out", "r"); + /* Read the output a line at a time - output it. */ + while( fgets( path, sizeof( path ), fp ) != NULL ) + { + printf( "Path: %s\n", path ); + } + + sprintf(cmd, "qemu-system-arm -machine mps2-an385 -monitor null -semihosting --semihosting-config enable=on,target=native -serial stdio -nographic -kernel %s", path); + printf("cmd= %s\n", cmd); + fp = popen( cmd, "r" ); + if( fp == NULL ) + { + printf( "Failed to run command\n" ); + exit( 1 ); + } + + /* Read the output a line at a time - output it. */ + while( fgets( path, sizeof( path ), fp ) != NULL ) + { + printf( "%s", path ); + } + + /* close */ + pclose( fp ); + + return 0; +} diff --git a/.github/scripts/release-requirements.txt b/.github/scripts/release-requirements.txt index 6cd924453..b5722b846 100644 --- a/.github/scripts/release-requirements.txt +++ b/.github/scripts/release-requirements.txt @@ -1,13 +1,14 @@ -certifi>=2020.12.5 -chardet>=3.0.4 -Deprecated>=1.2.10 -gitdb>=4.0.5 -GitPython>=3.1.11 -idna>=2.10 -PyGithub>=1.54 -PyJWT>=1.7.1 -PyYAML>=5.3.1 -requests>=2.24.0 -smmap>=3.0.4 -urllib3>=1.25.11 -wrapt>=1.12.1 +Deprecated +GitPython +PyGithub +PyJWT +PyYAML +certifi +chardet +colorama +gitdb +idna +requests +smmap +urllib3 +wrapt diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 991cd7528..d0860e5b7 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -26,13 +26,13 @@ jobs: # Source the release tools from FreeRTOS/FreeRTOS - name: Checkout FreeRTOS Release Tools - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: tools # Simpler git auth if we use checkout action and forward the repo to release script - name: Checkout FreeRTOS - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: local_core fetch-depth: 0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c13cc90d..e64341a7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,93 +1,80 @@ name: CI Checks +env: + bashPass: \033[32;1mPASSED - + bashWarn: \033[33;1mWARNING - + bashFail: \033[31;1mFAILED - + bashEnd: \033[0m + on: - push: - pull_request: - workflow_dispatch: + push: + pull_request: + workflow_dispatch: jobs: git-secrets: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: - submodules: recursive + submodules: recursive - name: Checkout awslabs/git-secrets - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: - repository: awslabs/git-secrets - ref: master - path: git-secrets + repository: awslabs/git-secrets + ref: master + path: git-secrets - name: Install git-secrets run: cd git-secrets && sudo make install && cd .. - name: Run git-secrets run: | - git-secrets --register-aws - git-secrets --scan + git-secrets --register-aws + git-secrets --scan formatting: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 - - name: Install Uncrustify - run: sudo apt-get install uncrustify=0.69.0+dfsg1-1build1 - - name: Run Uncrustify - run: | - # Uncrustify on C files while ignoring symlinks. - # Make a collapsible section in the log to run uncrustify - echo "::group::Uncrustify Check" - # GitHub automtically use "set -e" which causes scripts to fail on the first exit code - # This would mean the first time a file fails the check that we exit without formatting all files. - set +e - uncrustify --version - find FreeRTOS/Demo/Common FreeRTOS/Test \( -name ethernet -o -name drivers -o -path 'FreeRTOS/Test/CMock/CMock' \) -prune -false -o -name "*.[hc]" | xargs uncrustify --no-backup --replace --if-changed -c tools/uncrustify.cfg -l C - echo "::endgroup::" - # Run a git diff to print the differences if any exist, return an error code if there are any - git diff --exit-code - if [ "$?" = "0" ]; then - echo -e "\033[32;3mUncrustify check passed\033[0m" - exit 0 - else - echo -e "\033[32;31mFormatting check (using Uncrustify) failed...\033[0m" - # If there is an error, set this flag high again so the exit 1 fails the run - set -e - exit 1 - fi - - name: Check For Trailing Whitespace - run: | - # Trailing Whitespace Check - set +e - ERROR=0 - find . \( -name '.git' -o -path "./FreeRTOS/Test/CBMC/patches" -o -path "./FreeRTOS-Plus" -o -path "./FreeRTOS/Source" -o -path "./FreeRTOS/Test/CMock/CMock" -o -path "./FreeRTOS/Demo" \) -prune -false -o -type f -a -name "*" -exec grep -In -e "[[:blank:]]$" {} + - if [ "$?" = "0" ]; then - ERROR=1 - fi + - uses: actions/checkout@v3 - find FreeRTOS/Demo/Common \( -name "ethernet" \) -prune -o -false -o -type f -a -name "*" -exec grep --color=yes -In -e "[[:blank:]]$" {} + - if [ "$?" = "0" ]; then - echo -e "\033[32;31mFiles have trailing whitespace.\033[0m" - exit 1 - else - if [ "$ERROR" -eq "1" ]; then - echo -e "\033[32;31mFiles have trailing whitespace.\033[0m" - exit 1 - fi - echo -e "\033[32;3mTrailing whitespace check passed\033[0m" - exit 0 - fi + - name: Check Formatting of Common Demo Files + uses: FreeRTOS/CI-CD-Github-Actions/formatting@main + with: + path: FreeRTOS/Demo/Common + exclude-dirs: ethernet, drivers + + - name: Check Formatting + uses: FreeRTOS/CI-CD-Github-Actions/formatting@main + with: + exclude-dirs: ethernet, drivers, FreeRTOS/Demo + + spell-check: + runs-on: ubuntu-latest + steps: + - name: Checkout Parent Repo + uses: actions/checkout@v3 + + - name: Check Spelling of Common Demo Files + uses: FreeRTOS/CI-CD-GitHub-Actions/spellings@main + with: + path: FreeRTOS/Demo/Common + exclude-dirs: ethernet, drivers + + - name: Check Spelling + uses: FreeRTOS/CI-CD-GitHub-Actions/spellings@main + with: + exclude-dirs: ethernet, drivers, FreeRTOS/Demo doxygen: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Clone repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive path: freertos - name: Install Python3 - uses: actions/setup-python@v2 - with: - python-version: '3.8' + uses: actions/setup-python@v3 + - name: Download tag dependency of coreMQTT-Agent run: | # We don't need to generate the coreMQTT docs, we only need the tag file. @@ -95,8 +82,9 @@ jobs: mkdir -p freertos/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent/source/dependency/coreMQTT/docs/doxygen/output wget -O freertos/FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent/source/dependency/coreMQTT/docs/doxygen/output/mqtt.tag \ "https://freertos.org/Documentation/api-ref/coreMQTT/docs/doxygen/output/mqtt.tag" + - name: Generate doxygen ZIP - uses: FreeRTOS/CI-CD-GitHub-Actions/doxygen@main + uses: FreeRTOS/CI-CD-Github-Actions/doxygen@main with: path: ./freertos # List of directories containing libraries whose doxygen output will be generated. @@ -112,77 +100,49 @@ jobs: path: ./freertos/doxygen.zip retention-days: 2 - spell-check: - runs-on: ubuntu-20.04 - steps: - - name: Checkout Parent Repo - uses: actions/checkout@v2 - with: - ref: main - repository: FreeRTOS/CI-CD-Github-Actions - path: commonCI - - name: Clone This Repo - uses: actions/checkout@v2 - with: - path: ./FreeRTOS - - name: Install spell - run: | - sudo apt-get install spell - sudo apt-get install util-linux - - name: Check spelling - run: | - # Add path to the tool to the environment variable. - PATH=$PATH:commonCI/spellings/tools - # Make sure that only Amazon licenced files are checked. - sed -i 's/`find $DIRNAME \\( -iname \\\*\.\[ch\] -o -iname \\\*\.dox \\) -type f`/`grep -ril "copyright \(c\) \[0-9\]\[0-9\]\[0-9\]\[0-9\] amazon.com" | grep "\\.\[ch\]" | grep -v "FreeRTOS\/FreeRTOS\/Test\/VeriFast"`/g' commonCI/spellings/tools/find-unknown-comment-words - # Run the spell check script. - find-unknown-comment-words --directory FreeRTOS/ --lexicon FreeRTOS/lexicon.txt - # Check the exit status. - if [ "$?" = "0" ]; then - exit 0 - else - exit 1 - fi - verify-manifest: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true fetch-depth: 0 - - name: Install Python3 - uses: actions/setup-python@v2 - with: - python-version: '3.x' - name: Run manifest verifier - uses: FreeRTOS/CI-CD-Github-Actions/manifest-verifier@main + uses: FreeRTOS/CI-CD-GitHub-Actions/manifest-verifier@v2 with: path: ./ - exclude-submodules: FreeRTOS-Plus/Test/CMock,FreeRTOS/Test/CMock/CMock,FreeRTOS/Test/litani fail-on-incorrect-version: true memory-statistics: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest env: ARM_GCC_TOOLCHAIN_URL: "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2?revision=05382cca-1721-44e1-ae19-1e7c3dc96118&la=en&hash=D7C9D18FCA2DD9F894FD9F3C3DC9228498FA281A" steps: - name: Install ARM GCC - run: wget -qO- "${{ env.ARM_GCC_TOOLCHAIN_URL }}" | sudo tar --strip-components=1 -xj -C /usr/local + run: + wget -qO- "${{ env.ARM_GCC_TOOLCHAIN_URL }}" | sudo tar + --strip-components=1 -xj -C /usr/local - name: Clone FreeRTOS Repository with submodules - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - name: Clone mbedTLS submodule from corePKCS11 - run: git submodule update --init --recursive --checkout -- FreeRTOS-Plus/Source/corePKCS11 + run: + git submodule update --init --recursive --checkout -- + FreeRTOS-Plus/Source/corePKCS11 - name: Clone CI-CD-Github-Actions repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: - repository: FreeRTOS/CI-CD-Github-Actions + repository: FreeRTOS/CI-CD-GitHub-Actions path: tools - name: Run script to generate JSON memory statistics - run: tools/memory_statistics/memory_statistics.py --json_report --config tools/memory_statistics/paths.json --output freertos_lts_memory_estimates.json - - name: Upload memory size report as artifact (for main and release-candidate ONLY) + run: + tools/memory_statistics/memory_statistics.py --json_report + --config tools/memory_statistics/paths.json --output + freertos_lts_memory_estimates.json + - name: + Upload memory size report as artifact (for main and + release-candidate ONLY) if: success() && ( github.ref == 'refs/heads/main' || github.ref == 'refs/heads/release-candidate' ) uses: actions/upload-artifact@v2 with: @@ -191,16 +151,24 @@ jobs: retention-days: 2 proof_ci: + if: ${{ github.event.pull_request }} runs-on: cbmc_ubuntu-latest_16-core steps: - - uses: actions/checkout@v2 - - run: | + - uses: actions/checkout@v3 + - env: + stepName: Install Dependencies + run: | + echo -e "::group::${{ env.stepName }}" git submodule update --init --checkout --recursive --depth 1 sudo apt-get update sudo apt-get install --yes --no-install-recommends gcc-multilib + echo -e "::endgroup::" + echo -e "${{ env.bashPass }} ${{env.stepName}} ${{ env.bashEnd }}" + - name: Set up CBMC runner uses: FreeRTOS/CI-CD-Github-Actions/set_up_cbmc_runner@main + - name: Run CBMC uses: FreeRTOS/CI-CD-Github-Actions/run_cbmc@main with: - proofs_dir: FreeRTOS/Test/CBMC/proofs + proofs_dir: FreeRTOS/Test/CBMC/proofs diff --git a/.github/workflows/core-checks.yml b/.github/workflows/core-checks.yml index 16620ba1c..0e8d7f4cc 100644 --- a/.github/workflows/core-checks.yml +++ b/.github/workflows/core-checks.yml @@ -18,14 +18,14 @@ jobs: # Use the checks as defined by the user, so they can locally adjust as needed - name: Checkout FreeRTOS Tools - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} path: tools # Checkout user pull request changes - name: Checkout Pull Request - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} path: inspect diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml new file mode 100644 index 000000000..8257addac --- /dev/null +++ b/.github/workflows/formatting.yml @@ -0,0 +1,23 @@ +name: Format Pull Request Files + +on: + issue_comment: + types: [created] + +env: + bashPass: \033[32;1mPASSED - + bashInfo: \033[33;1mINFO - + bashFail: \033[31;1mFAILED - + bashEnd: \033[0m + +jobs: + Formatting: + name: Run Formatting Check + if: ${{ github.event.issue.pull_request }} && + ( ( github.event.comment.body == '/bot run uncrustify' ) || + ( github.event.comment.body == '/bot run formatting' ) ) + runs-on: ubuntu-20.04 + steps: + - name: Apply Formatting Fix + uses: FreeRTOS/CI-CD-Github-Actions/formatting-bot@main + id: check-formatting diff --git a/.github/workflows/freertos_demos.yml b/.github/workflows/freertos_demos.yml index 37f391985..c577b5e6d 100644 --- a/.github/workflows/freertos_demos.yml +++ b/.github/workflows/freertos_demos.yml @@ -1,195 +1,230 @@ name: FreeRTOS Demos on: - push: - pull_request: - workflow_dispatch: + push: + pull_request: + workflow_dispatch: + +env: + bashPass: \033[32;1mPASSED - + bashWarn: \033[33;1mWARNING - + bashFail: \033[31;1mFAILED - + bashEnd: \033[0m + + pwshPass: "`e[32;1mPASSED -" + pwshWarn: "`e[33;1mWARNING -" + pwshFail: "`e[31;1mFAILED -" + pwshEnd: "`e[0m" jobs: WIN32-MSVC: name: WIN32 MSVC runs-on: windows-latest steps: - - name: Checkout Repository - uses: actions/checkout@v2 + - env: + stepName: Checkout Repository + name: ${{ env.stepName }} + uses: actions/checkout@v3 - - name: Fetch Kernel Submodule + - env: + stepName: Fetch Kernel Submodule + name: ${{ env.stepName }} shell: bash run: | - # Fetch Kernel Submodule - echo "::group::Fetch Kernel Submodule" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e git submodule update --checkout --init --depth 1 FreeRTOS/Source - echo "::endgroup::" - if [[ "$?" = "0" ]] - then - echo -e "\033[32;3mCloned the Kernel\033[0m" + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{env.stepName}} ${{ env.bashEnd }}" else - echo -e "\033[32;31mKernel Clone Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{env.stepName}} ${{ env.bashEnd }}" exit 1 fi - - name: Add msbuild to PATH + - env: + stepName: Add msbuild to PATH + name: ${{ env.stepName }} uses: microsoft/setup-msbuild@v1.1 - - name: Build WIN32-MSVC Full Demo + - env: + stepName: Build WIN32-MSVC Full Demo + name: ${{ env.stepName }} id: build-win32-msvs-full-demo working-directory: FreeRTOS/Demo/WIN32-MSVC run: | - # Build WIN32-MSVC Full Demo - echo "::group::Build WIN32-MSVC Full Demo" + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" $content = Get-Content -Path 'main.c' -Raw $newContent = $content -replace 'int\s+main(.*?)void(.*?)\r?\n\s*{', 'int main( void ){setvbuf( stdout, NULL, _IONBF, 0 );' $newContent | Set-Content -Path 'main.c' msbuild WIN32.sln -t:rebuild + $exitStatus = $? echo "::endgroup::" - if($? -eq 1) { - Write-Host -ForegroundColor green "Built the WIN32-MSVC Full Demo" + if($exitStatus -eq 1) { + echo "${{ env.pwshPass }} ${{env.stepName}} ${{ env.pwshEnd }}" }else { - Write-Host -ForegroundColor red "Build WIN32-MSVC Full Demo Failed..." + echo "${{ env.pwshFail }} ${{env.stepName}} ${{ env.pwshEnd }}" exit 1 } - - name: Run and monitor WIN32-MSVC Full Demo - if: success() || failure() && steps.build-win32-msvs-full-demo.outcome == 'success' + - env: + stepName: Run and monitor WIN32-MSVC Full Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS/Demo/WIN32-MSVC/Debug/RTOSDemo.exe - log-dir: demo_run_logs timeout-seconds: 60 success-line: "No errors - tick count" + retry-attempts: 3 - - name: Build WIN32-MSVC Blinky Demo + - env: + stepName: Build WIN32-MSVC Blinky Demo + name: ${{ env.stepName }} id: build-win32-msvs-blinky-demo working-directory: FreeRTOS/Demo/WIN32-MSVC run: | - # Build WIN32-MSVC Blinky Demo - echo "::group::MSBuild of WIN32-MSVC Blinky Demo" + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" $content = Get-Content -Path 'main.c' -Raw $newContent = $content -replace '#define\s+mainCREATE_SIMPLE_BLINKY_DEMO_ONLY\s+0', '#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1' $newContent | Set-Content -Path 'main.c' - # Perform MSBuild of WIN32-MSVC Blinky Demo msbuild WIN32.sln -t:rebuild echo "::endgroup::" - if($? -eq 1) { - Write-Host -ForegroundColor green "Built the WIN32-MSVC Blinky Demo" + $exitStatus = $? + if($exitStatus -eq 1) { + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" }else { - Write-Host -ForegroundColor red "Build WIN32-MSVC Blinky Demo Failed..." + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" exit 1 } - - name: Run and monitor WIN32-MSVC Blinky Demo - if: success() || failure() && steps.build-win32-msvs-blinky-demo.outcome == 'success' + - env: + stepName: Run and monitor WIN32-MSVC Blinky Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: - exe-path: FreeRTOS/Demo/WIN32-MSVC/Debug/RTOSDemo.exe - log-dir: demo_run_logs - timeout-seconds: 60 - success-line: "Message received from software timer" + exe-path: FreeRTOS/Demo/WIN32-MSVC/Debug/RTOSDemo.exe + timeout-seconds: 60 + success-line: "Message received from software timer" + retry-attempts: 3 - - name: Build WIN32-MSVC-Static-Allocation-Only Demo + - env: + stepName: Build WIN32-MSVC-Static-Allocation-Only Demo + name: ${{ env.stepName }} id: build-win32-msvs-static-allocation-only-demo working-directory: FreeRTOS/Demo/WIN32-MSVC-Static-Allocation-Only run: | - # Build WIN32-MSVC-Static-Allocation-Only Demo - echo "::group::Build WIN32-MSVC-Static-Allocation-Only Demo" + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" $content = Get-Content -Path 'main.c' -Raw $newContent = $content -replace 'int\s+main(.*?)void(.*?)\r?\n\s*{', 'int main( void ){setvbuf( stdout, NULL, _IONBF, 0 );' $newContent | Set-Content -Path 'main.c' msbuild WIN32.sln -t:rebuild + $exitStatus = $? echo "::endgroup::" - if($? -eq 1) { - Write-Host -ForegroundColor green "Built the WIN32-MSVC-Static-Allocation-Only Demo" + if($exitStatus -eq 1) { + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" }else { - Write-Host -ForegroundColor red "Build WIN32-MSVC-Static-Allocation-Only Demo Failed..." + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" exit 1 } - - name: Run and monitor WIN32-MSVC-Static-Allocation-Only Demo - if: success() || failure() && steps.build-win32-msvs-static-allocation-only-demo.outcome == 'success' + - env: + stepName: + Run and monitor WIN32-MSVC-Static-Allocation-Only Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: - exe-path: FreeRTOS/Demo/WIN32-MSVC-Static-Allocation-Only/Debug/RTOSDemo.exe - log-dir: demo_run_logs - timeout-seconds: 60 - success-line: "No errors - tick count" + exe-path: FreeRTOS/Demo/WIN32-MSVC-Static-Allocation-Only/Debug/RTOSDemo.exe + timeout-seconds: 60 + success-line: "No errors - tick count" + retry-attempts: 3 WIN32-MingW: name: WIN32 MingW runs-on: windows-latest steps: - - name: Checkout Repository - uses: actions/checkout@v2 + - env: + stepName: Checkout Repository + name: ${{ env.stepName }} + uses: actions/checkout@v3 - - name: Fetch Kernel Submodule + - env: + stepName: Fetch Kernel Submodule + name: ${{ env.stepName }} shell: bash run: | - # Fetch Kernel Submodule - echo "::group::Fetch Kernel Submodule" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 FreeRTOS/Source - echo "::endgroup::" - if [[ "$?" = "0" ]] - then - echo -e "\033[32;3mCloned the Kernel\033[0m" - else - echo -e "\033[32;31mKernel Clone Failed...\033[0m" - exit 1 - fi + echo -e "::endgroup::" + echo -e "${{ env.bashPass }} ${{env.stepName}} ${{ env.bashEnd }}" - - - name: Build WIN32-MingW Full Demo + - env: + stepName: Build WIN32-MingW Full Demo + name: ${{ env.stepName }} id: build-win32-mingw-full-demo working-directory: FreeRTOS/Demo/WIN32-MingW run: | - # Build WIN32-MingW Full Demo - echo "::group::Build WIN32-MingW Full Demo" + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" $content = Get-Content -Path 'main.c' -Raw $newContent = $content -replace 'int\s+main(.*?)void(.*?)\r?\n\s*{', 'int main( void ){setvbuf( stdout, NULL, _IONBF, 0 );' $newContent | Set-Content -Path 'main.c' gcc --version make --version make + $exitStatus = $? echo "::endgroup::" - if($? -eq 1) { - Write-Host -ForegroundColor green "Built the WIN32-MingW Full Demo" + if($exitStatus -eq 1) { + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{env.pwshEnd}}" }else { - Write-Host -ForegroundColor red "Build WIN32-MingW Full Demo Failed..." + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{env.pwshEnd}}" exit 1 } - - name: Run and monitor WIN32-MingW Full Demo - if: success() || failure() && steps.build-win32-mingw-full-demo.outcome == 'success' + - env: + stepName: Run and monitor WIN32-MingW Full Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS/Demo/WIN32-MingW/build/RTOSDemo.exe - log-dir: demo_run_logs timeout-seconds: 60 success-line: "No errors - tick count" - - name: Build WIN32-MingW Blinky Demo + - env: + stepName: Build WIN32-MingW Blinky Demo + name: ${{ env.stepName }} id: build-win32-mingw-blinky-demo working-directory: FreeRTOS/Demo/WIN32-MingW run: | - # Build WIN32-MingW Blinky Demo - echo "::group::Build WIN32-MingW Blinky Demo" + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" $content = Get-Content -Path 'main.c' -Raw $newContent = $content -replace '#define\s+mainCREATE_SIMPLE_BLINKY_DEMO_ONLY\s+0', '#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1' + $newContent = $newContent -replace 'int\s+main(.*?)void(.*?)\r?\n\s*{', 'int main( void ){setvbuf( stdout, NULL, _IONBF, 0 );' $newContent | Set-Content -Path 'main.c' gcc --version make --version make + $exitStatus = $? echo "::endgroup::" - if($? -eq 1) { - Write-Host -ForegroundColor green "Built the WIN32-MingW Blinky Demo" + if($exitStatus -eq 1) { + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" }else { - Write-Host -ForegroundColor red "Build WIN32-MingW Blinky Demo Failed..." + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" exit 1 } - - name: Run and monitor WIN32-MingW Blinky Demo - if: success() || failure() && steps.build-win32-mingw-blinky-demo.outcome == 'success' + - env: + stepName: Run and monitor WIN32-MingW Blinky Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS/Demo/WIN32-MingW/build/RTOSDemo.exe - log-dir: demo_run_logs timeout-seconds: 60 success-line: "Message received from software timer" @@ -197,96 +232,111 @@ jobs: name: Posix GCC runs-on: ubuntu-latest steps: - - name: Checkout Repository - uses: actions/checkout@v2 + - env: + stepName: Checkout Repository + name: ${{ env.stepName }} + uses: actions/checkout@v3 - - name: Fetch Kernel Submodule + - env: + stepName: Fetch Kernel Submodule + name: ${{ env.stepName }} shell: bash run: | - # Fetch Kernel Submodule - echo "::group::Fetch Kernel Submodule" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e git submodule update --checkout --init --depth 1 FreeRTOS/Source - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mCloned the Kernel\033[0m" + set -e + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mKernel Clone Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Install GCC + - env: + stepName: Install GCC + name: ${{ env.stepName }} shell: bash run: | - # Install GCC - echo "::group::Install GCC" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e sudo apt-get -y update sudo apt-get -y install build-essential - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\e[0;32mInstall GCC Passed\e[0m" + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\e[0;32mInstall GCC Failed\e[0m" - # If there is an error, set this flag high again so the exit 1 fails the run - set -e + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Build Posix_GCC Demo for Coverage Test - shell: bash - working-directory: FreeRTOS/Demo/Posix_GCC - run: make -j COVERAGE_TEST=1 - - - name: Build Posix_GCC Full Demo + - env: + stepName: Build Posix_GCC Full Demo + name: ${{ env.stepName }} id: build-posix-gcc-full-demo shell: bash working-directory: FreeRTOS/Demo/Posix_GCC run: | - # Build Posix_GCC Full Demo - echo "::group::Build Posix_GCC Full Demo" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e sed -i -z "s/int[[:space:]]*main[[:space:]]*([[:space:]]*void[[:space:]]*)\n{/int main( void ){setvbuf( stdout, NULL, _IONBF, 0 );/g" main.c - make clean make -j - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuild Posix_GCC Full Demo Passed\033[0m" + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mBuild Posix_GCC Full Demo Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Run and monitor Posix_GCC Full Demo - if: success() || failure() && steps.build-posix-gcc-full-demo.outcome == 'success' + - env: + stepName: Run and monitor Posix_GCC Full Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: - exe-path: FreeRTOS/Demo/Posix_GCC/build/posix_demo - log-dir: demo_run_logs - timeout-seconds: 60 - success-line: "OK: No errors" + exe-path: FreeRTOS/Demo/Posix_GCC/build/posix_demo + timeout-seconds: 60 + success-line: "OK: No errors" + retry-attempts: 3 - - name: Build Posix_GCC Blinky Demo + - env: + stepName: Build Posix_GCC Blinky Demo + name: ${{ env.stepName }} id: build-posix-gcc-blinky-demo - if: success() || failure() shell: bash working-directory: FreeRTOS/Demo/Posix_GCC run: | - # Build Posix_GCC Blinky Demo - echo "::group::Build Posix_GCC Blinky Demo" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" rm -rf build + set +e make -j USER_DEMO=BLINKY_DEMO - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuilt the Posix_GCC Blinky Demo\033[0m" + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mBuild Posix_GCC Blinky Demo Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{env.stepName}} ${{ env.bashEnd }}" exit 1 fi - - name: Run and monitor Posix_GCC Blinky Demo - if: success() || failure() && steps.build-posix-gcc-blinky-demo.outcome == 'success' + - env: + stepName: Run and monitor Posix_GCC Blinky Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS/Demo/Posix_GCC/build/posix_demo - log-dir: demo_run_logs timeout-seconds: 60 success-line: "Message received from software timer" @@ -294,208 +344,290 @@ jobs: name: GNU MSP430 Toolchain runs-on: ubuntu-latest steps: - - name: Checkout Repository - uses: actions/checkout@v2 + - env: + stepName: Checkout Repository + name: ${{ env.stepName }} + uses: actions/checkout@v3 + with: + submodules: true - - name: Fetch Kernel Submodule - shell: bash - run: | - # Fetch Kernel Submodule - echo "::group::Fetch Kernel Submodule" - git submodule update --checkout --init --depth 1 FreeRTOS/Source - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mCloned the Kernel\033[0m" - else - echo -e "\033[32;31mKernel Clone Failed...\033[0m" - exit 1 - fi + - env: + stepName: Fetch Kernel Submodule + name: ${{ env.stepName }} + shell: bash + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e + git submodule update --checkout --init --depth 1 FreeRTOS/Source + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + else + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" + exit 1 + fi - - name: Install MSP430 Toolchain - shell: bash - run: | - # Install MSP430 Toolchain - echo "::group::Install MSP430 Toolchain" - sudo apt-get -y update - sudo apt-get -y install gcc-msp430 build-essential - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mInstalled the MSP430 Toolchain\033[0m" - else - echo -e "\033[32;31mInstalling the MSP430 ToolchainFailed...\033[0m" - exit 1 - fi + - env: + stepName: Install MSP430 Toolchain + name: ${{ env.stepName }} + shell: bash + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e + sudo apt-get -y update + sudo apt-get -y install gcc-msp430 build-essential + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + else + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" + exit 1 + fi - - name: Build msp430_GCC Demo - shell: bash - working-directory: FreeRTOS/Demo/msp430_GCC - run: | - # Build msp430_GCC Demo - echo "::group::Build msp430_GCC Demo" - make -j - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuilt the msp430_GCC Demo\033[0m" - else - echo -e "\033[32;31mBuilding the msp430_GCC Demo Failed...\033[0m" - exit 1 - fi + - env: + stepName: Build msp430_GCC Demo + name: ${{ env.stepName }} + shell: bash + working-directory: FreeRTOS/Demo/msp430_GCC + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e + make -j + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + else + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" + exit 1 + fi ARM-GCC: name: GNU ARM Toolchain runs-on: ubuntu-latest steps: - - name: Checkout Repository - uses: actions/checkout@v2 + - env: + stepName: Checkout Repository + name: ${{ env.stepName }} + uses: actions/checkout@v3 - - name: Fetch Kernel Submodule + - env: + stepName: Fetch Kernel Submodule + name: ${{ env.stepName }} shell: bash run: | - # Fetch Kernel Submodule - echo "::group::Fetch Kernel Submodule" - git submodule update --checkout --init --depth 1 FreeRTOS/Source - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mCloned the Kernel\033[0m" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e + git submodule update --checkout --init --depth 1 FreeRTOS/Source FreeRTOS/Demo/ThirdParty/Community-Supported-Demos + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mKernel Clone Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Fetch Community-Supported-Demos Submodule + - env: + stepName: Install GNU ARM Toolchain + name: Install GNU ARM Toolchain shell: bash run: | - # Fetch Community-Supported-Demos Submodule - echo "::group::Fetch Community-Supported-Demos Submodule" - git submodule update --checkout --init --depth 1 FreeRTOS/Demo/ThirdParty/Community-Supported-Demos - echo "::engdroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mCloned the Community-Supported-Demos\033[0m" - else - echo -e "\033[32;31mCommunity-Supported-Demos Clone Failed...\033[0m" - exit 1 - fi - - - name: Install GNU ARM Toolchain - shell: bash - run: | - # Install GNU ARM Toolchain - echo "::group::Install GNU ARM Toolchain" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e sudo apt-get -y update sudo apt-get -y install gcc-arm-none-eabi build-essential cmake git ninja-build python3-minimal - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mInstalled the GNU ARM Toolchain\033[0m" + sudo apt-get -y install qemu-system-arm qemu-efi + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mInstalling GNU ARM Toolchain Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Build CORTEX_MPU_M3_MPS2_QEMU_GCC Demo + - env: + stepName: Build CORTEX_MPU_M3_MPS2_QEMU_GCC Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS/Demo/CORTEX_MPU_M3_MPS2_QEMU_GCC run: | - # Build CORTEX_MPU_M3_MPS2_QEMU_GCC Demo - echo "::group::Build CORTEX_MPU_M3_MPS2_QEMU_GCC Demo" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e make -j - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuild CORTEX_MPU_M3_MPS2_QEMU_GCC Demo\033[0m" + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mBuild CORTEX_MPU_M3_MPS2_QEMU_GCC Demo Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Build CORTEX_LM3S102_GCC Demo + - env: + stepName: Build CORTEX_LM3S102_GCC Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS/Demo/CORTEX_LM3S102_GCC run: | - # Build CORTEX_LM3S102_GCC Demo - echo "::group::Build CORTEX_LM3S102_GCC Demo" - make -j - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuilt the CORTEX_LM3S102_GCC Demo Kernel\033[0m" - else - echo -e "\033[32;31mBuild CORTEX_LM3S102_GCC Demo Failed...\033[0m" - exit 1 - fi - - - name: Build CORTEX_M3_MPS2_QEMU_GCC Demo - shell: bash - working-directory: FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC - run: | - # Build CORTEX_M3_MPS2_QEMU_GCC Demo - echo "::group::Build CORTEX_M3_MPS2_QEMU_GCC Demo" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e make clean make -j - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuilt the CORTEX_M3_MPS2_QEMU_GCC Demo\033[0m" + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mBuild CORTEX_M3_MPS2_QEMU_GCC Demo Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Build CORTEX_M3_MPS2_QEMU_GCC Full Demo + - env: + stepName: Build CORTEX_M3_MPS2_QEMU_GCC Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC run: | - # Build CORTEX_M3_MPS2_QEMU_GCC Full Demo - echo "::group::Build CORTEX_M3_MPS2_QEMU_GCC Full Demo" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e + make clean + make -j + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + else + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" + exit 1 + fi + + - env: + stepName: Build CORTEX_M3_MPS2_QEMU_GCC Full Demo + name: ${{ env.stepName }} + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e make clean make FULL_DEMO=1 -j - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuilt the CORTEX_M3_MPS2_QEMU_GCC Full Demo\033[0m" + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mBuild CORTEX_M3_MPS2_QEMU_GCC Full Demo Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Build CORTEX_LM3S811_GCC Demo + - env: + stepName: Build CORTEX_LM3S811_GCC Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS/Demo/CORTEX_LM3S811_GCC run: | - # Build CORTEX_LM3S811_GCC Demo - echo "::group::Build CORTEX_LM3S811_GCC Demo" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e make -j - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuilt the CORTEX_LM3S811_GCC Demo\033[0m" + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mBuild CORTEX_LM3S811_GCC Demo Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Build CORTEX_M0+_RP2040 Demos + - env: + stepName: Build CORTEX_M0+_RP2040 Demos + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS/Demo/ThirdParty/Community-Supported-Demos/CORTEX_M0+_RP2040 run: | - # Build CORTEX_M0+_RP2040 Demos - echo "::group::Build CORTEX_M0+_RP2040 Demos" - git clone https://github.com/raspberrypi/pico-sdk.git - cmake -B build -DPICO_SDK_PATH=pico-sdk -GNinja - ninja -C build --verbose - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuilt CORTEX_M0+_RP2040 Demos\033[0m" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e + git clone https://github.com/raspberrypi/pico-sdk.git + cmake -B build -DPICO_SDK_PATH=pico-sdk -GNinja + ninja -C build --verbose + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + else + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" + exit 1 + fi + + - env: + stepName: Build Qemu Runner File + name: ${{ env.stepName }} + shell: bash + working-directory: .github/scripts + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + gcc qemu_reader.c -o ../../FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/qemu_reader.out + exitStatus=$? + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mBuild CORTEX_M0+_RP2040 Demos Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi - - name: Build CORTEX_MPS2_QEMU_IAR_GCC Demo + - env: + stepName: Build CORTEX_MPS2_QEMU_IAR_GCC Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC run: | - # Build CORTEX_MPS2_QEMU_IAR_GCC Demo - echo "::group::Build CORTEX_MPS2_QEMU_IAR_GCC Demo" + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + set +e make -C build/gcc -j - echo "::endgroup::" - if [ "$?" = "0" ]; then - echo -e "\033[32;3mBuilt the CORTEX_MPS2_QEMU_IAR_GCC Demo\033[0m" + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" else - echo -e "\033[32;31mBuild CORTEX_MPS2_QEMU_IAR_GCC Demo Failed...\033[0m" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" exit 1 fi + + - env: + stepName: Run and monitor CORTEX_MPS2_QEMU_IAR_GCC Demo + name: ${{ env.stepName }} + uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main + with: + exe-path: FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/qemu_reader.out + timeout-seconds: 20 + success-line: "Message received from software timer" + retry-attempts: 1 diff --git a/.github/workflows/freertos_plus_demos.yml b/.github/workflows/freertos_plus_demos.yml index 79fee021b..3c9efb234 100644 --- a/.github/workflows/freertos_plus_demos.yml +++ b/.github/workflows/freertos_plus_demos.yml @@ -6,6 +6,16 @@ on: pull_request: branches: [main] +env: + bashPass: \033[32;1mPASSED - + bashWarn: \033[33;1mWARNING - + bashFail: \033[31;1mFAILED - + bashEnd: \033[0m + + pwshPass: "`e[32;1mPASSED -" + pwshWarn: "`e[33;1mWARNING -" + pwshFail: "`e[31;1mFAILED -" + pwshEnd: "`e[0m" jobs: winsim_cellular: @@ -13,178 +23,342 @@ jobs: runs-on: windows-2019 steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - name: Fetch Submodules + - env: + stepName: Fetch Submodules + name: ${{ env.stepName}} shell: bash run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 \ - FreeRTOS/Source \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Interface \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/bg96 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/hl7802 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/sara-r4 \ - FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ - FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ - FreeRTOS-Plus/Source/coreJSON \ - FreeRTOS-Plus/Source/corePKCS11 \ - FreeRTOS-Plus/ThirdParty/mbedtls \ - FreeRTOS-Plus/ThirdParty/tinycbor + FreeRTOS/Source \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Interface \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/bg96 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/hl7802 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/sara-r4 \ + FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ + FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ + FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ + FreeRTOS-Plus/Source/coreJSON \ + FreeRTOS-Plus/Source/corePKCS11 \ + FreeRTOS-Plus/ThirdParty/mbedtls \ + FreeRTOS-Plus/ThirdParty/tinycbor git -C FreeRTOS-Plus/Source/corePKCS11 submodule update --checkout --init --depth 1 source/dependency/3rdparty/pkcs11 + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 - - name: Configure FreeRTOS+Cellular Demos + - env: + stepName: Configure FreeRTOS+Cellular Demos + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#define CELLULAR_COMM_INTERFACE_PORT ""' | tee -a */cellular_config.h echo '#define CELLULAR_APN ""' | tee -a */cellular_config.h echo '#ifndef DEMO_CONFIG_H_TEST_BUILD' | tee -a */demo_config.h - echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a */demo_config.h - echo ' #define democonfigMQTT_BROKER_ENDPOINT ""' | tee -a */demo_config.h - echo ' #define democonfigMQTT_BROKER_PORT ( 8883 )' | tee -a */demo_config.h - echo ' #define democonfigROOT_CA_PEM ""' | tee -a */demo_config.h - echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a */demo_config.h - echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a */demo_config.h - echo ' #define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 )' | tee -a */demo_config.h + echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a */demo_config.h + echo ' #define democonfigMQTT_BROKER_ENDPOINT ""' | tee -a */demo_config.h + echo ' #define democonfigMQTT_BROKER_PORT ( 8883 )' | tee -a */demo_config.h + echo ' #define democonfigROOT_CA_PEM ""' | tee -a */demo_config.h + echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a */demo_config.h + echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a */demo_config.h + echo ' #define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 )' | tee -a */demo_config.h echo '#endif /* DEMO_CONFIG_H_TEST_BUILD */' | tee -a */demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build Cellular MQTT Demo for BG96 + - env: + stepName: Build Cellular MQTT Demo for BG96 + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96 - run: msbuild mqtt_mutual_auth_demo_with_bg96.sln -t:rebuild -property:Configuration=Debug + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild mqtt_mutual_auth_demo_with_bg96.sln -t:rebuild -property:Configuration=Debug + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build Cellular MQTT Demo for HL7802 + - env: + stepName: Build Cellular MQTT Demo for HL7802 + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802 - run: msbuild mqtt_mutual_auth_demo_with_hl7802.sln -t:rebuild -property:Configuration=Debug + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild mqtt_mutual_auth_demo_with_hl7802.sln -t:rebuild -property:Configuration=Debug + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build Cellular MQTT Demo for SARA-R4 + - env: + stepName: Build Cellular MQTT Demo for SARA-R4 + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4 - run: msbuild mqtt_mutual_auth_demo_with_sara_r4.sln -t:rebuild -property:Configuration=Debug + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild mqtt_mutual_auth_demo_with_sara_r4.sln -t:rebuild -property:Configuration=Debug + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } winsim_coreHTTP: name: coreHTTP WinSim Demos runs-on: windows-2019 steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - name: Fetch Submodules + - env: + stepName: Fetch Submodules + name: ${{ env.stepName }} shell: bash run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 \ - FreeRTOS/Source \ - FreeRTOS-Plus/Source/AWS/sigv4 \ - FreeRTOS-Plus/Source/Application-Protocols/coreHTTP \ - FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ - FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ - FreeRTOS-Plus/Source/coreJSON \ - FreeRTOS-Plus/ThirdParty/mbedtls \ - FreeRTOS-Plus/ThirdParty/glib \ - FreeRTOS-Plus/ThirdParty/libslirp + FreeRTOS/Source \ + FreeRTOS-Plus/Source/AWS/sigv4 \ + FreeRTOS-Plus/Source/Application-Protocols/coreHTTP \ + FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ + FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ + FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ + FreeRTOS-Plus/Source/coreJSON \ + FreeRTOS-Plus/ThirdParty/mbedtls \ + FreeRTOS-Plus/ThirdParty/glib \ + FreeRTOS-Plus/ThirdParty/libslirp git -C FreeRTOS-Plus/Source/Application-Protocols/coreHTTP submodule update --checkout --init --depth 1 source/dependency/3rdparty/llhttp + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 - - name: Configure coreHTTP Demos + - env: + stepName: Configure coreHTTP Demos + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#ifndef DEMO_CONFIG_H_TEST_BUILD' | tee -a */demo_config.h - echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a */demo_config.h - echo ' #define democonfigSERVER_HOSTNAME ""' | tee -a */demo_config.h - echo ' #define democonfigAWS_IOT_ENDPOINT ""' | tee -a */demo_config.h - echo ' #define democonfigROOT_CA_PEM ""' | tee -a */demo_config.h - echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a */demo_config.h - echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a */demo_config.h - echo ' #define democonfigIOT_CRED_PROVIDER_ROOT_CA_PEM ""' | tee -a */demo_config.h - echo ' #define democonfigIOT_CREDENTIAL_PROVIDER_ENDPOINT ""' | tee -a */demo_config.h - echo ' #define democonfigIOT_CREDENTIAL_PROVIDER_ROLE ""' | tee -a */demo_config.h - echo ' #define democonfigIOT_THING_NAME ""' | tee -a */demo_config.h - echo ' #define democonfigS3_PRESIGNED_GET_URL "ABCDEF"' | tee -a */demo_config.h - echo ' #define democonfigS3_PRESIGNED_PUT_URL "ABCDEF"' | tee -a */demo_config.h - echo ' #define democonfigS3_ROOT_CA_PEM ""' | tee -a */demo_config.h - echo ' #define democonfigS3_BUCKET_NAME ""' | tee -a */demo_config.h - echo ' #define democonfigS3_BUCKET_REGION ""' | tee -a */demo_config.h - echo ' #define democonfigS3_OBJECT_NAME ""' | tee -a */demo_config.h + echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a */demo_config.h + echo ' #define democonfigSERVER_HOSTNAME ""' | tee -a */demo_config.h + echo ' #define democonfigAWS_IOT_ENDPOINT ""' | tee -a */demo_config.h + echo ' #define democonfigROOT_CA_PEM ""' | tee -a */demo_config.h + echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a */demo_config.h + echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a */demo_config.h + echo ' #define democonfigIOT_CRED_PROVIDER_ROOT_CA_PEM ""' | tee -a */demo_config.h + echo ' #define democonfigIOT_CREDENTIAL_PROVIDER_ENDPOINT ""' | tee -a */demo_config.h + echo ' #define democonfigIOT_CREDENTIAL_PROVIDER_ROLE ""' | tee -a */demo_config.h + echo ' #define democonfigIOT_THING_NAME ""' | tee -a */demo_config.h + echo ' #define democonfigS3_PRESIGNED_GET_URL "ABCDEF"' | tee -a */demo_config.h + echo ' #define democonfigS3_PRESIGNED_PUT_URL "ABCDEF"' | tee -a */demo_config.h + echo ' #define democonfigS3_ROOT_CA_PEM ""' | tee -a */demo_config.h + echo ' #define democonfigS3_BUCKET_NAME ""' | tee -a */demo_config.h + echo ' #define democonfigS3_BUCKET_REGION ""' | tee -a */demo_config.h + echo ' #define democonfigS3_OBJECT_NAME ""' | tee -a */demo_config.h echo '#endif /* DEMO_CONFIG_H_TEST_BUILD */' | tee -a */demo_config.h + exitStatus=$? + set -e + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build HTTP Plain Text Demo + - env: + stepName: Build HTTP Plain Text Demo + name: ${{ env.stepName }} id: build-http-plain-text-demo working-directory: FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext - run: msbuild http_plain_text_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild http_plain_text_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build HTTP Mutual Auth Demo + - env: + stepName: Build HTTP Mutual Auth Demo + name: ${{ env.stepName }} id: build-http-mutual-auth-demo working-directory: FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth - run: msbuild http_mutual_auth_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild http_mutual_auth_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build HTTP S3 Upload Demo + - env: + stepName: Build HTTP S3 Upload Demo + name: ${{ env.stepName }} id: build-http-s3-upload-demo working-directory: FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload - run: msbuild http_s3_upload_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild http_s3_upload_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build HTTP S3 Download Multithreaded Demo + - env: + stepName: Build HTTP S3 Download Multithreaded Demo + name: ${{ env.stepName }} id: build-http-s3-download-multithreaded-demo working-directory: FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded - run: msbuild http_s3_download_multithreaded_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild http_s3_download_multithreaded_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build HTTP S3 Download Demo + - env: + stepName: Build HTTP S3 Download Demo + name: ${{ env.stepName }} id: build-http-s3-download-demo working-directory: FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download - run: msbuild http_s3_download_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild http_s3_download_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } winsim_corePKCS11: name: corePKCS11 WinSim Demos runs-on: windows-2019 steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - name: Fetch Submodules + - env: + stepName: Fetch Submodules + name: ${{ env.stepName }} shell: bash run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 \ - FreeRTOS/Source \ - FreeRTOS-Plus/Source/AWS/fleet-provisioning \ - FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ - FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ - FreeRTOS-Plus/Source/coreJSON \ - FreeRTOS-Plus/Source/corePKCS11 \ - FreeRTOS-Plus/ThirdParty/mbedtls \ - FreeRTOS-Plus/ThirdParty/glib \ - FreeRTOS-Plus/ThirdParty/libslirp + FreeRTOS/Source \ + FreeRTOS-Plus/Source/AWS/fleet-provisioning \ + FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ + FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ + FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ + FreeRTOS-Plus/Source/coreJSON \ + FreeRTOS-Plus/Source/corePKCS11 \ + FreeRTOS-Plus/ThirdParty/mbedtls \ + FreeRTOS-Plus/ThirdParty/glib \ + FreeRTOS-Plus/ThirdParty/libslirp git -C FreeRTOS-Plus/Source/corePKCS11 submodule update --checkout --init --depth 1 source/dependency/3rdparty/pkcs11 + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 - - name: Install meson - run: pip install meson - - - name: Install Glib - continue-on-error: true - shell: cmd + - env: + stepName: Install Glib + name: ${{ env.stepName }} + working-directory: FreeRTOS-Plus\ThirdParty\glib run: | - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" - cd FreeRTOS-Plus/ThirdParty/glib + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + Push-Location + Get-Location + & "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\Launch-VsDevShell.ps1" + Get-Location + Pop-Location + + pip install meson meson setup build --backend=vs2019 -Dselinux=disabled -Dxattr=false -Dbsymbolic_functions=false -Dtests=false -Dglib_debug=disabled -Dglib_assert=false --buildtype=release meson compile -C build - - name: Build corePKCS11 Demo + echo "::endgroup::" + if(Test-Path -Path build\glib\glib-2.0.lib) { + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 0 + }else { + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } + + - env: + stepName: Build corePKCS11 Demo + name: ${{ env.stepName }} id: build-corePKCS11-demo working-directory: FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator - run: msbuild CorePKCS11_Demos.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild CorePKCS11_Demos.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Run and monitor corePKCS11 Demo - if: success() || failure() && steps.build-corePKCS11-demo.outcome == 'success' + - env: + stepName: Run and monitor corePKCS11 Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/Debug_with_Libslirp/CorePKCS11_Demos.exe @@ -199,55 +373,75 @@ jobs: runs-on: windows-2019 steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - name: Fetch Submodules + - env: + stepName: Fetch Submodules + name: ${{ env.stepName }} shell: bash run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 \ - FreeRTOS/Source \ - FreeRTOS-Plus/Source/AWS/device-defender \ - FreeRTOS-Plus/Source/AWS/device-shadow \ - FreeRTOS-Plus/Source/AWS/fleet-provisioning \ - FreeRTOS-Plus/Source/AWS/jobs \ - FreeRTOS-Plus/Source/AWS/ota \ - FreeRTOS-Plus/Source/AWS/sigv4 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Interface \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/bg96 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/hl7802 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/sara-r4 \ - FreeRTOS-Plus/Source/Application-Protocols/coreHTTP \ - FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ - FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent \ - FreeRTOS-Plus/Source/Application-Protocols/coreSNTP \ - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ - FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ - FreeRTOS-Plus/Source/coreJSON \ - FreeRTOS-Plus/Source/corePKCS11 \ - FreeRTOS-Plus/ThirdParty/mbedtls \ - FreeRTOS-Plus/ThirdParty/tinycbor \ - FreeRTOS-Plus/ThirdParty/wolfSSL \ - FreeRTOS-Plus/ThirdParty/glib \ - FreeRTOS-Plus/ThirdParty/libslirp + FreeRTOS/Source \ + FreeRTOS-Plus/Source/AWS/device-defender \ + FreeRTOS-Plus/Source/AWS/device-shadow \ + FreeRTOS-Plus/Source/AWS/fleet-provisioning \ + FreeRTOS-Plus/Source/AWS/jobs \ + FreeRTOS-Plus/Source/AWS/ota \ + FreeRTOS-Plus/Source/AWS/sigv4 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Interface \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/bg96 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/hl7802 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/sara-r4 \ + FreeRTOS-Plus/Source/Application-Protocols/coreHTTP \ + FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ + FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent \ + FreeRTOS-Plus/Source/Application-Protocols/coreSNTP \ + FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ + FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ + FreeRTOS-Plus/Source/coreJSON \ + FreeRTOS-Plus/Source/corePKCS11 \ + FreeRTOS-Plus/ThirdParty/mbedtls \ + FreeRTOS-Plus/ThirdParty/tinycbor \ + FreeRTOS-Plus/ThirdParty/wolfSSL \ + FreeRTOS-Plus/ThirdParty/glib \ + FreeRTOS-Plus/ThirdParty/libslirp git -C FreeRTOS-Plus/Source/Application-Protocols/coreHTTP submodule update --checkout --init --depth 1 source/dependency/3rdparty/llhttp git -C FreeRTOS-Plus/Source/corePKCS11 submodule update --checkout --init --depth 1 source/dependency/3rdparty/pkcs11 + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 - - name: Install meson - run: pip install meson - - - name: Install Glib - continue-on-error: true - shell: cmd + - env: + stepName: Install Glib + name: ${{ env.stepName }} + working-directory: FreeRTOS-Plus\ThirdParty\glib run: | - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" - cd FreeRTOS-Plus/ThirdParty/glib + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + Push-Location + Get-Location + & "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\Launch-VsDevShell.ps1" + Get-Location + Pop-Location + + pip install meson meson setup build --backend=vs2019 -Dselinux=disabled -Dxattr=false -Dbsymbolic_functions=false -Dtests=false -Dglib_debug=disabled -Dglib_assert=false --buildtype=release meson compile -C build + echo "::endgroup::" + if(Test-Path -Path build\glib\glib-2.0.lib) { + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 0 + }else { + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } + - name: Generate SSL credentials id: generate-credentials uses: FreeRTOS/CI-CD-GitHub-Actions/ssl-credential-creator@main @@ -256,33 +450,57 @@ jobs: id: mqtt-broker uses: FreeRTOS/CI-CD-GitHub-Actions/localhost-mqtt-broker@main with: - root-ca-cert-path: ${{ steps.generate-credentials.outputs.root-ca-cert-path }} - server-priv-key-path: ${{ steps.generate-credentials.outputs.server-priv-key-path }} - server-cert-path: ${{ steps.generate-credentials.outputs.server-cert-path }} + root-ca-cert-path: + ${{ steps.generate-credentials.outputs.root-ca-cert-path }} + server-priv-key-path: + ${{ steps.generate-credentials.outputs.server-priv-key-path }} + server-cert-path: + ${{ steps.generate-credentials.outputs.server-cert-path }} - - name: Update main.c to force stdout to write immediately + - env: + stepName: Update main.c to force stdout to write immediately + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/Common run: | $content = Get-Content -Path 'main.c' -Raw $newContent = $content -replace 'int\s+main(.*?)void(.*?)\r?\n\s*{', 'int main( void ){setvbuf( stdout, NULL, _IONBF, 0 );' $newContent | Set-Content -Path 'main.c' - - name: Configure MQTT Plain Text Demo + - env: + stepName: Configure MQTT Plain Text Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#define democonfigCLIENT_IDENTIFIER "mqtt_demo_test"' >> demo_config.h echo '#define democonfigMQTT_BROKER_ENDPOINT "127.0.0.1"' >> demo_config.h echo '#define democonfigMQTT_BROKER_PORT ( 1883 )' >> demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build MQTT Plain Text Demo + - env: + stepName: Build MQTT Plain Text Demo + name: ${{ env.stepName }} id: build-mqtt-plain-text-demo working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" msbuild mqtt_plain_text_demo.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Run and monitor MQTT Plain Text Demo - if: success() || failure() && steps.build-mqtt-plain-text-demo.outcome == 'success' + - env: + stepName: Run and monitor MQTT Plain Text Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/Debug_with_Libslirp/MQTT_Plain_Text.exe @@ -291,10 +509,14 @@ jobs: success-line: "Demo completed successfully" retry-attempts: 3 - - name: Configure MQTT Basic TLS Demo + - env: + stepName: Configure MQTT Basic TLS Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#define democonfigROOT_CA_PEM \' >> demo_config.h sed 's/.*/"&\\n"\\/' ${{ steps.generate-credentials.outputs.root-ca-cert-path }} >> root_ca_cert.txt sed '$ s/.$//' root_ca_cert.txt >> demo_config.h @@ -302,14 +524,31 @@ jobs: echo '#define democonfigMQTT_BROKER_ENDPOINT "127.0.0.1"' >> demo_config.h echo '#define democonfigMQTT_BROKER_PORT ( 8883 )' >> demo_config.h sed -i -z "s/define[[:space:]]*democonfigDISABLE_SNI[[:space:]]*([[:space:]]*[a-zA-Z0-9]\+[[:space:]]*)/define democonfigDISABLE_SNI ( pdTRUE )/g" demo_config.h + exitStatus=$? + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build MQTT Basic TLS Demo + - env: + stepName: Build MQTT Basic TLS Demo + name: ${{ env.stepName }} id: build-mqtt-basic-tls-demo working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS - run: msbuild mqtt_basic_tls_demo.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild mqtt_basic_tls_demo.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Run and monitor MQTT Basic TLS Demo - if: success() || failure() && steps.build-mqtt-basic-tls-demo.outcome == 'success' + - env: + stepName: Run and monitor MQTT Basic TLS Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/Debug_with_Libslirp/MQTT_Basic_TLS.exe @@ -318,10 +557,14 @@ jobs: success-line: "Demo completed successfully" retry-attempts: 3 - - name: Configure MQTT Mutual Authentication with mbedtls Demo + - env: + stepName: Configure MQTT Mutual Authentication with mbedtls Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#define democonfigROOT_CA_PEM \' >> demo_config.h sed 's/.*/"&\\n"\\/' ${{ steps.generate-credentials.outputs.root-ca-cert-path }} >> root_ca_cert.txt sed '$ s/.$//' root_ca_cert.txt >> demo_config.h @@ -335,14 +578,30 @@ jobs: echo '#define democonfigMQTT_BROKER_ENDPOINT "127.0.0.1"' >> demo_config.h echo '#define democonfigMQTT_BROKER_PORT ( 8883 )' >> demo_config.h sed -i -z "s/define[[:space:]]*democonfigDISABLE_SNI[[:space:]]*([[:space:]]*[a-zA-Z0-9]\+[[:space:]]*)/define democonfigDISABLE_SNI ( pdTRUE )/g" demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build MQTT Mutual Authentication with mbedtls Demo + - env: + stepName: Build MQTT Mutual Authentication with mbedtls Demo + name: ${{ env.stepName }} id: build-mqtt-mutual-auth-demo working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth - run: msbuild mqtt_mutual_auth_demo.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild mqtt_mutual_auth_demo.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Run and monitor MQTT Mutual Authentication with mbedtls Demo - if: success() || failure() && steps.build-mqtt-mutual-auth-demo.outcome == 'success' + - env: + stepName: Run and monitor MQTT Mutual Authentication with mbedtls Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/Debug_with_Libslirp/MQTT_Mutual_Auth.exe @@ -351,24 +610,44 @@ jobs: success-line: "Demo completed successfully" retry-attempts: 3 - - name: Configure MQTT Keep Alive Demo + - env: + stepName: Configure MQTT Keep Alive Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#ifndef DEMO_CONFIG_H_TEST_BUILD' >> demo_config.h - echo ' #define DEMO_CONFIG_H_TEST_BUILD' >> demo_config.h - echo ' #define democonfigCLIENT_IDENTIFIER "mqtt_demo_test"' >> demo_config.h - echo ' #define democonfigMQTT_BROKER_ENDPOINT "127.0.0.1"' >> demo_config.h - echo ' #define democonfigMQTT_BROKER_PORT ( 1883 )' >> demo_config.h + echo ' #define DEMO_CONFIG_H_TEST_BUILD' >> demo_config.h + echo ' #define democonfigCLIENT_IDENTIFIER "mqtt_demo_test"' >> demo_config.h + echo ' #define democonfigMQTT_BROKER_ENDPOINT "127.0.0.1"' >> demo_config.h + echo ' #define democonfigMQTT_BROKER_PORT ( 1883 )' >> demo_config.h echo '#endif /* DEMO_CONFIG_H_TEST_BUILD */' >> demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build MQTT Keep Alive Demo + - env: + stepName: Build MQTT Keep Alive Demo + name: ${{ env.stepName }} id: build-mqtt-keep-alive-demo working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive - run: msbuild mqtt_keep_alive_demo.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild mqtt_keep_alive_demo.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Run and monitor MQTT Keep Alive Demo - if: success() || failure() && steps.build-mqtt-keep-alive-demo.outcome == 'success' + - env: + stepName: Run and monitor MQTT Keep Alive Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/Debug_with_Libslirp/MQTT_Keep_Alive.exe @@ -377,21 +656,33 @@ jobs: success-line: "Demo completed successfully" retry-attempts: 3 - - name: Configure MQTT Serializer Demo + - env: + stepName: Configure MQTT Serializer Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#define democonfigCLIENT_IDENTIFIER "mqtt_demo_test"' >> demo_config.h echo '#define democonfigMQTT_BROKER_ENDPOINT "127.0.0.1"' >> demo_config.h echo '#define democonfigMQTT_BROKER_PORT ( 1883 )' >> demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build MQTT Serializer Demo + - env: + stepName: Build MQTT Serializer Demo + name: ${{ env.stepName }} id: build-mqtt-serializer-demo working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer - run: msbuild mqtt_serializer_demo.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + run: + msbuild mqtt_serializer_demo.sln -t:rebuild + -property:Configuration=Debug_with_Libslirp + -property:Platform=Win32 -m - - name: Run and monitor MQTT Serializer Demo - if: success() || failure() && steps.build-mqtt-serializer-demo.outcome == 'success' + - env: + stepName: Run and monitor MQTT Serializer Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/Debug_with_Libslirp/MQTT_Serializer.exe @@ -400,10 +691,14 @@ jobs: success-line: "Demo completed successfully" retry-attempts: 3 - - name: Configure MQTT Mutual Authentication with WolfSSL Demo + - env: + stepName: Configure MQTT Mutual Authentication with WolfSSL Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#define democonfigCREDENTIALS_IN_BUFFER 0' >> demo_config.h echo '#define democonfigROOT_CA_PEM \' >> demo_config.h sed 's/.*/"&\\n"\\/' ${{ steps.generate-credentials.outputs.root-ca-cert-path }} >> root_ca_cert.txt @@ -417,14 +712,30 @@ jobs: echo '#define democonfigCLIENT_IDENTIFIER "mqtt_demo_test"' >> demo_config.h echo '#define democonfigMQTT_BROKER_ENDPOINT "127.0.0.1"' >> demo_config.h echo '#define democonfigMQTT_BROKER_PORT ( 8883 )' >> demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build MQTT Mutual Authentication with WolfSSL Demo + - env: + stepName: Build MQTT Mutual Authentication with WolfSSL Demo + name: ${{ env.stepName }} id: build-mqtt-mutual-auth-with-wolfssl-demo working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL - run: msbuild mqtt_mutual_auth_demo_wolfSSL.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild mqtt_mutual_auth_demo_wolfSSL.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Run and monitor MQTT Mutual Authentication with WolfSSL Demo - if: success() || failure() && steps.build-mqtt-mutual-auth-with-wolfssl-demo.outcome == 'success' + - env: + stepName: Run and monitor MQTT Mutual Authentication with WolfSSL Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/Debug/RTOSDemo.exe @@ -433,160 +744,311 @@ jobs: success-line: "Demo completed successfully" retry-attempts: 3 - - name: Configure MQTT Multi-Task Demo + - env: + stepName: Configure MQTT Multi-Task Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#ifndef DEMO_CONFIG_H_TEST_BUILD' | tee -a demo_config.h - echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a demo_config.h - echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a demo_config.h - echo ' #define democonfigCLIENT_IDENTIFIER ""' | tee -a demo_config.h - echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a demo_config.h - echo ' #define democonfigMQTT_BROKER_ENDPOINT ""' | tee -a demo_config.h - echo ' #define democonfigMQTT_BROKER_PORT ( 8883 )' | tee -a demo_config.h - echo ' #define democonfigROOT_CA_PEM ""' | tee -a demo_config.h + echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a demo_config.h + echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a demo_config.h + echo ' #define democonfigCLIENT_IDENTIFIER ""' | tee -a demo_config.h + echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a demo_config.h + echo ' #define democonfigMQTT_BROKER_ENDPOINT ""' | tee -a demo_config.h + echo ' #define democonfigMQTT_BROKER_PORT ( 8883 )' | tee -a demo_config.h + echo ' #define democonfigROOT_CA_PEM ""' | tee -a demo_config.h echo '#endif /* DEMO_CONFIG_H_TEST_BUILD */' | tee -a demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build MQTT Multi-Task Demo + - env: + stepName: Build MQTT Multi-Task Demo + name: ${{ env.stepName }} id: build-mqtt-multitask-demo working-directory: FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask - run: msbuild mqtt_multitask_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild mqtt_multitask_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Configure corePKCS11_MQTT_Mutual_Auth_Windows_Simulator + - env: + stepName: Configure corePKCS11_MQTT_Mutual_Auth_Windows_Simulator + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#ifndef DEMO_CONFIG_H_TEST_BUILD' | tee -a demo_config.h - echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a demo_config.h - echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a demo_config.h - echo ' #define democonfigCLIENT_IDENTIFIER ""' | tee -a demo_config.h - echo ' #define democonfigTHING_NAME ""' | tee -a demo_config.h - echo ' #define democonfigPROVISIONING_TEMPLATE_NAME ""' | tee -a demo_config.h - echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a demo_config.h - echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a demo_config.h - echo ' #define democonfigMQTT_BROKER_ENDPOINT ""' | tee -a demo_config.h - echo ' #define democonfigMQTT_BROKER_PORT ( 8883 )' | tee -a demo_config.h - echo ' #define democonfigROOT_CA_PEM ""' | tee -a demo_config.h + echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a demo_config.h + echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a demo_config.h + echo ' #define democonfigCLIENT_IDENTIFIER ""' | tee -a demo_config.h + echo ' #define democonfigTHING_NAME ""' | tee -a demo_config.h + echo ' #define democonfigPROVISIONING_TEMPLATE_NAME ""' | tee -a demo_config.h + echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a demo_config.h + echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a demo_config.h + echo ' #define democonfigMQTT_BROKER_ENDPOINT ""' | tee -a demo_config.h + echo ' #define democonfigMQTT_BROKER_PORT ( 8883 )' | tee -a demo_config.h + echo ' #define democonfigROOT_CA_PEM ""' | tee -a demo_config.h echo '#endif /* DEMO_CONFIG_H_TEST_BUILD */' | tee -a demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build corePKCS11 + coreMQTT Mutual Auth Demo + - env: + stepName: Build corePKCS11 + coreMQTT Mutual Auth Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator - run: msbuild corePKCS11_MQTT_Mutual_Auth.sln -t:rebuild -property:Configuration=Debug -property:Platform=Win32 -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild corePKCS11_MQTT_Mutual_Auth.sln -t:rebuild -property:Configuration=Debug -property:Platform=Win32 -m - - name: Configure coreSNTP_Windows_Simulator + - env: + stepName: Configure coreSNTP_Windows_Simulator + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#ifndef DEMO_CONFIG_H_TEST_BUILD' | tee -a demo_config.h - echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a demo_config.h - echo ' #define democonfigLIST_OF_TIME_SERVERS ""' | tee -a demo_config.h - echo ' #define democonfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS ""' | tee -a demo_config.h - echo ' #define democonfigLIST_OF_AUTHENTICATION_KEY_IDS ""' | tee -a demo_config.h - echo ' #define democonfigSNTP_CLIENT_POLLING_INTERVAL_SECONDS 500U' | tee -a demo_config.h + echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a demo_config.h + echo ' #define democonfigLIST_OF_TIME_SERVERS ""' | tee -a demo_config.h + echo ' #define democonfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS ""' | tee -a demo_config.h + echo ' #define democonfigLIST_OF_AUTHENTICATION_KEY_IDS ""' | tee -a demo_config.h + echo ' #define democonfigSNTP_CLIENT_POLLING_INTERVAL_SECONDS 500U' | tee -a demo_config.h echo '#endif /* DEMO_CONFIG_H_TEST_BUILD */' | tee -a demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build coreSNTP Demo + - env: + stepName: Build coreSNTP Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator - run: msbuild core_sntp_demo.sln -t:rebuild -property:Configuration=Debug -property:Platform=Win32 -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild core_sntp_demo.sln -t:rebuild -property:Configuration=Debug -property:Platform=Win32 -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } + winsim_aws_iot: name: AWS IoT Windows Simulator Demos runs-on: windows-2019 - continue-on-error: true steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - name: Fetch Submodules + - env: + stepName: Fetch Submodules + name: ${{ env.stepName }} shell: bash run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 \ - FreeRTOS/Source \ - FreeRTOS-Plus/Source/AWS/device-defender \ - FreeRTOS-Plus/Source/AWS/device-shadow \ - FreeRTOS-Plus/Source/AWS/fleet-provisioning \ - FreeRTOS-Plus/Source/AWS/jobs \ - FreeRTOS-Plus/Source/AWS/ota \ - FreeRTOS-Plus/Source/AWS/sigv4 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Interface \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/bg96 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/hl7802 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/sara-r4 \ - FreeRTOS-Plus/Source/Application-Protocols/coreHTTP \ - FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ - FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent \ - FreeRTOS-Plus/Source/Application-Protocols/coreSNTP \ - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ - FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ - FreeRTOS-Plus/Source/coreJSON \ - FreeRTOS-Plus/Source/corePKCS11 \ - FreeRTOS-Plus/ThirdParty/mbedtls \ - FreeRTOS-Plus/ThirdParty/tinycbor \ - FreeRTOS-Plus/ThirdParty/wolfSSL + FreeRTOS/Source \ + FreeRTOS-Plus/Source/AWS/device-defender \ + FreeRTOS-Plus/Source/AWS/device-shadow \ + FreeRTOS-Plus/Source/AWS/fleet-provisioning \ + FreeRTOS-Plus/Source/AWS/jobs \ + FreeRTOS-Plus/Source/AWS/ota \ + FreeRTOS-Plus/Source/AWS/sigv4 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Interface \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/bg96 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/hl7802 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/sara-r4 \ + FreeRTOS-Plus/Source/Application-Protocols/coreHTTP \ + FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ + FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent \ + FreeRTOS-Plus/Source/Application-Protocols/coreSNTP \ + FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ + FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ + FreeRTOS-Plus/Source/coreJSON \ + FreeRTOS-Plus/Source/corePKCS11 \ + FreeRTOS-Plus/ThirdParty/mbedtls \ + FreeRTOS-Plus/ThirdParty/tinycbor \ + FreeRTOS-Plus/ThirdParty/wolfSSL git -C FreeRTOS-Plus/Source/Application-Protocols/coreHTTP submodule update --checkout --init --depth 1 source/dependency/3rdparty/llhttp git -C FreeRTOS-Plus/Source/corePKCS11 submodule update --checkout --init --depth 1 source/dependency/3rdparty/pkcs11 + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 - - name: Adjust Configuration files + - env: + stepName: Adjust Configuration files + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/AWS run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" echo '#ifndef DEMO_CONFIG_H_TEST_BUILD' | tee -a */*/demo_config.h - echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a */*/demo_config.h - echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a */*/demo_config.h - echo ' #define democonfigCLIENT_IDENTIFIER ""' | tee -a */*/demo_config.h - echo ' #define democonfigTHING_NAME ""' | tee -a */*/demo_config.h - echo ' #define democonfigPROVISIONING_TEMPLATE_NAME ""' | tee -a */*/demo_config.h - echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a */*/demo_config.h - echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a */*/demo_config.h - echo ' #define democonfigMQTT_BROKER_ENDPOINT ""' | tee -a */*/demo_config.h - echo ' #define democonfigMQTT_BROKER_PORT ( 8883 )' | tee -a */*/demo_config.h - echo ' #define democonfigROOT_CA_PEM ""' | tee -a */*/demo_config.h + echo ' #define DEMO_CONFIG_H_TEST_BUILD' | tee -a */*/demo_config.h + echo ' #define democonfigCLIENT_CERTIFICATE_PEM ""' | tee -a */*/demo_config.h + echo ' #define democonfigCLIENT_IDENTIFIER ""' | tee -a */*/demo_config.h + echo ' #define democonfigTHING_NAME ""' | tee -a */*/demo_config.h + echo ' #define democonfigPROVISIONING_TEMPLATE_NAME ""' | tee -a */*/demo_config.h + echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a */*/demo_config.h + echo ' #define democonfigCLIENT_PRIVATE_KEY_PEM ""' | tee -a */*/demo_config.h + echo ' #define democonfigMQTT_BROKER_ENDPOINT ""' | tee -a */*/demo_config.h + echo ' #define democonfigMQTT_BROKER_PORT ( 8883 )' | tee -a */*/demo_config.h + echo ' #define democonfigROOT_CA_PEM ""' | tee -a */*/demo_config.h echo '#endif /* DEMO_CONFIG_H_TEST_BUILD */' | tee -a */*/demo_config.h + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build AWS IoT Device Defender Demo + - env: + stepName: Build AWS IoT Device Defender Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo - run: msbuild defender_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild defender_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build AWS IoT Device Shadow Demo + - env: + stepName: Build AWS IoT Device Shadow Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo - run: msbuild shadow_main_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild shadow_main_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build AWS IoT Fleet Provisioning Demo + - env: + stepName: Build AWS IoT Fleet Provisioning Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo - run: msbuild fleet_provisioning_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild fleet_provisioning_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build AWS IoT Jobs Demo + - env: + stepName: Build AWS IoT Jobs Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo - run: msbuild jobs_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild jobs_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build AWS IoT OTA over MQTT + - env: + stepName: Build AWS IoT OTA over MQTT + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo - run: msbuild ota_over_mqtt_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild ota_over_mqtt_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } - - name: Build AWS IoT OTA over HTTP + - env: + stepName: Build AWS IoT OTA over HTTP + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo - run: msbuild ota_over_http_demo.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild ota_over_http_demo.sln -t:rebuild -property:Configuration=Debug -m + if($? -eq 1) { + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + }else { + echo "::endgroup::" + echo "${{ env.pwshFail }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } plus_tcp_posix: name: FreeRTOS+TCP Posix Simulator Demo runs-on: ubuntu-22.04 steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - name: Fetch Submodules + - env: + stepName: Fetch Submodules shell: bash run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 \ - FreeRTOS/Source \ - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP + FreeRTOS/Source \ + FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Install prerequisite packages - run: sudo apt-get install -y git build-essential libglib2.0-dev libslirp-dev + - env: + stepName: Install prerequisite packages + name: ${{ env.stepName }} + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + sudo apt-get install -y git build-essential libglib2.0-dev libslirp-dev + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - name: Start localhost Echo server id: echo-server @@ -594,16 +1056,23 @@ jobs: with: port_number: 5000 - - name: Build FreeRTOS+TCP Echo Posix Demo + - env: + stepName: Build FreeRTOS+TCP Echo Posix Demo + name: ${{ env.stepName }} id: build-echo-posix-demo working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" sed -i -z "s/define[[:space:]]*echoECHO_PORT[[:space:]]*([[:space:]]*[0-9]\+[[:space:]]*)/define echoECHO_PORT ( 5000 )/g" TCPEchoClient_SingleTasks.c sed -i -z "s/int[[:space:]]*main[[:space:]]*([[:space:]]*void[[:space:]]*)\n{/int main( void ){setvbuf( stdout, NULL, _IONBF, 0 );/g" main.c make -j TRACE_ON_ENTER=0 + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Run and monitor FreeRTOS+TCP Echo Posix Demo - if: success() || failure() && steps.build-echo-posix-demo.outcome == 'success' + - env: + stepName: Run and monitor FreeRTOS+TCP Echo Posix Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/build/posix_tcp_demo @@ -614,24 +1083,44 @@ jobs: plus_tcp_arm: name: FreeRTOS+TCP QEMU ARM MPS2 AN385 - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - name: Fetch Submodules + - env: + stepName: Fetch Submodules + name: ${{ env.stepName }} shell: bash run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 \ - FreeRTOS/Source \ - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP + FreeRTOS/Source \ + FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Install prerequisite packages - run: sudo apt-get install -y git make gcc-arm-none-eabi + - env: + stepName: Install prerequisite packages + name: ${{ env.stepName }} + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + sudo apt-get install -y git make gcc-arm-none-eabi + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build FreeRTOS+TCP Minimal Demo + - env: + stepName: Build FreeRTOS+TCP Minimal Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2 - run: make -j + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" + make -j + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " plus_tcp_winsim: name: FreeRTOS+TCP Windows Simulator Demos @@ -639,57 +1128,83 @@ jobs: continue-on-error: true steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - name: Fetch Submodules + - env: + stepName: Fetch Submodules + name: ${{ env.stepName }} shell: bash run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 \ - FreeRTOS/Source \ - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ - FreeRTOS-Plus/ThirdParty/mbedtls \ - FreeRTOS-Plus/ThirdParty/wolfSSL \ - FreeRTOS-Plus/ThirdParty/glib \ - FreeRTOS-Plus/ThirdParty/libslirp + FreeRTOS/Source \ + FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ + FreeRTOS-Plus/ThirdParty/mbedtls \ + FreeRTOS-Plus/ThirdParty/wolfSSL \ + FreeRTOS-Plus/ThirdParty/glib \ + FreeRTOS-Plus/ThirdParty/libslirp + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 - - name: Install meson - run: pip install meson - - - name: Install Glib - continue-on-error: true - shell: cmd + - env: + stepName: Install Glib + name: ${{ env.stepName }} + working-directory: FreeRTOS-Plus\ThirdParty\glib run: | - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" - cd FreeRTOS-Plus/ThirdParty/glib + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + Push-Location + Get-Location + & "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\Launch-VsDevShell.ps1" + Get-Location + Pop-Location + + pip install meson meson setup build --backend=vs2019 -Dselinux=disabled -Dxattr=false -Dbsymbolic_functions=false -Dtests=false -Dglib_debug=disabled -Dglib_assert=false --buildtype=release meson compile -C build + echo "::endgroup::" + if(Test-Path -Path build\glib\glib-2.0.lib) { + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 0 + }else { + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" + exit 1 + } + - name: Start localhost Echo server id: echo-server uses: FreeRTOS/CI-CD-GitHub-Actions/localhost-echo-server@main with: port_number: 5000 - - name: Build FreeRTOS+TCP Minimal Demo + - env: + stepName: Build FreeRTOS+TCP Minimal Demo + name: ${{ env.stepName }} id: build-plus-tcp-minimal-demo working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" $content = Get-Content -Path 'DemoTasks\TCPEchoClient_SingleTasks.c' -Raw $newContent = $content -replace '#define\s+echoECHO_PORT.*', '#define echoECHO_PORT ( 5000 )' $newContent | Set-Content -Path 'DemoTasks\TCPEchoClient_SingleTasks.c' $content = Get-Content -Path 'tcp_echo_config.h' -Raw - $newContent = $content -replace '#define\s+configECHO_SERVER_ADDR.*', '#define configECHO_SERVER_ADDR "127.0.0.1"' + $newContent = $content -replace '#define\s+configECHO_SERVER_ADDR.*', '#define configECHO_SERVER_ADDR "127.0.0.1"' $newContent | Set-Content -Path 'tcp_echo_config.h' $content = Get-Content -Path 'main.c' -Raw $newContent = $content -replace 'int\s+main(.*?)void(.*?)\r?\n\s*{', 'int main( void ){setvbuf( stdout, NULL, _IONBF, 0 );' $newContent | Set-Content -Path 'main.c' msbuild FreeRTOS_Plus_TCP_Minimal.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" - - name: Run and monitor FreeRTOS+TCP Minimal Demo - if: success() || failure() && steps.build-plus-tcp-minimal-demo.outcome == 'success' + - env: + stepName: Run and monitor FreeRTOS+TCP Minimal Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/Debug_with_Libslirp/FreeRTOS_Plus_TCP_Minimal.exe @@ -702,10 +1217,14 @@ jobs: id: generate-credentials uses: FreeRTOS/CI-CD-GitHub-Actions/ssl-credential-creator@main - - name: Configure FreeRTOS+WolfSSL Demo + - env: + stepName: Configure FreeRTOS+WolfSSL Demo + name: ${{ env.stepName }} shell: bash working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" cp ${{ steps.generate-credentials.outputs.root-ca-cert-path }} . cp ${{ steps.generate-credentials.outputs.server-cert-path }} . cp ${{ steps.generate-credentials.outputs.server-priv-key-path }} . @@ -713,29 +1232,42 @@ jobs: sed -i -z "s/server-cert.pem/server_cert.crt/g" SecureTCPServerTask.c sed -i -z "s/server-key.pem/server_priv_key.key/g" SecureTCPServerTask.c sed -i -z "s/ca-cert.pem/root_ca_cert.crt/g" SecureTCPClientTask.c + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - - name: Build FreeRTOS+WolfSSL Demo + - env: + stepName: Build FreeRTOS+WolfSSL Demo + name: ${{ env.stepName }} id: build-freertos-wolfssl-demo working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator - run: msbuild FreeRTOS_Plus_WolfSSL.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + continue-on-error: true + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild FreeRTOS_Plus_WolfSSL.sln -t:rebuild -property:Configuration=Debug_with_Libslirp -property:Platform=Win32 -m + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" - - name: Run and monitor FreeRTOS+WolfSSL Demo - if: success() || failure() && steps.build-freertos-wolfssl-demo.outcome == 'success' + - env: + stepName: Run and monitor FreeRTOS+WolfSSL Demo + name: ${{ env.stepName }} uses: FreeRTOS/CI-CD-GitHub-Actions/executable-monitor@main with: exe-path: FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/Debug_with_Libslirp/FreeRTOS_Plus_WolfSSL_Windows_Simulator.exe log-dir: demo_run_logs timeout-seconds: 60 - success-line: "Received by the secure server: Message number 9" + success-line: + "Received by the secure server: Message number 9" retry-attempts: 3 - - name: Build FreeRTOS+TCP UDP CLI Demo + - env: + stepName: Build FreeRTOS+TCP UDP CLI Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator - run: msbuild FreeRTOS_Plus_UDP_with_CLI.sln -t:rebuild -property:Configuration=Debug -m - - - name: Build FreeRTOS+TCP IPv6 Demo - working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo - run: msbuild FreeRTOS_Plus_TCP_IPv6_Multi.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild FreeRTOS_Plus_UDP_with_CLI.sln -t:rebuild -property:Configuration=Debug -m + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" winsim_plus_demos: name: FreeRTOS+CLI Windows Simulator Demos @@ -743,45 +1275,64 @@ jobs: continue-on-error: true steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - name: Fetch Submodules + - env: + stepName: Fetch Submodules + name: ${{ env.stepName }} shell: bash run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.stepName }}" git submodule update --checkout --init --depth 1 \ - FreeRTOS/Source \ - FreeRTOS-Plus/Source/AWS/device-defender \ - FreeRTOS-Plus/Source/AWS/device-shadow \ - FreeRTOS-Plus/Source/AWS/fleet-provisioning \ - FreeRTOS-Plus/Source/AWS/jobs \ - FreeRTOS-Plus/Source/AWS/ota \ - FreeRTOS-Plus/Source/AWS/sigv4 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Interface \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/bg96 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/hl7802 \ - FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/sara-r4 \ - FreeRTOS-Plus/Source/Application-Protocols/coreHTTP \ - FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ - FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent \ - FreeRTOS-Plus/Source/Application-Protocols/coreSNTP \ - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ - FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ - FreeRTOS-Plus/Source/coreJSON \ - FreeRTOS-Plus/Source/corePKCS11 \ - FreeRTOS-Plus/ThirdParty/mbedtls \ - FreeRTOS-Plus/ThirdParty/tinycbor \ - FreeRTOS-Plus/ThirdParty/wolfSSL + FreeRTOS/Source \ + FreeRTOS-Plus/Source/AWS/device-defender \ + FreeRTOS-Plus/Source/AWS/device-shadow \ + FreeRTOS-Plus/Source/AWS/fleet-provisioning \ + FreeRTOS-Plus/Source/AWS/jobs \ + FreeRTOS-Plus/Source/AWS/ota \ + FreeRTOS-Plus/Source/AWS/sigv4 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Interface \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/bg96 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/hl7802 \ + FreeRTOS-Plus/Source/FreeRTOS-Cellular-Modules/sara-r4 \ + FreeRTOS-Plus/Source/Application-Protocols/coreHTTP \ + FreeRTOS-Plus/Source/Application-Protocols/coreMQTT \ + FreeRTOS-Plus/Source/Application-Protocols/coreMQTT-Agent \ + FreeRTOS-Plus/Source/Application-Protocols/coreSNTP \ + FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP \ + FreeRTOS-Plus/Source/Utilities/backoff_algorithm \ + FreeRTOS-Plus/Source/coreJSON \ + FreeRTOS-Plus/Source/corePKCS11 \ + FreeRTOS-Plus/ThirdParty/mbedtls \ + FreeRTOS-Plus/ThirdParty/tinycbor \ + FreeRTOS-Plus/ThirdParty/wolfSSL git -C FreeRTOS-Plus/Source/Application-Protocols/coreHTTP submodule update --checkout --init --depth 1 source/dependency/3rdparty/llhttp git -C FreeRTOS-Plus/Source/corePKCS11 submodule update --checkout --init --depth 1 source/dependency/3rdparty/pkcs11 + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 - - name: Build FreeRTOS+CLI+Trace Demo + - env: + stepName: Build FreeRTOS+CLI+Trace Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator - run: msbuild FreeRTOS_Plus_CLI_with_Trace.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::Build FreeRTOS+CLI+Trace Demo" + msbuild FreeRTOS_Plus_CLI_with_Trace.sln -t:rebuild -property:Configuration=Debug -m + echo "::endgroup::" + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" - - name: Build FreeRTOS+RelianceEdge+CLI Demo + - env: + stepName: Build FreeRTOS+RelianceEdge+CLI Demo + name: ${{ env.stepName }} working-directory: FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator - run: msbuild FreeRTOS_Plus_Reliance_Edge_with_CLI.sln -t:rebuild -property:Configuration=Debug -m + run: | + # ${{ env.stepName }} + echo "::group::${{ env.stepName }}" + msbuild FreeRTOS_Plus_Reliance_Edge_with_CLI.sln -t:rebuild -property:Configuration=Debug -m + echo "${{ env.pwshPass }} ${{ env.stepName }} ${{ env.pwshEnd }}" \ No newline at end of file diff --git a/.github/workflows/kernel-unit-tests.yml b/.github/workflows/kernel-unit-tests.yml index 2d9c5a214..46945c4eb 100644 --- a/.github/workflows/kernel-unit-tests.yml +++ b/.github/workflows/kernel-unit-tests.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: 'recursive' fetch-depth: 5 @@ -42,12 +42,12 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: 'recursive' fetch-depth: 5 - name: Checkout the main branch from the FreeRTOS-Kernel repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: ./FreeRTOS/Source ref: main diff --git a/FreeRTOS+TCP.url b/FreeRTOS+TCP.url index 2da199cac..6617b6062 100644 --- a/FreeRTOS+TCP.url +++ b/FreeRTOS+TCP.url @@ -1,5 +1,5 @@ -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 -[InternetShortcut] -URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html -IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html +IDList= diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c index 7d8146b50..544f3f2e7 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj.filters index c273ca480..490df121d 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/Device_Defender_Demo.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/core_mqtt_config.h b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/core_mqtt_config.h index 4e1c81439..149a10288 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/core_mqtt_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/core_mqtt_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/defender_config.h b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/defender_config.h index bf8ce4c7c..6bfe3f6c2 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/defender_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/defender_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/defender_demo.sln b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/defender_demo.sln index d5b26f8e4..39db36bcd 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/defender_demo.sln +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/defender_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31205.134 diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/demo_config.h b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/demo_config.h index fac2e1ab7..b0fd52327 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/demo_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/main.c b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/main.c index 81ec84e71..833a74698 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/main.c +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/metrics_collector.c b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/metrics_collector.c index 459d4dc00..ef47d1d7e 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/metrics_collector.c +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/metrics_collector.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/metrics_collector.h b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/metrics_collector.h index 8b237b5ff..d091642fa 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/metrics_collector.h +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/metrics_collector.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/report_builder.c b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/report_builder.c index c41a55501..a1aa391fa 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/report_builder.c +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/report_builder.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -160,8 +160,8 @@ static eReportBuilderStatus prvWritePortsArray( char * pcBuffer, lCharactersWritten = snprintf( pcCurrentWritePos, xRemainingBufferLength, "{" - "\"" DEFENDER_REPORT_PORT_KEY "\":%u" - "},", + "\"" DEFENDER_REPORT_PORT_KEY "\":%u" + "},", ( unsigned int ) pusOpenPortsArray[ uxIdx ] ); if( !reportbuilderSNPRINTF_SUCCESS( lCharactersWritten, xRemainingBufferLength ) ) @@ -238,9 +238,9 @@ static eReportBuilderStatus prvWriteConnectionsArray( char * pcBuffer, lCharactersWritten = snprintf( pcCurrentWritePos, xRemainingBufferLength, "{" - "\""DEFENDER_REPORT_LOCAL_PORT_KEY"\": %u," - "\""DEFENDER_REPORT_REMOTE_ADDR_KEY"\": \"%u.%u.%u.%u:%u\"" - "},", + "\""DEFENDER_REPORT_LOCAL_PORT_KEY "\": %u," + "\""DEFENDER_REPORT_REMOTE_ADDR_KEY "\": \"%u.%u.%u.%u:%u\"" + "},", ( unsigned int ) pxConn->usLocalPort, ( unsigned int ) ( pxConn->ulRemoteIp >> 24 ) & 0xFF, ( unsigned int ) ( pxConn->ulRemoteIp >> 16 ) & 0xFF, @@ -399,13 +399,13 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer, lCharactersWritten = snprintf( pcCurrentWritePos, xRemainingBufferLength, "{" - "\""DEFENDER_REPORT_HEADER_KEY"\": {" - "\""DEFENDER_REPORT_ID_KEY"\": %u," - "\""DEFENDER_REPORT_VERSION_KEY"\": \"%u.%u\"" - "}," - "\""DEFENDER_REPORT_METRICS_KEY"\": {" - "\""DEFENDER_REPORT_TCP_LISTENING_PORTS_KEY"\": {" - "\""DEFENDER_REPORT_PORTS_KEY"\": ", + "\""DEFENDER_REPORT_HEADER_KEY "\": {" + "\""DEFENDER_REPORT_ID_KEY "\": %u," + "\""DEFENDER_REPORT_VERSION_KEY "\": \"%u.%u\"" + "}," + "\""DEFENDER_REPORT_METRICS_KEY "\": {" + "\""DEFENDER_REPORT_TCP_LISTENING_PORTS_KEY "\": {" + "\""DEFENDER_REPORT_PORTS_KEY "\": ", ( unsigned int ) ulReportId, ( unsigned int ) ulMajorReportVersion, ( unsigned int ) ulMinorReportVersion ); @@ -447,11 +447,11 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer, { lCharactersWritten = snprintf( pcCurrentWritePos, xRemainingBufferLength, - "," - "\""DEFENDER_REPORT_TOTAL_KEY"\": %u" - "}," - "\""DEFENDER_REPORT_UDP_LISTENING_PORTS_KEY"\": {" - "\""DEFENDER_REPORT_PORTS_KEY"\": ", + "," + "\""DEFENDER_REPORT_TOTAL_KEY "\": %u" + "}," + "\""DEFENDER_REPORT_UDP_LISTENING_PORTS_KEY "\": {" + "\""DEFENDER_REPORT_PORTS_KEY "\": ", ( unsigned int ) pxMetrics->xOpenTcpPortsArrayLength ); if( !reportbuilderSNPRINTF_SUCCESS( lCharactersWritten, xRemainingBufferLength ) ) @@ -491,18 +491,18 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer, { lCharactersWritten = snprintf( pcCurrentWritePos, xRemainingBufferLength, - "," - "\""DEFENDER_REPORT_TOTAL_KEY"\": %u" - "}," - "\""DEFENDER_REPORT_NETWORK_STATS_KEY"\": {" - "\""DEFENDER_REPORT_BYTES_IN_KEY"\": %u," - "\""DEFENDER_REPORT_BYTES_OUT_KEY"\": %u," - "\""DEFENDER_REPORT_PKTS_IN_KEY"\": %u," - "\""DEFENDER_REPORT_PKTS_OUT_KEY"\": %u" - "}," - "\""DEFENDER_REPORT_TCP_CONNECTIONS_KEY"\": {" - "\""DEFENDER_REPORT_ESTABLISHED_CONNECTIONS_KEY"\": {" - "\""DEFENDER_REPORT_CONNECTIONS_KEY"\": ", + "," + "\""DEFENDER_REPORT_TOTAL_KEY "\": %u" + "}," + "\""DEFENDER_REPORT_NETWORK_STATS_KEY "\": {" + "\""DEFENDER_REPORT_BYTES_IN_KEY "\": %u," + "\""DEFENDER_REPORT_BYTES_OUT_KEY "\": %u," + "\""DEFENDER_REPORT_PKTS_IN_KEY "\": %u," + "\""DEFENDER_REPORT_PKTS_OUT_KEY "\": %u" + "}," + "\""DEFENDER_REPORT_TCP_CONNECTIONS_KEY "\": {" + "\""DEFENDER_REPORT_ESTABLISHED_CONNECTIONS_KEY "\": {" + "\""DEFENDER_REPORT_CONNECTIONS_KEY "\": ", ( unsigned int ) pxMetrics->xOpenUdpPortsArrayLength, ( unsigned int ) pxMetrics->pxNetworkStats->uxBytesReceived, ( unsigned int ) pxMetrics->pxNetworkStats->uxBytesSent, @@ -546,20 +546,20 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer, { lCharactersWritten = snprintf( pcCurrentWritePos, xRemainingBufferLength, - "," - "\""DEFENDER_REPORT_TOTAL_KEY"\": %u" - "}" - "}" - "}," - "\""DEFENDER_REPORT_CUSTOM_METRICS_KEY"\": {" - "\"stack_high_water_mark\": [" - "{" - "\""DEFENDER_REPORT_NUMBER_KEY"\": %u" - "}" - "]," - "\"task_numbers\": [" - "{" - "\""DEFENDER_REPORT_NUMBER_LIST_KEY"\": ", + "," + "\""DEFENDER_REPORT_TOTAL_KEY "\": %u" + "}" + "}" + "}," + "\""DEFENDER_REPORT_CUSTOM_METRICS_KEY "\": {" + "\"stack_high_water_mark\": [" + "{" + "\""DEFENDER_REPORT_NUMBER_KEY "\": %u" + "}" + "]," + "\"task_numbers\": [" + "{" + "\""DEFENDER_REPORT_NUMBER_LIST_KEY "\": ", ( unsigned int ) pxMetrics->xEstablishedConnectionsArrayLength, ( unsigned int ) pxMetrics->ulStackHighWaterMark ); @@ -600,9 +600,9 @@ eReportBuilderStatus eGenerateJsonReport( char * pcBuffer, { lCharactersWritten = snprintf( pcCurrentWritePos, xRemainingBufferLength, - "}" - "]" - "}" + "}" + "]" + "}" "}" ); if( !reportbuilderSNPRINTF_SUCCESS( lCharactersWritten, xRemainingBufferLength ) ) diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/report_builder.h b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/report_builder.h index e7d89ba0d..c305dcd0c 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/report_builder.h +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/report_builder.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Common/main.c b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Common/main.c index 236bcc719..708f3706a 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Common/main.c +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Common/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/DemoTasks/ShadowDemoMainExample.c b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/DemoTasks/ShadowDemoMainExample.c index ae0400f2f..e401b85b6 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/DemoTasks/ShadowDemoMainExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/DemoTasks/ShadowDemoMainExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj.filters index 69802d896..ebe7fefa3 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/Device_Shadow_Demo.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/core_mqtt_config.h b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/core_mqtt_config.h index e763c5b10..5f293106c 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/core_mqtt_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/core_mqtt_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,8 +20,10 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS + * */ + #ifndef CORE_MQTT_CONFIG_H #define CORE_MQTT_CONFIG_H diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/demo_config.h b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/demo_config.h index 27be42efd..7a15f7ac3 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/demo_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -220,7 +220,7 @@ extern void vLoggingPrintf( const char * pcFormatString, * @brief The name of the MQTT library used and its version, following an "@" * symbol. */ -#include "core_mqtt.h" /* Include coreMQTT header for MQTT_LIBRARY_VERSION macro. */ +#include "core_mqtt.h" /* Include coreMQTT header for MQTT_LIBRARY_VERSION macro. */ #define democonfigMQTT_LIB "core-mqtt@"MQTT_LIBRARY_VERSION /** diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/shadow_config.h b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/shadow_config.h index bfd5a4d75..c57561e7f 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/shadow_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/shadow_config.h @@ -1,6 +1,6 @@ /* - * AWS IoT Device SDK for Embedded C V202009.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -18,6 +18,10 @@ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #ifndef SHADOW_CONFIG_H diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/shadow_main_demo.sln b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/shadow_main_demo.sln index ff6ec664d..ff279cd1c 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/shadow_main_demo.sln +++ b/FreeRTOS-Plus/Demo/AWS/Device_Shadow_Windows_Simulator/Device_Shadow_Demo/shadow_main_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31205.134 diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/DemoSetup/demo_config.templ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/DemoSetup/demo_config.templ index 03f5daa2b..c111b031c 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/DemoSetup/demo_config.templ +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/DemoSetup/demo_config.templ @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/DemoSetup/demo_config_empty.templ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/DemoSetup/demo_config_empty.templ index 23fc9ab82..8800ba4a0 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/DemoSetup/demo_config_empty.templ +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/DemoSetup/demo_config_empty.templ @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/FleetProvisioningDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/FleetProvisioningDemoExample.c index 11e0978b3..39e3ebb01 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/FleetProvisioningDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/FleetProvisioningDemoExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -316,11 +316,11 @@ static void prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, configASSERT( pxDeserializedInfo->pPublishInfo != NULL ); pxPublishInfo = pxDeserializedInfo->pPublishInfo; - xStatus = FleetProvisioning_MatchTopic(pxPublishInfo->pTopicName, - pxPublishInfo->topicNameLength, - &xApi); + xStatus = FleetProvisioning_MatchTopic( pxPublishInfo->pTopicName, + pxPublishInfo->topicNameLength, + &xApi ); - if (xStatus != FleetProvisioningSuccess) + if( xStatus != FleetProvisioningSuccess ) { LogWarn( ( "Unexpected publish message received. Topic: %.*s.", ( int ) pxPublishInfo->topicNameLength, @@ -328,7 +328,7 @@ static void prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, } else { - if (xApi == FleetProvCborCreateCertFromCsrAccepted) + if( xApi == FleetProvCborCreateCertFromCsrAccepted ) { LogInfo( ( "Received accepted response from Fleet Provisioning CreateCertificateFromCsr API." ) ); @@ -341,13 +341,13 @@ static void prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, xPayloadLength = pxPublishInfo->payloadLength; } - else if (xApi == FleetProvCborCreateCertFromCsrRejected) + else if( xApi == FleetProvCborCreateCertFromCsrRejected ) { LogError( ( "Received rejected response from Fleet Provisioning CreateCertificateFromCsr API." ) ); xResponseStatus = ResponseRejected; } - else if (xApi == FleetProvCborRegisterThingAccepted) + else if( xApi == FleetProvCborRegisterThingAccepted ) { LogInfo( ( "Received accepted response from Fleet Provisioning RegisterThing API." ) ); @@ -360,7 +360,7 @@ static void prvProvisioningPublishCallback( MQTTContext_t * pxMqttContext, xPayloadLength = pxPublishInfo->payloadLength; } - else if (xApi == FleetProvCborRegisterThingRejected) + else if( xApi == FleetProvCborRegisterThingRejected ) { LogError( ( "Received rejected response from Fleet Provisioning RegisterThing API." ) ); @@ -804,7 +804,7 @@ int prvFleetProvisioningTask( void * pvParameters ) } else { - LogInfo( ( "Sucessfully established connection with provisioned credentials." ) ); + LogInfo( ( "Successfully established connection with provisioned credentials." ) ); xConnectionEstablished = true; } } diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/core_mqtt_config.h b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/core_mqtt_config.h index a23277e1a..88edbe4b4 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/core_mqtt_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/core_mqtt_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/demo_config.h b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/demo_config.h index 23fc9ab82..8800ba4a0 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/demo_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_config.h b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_config.h index fdde85a03..02f155c70 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_demo.sln b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_demo.sln index 820c345be..cad1733c9 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_demo.sln +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_demo.vcxproj.filters index 078f7d2a8..49d9e7469 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/fleet_provisioning_demo.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/main.c b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/main.c index 788b53551..ba12350ac 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/main.c +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/pkcs11_operations.c b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/pkcs11_operations.c index 9bdd9bc6a..1e8037862 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/pkcs11_operations.c +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/pkcs11_operations.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/pkcs11_operations.h b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/pkcs11_operations.h index aba33de84..edc377b75 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/pkcs11_operations.h +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/pkcs11_operations.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/tinycbor_serializer.c b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/tinycbor_serializer.c index 786e06652..70f033025 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/tinycbor_serializer.c +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/tinycbor_serializer.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/tinycbor_serializer.h b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/tinycbor_serializer.h index 355d433cc..8408a23a1 100644 --- a/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/tinycbor_serializer.h +++ b/FreeRTOS-Plus/Demo/AWS/Fleet_Provisioning_Windows_Simulator/Fleet_Provisioning_With_CSR_Demo/tinycbor_serializer.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/DemoTasks/JobsDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/DemoTasks/JobsDemoExample.c index 1b96da0dc..8b816c521 100644 --- a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/DemoTasks/JobsDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/DemoTasks/JobsDemoExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj.filters index a7f2e34f9..600bbd5ad 100644 --- a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/Jobs_Demo.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/core_mqtt_config.h b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/core_mqtt_config.h index 3e6de0ecb..0face6d64 100644 --- a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/core_mqtt_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/core_mqtt_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,8 +20,10 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS + * */ + #ifndef CORE_MQTT_CONFIG_H #define CORE_MQTT_CONFIG_H diff --git a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/demo_config.h b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/demo_config.h index dd2faa2a4..2193075e6 100644 --- a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/demo_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -213,7 +213,7 @@ extern void vLoggingPrintf( const char * pcFormatString, * @brief The name of the MQTT library used and its version, following an "@" * symbol. */ -#include "core_mqtt.h" /* Include coreMQTT header for MQTT_LIBRARY_VERSION macro. */ +#include "core_mqtt.h" /* Include coreMQTT header for MQTT_LIBRARY_VERSION macro. */ #define democonfigMQTT_LIB "core-mqtt@"MQTT_LIBRARY_VERSION /** diff --git a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/jobs_demo.sln b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/jobs_demo.sln index c82ca2fb2..68540f051 100644 --- a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/jobs_demo.sln +++ b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/jobs_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31205.134 diff --git a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/main.c b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/main.c index ac26e8206..f8ac23524 100644 --- a/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/main.c +++ b/FreeRTOS-Plus/Demo/AWS/Jobs_Windows_Simulator/Jobs_Demo/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c index ac01e5e70..c7dde38a9 100644 --- a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c +++ b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -379,26 +379,28 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkContext uint16_t usNextRetryBackOff = 0U; #if defined( democonfigCLIENT_USERNAME ) - /* - * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect - * to AWS IoT Core with Custom Authentication on port 443. - * - * Custom Authentication uses the contents of the username and password - * fields of the MQTT CONNECT packet to authenticate the client. - * - * For more information, refer to the documentation at: - * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html - */ - static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; - #if democonfigMQTT_BROKER_PORT != 443U - #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." - #endif /* democonfigMQTT_BROKER_PORT != 443U */ + + /* + * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect + * to AWS IoT Core with Custom Authentication on port 443. + * + * Custom Authentication uses the contents of the username and password + * fields of the MQTT CONNECT packet to authenticate the client. + * + * For more information, refer to the documentation at: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + */ + static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; + #if democonfigMQTT_BROKER_PORT != 443U + #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." + #endif /* democonfigMQTT_BROKER_PORT != 443U */ #else /* if !defined( democonfigCLIENT_USERNAME ) */ - /* - * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using - * x509 Certificate Authentication. - */ - static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; + + /* + * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using + * x509 Certificate Authentication. + */ + static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; #endif /* !defined( democonfigCLIENT_USERNAME ) */ /* diff --git a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.h b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.h index ed404616e..64937efe7 100644 --- a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.h +++ b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_demo_helpers.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.c b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.c index ae213665e..8d4d8b0a7 100644 --- a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.c +++ b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -377,26 +377,28 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkContext uint16_t usNextRetryBackOff = 0U; #if defined( democonfigCLIENT_USERNAME ) - /* - * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect - * to AWS IoT Core with Custom Authentication on port 443. - * - * Custom Authentication uses the contents of the username and password - * fields of the MQTT CONNECT packet to authenticate the client. - * - * For more information, refer to the documentation at: - * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html - */ - static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; - #if democonfigMQTT_BROKER_PORT != 443U - #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." - #endif /* democonfigMQTT_BROKER_PORT != 443U */ + + /* + * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect + * to AWS IoT Core with Custom Authentication on port 443. + * + * Custom Authentication uses the contents of the username and password + * fields of the MQTT CONNECT packet to authenticate the client. + * + * For more information, refer to the documentation at: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + */ + static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; + #if democonfigMQTT_BROKER_PORT != 443U + #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." + #endif /* democonfigMQTT_BROKER_PORT != 443U */ #else /* if !defined( democonfigCLIENT_USERNAME ) */ - /* - * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using - * x509 Certificate Authentication. - */ - static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; + + /* + * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using + * x509 Certificate Authentication. + */ + static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; #endif /* !defined( democonfigCLIENT_USERNAME ) */ /* diff --git a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.h b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.h index 91955f8c4..e9c18a8f4 100644 --- a/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.h +++ b/FreeRTOS-Plus/Demo/AWS/Mqtt_Demo_Helpers/mqtt_pkcs11_demo_helpers.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/HTTP_Utils/http_demo_utils.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/HTTP_Utils/http_demo_utils.c index df0f61933..61d7eb548 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/HTTP_Utils/http_demo_utils.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/HTTP_Utils/http_demo_utils.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -63,8 +63,8 @@ /*-----------------------------------------------------------*/ -/** - * @brief Each compilation unit that consumes the NetworkContext must define it. +/** + * @brief Each compilation unit that consumes the NetworkContext must define it. * It should contain a single pointer to the type of your desired transport. * This utility is used by both TLS and plaintext HTTP demos, so define this pointer as void *. * diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/HTTP_Utils/http_demo_utils.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/HTTP_Utils/http_demo_utils.h index 350177457..175f2899d 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/HTTP_Utils/http_demo_utils.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/HTTP_Utils/http_demo_utils.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/aws_ota_codesigner_certificate.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/aws_ota_codesigner_certificate.h index dd3251956..cbc4b88ce 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/aws_ota_codesigner_certificate.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/aws_ota_codesigner_certificate.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -24,14 +24,14 @@ * */ - /** - * @file aws_ota_codesigner_certificate.h - * @brief Code signer certificate as char array. - * - * Define this char array containing the PEM encode signing certificate. - * Note - It is highly recommended to use this for demo purpose and store - * certificates in secure location in production devices. - */ +/** + * @file aws_ota_codesigner_certificate.h + * @brief Code signer certificate as char array. + * + * Define this char array containing the PEM encode signing certificate. + * Note - It is highly recommended to use this for demo purpose and store + * certificates in secure location in production devices. + */ #ifndef __CODESIGNER_CERTIFICATE__H__ #define __CODESIGNER_CERTIFICATE__H__ diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/code_signature_verification.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/code_signature_verification.h index b611155cd..562dd09cd 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/code_signature_verification.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/code_signature_verification.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -24,22 +24,22 @@ * */ - /** - * @file code_signature_verification.h - * @brief Interface for code signature verification functions. - * - */ +/** + * @file code_signature_verification.h + * @brief Interface for code signature verification functions. + * + */ #ifndef CODE_SIGNATURE_VERIFICATION_H #define CODE_SIGNATURE_VERIFICATION_H #include "FreeRTOS.h" - - /** + +/** * @brief Validate the integrity of the new image to be activated. * @param[in] pFileContext pointer to File context * @return OtaPalMainStatus_t , OtaPalSuccess if the signature of the image is valid. */ -OtaPalMainStatus_t xValidateImageSignature( OtaFileContext_t* const pFileContext ); +OtaPalMainStatus_t xValidateImageSignature( OtaFileContext_t * const pFileContext ); #endif diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/code_signature_verification_mbedtls.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/code_signature_verification_mbedtls.c index 851253305..c76948575 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/code_signature_verification_mbedtls.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/Code_Signature_Verification/code_signature_verification_mbedtls.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -24,25 +24,25 @@ * */ - /** - * @file code_signature_verification_mbedtls.c - * @brief Code signature verification using mbedtls crypto. - * - * The file demonstrates implements the code signature verification functionality on - * the specified file using mbedtls for SHA256 ECDSA. - */ +/** + * @file code_signature_verification_mbedtls.c + * @brief Code signature verification using mbedtls crypto. + * + * The file demonstrates implements the code signature verification functionality on + * the specified file using mbedtls for SHA256 ECDSA. + */ - /* C runtime includes. */ +/* C runtime includes. */ #include - /* FreeRTOS includes. */ +/* FreeRTOS includes. */ #include "FreeRTOS.h" /* mbedTLS includes. */ #if !defined( MBEDTLS_CONFIG_FILE ) -#include "mbedtls_config_v3.2.1.h" + #include "mbedtls_config_v3.2.1.h" #else -#include MBEDTLS_CONFIG_FILE + #include MBEDTLS_CONFIG_FILE #endif #include "mbedtls/platform.h" #include "mbedtls/sha256.h" @@ -60,10 +60,10 @@ /** * @brief SHA256 buffer size for storing cryptographic hash computation results. */ -#define SHA256_DIGEST_BYTES 32 +#define SHA256_DIGEST_BYTES 32 - /* Size of buffer used in file operations on this platform (Windows). */ -#define OTA_PAL_WIN_BUF_SIZE ( ( size_t ) 4096UL ) +/* Size of buffer used in file operations on this platform (Windows). */ +#define OTA_PAL_WIN_BUF_SIZE ( ( size_t ) 4096UL ) /** * @brief Library-independent cryptographic algorithm identifiers. @@ -73,9 +73,9 @@ #define ASYMMETRIC_ALGORITHM_RSA 1 #define ASYMMETRIC_ALGORITHM_ECDSA 2 - /** - * @brief Internal signature verification context structure. - */ +/** + * @brief Internal signature verification context structure. + */ typedef struct SignatureVerificationState { BaseType_t xAsymmetricAlgorithm; @@ -92,9 +92,9 @@ typedef struct SignatureVerificationState * * @return pdTRUE if initialization succeeds, or pdFALSE otherwise. */ -static BaseType_t prvSignatureVerificationStart(void** ppvContext, - BaseType_t xAsymmetricAlgorithm, - BaseType_t xHashAlgorithm); +static BaseType_t prvSignatureVerificationStart( void ** ppvContext, + BaseType_t xAsymmetricAlgorithm, + BaseType_t xHashAlgorithm ); /** * @brief Updates a cryptographic hash computation with the specified byte array. @@ -103,9 +103,9 @@ static BaseType_t prvSignatureVerificationStart(void** ppvContext, * @param[in] pucData Byte array that was signed. * @param[in] xDataLength Length in bytes of data that was signed. */ -static void prvSignatureVerificationUpdate(void* pvContext, - const uint8_t* pucData, - size_t xDataLength); +static void prvSignatureVerificationUpdate( void * pvContext, + const uint8_t * pucData, + size_t xDataLength ); /** * @brief Verifies a digital signature computation using the public key from the @@ -120,41 +120,41 @@ static void prvSignatureVerificationUpdate(void* pvContext, * * @return pdTRUE if the signature is correct or pdFALSE if the signature is invalid. */ -static BaseType_t prvSignatureVerificationFinal(void* pvContext, - char* pcSignerCertificate, - size_t xSignerCertificateLength, - uint8_t* pucSignature, - size_t xSignatureLength); +static BaseType_t prvSignatureVerificationFinal( void * pvContext, + char * pcSignerCertificate, + size_t xSignerCertificateLength, + uint8_t * pucSignature, + size_t xSignatureLength ); /* Read the specified signer certificate from the filesystem into a local buffer. The allocated * memory becomes the property of the caller who is responsible for freeing it. */ -static uint8_t* otaPal_ReadAndAssumeCertificate(const uint8_t* const pucCertName, - uint32_t* const ulSignerCertSize) +static uint8_t * otaPal_ReadAndAssumeCertificate( const uint8_t * const pucCertName, + uint32_t * const ulSignerCertSize ) { - FILE* pFile; - uint8_t* pucSignerCert = NULL; - uint8_t* pucCertData = NULL; + FILE * pFile; + uint8_t * pucSignerCert = NULL; + uint8_t * pucCertData = NULL; int32_t lSize = 0; /* For MISRA mandatory. */ int32_t lWindowsError; - pFile = fopen((const char*)pucCertName, "rb"); /*lint !e586 - * C standard library call is being used for portability. */ + pFile = fopen( ( const char * ) pucCertName, "rb" ); /*lint !e586 + * C standard library call is being used for portability. */ - if (pFile != NULL) + if( pFile != NULL ) { - lWindowsError = fseek(pFile, 0, SEEK_END); /*lint !e586 - * C standard library call is being used for portability. */ + lWindowsError = fseek( pFile, 0, SEEK_END ); /*lint !e586 + * C standard library call is being used for portability. */ - if (lWindowsError == 0) /* fseek returns a non-zero value on error. */ + if( lWindowsError == 0 ) /* fseek returns a non-zero value on error. */ { - lSize = (int32_t)ftell(pFile); /*lint !e586 Allow call in this context. */ + lSize = ( int32_t ) ftell( pFile ); /*lint !e586 Allow call in this context. */ - if (lSize != -1L) /* ftell returns -1 on error. */ + if( lSize != -1L ) /* ftell returns -1 on error. */ { - lWindowsError = fseek(pFile, 0, SEEK_SET); /*lint !e586 - * C standard library call is being used for portability. */ + lWindowsError = fseek( pFile, 0, SEEK_SET ); /*lint !e586 + * C standard library call is being used for portability. */ } else /* ftell returned an error, pucSignerCert remains NULL. */ { @@ -162,60 +162,60 @@ static uint8_t* otaPal_ReadAndAssumeCertificate(const uint8_t* const pucCertName } } /* else fseek returned an error, pucSignerCert remains NULL. */ - if (lWindowsError == 0) + if( lWindowsError == 0 ) { /* Allocate memory for the signer certificate plus a terminating zero so we can load and return it to the caller. */ - pucSignerCert = pvPortMalloc(lSize + 1); /*lint !e732 !e9034 !e9079 Allow conversion. */ + pucSignerCert = pvPortMalloc( lSize + 1 ); /*lint !e732 !e9034 !e9079 Allow conversion. */ } - if (pucSignerCert != NULL) + if( pucSignerCert != NULL ) { - if (fread(pucSignerCert, 1, lSize, pFile) == (size_t)lSize) /*lint !e586 !e732 !e9034 - * C standard library call is being used for portability. */ + if( fread( pucSignerCert, 1, lSize, pFile ) == ( size_t ) lSize ) /*lint !e586 !e732 !e9034 + * C standard library call is being used for portability. */ { /* The crypto code requires the terminating zero to be part of the length so add 1 to the size. */ *ulSignerCertSize = lSize + 1; - pucSignerCert[lSize] = 0; + pucSignerCert[ lSize ] = 0; } else - { /* There was a problem reading the certificate file so free the memory and abort. */ - vPortFree(pucSignerCert); + { /* There was a problem reading the certificate file so free the memory and abort. */ + vPortFree( pucSignerCert ); pucSignerCert = NULL; } } else { - LogError(("Failed to allocate memory for signer cert contents.\r\n")); + LogError( ( "Failed to allocate memory for signer cert contents.\r\n" ) ); /* Nothing special to do. */ } - lWindowsError = fclose(pFile); /*lint !e586 - * C standard library call is being used for portability. */ + lWindowsError = fclose( pFile ); /*lint !e586 + * C standard library call is being used for portability. */ - if (lWindowsError != 0) + if( lWindowsError != 0 ) { - LogError(("File pointer operation failed.\r\n")); + LogError( ( "File pointer operation failed.\r\n" ) ); pucSignerCert = NULL; } } else { - LogError(("No such certificate file: %s. Using aws_ota_codesigner_certificate.h.\r\n", - (const char*)pucCertName)); + LogError( ( "No such certificate file: %s. Using aws_ota_codesigner_certificate.h.\r\n", + ( const char * ) pucCertName ) ); /* Allocate memory for the signer certificate plus a terminating zero so we can copy it and return to the caller. */ - lSize = sizeof(signingcredentialSIGNING_CERTIFICATE_PEM); - pucSignerCert = pvPortMalloc(lSize); /*lint !e9029 !e9079 !e838 malloc proto requires void*. */ - pucCertData = (uint8_t*)signingcredentialSIGNING_CERTIFICATE_PEM; /*lint !e9005 we don't modify the cert but it could be set by PKCS11 so it's not const. */ + lSize = sizeof( signingcredentialSIGNING_CERTIFICATE_PEM ); + pucSignerCert = pvPortMalloc( lSize ); /*lint !e9029 !e9079 !e838 malloc proto requires void*. */ + pucCertData = ( uint8_t * ) signingcredentialSIGNING_CERTIFICATE_PEM; /*lint !e9005 we don't modify the cert but it could be set by PKCS11 so it's not const. */ - if (pucSignerCert != NULL) + if( pucSignerCert != NULL ) { - memcpy(pucSignerCert, pucCertData, lSize); + memcpy( pucSignerCert, pucCertData, lSize ); *ulSignerCertSize = lSize; } else { - LogError(("No memory for certificate of size %d!\r\n", lSize)); + LogError( ( "No memory for certificate of size %d!\r\n", lSize ) ); } } @@ -226,29 +226,29 @@ static uint8_t* otaPal_ReadAndAssumeCertificate(const uint8_t* const pucCertName * @brief Verifies a cryptographic signature based on the signer * certificate, hash algorithm, and the data that was signed. */ -static BaseType_t prvVerifySignature(char* pcSignerCertificate, - size_t xSignerCertificateLength, - BaseType_t xHashAlgorithm, - uint8_t* pucHash, - size_t xHashLength, - uint8_t* pucSignature, - size_t xSignatureLength) +static BaseType_t prvVerifySignature( char * pcSignerCertificate, + size_t xSignerCertificateLength, + BaseType_t xHashAlgorithm, + uint8_t * pucHash, + size_t xHashLength, + uint8_t * pucSignature, + size_t xSignatureLength ) { BaseType_t xResult = pdTRUE; mbedtls_x509_crt xCertCtx; mbedtls_md_type_t xMbedHashAlg = MBEDTLS_MD_SHA256; - (void)xHashAlgorithm; + ( void ) xHashAlgorithm; - memset(&xCertCtx, 0, sizeof(mbedtls_x509_crt)); + memset( &xCertCtx, 0, sizeof( mbedtls_x509_crt ) ); /* * Decode and create a certificate context */ - mbedtls_x509_crt_init(&xCertCtx); + mbedtls_x509_crt_init( &xCertCtx ); - if (0 != mbedtls_x509_crt_parse( - &xCertCtx, (const unsigned char*)pcSignerCertificate, xSignerCertificateLength)) + if( 0 != mbedtls_x509_crt_parse( + &xCertCtx, ( const unsigned char * ) pcSignerCertificate, xSignerCertificateLength ) ) { xResult = pdFALSE; } @@ -256,15 +256,15 @@ static BaseType_t prvVerifySignature(char* pcSignerCertificate, /* * Verify the signature using the public key from the decoded certificate */ - if (pdTRUE == xResult) + if( pdTRUE == xResult ) { - if (0 != mbedtls_pk_verify( - &xCertCtx.pk, - xMbedHashAlg, - pucHash, - xHashLength, - pucSignature, - xSignatureLength)) + if( 0 != mbedtls_pk_verify( + &xCertCtx.pk, + xMbedHashAlg, + pucHash, + xHashLength, + pucSignature, + xSignatureLength ) ) { xResult = pdFALSE; } @@ -273,7 +273,7 @@ static BaseType_t prvVerifySignature(char* pcSignerCertificate, /* * Clean-up */ - mbedtls_x509_crt_free(&xCertCtx); + mbedtls_x509_crt_free( &xCertCtx ); return xResult; } @@ -283,23 +283,23 @@ static BaseType_t prvVerifySignature(char* pcSignerCertificate, /** * @brief Creates signature verification context. */ -static BaseType_t prvSignatureVerificationStart(void** ppvContext, - BaseType_t xAsymmetricAlgorithm, - BaseType_t xHashAlgorithm) +static BaseType_t prvSignatureVerificationStart( void ** ppvContext, + BaseType_t xAsymmetricAlgorithm, + BaseType_t xHashAlgorithm ) { BaseType_t xResult = pdTRUE; - SignatureVerificationState_t* pxCtx = NULL; + SignatureVerificationState_t * pxCtx = NULL; /* * Allocate the context */ - if (NULL == (pxCtx = (SignatureVerificationStatePtr_t)pvPortMalloc( - sizeof(*pxCtx)))) /*lint !e9087 Allow casting void* to other types. */ + if( NULL == ( pxCtx = ( SignatureVerificationStatePtr_t ) pvPortMalloc( + sizeof( *pxCtx ) ) ) ) /*lint !e9087 Allow casting void* to other types. */ { xResult = pdFALSE; } - if (pdTRUE == xResult) + if( pdTRUE == xResult ) { *ppvContext = pxCtx; @@ -312,8 +312,8 @@ static BaseType_t prvSignatureVerificationStart(void** ppvContext, /* * Initialize the requested hash type */ - mbedtls_sha256_init(&pxCtx->xSHA256Context); - (void)mbedtls_sha256_starts(&pxCtx->xSHA256Context, 0); + mbedtls_sha256_init( &pxCtx->xSHA256Context ); + ( void ) mbedtls_sha256_starts( &pxCtx->xSHA256Context, 0 ); } return xResult; @@ -322,59 +322,58 @@ static BaseType_t prvSignatureVerificationStart(void** ppvContext, /** * @brief Adds bytes to an in-progress hash for subsequent signature verification. */ -static void prvSignatureVerificationUpdate(void* pvContext, - const uint8_t* pucData, - size_t xDataLength) +static void prvSignatureVerificationUpdate( void * pvContext, + const uint8_t * pucData, + size_t xDataLength ) { - SignatureVerificationState_t* pxCtx = (SignatureVerificationStatePtr_t)pvContext; /*lint !e9087 Allow casting void* to other types. */ + SignatureVerificationState_t * pxCtx = ( SignatureVerificationStatePtr_t ) pvContext; /*lint !e9087 Allow casting void* to other types. */ /* * Add the data to the hash of the requested type */ - (void)mbedtls_sha256_update(&pxCtx->xSHA256Context, pucData, xDataLength); - + ( void ) mbedtls_sha256_update( &pxCtx->xSHA256Context, pucData, xDataLength ); } /** * @brief Performs signature verification on a cryptographic hash. */ -static BaseType_t prvSignatureVerificationFinal(void* pvContext, - char* pcSignerCertificate, - size_t xSignerCertificateLength, - uint8_t* pucSignature, - size_t xSignatureLength) +static BaseType_t prvSignatureVerificationFinal( void * pvContext, + char * pcSignerCertificate, + size_t xSignerCertificateLength, + uint8_t * pucSignature, + size_t xSignatureLength ) { BaseType_t xResult = pdFALSE; - if (pvContext != NULL) + if( pvContext != NULL ) { - SignatureVerificationStatePtr_t pxCtx = (SignatureVerificationStatePtr_t)pvContext; /*lint !e9087 Allow casting void* to other types. */ - uint8_t ucSHA256[SHA256_DIGEST_BYTES]; /* Reserve enough space for the larger for SHA256 results. */ - uint8_t* pucHash = NULL; + SignatureVerificationStatePtr_t pxCtx = ( SignatureVerificationStatePtr_t ) pvContext; /*lint !e9087 Allow casting void* to other types. */ + uint8_t ucSHA256[ SHA256_DIGEST_BYTES ]; /* Reserve enough space for the larger for SHA256 results. */ + uint8_t * pucHash = NULL; size_t xHashLength = 0; - if ((pcSignerCertificate != NULL) && - (pucSignature != NULL) && - (xSignerCertificateLength > 0UL) && - (xSignatureLength > 0UL)) + if( ( pcSignerCertificate != NULL ) && + ( pucSignature != NULL ) && + ( xSignerCertificateLength > 0UL ) && + ( xSignatureLength > 0UL ) ) { /* * Finish the hash. */ - (void)mbedtls_sha256_finish(&pxCtx->xSHA256Context, ucSHA256); + ( void ) mbedtls_sha256_finish( &pxCtx->xSHA256Context, ucSHA256 ); pucHash = ucSHA256; xHashLength = SHA256_DIGEST_BYTES; /* * Verify the signature. */ - xResult = prvVerifySignature(pcSignerCertificate, - xSignerCertificateLength, - pxCtx->xHashAlgorithm, - pucHash, - xHashLength, - pucSignature, - xSignatureLength); + xResult = prvVerifySignature( pcSignerCertificate, + xSignerCertificateLength, + pxCtx->xHashAlgorithm, + pucHash, + xHashLength, + pucSignature, + xSignatureLength ); } else { @@ -384,82 +383,83 @@ static BaseType_t prvSignatureVerificationFinal(void* pvContext, /* * Clean-up */ - vPortFree(pxCtx); + vPortFree( pxCtx ); } return xResult; } /* Verify the signature of the specified file. */ -OtaPalMainStatus_t xValidateImageSignature(OtaFileContext_t* const C) +OtaPalMainStatus_t xValidateImageSignature( OtaFileContext_t * const C ) { OtaPalMainStatus_t eResult = OtaPalSuccess; uint32_t ulBytesRead; uint32_t ulSignerCertSize; - uint8_t* pucBuf, * pucSignerCert; - void* pvSigVerifyContext; + uint8_t * pucBuf, * pucSignerCert; + void * pvSigVerifyContext; - /* Verify an ECDSA-SHA256 signature. */ - if (pdFALSE == prvSignatureVerificationStart(&pvSigVerifyContext, ASYMMETRIC_ALGORITHM_ECDSA, HASH_ALGORITHM_SHA256)) - { - eResult = OtaPalSignatureCheckFailed; - } - else - { - LogInfo(("Started %s signature verification, file: %s\r\n", - OTA_JsonFileSignatureKey, (const char*)C->pCertFilepath)); - pucSignerCert = otaPal_ReadAndAssumeCertificate((const uint8_t* const)C->pCertFilepath, &ulSignerCertSize); + /* Verify an ECDSA-SHA256 signature. */ + if( pdFALSE == prvSignatureVerificationStart( &pvSigVerifyContext, ASYMMETRIC_ALGORITHM_ECDSA, HASH_ALGORITHM_SHA256 ) ) + { + eResult = OtaPalSignatureCheckFailed; + } + else + { + LogInfo( ( "Started %s signature verification, file: %s\r\n", + OTA_JsonFileSignatureKey, ( const char * ) C->pCertFilepath ) ); + pucSignerCert = otaPal_ReadAndAssumeCertificate( ( const uint8_t * const ) C->pCertFilepath, &ulSignerCertSize ); - if (pucSignerCert != NULL) + if( pucSignerCert != NULL ) + { + pucBuf = pvPortMalloc( OTA_PAL_WIN_BUF_SIZE ); /*lint !e9079 Allow conversion. */ + + if( pucBuf != NULL ) { - pucBuf = pvPortMalloc( OTA_PAL_WIN_BUF_SIZE ); /*lint !e9079 Allow conversion. */ - - if (pucBuf != NULL) + /* Rewind the received file to the beginning. */ + if( fseek( C->pFile, 0L, SEEK_SET ) == 0 ) /*lint !e586 + * C standard library call is being used for portability. */ { - /* Rewind the received file to the beginning. */ - if (fseek(C->pFile, 0L, SEEK_SET) == 0) /*lint !e586 - * C standard library call is being used for portability. */ + do { - do - { - ulBytesRead = fread(pucBuf, 1, OTA_PAL_WIN_BUF_SIZE, C->pFile); /*lint !e586 - * C standard library call is being used for portability. */ - /* Include the file chunk in the signature validation. Zero size is OK. */ - prvSignatureVerificationUpdate(pvSigVerifyContext, pucBuf, ulBytesRead); - } while (ulBytesRead > 0UL); + ulBytesRead = fread( pucBuf, 1, OTA_PAL_WIN_BUF_SIZE, C->pFile ); /*lint !e586 + * C standard library call is being used for portability. */ + /* Include the file chunk in the signature validation. Zero size is OK. */ + prvSignatureVerificationUpdate( pvSigVerifyContext, pucBuf, ulBytesRead ); + } while( ulBytesRead > 0UL ); - if (pdFALSE == prvSignatureVerificationFinal(pvSigVerifyContext, - (char*)pucSignerCert, - (size_t)ulSignerCertSize, - C->pSignature->data, - C->pSignature->size)) /*lint !e732 !e9034 Allow comparison in this context. */ - { - eResult = OtaPalSignatureCheckFailed; - } - pvSigVerifyContext = NULL; /* The context has been freed by prvSignatureVerificationFinal(). */ - } - else + if( pdFALSE == prvSignatureVerificationFinal( pvSigVerifyContext, + ( char * ) pucSignerCert, + ( size_t ) ulSignerCertSize, + C->pSignature->data, + C->pSignature->size ) ) /*lint !e732 !e9034 Allow comparison in this context. */ { - /* Nothing special to do. */ + eResult = OtaPalSignatureCheckFailed; } - /* Free the temporary file page buffer. */ - vPortFree(pucBuf); + pvSigVerifyContext = NULL; /* The context has been freed by prvSignatureVerificationFinal(). */ } else { - LogError(("Failed to allocate buffer memory.\r\n")); - eResult = OtaPalOutOfMemory; + /* Nothing special to do. */ } - /* Free the signer certificate that we now own after prvReadAndAssumeCertificate(). */ - vPortFree(pucSignerCert); + /* Free the temporary file page buffer. */ + vPortFree( pucBuf ); } else { - eResult = OtaPalBadSignerCert; + LogError( ( "Failed to allocate buffer memory.\r\n" ) ); + eResult = OtaPalOutOfMemory; } + + /* Free the signer certificate that we now own after prvReadAndAssumeCertificate(). */ + vPortFree( pucSignerCert ); } + else + { + eResult = OtaPalBadSignerCert; + } + } return eResult; -} \ No newline at end of file +} diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/ota_pal.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/ota_pal.c index 8b9471e96..08072bbec 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/ota_pal.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/ota_pal.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -52,7 +52,7 @@ static OtaPalMainStatus_t otaPal_CheckFileSignature( OtaFileContext_t * const C /*-----------------------------------------------------------*/ -static inline BaseType_t prvContextValidate( OtaFileContext_t* pFileContext ) +static inline BaseType_t prvContextValidate( OtaFileContext_t * pFileContext ) { return( ( pFileContext != NULL ) && ( pFileContext->pFile != NULL ) ); /*lint !e9034 Comparison is correct for file pointer type. */ @@ -63,19 +63,19 @@ static inline BaseType_t prvContextValidate( OtaFileContext_t* pFileContext ) /* Attempt to create a new receive file for the file chunks as they come in. */ -OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t* const C ) +OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t * const C ) { OtaPalMainStatus_t mainErr = OtaPalUninitialized; OtaPalSubStatus_t subErr = 0; if( C != NULL ) { - if ( C->pFilePath != NULL ) + if( C->pFilePath != NULL ) { - C->pFile = fopen( ( const char * )C->pFilePath, "w+b" ); /*lint !e586 - * C standard library call is being used for portability. */ + C->pFile = fopen( ( const char * ) C->pFilePath, "w+b" ); /*lint !e586 + * C standard library call is being used for portability. */ - if ( C->pFile != NULL ) + if( C->pFile != NULL ) { mainErr = OtaPalSuccess; LogInfo( ( "Receive file created.\r\n" ) ); @@ -99,7 +99,7 @@ OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t* const C ) LogError( ( "ERROR - Invalid file context provided.\r\n" ) ); } - return OTA_PAL_COMBINE_ERR(mainErr,subErr); + return OTA_PAL_COMBINE_ERR( mainErr, subErr ); } @@ -118,7 +118,7 @@ OtaPalStatus_t otaPal_Abort( OtaFileContext_t * const C ) if( NULL != C->pFile ) { lFileCloseResult = fclose( C->pFile ); /*lint !e482 !e586 - * Context file handle state is managed by this API. */ + * Context file handle state is managed by this API. */ C->pFile = NULL; if( 0 == lFileCloseResult ) @@ -145,7 +145,7 @@ OtaPalStatus_t otaPal_Abort( OtaFileContext_t * const C ) mainErr = OtaPalFileAbort; } - return OTA_PAL_COMBINE_ERR(mainErr,subErr); + return OTA_PAL_COMBINE_ERR( mainErr, subErr ); } /* Write a block of data to the specified file. */ @@ -159,12 +159,12 @@ int16_t otaPal_WriteBlock( OtaFileContext_t * const C, if( prvContextValidate( C ) == pdTRUE ) { lResult = fseek( C->pFile, ulOffset, SEEK_SET ); /*lint !e586 !e713 !e9034 - * C standard library call is being used for portability. */ + * C standard library call is being used for portability. */ if( 0 == lResult ) { lResult = fwrite( pacData, 1, ulBlockSize, C->pFile ); /*lint !e586 !e713 !e9034 - * C standard library call is being used for portability. */ + * C standard library call is being used for portability. */ if( lResult < 0 ) { @@ -216,7 +216,7 @@ OtaPalStatus_t otaPal_CloseFile( OtaFileContext_t * const C ) /* Close the file. */ lWindowsError = fclose( C->pFile ); /*lint !e482 !e586 - * C standard library call is being used for portability. */ + * C standard library call is being used for portability. */ C->pFile = NULL; if( lWindowsError != 0 ) @@ -233,11 +233,10 @@ OtaPalStatus_t otaPal_CloseFile( OtaFileContext_t * const C ) else { LogError( ( "Failed to pass %s signature verification: %d.\r\n", - OTA_JsonFileSignatureKey, OTA_PAL_COMBINE_ERR(mainErr,subErr) ) ); + OTA_JsonFileSignatureKey, OTA_PAL_COMBINE_ERR( mainErr, subErr ) ) ); /* If we fail to verify the file signature that means the image is not valid. We need to set the image state to aborted. */ otaPal_SetPlatformImageState( C, OtaImageStateAborted ); - } } else /* Invalid OTA Context. */ @@ -247,17 +246,17 @@ OtaPalStatus_t otaPal_CloseFile( OtaFileContext_t * const C ) mainErr = OtaPalFileClose; } - return OTA_PAL_COMBINE_ERR(mainErr,subErr); + return OTA_PAL_COMBINE_ERR( mainErr, subErr ); } /* Verify the signature of the specified file. */ -static OtaPalMainStatus_t otaPal_CheckFileSignature( OtaFileContext_t* const C ) +static OtaPalMainStatus_t otaPal_CheckFileSignature( OtaFileContext_t * const C ) { OtaPalMainStatus_t eResult = OtaPalSignatureCheckFailed; - if ( prvContextValidate( C ) == pdTRUE ) + if( prvContextValidate( C ) == pdTRUE ) { eResult = xValidateImageSignature( C ); } @@ -271,40 +270,41 @@ static OtaPalMainStatus_t otaPal_CheckFileSignature( OtaFileContext_t* const C ) /*-----------------------------------------------------------*/ -OtaPalStatus_t otaPal_ResetDevice( OtaFileContext_t* const pFileContext ) +OtaPalStatus_t otaPal_ResetDevice( OtaFileContext_t * const pFileContext ) { - (void)pFileContext; + ( void ) pFileContext; /* Return no error. Windows implementation does not reset device. */ - return OTA_PAL_COMBINE_ERR(OtaPalSuccess,0); + return OTA_PAL_COMBINE_ERR( OtaPalSuccess, 0 ); } /*-----------------------------------------------------------*/ -OtaPalStatus_t otaPal_ActivateNewImage( OtaFileContext_t* const pFileContext ) +OtaPalStatus_t otaPal_ActivateNewImage( OtaFileContext_t * const pFileContext ) { - (void)pFileContext; + ( void ) pFileContext; /* Return no error. Windows implementation simply does nothing on activate. * To run the new firmware image, double click the newly downloaded exe */ - return OTA_PAL_COMBINE_ERR(OtaPalSuccess,0); + return OTA_PAL_COMBINE_ERR( OtaPalSuccess, 0 ); } /* * Set the final state of the last transferred (final) OTA file (or bundle). - * On Windows, the state of the OTA image is stored in PlaformImageState.txt. + * On Windows, the state of the OTA image is stored in PlatformImageState.txt. */ -OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const pFileContext, OtaImageState_t eState ) +OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const pFileContext, + OtaImageState_t eState ) { - (void)pFileContext; + ( void ) pFileContext; OtaPalMainStatus_t mainErr = OtaPalSuccess; OtaPalSubStatus_t subErr = 0; FILE * pstPlatformImageState; - if( eState != OtaImageStateUnknown && eState <= OtaLastImageState ) + if( ( eState != OtaImageStateUnknown ) && ( eState <= OtaLastImageState ) ) { pstPlatformImageState = fopen( "PlatformImageState.txt", "w+b" ); /*lint !e586 * C standard library call is being used for portability. */ @@ -313,7 +313,7 @@ OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const pFileConte { /* Write the image state to PlatformImageState.txt. */ if( 1 != fwrite( &eState, sizeof( OtaImageState_t ), 1, pstPlatformImageState ) ) /*lint !e586 !e9029 - * C standard library call is being used for portability. */ + * C standard library call is being used for portability. */ { LogError( ( "Unable to write to image state file.\r\n" ) ); mainErr = OtaPalBadImageState; @@ -334,14 +334,14 @@ OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const pFileConte mainErr = OtaPalBadImageState; subErr = errno; } - } /*lint !e481 Allow fopen and fclose calls in this context. */ + } /*lint !e481 Allow fopen and fclose calls in this context. */ else /* Image state invalid. */ { LogError( ( "ERROR - Invalid image state provided.\r\n" ) ); mainErr = OtaPalBadImageState; } - return OTA_PAL_COMBINE_ERR(mainErr,subErr); + return OTA_PAL_COMBINE_ERR( mainErr, subErr ); } /* Get the state of the currently running image. @@ -358,7 +358,7 @@ OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const pFileConte */ OtaPalImageState_t otaPal_GetPlatformImageState( OtaFileContext_t * const pFileContext ) { - (void)pFileContext; + ( void ) pFileContext; FILE * pstPlatformImageState; OtaImageState_t eSavedAgentState = OtaImageStateUnknown; @@ -369,23 +369,25 @@ OtaPalImageState_t otaPal_GetPlatformImageState( OtaFileContext_t * const pFileC if( pstPlatformImageState != NULL ) { - if( 1 != fread( &eSavedAgentState, sizeof(OtaImageState_t), 1, pstPlatformImageState ) ) /*lint !e586 !e9029 - * C standard library call is being used for portability. */ + if( 1 != fread( &eSavedAgentState, sizeof( OtaImageState_t ), 1, pstPlatformImageState ) ) /*lint !e586 !e9029 + * C standard library call is being used for portability. */ { /* If an error occurred reading the file, mark the state as aborted. */ LogError( ( "Unable to read image state file.\r\n" ) ); - ePalState = ( OtaPalImageStateInvalid | (errno & OTA_PAL_ERR_MASK) ); + ePalState = ( OtaPalImageStateInvalid | ( errno & OTA_PAL_ERR_MASK ) ); } else { - switch (eSavedAgentState) + switch( eSavedAgentState ) { case OtaImageStateTesting: ePalState = OtaPalImageStatePendingCommit; break; + case OtaImageStateAccepted: ePalState = OtaPalImageStateValid; break; + case OtaImageStateRejected: case OtaImageStateAborted: default: @@ -394,12 +396,11 @@ OtaPalImageState_t otaPal_GetPlatformImageState( OtaFileContext_t * const pFileC } } - if( 0 != fclose( pstPlatformImageState ) ) /*lint !e586 * C standard library call is being used for portability. */ { LogError( ( "Unable to close image state file.\r\n" ) ); - ePalState = (OtaPalImageStateInvalid | ( errno & OTA_PAL_ERR_MASK ) ); + ePalState = ( OtaPalImageStateInvalid | ( errno & OTA_PAL_ERR_MASK ) ); } } else @@ -415,5 +416,5 @@ OtaPalImageState_t otaPal_GetPlatformImageState( OtaFileContext_t * const pFileC /* Provide access to private members for testing. */ #ifdef FREERTOS_ENABLE_UNIT_TESTS -#include "aws_ota_pal_test_access_define.h" + #include "aws_ota_pal_test_access_define.h" #endif diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/ota_pal.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/ota_pal.h index 2159a5c97..f8c707659 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/ota_pal.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/Ota_PAL/Win32/ota_pal.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -26,7 +26,7 @@ /** * @file ota_pal.h - * @brief Function declarations for ota_ptal.c. + * @brief Function declarations for ota_pal.c. */ #ifndef _OTA_PAL_H_ @@ -54,7 +54,7 @@ * OTA_ERR_NONE is returned when aborting access to the open file was successful. * OTA_ERR_FILE_ABORT is returned when aborting access to the open file context was unsuccessful. */ -OtaPalStatus_t otaPal_Abort( OtaFileContext_t * const C ); +OtaPalStatus_t otaPal_Abort( OtaFileContext_t * const C ); /** * @brief Create a new receive file for the data chunks as they come in. @@ -79,7 +79,7 @@ OtaPalStatus_t otaPal_Abort( OtaFileContext_t * const C ); * OTA_ERR_BOOT_INFO_CREATE_FAILED is returned if the bootloader information file creation fails. * OTA_ERR_RX_FILE_CREATE_FAILED is returned for other errors creating the file in the device's non-volatile memory. */ -OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t * const C ); +OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t * const C ); /* @brief Authenticate and close the underlying receive file in the specified OTA context. * @@ -104,7 +104,7 @@ OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t * const C ); * OTA_ERR_BAD_SIGNER_CERT is returned for errors in the certificate itself. * OTA_ERR_FILE_CLOSE is returned when closing the file fails. */ -OtaPalStatus_t otaPal_CloseFile( OtaFileContext_t * const C ); +OtaPalStatus_t otaPal_CloseFile( OtaFileContext_t * const C ); /** * @brief Write a block of data to the specified file at the given offset. @@ -141,7 +141,7 @@ int16_t otaPal_WriteBlock( OtaFileContext_t * const C, * @return The OTA PAL layer error code combined with the MCU specific error code. See OTA Agent * error codes information in ota.h. */ -OtaPalStatus_t otaPal_ActivateNewImage( OtaFileContext_t * const C ); +OtaPalStatus_t otaPal_ActivateNewImage( OtaFileContext_t * const C ); /** * @brief Reset the device. @@ -155,7 +155,7 @@ OtaPalStatus_t otaPal_ActivateNewImage( OtaFileContext_t * const C ); * error codes information in ota.h. */ -OtaPalStatus_t otaPal_ResetDevice( OtaFileContext_t * const C ); +OtaPalStatus_t otaPal_ResetDevice( OtaFileContext_t * const C ); /** * @brief Attempt to set the state of the OTA update image. @@ -176,8 +176,8 @@ OtaPalStatus_t otaPal_ResetDevice( OtaFileContext_t * const C ); * OTA_ERR_REJECT_FAILED: failed to roll back the update image as requested by OtaImageStateRejected. * OTA_ERR_COMMIT_FAILED: failed to make the update image permanent as requested by OtaImageStateAccepted. */ -OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const C, - OtaImageState_t eState ); +OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const C, + OtaImageState_t eState ); /** * @brief Get the state of the OTA update image. @@ -202,4 +202,4 @@ OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const C, */ OtaPalImageState_t otaPal_GetPlatformImageState( OtaFileContext_t * const C ); -#endif /* ifndef _OTA_PAL_H_ */ \ No newline at end of file +#endif /* ifndef _OTA_PAL_H_ */ diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/subscription-manager/subscription_manager.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/subscription-manager/subscription_manager.c index f9c69a02a..0ab787aa0 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/subscription-manager/subscription_manager.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/subscription-manager/subscription_manager.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/subscription-manager/subscription_manager.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/subscription-manager/subscription_manager.h index d95dcfd25..30ffa591a 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/subscription-manager/subscription_manager.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Common/subscription-manager/subscription_manager.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/DemoTasks/OtaOverHttpDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/DemoTasks/OtaOverHttpDemoExample.c index 876d899ab..762c3890c 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/DemoTasks/OtaOverHttpDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/DemoTasks/OtaOverHttpDemoExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -672,7 +672,7 @@ static void prvMQTTAgentTask( void * pParam ); * * The implementation uses MQTT agent to queue a publish request. It then waits * for the request complete notification from the agent. The notification along with result of the - * operation is sent back to the caller task using xTaksNotify API. For publishes involving QOS 1 and + * operation is sent back to the caller task using xTaskNotify API. For publishes involving QOS 1 and * QOS2 the operation is complete once an acknowledgment (PUBACK) is received. OTA agent uses this function * to fetch new job, provide status update and send other control related messages to the MQTT broker. * @@ -808,7 +808,7 @@ static void prvMqttDataCallback( void * pContext, * * The callback is not subscribed with MQTT broker, but only with local subscription manager. * A wildcard OTA job topic is used for subscription so that all unsolicited messages related to OTA is - * forwarded to this callback for filteration. Right now the callback is used to filter responses to job requests + * forwarded to this callback for filtration. Right now the callback is used to filter responses to job requests * from the OTA service. * * @param[in] pvIncomingPublishCallbackContext MQTT context which stores the connection. @@ -1186,12 +1186,12 @@ static void prvCommandCallback( MQTTAgentCommandContext_t * pxCommandContext, static void prvMQTTSubscribeCompleteCallback( MQTTAgentCommandContext_t * pxCommandContext, MQTTAgentReturnInfo_t * pxReturnInfo ) { - MQTTAgentSubscribeArgs_t * pSubsribeArgs; + MQTTAgentSubscribeArgs_t * pSubscribeArgs; if( pxReturnInfo->returnCode == MQTTSuccess ) { - pSubsribeArgs = ( MQTTAgentSubscribeArgs_t * ) ( pxCommandContext->pArgs ); - prvRegisterOTACallback( pSubsribeArgs->pSubscribeInfo->pTopicFilter, pSubsribeArgs->pSubscribeInfo->topicFilterLength ); + pSubscribeArgs = ( MQTTAgentSubscribeArgs_t * ) ( pxCommandContext->pArgs ); + prvRegisterOTACallback( pSubscribeArgs->pSubscribeInfo->pTopicFilter, pSubscribeArgs->pSubscribeInfo->topicFilterLength ); } /* Store the result in the application defined context so the task that @@ -1431,41 +1431,43 @@ static BaseType_t prvSocketConnect( NetworkContext_t * pxNetworkContext ) NetworkCredentials_t xNetworkCredentials = { 0 }; #if defined( democonfigUSE_AWS_IOT_CORE_BROKER ) - #if defined( democonfigCLIENT_USERNAME ) - /* - * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect - * to AWS IoT Core with Custom Authentication on port 443. - * - * Custom Authentication uses the contents of the username and password - * fields of the MQTT CONNECT packet to authenticate the client. - * - * For more information, refer to the documentation at: - * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html - */ - static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; - #if democonfigMQTT_BROKER_PORT != 443U - #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." - #endif /* democonfigMQTT_BROKER_PORT != 443U */ - #else /* if !defined( democonfigCLIENT_USERNAME ) */ - /* - * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using - * x509 Certificate Authentication. - */ - static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; - #endif /* !defined( democonfigCLIENT_USERNAME ) */ + #if defined( democonfigCLIENT_USERNAME ) /* - * An ALPN identifier is only required when connecting to AWS IoT core on port 443. - * https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html + * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect + * to AWS IoT Core with Custom Authentication on port 443. + * + * Custom Authentication uses the contents of the username and password + * fields of the MQTT CONNECT packet to authenticate the client. + * + * For more information, refer to the documentation at: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html */ - #if democonfigMQTT_BROKER_PORT == 443U - xNetworkCredentials.pAlpnProtos = ppcAlpnProtocols; - #elif democonfigMQTT_BROKER_PORT == 8883U - xNetworkCredentials.pAlpnProtos = NULL; - #else /* democonfigMQTT_BROKER_PORT != 8883U */ - xNetworkCredentials.pAlpnProtos = NULL; - #error "MQTT connections to AWS IoT Core are only allowed on ports 443 and 8883." + static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; + #if democonfigMQTT_BROKER_PORT != 443U + #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." #endif /* democonfigMQTT_BROKER_PORT != 443U */ + #else /* if !defined( democonfigCLIENT_USERNAME ) */ + + /* + * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using + * x509 Certificate Authentication. + */ + static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; + #endif /* !defined( democonfigCLIENT_USERNAME ) */ + + /* + * An ALPN identifier is only required when connecting to AWS IoT core on port 443. + * https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html + */ + #if democonfigMQTT_BROKER_PORT == 443U + xNetworkCredentials.pAlpnProtos = ppcAlpnProtocols; + #elif democonfigMQTT_BROKER_PORT == 8883U + xNetworkCredentials.pAlpnProtos = NULL; + #else /* democonfigMQTT_BROKER_PORT != 8883U */ + xNetworkCredentials.pAlpnProtos = NULL; + #error "MQTT connections to AWS IoT Core are only allowed on ports 443 and 8883." + #endif /* democonfigMQTT_BROKER_PORT != 443U */ #else /* !defined( democonfigUSE_AWS_IOT_CORE_BROKER ) */ xNetworkCredentials.pAlpnProtos = NULL; #endif /* !defined( democonfigUSE_AWS_IOT_CORE_BROKER ) */ @@ -2501,7 +2503,7 @@ static BaseType_t prvRunOTADemo( void ) } /** - * Remvove callback for receiving messages intended for OTA agent from broker, + * Remove callback for receiving messages intended for OTA agent from broker, * for which the topic has not been subscribed for. */ removeSubscription( ( SubscriptionElement_t * ) xGlobalMqttAgentContext.pIncomingCallbackContext, diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj index 7fefbf559..06d191f1f 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj @@ -1,249 +1,249 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {4be4e103-5bf4-4a85-9656-ec20852a2b8e} - OtaOverHttpDemo - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - RTOSDemo - - - false - RTOSDemo - - - true - RTOSDemo - - - false - RTOSDemo - - - - Level3 - false - MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;WIN32;__little_endian__=1;_DEBUG;_CONSOLE;WIN32;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - true - ..\Common\HTTP_Utils;..\..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\..\Source\Application-Protocols\network_transport;..\..\..\Common\coreMQTT_Agent_Interface\include;..\..\..\..\ThirdParty\tinycbor\src;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\..\..\Source\AWS\ota\source\include;..\..\..\..\Source\AWS\ota\source\portable\os;..\..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\Common\Ota_PAL\Win32\Code_Signature_Verification;..\Common\Ota_PAL\Win32;..\Common\subscription-manager;.\;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - false - MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;WIN32;__little_endian__=1;WIN32;NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - true - ..\Common\HTTP_Utils;..\..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\..\Source\Application-Protocols\network_transport;..\..\..\Common\coreMQTT_Agent_Interface\include;..\..\..\..\ThirdParty\tinycbor\src;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\..\..\Source\AWS\ota\source\include;..\..\..\..\Source\AWS\ota\source\portable\os;..\..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\Common\Ota_PAL\Win32\Code_Signature_Verification;..\Common\Ota_PAL\Win32;..\Common\subscription-manager;.\;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - false - MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;WIN32;__little_endian__=1;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - true - ..\Common\HTTP_Utils;..\..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\..\Source\Application-Protocols\network_transport;..\..\..\Common\coreMQTT_Agent_Interface\include;..\..\..\..\ThirdParty\tinycbor\src;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\..\..\Source\AWS\ota\source\include;..\..\..\..\Source\AWS\ota\source\portable\os;..\..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\Common\Ota_PAL\Win32\Code_Signature_Verification;..\Common\Ota_PAL\Win32;..\Common\subscription-manager;.\;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - false - MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;WIN32;__little_endian__=1;NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - true - ..\Common\HTTP_Utils;..\..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\..\Source\Application-Protocols\network_transport;..\..\..\Common\coreMQTT_Agent_Interface\include;..\..\..\..\ThirdParty\tinycbor\src;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\..\..\Source\AWS\ota\source\include;..\..\..\..\Source\AWS\ota\source\portable\os;..\..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\Common\Ota_PAL\Win32\Code_Signature_Verification;..\Common\Ota_PAL\Win32;..\Common\subscription-manager;.\;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - {ee39fa0f-cefb-4c29-a571-05a28fdd47fd} - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {4be4e103-5bf4-4a85-9656-ec20852a2b8e} + OtaOverHttpDemo + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + RTOSDemo + + + false + RTOSDemo + + + true + RTOSDemo + + + false + RTOSDemo + + + + Level3 + false + MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;WIN32;__little_endian__=1;_DEBUG;_CONSOLE;WIN32;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + true + ..\Common\HTTP_Utils;..\..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\..\Source\Application-Protocols\network_transport;..\..\..\Common\coreMQTT_Agent_Interface\include;..\..\..\..\ThirdParty\tinycbor\src;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\..\..\Source\AWS\ota\source\include;..\..\..\..\Source\AWS\ota\source\portable\os;..\..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\Common\Ota_PAL\Win32\Code_Signature_Verification;..\Common\Ota_PAL\Win32;..\Common\subscription-manager;.\;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + false + MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;WIN32;__little_endian__=1;WIN32;NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + true + ..\Common\HTTP_Utils;..\..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\..\Source\Application-Protocols\network_transport;..\..\..\Common\coreMQTT_Agent_Interface\include;..\..\..\..\ThirdParty\tinycbor\src;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\..\..\Source\AWS\ota\source\include;..\..\..\..\Source\AWS\ota\source\portable\os;..\..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\Common\Ota_PAL\Win32\Code_Signature_Verification;..\Common\Ota_PAL\Win32;..\Common\subscription-manager;.\;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + false + MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;WIN32;__little_endian__=1;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + true + ..\Common\HTTP_Utils;..\..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\..\Source\Application-Protocols\network_transport;..\..\..\Common\coreMQTT_Agent_Interface\include;..\..\..\..\ThirdParty\tinycbor\src;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\..\..\Source\AWS\ota\source\include;..\..\..\..\Source\AWS\ota\source\portable\os;..\..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\Common\Ota_PAL\Win32\Code_Signature_Verification;..\Common\Ota_PAL\Win32;..\Common\subscription-manager;.\;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + false + MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;WIN32;__little_endian__=1;NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + true + ..\Common\HTTP_Utils;..\..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\..\Source\Application-Protocols\network_transport;..\..\..\Common\coreMQTT_Agent_Interface\include;..\..\..\..\ThirdParty\tinycbor\src;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\..\..\Source\AWS\ota\source\include;..\..\..\..\Source\AWS\ota\source\portable\os;..\..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\Common\Ota_PAL\Win32\Code_Signature_Verification;..\Common\Ota_PAL\Win32;..\Common\subscription-manager;.\;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + {ee39fa0f-cefb-4c29-a571-05a28fdd47fd} + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj.filters index 14cac11af..d5aafccd1 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/Ota_Over_Http_Demo.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/core_mqtt_config.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/core_mqtt_config.h index 7d65ca192..dc668f6bb 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/core_mqtt_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/core_mqtt_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -23,7 +23,7 @@ * https://github.com/FreeRTOS * */ - + #ifndef CORE_MQTT_CONFIG_H #define CORE_MQTT_CONFIG_H @@ -76,33 +76,34 @@ extern void vLoggingPrintf( const char * pcFormatString, */ #define MQTT_STATE_ARRAY_MAX_COUNT 10U - /*********************** coreMQTT Agent Configurations **********************/ - /** - * @brief The maximum number of pending acknowledgments to track for a single - * connection. - * - * @note The MQTT agent tracks MQTT commands (such as PUBLISH and SUBSCRIBE) th - * at are still waiting to be acknowledged. MQTT_AGENT_MAX_OUTSTANDING_ACKS set - * the maximum number of acknowledgments that can be outstanding at any one time. - * The higher this number is the greater the agent's RAM consumption will be. - */ +/*********************** coreMQTT Agent Configurations **********************/ + +/** + * @brief The maximum number of pending acknowledgments to track for a single + * connection. + * + * @note The MQTT agent tracks MQTT commands (such as PUBLISH and SUBSCRIBE) th + * at are still waiting to be acknowledged. MQTT_AGENT_MAX_OUTSTANDING_ACKS set + * the maximum number of acknowledgments that can be outstanding at any one time. + * The higher this number is the greater the agent's RAM consumption will be. + */ #define MQTT_AGENT_MAX_OUTSTANDING_ACKS ( 20U ) - /** - * @brief Time in MS that the MQTT agent task will wait in the Blocked state (so - * not using any CPU time) for a command to arrive in its command queue before - * exiting the blocked state so it can call MQTT_ProcessLoop(). - * - * @note It is important MQTT_ProcessLoop() is called often if there is known - * MQTT traffic, but calling it too often can take processing time away from - * lower priority tasks and waste CPU time and power. - */ +/** + * @brief Time in MS that the MQTT agent task will wait in the Blocked state (so + * not using any CPU time) for a command to arrive in its command queue before + * exiting the blocked state so it can call MQTT_ProcessLoop(). + * + * @note It is important MQTT_ProcessLoop() is called often if there is known + * MQTT traffic, but calling it too often can take processing time away from + * lower priority tasks and waste CPU time and power. + */ #define MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME ( 1000 ) - /** - * @brief The number of command structures to allocate in the pool - * for the agent. - */ +/** + * @brief The number of command structures to allocate in the pool + * for the agent. + */ #define MQTT_COMMAND_CONTEXTS_POOL_SIZE 10 diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/demo_config.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/demo_config.h index 5e134173c..f7ae0eabd 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/demo_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/main.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/main.c index 8aab83f99..b0637c5be 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/main.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/ota_config.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/ota_config.h index ad69a5506..d07e66ad0 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/ota_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/ota_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -179,8 +179,8 @@ extern void vLoggingPrintf( const char * pcFormatString, * can be set to following - * Enable data over MQTT - ( OTA_DATA_OVER_MQTT ) * Enable data over HTTP - ( OTA_DATA_OVER_HTTP) - * - * Note - Please check the OTA over MQTT demo which has the MQTT data transfer functionality and + * + * Note - Please check the OTA over MQTT demo which has the MQTT data transfer functionality and * and this configuration is set to OTA_DATA_OVER_MQTT. */ #define configENABLED_DATA_PROTOCOLS ( OTA_DATA_OVER_HTTP ) diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/ota_over_http_demo.sln b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/ota_over_http_demo.sln index 1d3553d50..25e640eda 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/ota_over_http_demo.sln +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Http_Demo/ota_over_http_demo.sln @@ -1,116 +1,116 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31205.134 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ota_Over_Http_Demo", "Ota_Over_Http_Demo.vcxproj", "{4BE4E103-5BF4-4A85-9656-EC20852A2B8E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{9799AFF4-25E2-43CD-8829-C066177E3748}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ww", "..\..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "coreHTTP", "..\..\..\..\VisualStudio_StaticProjects\coreHTTP\coreHTTP.vcxproj", "{EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|Win32.ActiveCfg = Debug|Win32 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|Win32.Build.0 = Debug|Win32 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|x64.ActiveCfg = Debug|x64 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|x64.Build.0 = Debug|x64 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|x86.ActiveCfg = Debug|Win32 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|x86.Build.0 = Debug|Win32 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|Win32.ActiveCfg = Release|Win32 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|Win32.Build.0 = Release|Win32 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|x64.ActiveCfg = Release|x64 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|x64.Build.0 = Release|x64 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|x86.ActiveCfg = Release|Win32 - {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|Win32.ActiveCfg = Debug|Win32 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|Win32.Build.0 = Debug|Win32 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|x64.ActiveCfg = Debug|x64 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|x64.Build.0 = Debug|x64 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|x86.ActiveCfg = Debug|Win32 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|x86.Build.0 = Debug|Win32 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|Win32.ActiveCfg = Release|Win32 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|Win32.Build.0 = Release|Win32 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|x64.ActiveCfg = Release|x64 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|x64.Build.0 = Release|x64 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|x86.ActiveCfg = Release|Win32 - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {9799AFF4-25E2-43CD-8829-C066177E3748} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {9799AFF4-25E2-43CD-8829-C066177E3748} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {9799AFF4-25E2-43CD-8829-C066177E3748} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {9799AFF4-25E2-43CD-8829-C066177E3748} - {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD} = {9799AFF4-25E2-43CD-8829-C066177E3748} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {03800DFF-BAFA-4654-8E51-C4E654A54416} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31205.134 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ota_Over_Http_Demo", "Ota_Over_Http_Demo.vcxproj", "{4BE4E103-5BF4-4A85-9656-EC20852A2B8E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{9799AFF4-25E2-43CD-8829-C066177E3748}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ww", "..\..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "coreHTTP", "..\..\..\..\VisualStudio_StaticProjects\coreHTTP\coreHTTP.vcxproj", "{EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|Win32.ActiveCfg = Debug|Win32 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|Win32.Build.0 = Debug|Win32 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|x64.ActiveCfg = Debug|x64 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|x64.Build.0 = Debug|x64 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|x86.ActiveCfg = Debug|Win32 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Debug|x86.Build.0 = Debug|Win32 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|Win32.ActiveCfg = Release|Win32 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|Win32.Build.0 = Release|Win32 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|x64.ActiveCfg = Release|x64 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|x64.Build.0 = Release|x64 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|x86.ActiveCfg = Release|Win32 + {4BE4E103-5BF4-4A85-9656-EC20852A2B8E}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|Win32.ActiveCfg = Debug|Win32 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|Win32.Build.0 = Debug|Win32 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|x64.ActiveCfg = Debug|x64 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|x64.Build.0 = Debug|x64 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|x86.ActiveCfg = Debug|Win32 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Debug|x86.Build.0 = Debug|Win32 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|Win32.ActiveCfg = Release|Win32 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|Win32.Build.0 = Release|Win32 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|x64.ActiveCfg = Release|x64 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|x64.Build.0 = Release|x64 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|x86.ActiveCfg = Release|Win32 + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {9799AFF4-25E2-43CD-8829-C066177E3748} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {9799AFF4-25E2-43CD-8829-C066177E3748} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {9799AFF4-25E2-43CD-8829-C066177E3748} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {9799AFF4-25E2-43CD-8829-C066177E3748} + {EE39FA0F-CEFB-4C29-A571-05A28FDD47FD} = {9799AFF4-25E2-43CD-8829-C066177E3748} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {03800DFF-BAFA-4654-8E51-C4E654A54416} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/DemoTasks/OtaOverMqttDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/DemoTasks/OtaOverMqttDemoExample.c index 5b1ea6a9c..fea5663db 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/DemoTasks/OtaOverMqttDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/DemoTasks/OtaOverMqttDemoExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -304,13 +304,13 @@ #ifndef democonfigCLIENT_IDENTIFIER - /** - * @brief The MQTT client identifier used in this example. Each client identifier - * must be unique so edit as required to ensure no two clients connecting to the - * same broker use the same client identifier. Using a #define is for convenience - * of demonstration only - production devices should use something unique to the - * device that can be read from software - such as a production serial number. - */ +/** + * @brief The MQTT client identifier used in this example. Each client identifier + * must be unique so edit as required to ensure no two clients connecting to the + * same broker use the same client identifier. Using a #define is for convenience + * of demonstration only - production devices should use something unique to the + * device that can be read from software - such as a production serial number. + */ #error "Please define democonfigCLIENT_IDENTIFIER in demo_config.h to something unique for this device." #endif @@ -320,14 +320,14 @@ #error "Please define Root CA certificate of the MQTT broker(democonfigROOT_CA_PEM) in demo_config.h." #endif - /* If no username is defined, then a client certificate/key is required. */ +/* If no username is defined, then a client certificate/key is required. */ #ifndef democonfigCLIENT_USERNAME - /* - *!!! Please note democonfigCLIENT_PRIVATE_KEY_PEM in used for - *!!! convenience of demonstration only. Production devices should - *!!! store keys securely, such as within a secure element. - */ +/* + *!!! Please note democonfigCLIENT_PRIVATE_KEY_PEM in used for + *!!! convenience of demonstration only. Production devices should + *!!! store keys securely, such as within a secure element. + */ #ifndef democonfigCLIENT_CERTIFICATE_PEM #error "Please define client certificate(democonfigCLIENT_CERTIFICATE_PEM) in demo_config.h." @@ -337,14 +337,14 @@ #endif #else - /* If a username is defined, a client password also would need to be defined for - * client authentication. */ +/* If a username is defined, a client password also would need to be defined for + * client authentication. */ #ifndef democonfigCLIENT_PASSWORD #error "Please define client password(democonfigCLIENT_PASSWORD) in demo_config.h for client authentication based on username/password." #endif - /* AWS IoT MQTT broker port needs to be 443 for client authentication based on - * username/password. */ +/* AWS IoT MQTT broker port needs to be 443 for client authentication based on + * username/password. */ #if defined( democonfigUSE_AWS_IOT_CORE_BROKER ) && democonfigMQTT_BROKER_PORT != 443 #error "Broker port(democonfigMQTT_BROKER_PORT) should be defined as 443 in demo_config.h for client authentication based on username/password in AWS IoT Core." #endif @@ -529,7 +529,7 @@ static void prvMQTTAgentTask( void * pParam ); * * The implementation uses MQTT agent to queue a publish request. It then waits * for the request complete notification from the agent. The notification along with result of the - * operation is sent back to the caller task using xTaksNotify API. For publishes involving QOS 1 and + * operation is sent back to the caller task using xTaskNotify API. For publishes involving QOS 1 and * QOS2 the operation is complete once an acknowledgment (PUBACK) is received. OTA agent uses this function * to fetch new job, provide status update and send other control related messages to the MQTT broker. * @@ -593,7 +593,7 @@ static OtaMqttStatus_t prvMQTTUnsubscribe( const char * pTopicFilter, * within ota_config.h. This function is used to fetch a free buffer from the pool for processing * by the OTA agent task. It uses a mutex for thread safe access to the pool. * - * @return A pointer to an unusued buffer. NULL if there are no buffers available. + * @return A pointer to an unused buffer. NULL if there are no buffers available. */ static OtaEventData_t * prvOTAEventBufferGet( void ); @@ -667,7 +667,7 @@ static void prvMqttDataCallback( void * pContext, * * The callback is not subscribed with MQTT broker, but only with local subscription manager. * A wildcard OTA job topic is used for subscription so that all unsolicited messages related to OTA is - * forwarded to this callback for filteration. Right now the callback is used to filter responses to job requests + * forwarded to this callback for filtration. Right now the callback is used to filter responses to job requests * from the OTA service. * * @param[in] pvIncomingPublishCallbackContext MQTT context which stores the connection. @@ -1043,12 +1043,12 @@ static void prvCommandCallback( MQTTAgentCommandContext_t * pxCommandContext, static void prvMQTTSubscribeCompleteCallback( MQTTAgentCommandContext_t * pxCommandContext, MQTTAgentReturnInfo_t * pxReturnInfo ) { - MQTTAgentSubscribeArgs_t * pSubsribeArgs; + MQTTAgentSubscribeArgs_t * pSubscribeArgs; if( pxReturnInfo->returnCode == MQTTSuccess ) { - pSubsribeArgs = ( MQTTAgentSubscribeArgs_t * ) ( pxCommandContext->pArgs ); - prvRegisterOTACallback( pSubsribeArgs->pSubscribeInfo->pTopicFilter, pSubsribeArgs->pSubscribeInfo->topicFilterLength ); + pSubscribeArgs = ( MQTTAgentSubscribeArgs_t * ) ( pxCommandContext->pArgs ); + prvRegisterOTACallback( pSubscribeArgs->pSubscribeInfo->pTopicFilter, pSubscribeArgs->pSubscribeInfo->topicFilterLength ); } /* Store the result in the application defined context so the task that @@ -1288,42 +1288,43 @@ static BaseType_t prvSocketConnect( NetworkContext_t * pxNetworkContext ) NetworkCredentials_t xNetworkCredentials = { 0 }; #if defined( democonfigUSE_AWS_IOT_CORE_BROKER ) - #if defined( democonfigCLIENT_USERNAME ) - /* - * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect - * to AWS IoT Core with Custom Authentication on port 443. - * - * Custom Authentication uses the contents of the username and password - * fields of the MQTT CONNECT packet to authenticate the client. - * - * For more information, refer to the documentation at: - * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html - */ - static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; - #if democonfigMQTT_BROKER_PORT != 443U - #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." - #endif /* democonfigMQTT_BROKER_PORT != 443U */ - #else /* if !defined( democonfigCLIENT_USERNAME ) */ - /* - * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using - * x509 Certificate Authentication. - */ - static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; - - #endif /* !defined( democonfigCLIENT_USERNAME ) */ + #if defined( democonfigCLIENT_USERNAME ) /* - * An ALPN identifier is only required when connecting to AWS IoT core on port 443. - * https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html - */ - #if democonfigMQTT_BROKER_PORT == 443U - xNetworkCredentials.pAlpnProtos = ppcAlpnProtocols; - #elif democonfigMQTT_BROKER_PORT == 8883U - xNetworkCredentials.pAlpnProtos = NULL; - #else /* democonfigMQTT_BROKER_PORT != 8883U */ - xNetworkCredentials.pAlpnProtos = NULL; - #error "MQTT connections to AWS IoT Core are only allowed on ports 443 and 8883." + * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect + * to AWS IoT Core with Custom Authentication on port 443. + * + * Custom Authentication uses the contents of the username and password + * fields of the MQTT CONNECT packet to authenticate the client. + * + * For more information, refer to the documentation at: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + */ + static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; + #if democonfigMQTT_BROKER_PORT != 443U + #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." #endif /* democonfigMQTT_BROKER_PORT != 443U */ + #else /* if !defined( democonfigCLIENT_USERNAME ) */ + + /* + * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using + * x509 Certificate Authentication. + */ + static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; + #endif /* !defined( democonfigCLIENT_USERNAME ) */ + + /* + * An ALPN identifier is only required when connecting to AWS IoT core on port 443. + * https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html + */ + #if democonfigMQTT_BROKER_PORT == 443U + xNetworkCredentials.pAlpnProtos = ppcAlpnProtocols; + #elif democonfigMQTT_BROKER_PORT == 8883U + xNetworkCredentials.pAlpnProtos = NULL; + #else /* democonfigMQTT_BROKER_PORT != 8883U */ + xNetworkCredentials.pAlpnProtos = NULL; + #error "MQTT connections to AWS IoT Core are only allowed on ports 443 and 8883." + #endif /* democonfigMQTT_BROKER_PORT != 443U */ #else /* !defined( democonfigUSE_AWS_IOT_CORE_BROKER ) */ xNetworkCredentials.pAlpnProtos = NULL; #endif /* !defined( democonfigUSE_AWS_IOT_CORE_BROKER ) */ @@ -2037,7 +2038,7 @@ static BaseType_t prvRunOTADemo( void ) } /** - * Remvove callback for receiving messages intended for OTA agent from broker, + * Remove callback for receiving messages intended for OTA agent from broker, * for which the topic has not been subscribed for. */ removeSubscription( ( SubscriptionElement_t * ) xGlobalMqttAgentContext.pIncomingCallbackContext, @@ -2086,6 +2087,7 @@ void vOtaDemoTask( void * pvParam ) if( xPlatformIsNetworkUp() == pdFALSE ) { LogInfo( ( "Waiting for the network link up event..." ) ); + while( xPlatformIsNetworkUp() == pdFALSE ) { vTaskDelay( pdMS_TO_TICKS( 1000U ) ); diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj.filters index d3b4aeac9..032f5b8ae 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/Ota_Over_Mqtt_Demo.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/core_mqtt_config.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/core_mqtt_config.h index 7d65ca192..dc668f6bb 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/core_mqtt_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/core_mqtt_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -23,7 +23,7 @@ * https://github.com/FreeRTOS * */ - + #ifndef CORE_MQTT_CONFIG_H #define CORE_MQTT_CONFIG_H @@ -76,33 +76,34 @@ extern void vLoggingPrintf( const char * pcFormatString, */ #define MQTT_STATE_ARRAY_MAX_COUNT 10U - /*********************** coreMQTT Agent Configurations **********************/ - /** - * @brief The maximum number of pending acknowledgments to track for a single - * connection. - * - * @note The MQTT agent tracks MQTT commands (such as PUBLISH and SUBSCRIBE) th - * at are still waiting to be acknowledged. MQTT_AGENT_MAX_OUTSTANDING_ACKS set - * the maximum number of acknowledgments that can be outstanding at any one time. - * The higher this number is the greater the agent's RAM consumption will be. - */ +/*********************** coreMQTT Agent Configurations **********************/ + +/** + * @brief The maximum number of pending acknowledgments to track for a single + * connection. + * + * @note The MQTT agent tracks MQTT commands (such as PUBLISH and SUBSCRIBE) th + * at are still waiting to be acknowledged. MQTT_AGENT_MAX_OUTSTANDING_ACKS set + * the maximum number of acknowledgments that can be outstanding at any one time. + * The higher this number is the greater the agent's RAM consumption will be. + */ #define MQTT_AGENT_MAX_OUTSTANDING_ACKS ( 20U ) - /** - * @brief Time in MS that the MQTT agent task will wait in the Blocked state (so - * not using any CPU time) for a command to arrive in its command queue before - * exiting the blocked state so it can call MQTT_ProcessLoop(). - * - * @note It is important MQTT_ProcessLoop() is called often if there is known - * MQTT traffic, but calling it too often can take processing time away from - * lower priority tasks and waste CPU time and power. - */ +/** + * @brief Time in MS that the MQTT agent task will wait in the Blocked state (so + * not using any CPU time) for a command to arrive in its command queue before + * exiting the blocked state so it can call MQTT_ProcessLoop(). + * + * @note It is important MQTT_ProcessLoop() is called often if there is known + * MQTT traffic, but calling it too often can take processing time away from + * lower priority tasks and waste CPU time and power. + */ #define MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME ( 1000 ) - /** - * @brief The number of command structures to allocate in the pool - * for the agent. - */ +/** + * @brief The number of command structures to allocate in the pool + * for the agent. + */ #define MQTT_COMMAND_CONTEXTS_POOL_SIZE 10 diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/demo_config.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/demo_config.h index c275659ac..e8c38fe49 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/demo_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/main.c b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/main.c index 8aab83f99..b0637c5be 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/main.c +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/ota_config.h b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/ota_config.h index d3d9159e4..03ecd1d52 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/ota_config.h +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/ota_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -179,8 +179,8 @@ extern void vLoggingPrintf( const char * pcFormatString, * can be set to following - * Enable data over MQTT - ( OTA_DATA_OVER_MQTT ) * Enable data over HTTP - ( OTA_DATA_OVER_HTTP) - * - * Note - Please check the OTA over HTTP demo which has the HTTP data transfer functionality and + * + * Note - Please check the OTA over HTTP demo which has the HTTP data transfer functionality and * and this configuration is set to OTA_DATA_OVER_HTTP. */ #define configENABLED_DATA_PROTOCOLS ( OTA_DATA_OVER_MQTT ) diff --git a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/ota_over_mqtt_demo.sln b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/ota_over_mqtt_demo.sln index 18250fab6..1bf519237 100644 --- a/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/ota_over_mqtt_demo.sln +++ b/FreeRTOS-Plus/Demo/AWS/Ota_Windows_Simulator/Ota_Over_Mqtt_Demo/ota_over_mqtt_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31205.134 diff --git a/FreeRTOS-Plus/Demo/Also_See_More_FreeRTOS+TCP_and_FreeRTOS_FAT_in_the_lab.url b/FreeRTOS-Plus/Demo/Also_See_More_FreeRTOS+TCP_and_FreeRTOS_FAT_in_the_lab.url index dd4e3426b..c22a9242b 100644 --- a/FreeRTOS-Plus/Demo/Also_See_More_FreeRTOS+TCP_and_FreeRTOS_FAT_in_the_lab.url +++ b/FreeRTOS-Plus/Demo/Also_See_More_FreeRTOS+TCP_and_FreeRTOS_FAT_in_the_lab.url @@ -1,5 +1,5 @@ -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 -[InternetShortcut] -URL=http://www.freertos.org/labs -IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/labs +IDList= diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/Common/FreeRTOS_TCP_server.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/Common/FreeRTOS_TCP_server.c index 9fb2feed1..39e6b3e4e 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/Common/FreeRTOS_TCP_server.c +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/Common/FreeRTOS_TCP_server.c @@ -1,372 +1,385 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* Standard includes. */ -#include -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" -#include "FreeRTOS_TCP_server.h" -#include "FreeRTOS_server_private.h" - -/* Remove the entire file if TCP is not being used. */ -#if( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) ) - -#if !defined( ARRAY_SIZE ) - #define ARRAY_SIZE(x) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] ) -#endif - - -static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket ); -static char *strnew( const char *pcString ); -/* Remove slashes at the end of a path. */ -static void prvRemoveSlash( char *pcDir ); - -TCPServer_t *FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG *pxConfigs, BaseType_t xCount ) -{ -TCPServer_t *pxServer; -SocketSet_t xSocketSet; - - /* Create a new server. - xPort / xPortAlt : Make the service available on 1 or 2 public port numbers. */ - xSocketSet = FreeRTOS_CreateSocketSet(); - - if( xSocketSet != NULL ) - { - BaseType_t xSize; - - xSize = sizeof( *pxServer ) - sizeof( pxServer->xServers ) + xCount * sizeof( pxServer->xServers[ 0 ] ); - - pxServer = ( TCPServer_t * ) pvPortMallocLarge( xSize ); - if( pxServer != NULL ) - { - struct freertos_sockaddr xAddress; - BaseType_t xNoTimeout = 0; - BaseType_t xIndex; - - memset( pxServer, '\0', xSize ); - pxServer->xServerCount = xCount; - pxServer->xSocketSet = xSocketSet; - - for( xIndex = 0; xIndex < xCount; xIndex++ ) - { - BaseType_t xPortNumber = pxConfigs[ xIndex ].xPortNumber; - - if( xPortNumber > 0 ) - { - Socket_t xSocket; - - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); - FreeRTOS_printf( ( "TCP socket on port %d\n", ( int )xPortNumber ) ); - - if( xSocket != FREERTOS_INVALID_SOCKET ) - { - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xAddress.sin_address.ulIP_IPv4 = FreeRTOS_GetIPAddress(); /* Single NIC, currently not used */ - } - #else - { - xAddress.sin_addr = FreeRTOS_GetIPAddress(); /* Single NIC, currently not used */ - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xAddress.sin_port = FreeRTOS_htons( xPortNumber ); - xAddress.sin_family = FREERTOS_AF_INET; - - FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) ); - FreeRTOS_listen( xSocket, pxConfigs[ xIndex ].xBackLog ); - - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) ); - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) ); - - #if( ipconfigHTTP_RX_BUFSIZE > 0 ) - { - if( pxConfigs[ xIndex ].eType == eSERVER_HTTP ) - { - WinProperties_t xWinProps; - - memset( &xWinProps, '\0', sizeof( xWinProps ) ); - /* The parent socket itself won't get connected. The properties below - will be inherited by each new child socket. */ - xWinProps.lTxBufSize = ipconfigHTTP_TX_BUFSIZE; - xWinProps.lTxWinSize = ipconfigHTTP_TX_WINSIZE; - xWinProps.lRxBufSize = ipconfigHTTP_RX_BUFSIZE; - xWinProps.lRxWinSize = ipconfigHTTP_RX_WINSIZE; - - /* Set the window and buffer sizes. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); - } - } - #endif - - FreeRTOS_FD_SET( xSocket, xSocketSet, eSELECT_READ|eSELECT_EXCEPT ); - pxServer->xServers[ xIndex ].xSocket = xSocket; - pxServer->xServers[ xIndex ].eType = pxConfigs[ xIndex ].eType; - pxServer->xServers[ xIndex ].pcRootDir = strnew( pxConfigs[ xIndex ].pcRootDir ); - prvRemoveSlash( ( char * ) pxServer->xServers[ xIndex ].pcRootDir ); - } - } - } - } - else - { - /* Could not allocate the server, delete the socket set */ - FreeRTOS_DeleteSocketSet( xSocketSet ); - } - } - else - { - /* Could not create a socket set, return NULL */ - pxServer = NULL; - } - - return pxServer; -} -/*-----------------------------------------------------------*/ - -static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket ) -{ -TCPClient_t *pxClient = NULL; -BaseType_t xSize = 0; -FTCPWorkFunction fWorkFunc = NULL; -FTCPDeleteFunction fDeleteFunc = NULL; -const char *pcType = "Unknown"; - - /*_RB_ Can the work and delete functions be part of the xSERVER_CONFIG structure - becomes generic, with no pre-processing required? */ - #if( ipconfigUSE_HTTP != 0 ) - { - if( pxServer->xServers[ xIndex ].eType == eSERVER_HTTP ) - { - xSize = sizeof( HTTPClient_t ); - fWorkFunc = xHTTPClientWork; - fDeleteFunc = vHTTPClientDelete; - pcType = "HTTP"; - } - } - #endif /* ipconfigUSE_HTTP != 0 */ - - #if( ipconfigUSE_FTP != 0 ) - { - if( pxServer->xServers[ xIndex ].eType == eSERVER_FTP ) - { - xSize = sizeof( FTPClient_t ); - fWorkFunc = xFTPClientWork; - fDeleteFunc = vFTPClientDelete; - pcType = "FTP"; - } - } - #endif /* ipconfigUSE_FTP != 0 */ - - /* Malloc enough space for a new HTTP-client */ - if( xSize ) - { - pxClient = ( TCPClient_t* ) pvPortMallocLarge( xSize ); - } - - if( pxClient != NULL ) - { - memset( pxClient, '\0', xSize ); - - /* Put the new client in front of the list. */ - pxClient->eType = pxServer->xServers[ xIndex ].eType; - pxClient->pcRootDir = pxServer->xServers[ xIndex ].pcRootDir; - pxClient->pxParent = pxServer; - pxClient->xSocket = xNexSocket; - pxClient->pxNextClient = pxServer->pxClients; - pxClient->fWorkFunction = fWorkFunc; - pxClient->fDeleteFunction = fDeleteFunc; - pxServer->pxClients = pxClient; - - FreeRTOS_FD_SET( xNexSocket, pxServer->xSocketSet, eSELECT_READ|eSELECT_EXCEPT ); - } - else - { - pcType = "closed"; - FreeRTOS_closesocket( xNexSocket ); - } - { - struct freertos_sockaddr xRemoteAddress; - FreeRTOS_GetRemoteAddress( pxClient->xSocket, &xRemoteAddress ); - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - FreeRTOS_printf( ( "TPC-server: new %s client %xip\n", pcType, (unsigned)FreeRTOS_ntohl( xRemoteAddress.sin_address.ulIP_IPv4 ) ) ); - } - #else - { - FreeRTOS_printf( ( "TPC-server: new %s client %xip\n", pcType, (unsigned)FreeRTOS_ntohl( xRemoteAddress.sin_addr ) ) ); - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - } - - /* Remove compiler warnings in case FreeRTOS_printf() is not used. */ - ( void ) pcType; -} -/*-----------------------------------------------------------*/ - -void FreeRTOS_TCPServerWork( TCPServer_t *pxServer, TickType_t xBlockingTime ) -{ -TCPClient_t **ppxClient; -BaseType_t xIndex; -BaseType_t xRc; - - /* Let the server do one working cycle */ - xRc = FreeRTOS_select( pxServer->xSocketSet, xBlockingTime ); - - if( xRc != 0 ) - { - for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ ) - { - struct freertos_sockaddr xAddress; - Socket_t xNexSocket; - socklen_t xSocketLength; - - if( pxServer->xServers[ xIndex ].xSocket == FREERTOS_NO_SOCKET ) - { - continue; - } - - xSocketLength = sizeof( xAddress ); - xNexSocket = FreeRTOS_accept( pxServer->xServers[ xIndex ].xSocket, &xAddress, &xSocketLength); - - if( ( xNexSocket != FREERTOS_NO_SOCKET ) && ( xNexSocket != FREERTOS_INVALID_SOCKET ) ) - { - prvReceiveNewClient( pxServer, xIndex, xNexSocket ); - } - } - } - - ppxClient = &pxServer->pxClients; - - while( ( * ppxClient ) != NULL ) - { - TCPClient_t *pxThis = *ppxClient; - - /* Almost C++ */ - xRc = pxThis->fWorkFunction( pxThis ); - - if (xRc < 0 ) - { - *ppxClient = pxThis->pxNextClient; - /* Close handles, resources */ - pxThis->fDeleteFunction( pxThis ); - /* Free the space */ - vPortFreeLarge( pxThis ); - } - else - { - ppxClient = &( pxThis->pxNextClient ); - } - } -} -/*-----------------------------------------------------------*/ - -static char *strnew( const char *pcString ) -{ -BaseType_t xLength; -char *pxBuffer; - - xLength = strlen( pcString ) + 1; - pxBuffer = ( char * ) pvPortMalloc( xLength ); - if( pxBuffer != NULL ) - { - memcpy( pxBuffer, pcString, xLength ); - } - - return pxBuffer; -} -/*-----------------------------------------------------------*/ - -static void prvRemoveSlash( char *pcDir ) -{ -BaseType_t xLength = strlen( pcDir ); - - while( ( xLength > 0 ) && ( pcDir[ xLength - 1 ] == '/' ) ) - { - pcDir[ --xLength ] = '\0'; - } -} -/*-----------------------------------------------------------*/ - -#if( ipconfigSUPPORT_SIGNALS != 0 ) - - /* FreeRTOS_TCPServerWork() calls select(). - The two functions below provide a possibility to interrupt - the call to select(). After the interruption, resume - by calling FreeRTOS_TCPServerWork() again. */ - BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t *pxServer ) - { - BaseType_t xIndex; - BaseType_t xResult = pdFALSE; - for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ ) - { - if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET ) - { - FreeRTOS_SignalSocket( pxServer->xServers[ xIndex ].xSocket ); - xResult = pdTRUE; - break; - } - } - - return xResult; - } - -#endif /* ipconfigSUPPORT_SIGNALS */ -/*-----------------------------------------------------------*/ - -#if( ipconfigSUPPORT_SIGNALS != 0 ) - - /* Same as above: this function may be called from an ISR, - for instance a GPIO interrupt. */ - BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t *pxServer, BaseType_t *pxHigherPriorityTaskWoken ) - { - BaseType_t xIndex; - BaseType_t xResult = pdFALSE; - for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ ) - { - if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET ) - { - FreeRTOS_SignalSocketFromISR( pxServer->xServers[ xIndex ].xSocket, pxHigherPriorityTaskWoken ); - xResult = pdTRUE; - break; - } - } - - return xResult; - } -#endif /* ipconfigSUPPORT_SIGNALS */ -/*-----------------------------------------------------------*/ - -#endif /* ( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) ) */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" +#include "FreeRTOS_TCP_server.h" +#include "FreeRTOS_server_private.h" + +/* Remove the entire file if TCP is not being used. */ +#if ( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) ) + + #if !defined( ARRAY_SIZE ) + #define ARRAY_SIZE( x ) ( BaseType_t ) ( sizeof( x ) / sizeof( x )[ 0 ] ) + #endif + + + static void prvReceiveNewClient( TCPServer_t * pxServer, + BaseType_t xIndex, + Socket_t xNexSocket ); + static char * strnew( const char * pcString ); +/* Remove slashes at the end of a path. */ + static void prvRemoveSlash( char * pcDir ); + + TCPServer_t * FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG * pxConfigs, + BaseType_t xCount ) + { + TCPServer_t * pxServer; + SocketSet_t xSocketSet; + + /* Create a new server. + * xPort / xPortAlt : Make the service available on 1 or 2 public port numbers. */ + xSocketSet = FreeRTOS_CreateSocketSet(); + + if( xSocketSet != NULL ) + { + BaseType_t xSize; + + xSize = sizeof( *pxServer ) - sizeof( pxServer->xServers ) + xCount * sizeof( pxServer->xServers[ 0 ] ); + + pxServer = ( TCPServer_t * ) pvPortMallocLarge( xSize ); + + if( pxServer != NULL ) + { + struct freertos_sockaddr xAddress; + BaseType_t xNoTimeout = 0; + BaseType_t xIndex; + + memset( pxServer, '\0', xSize ); + pxServer->xServerCount = xCount; + pxServer->xSocketSet = xSocketSet; + + for( xIndex = 0; xIndex < xCount; xIndex++ ) + { + BaseType_t xPortNumber = pxConfigs[ xIndex ].xPortNumber; + + if( xPortNumber > 0 ) + { + Socket_t xSocket; + + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); + FreeRTOS_printf( ( "TCP socket on port %d\n", ( int ) xPortNumber ) ); + + if( xSocket != FREERTOS_INVALID_SOCKET ) + { + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xAddress.sin_address.ulIP_IPv4 = FreeRTOS_GetIPAddress(); /* Single NIC, currently not used */ + } + #else + { + xAddress.sin_addr = FreeRTOS_GetIPAddress(); /* Single NIC, currently not used */ + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xAddress.sin_port = FreeRTOS_htons( xPortNumber ); + xAddress.sin_family = FREERTOS_AF_INET; + + FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) ); + FreeRTOS_listen( xSocket, pxConfigs[ xIndex ].xBackLog ); + + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) ); + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) ); + + #if ( ipconfigHTTP_RX_BUFSIZE > 0 ) + { + if( pxConfigs[ xIndex ].eType == eSERVER_HTTP ) + { + WinProperties_t xWinProps; + + memset( &xWinProps, '\0', sizeof( xWinProps ) ); + + /* The parent socket itself won't get connected. The properties below + * will be inherited by each new child socket. */ + xWinProps.lTxBufSize = ipconfigHTTP_TX_BUFSIZE; + xWinProps.lTxWinSize = ipconfigHTTP_TX_WINSIZE; + xWinProps.lRxBufSize = ipconfigHTTP_RX_BUFSIZE; + xWinProps.lRxWinSize = ipconfigHTTP_RX_WINSIZE; + + /* Set the window and buffer sizes. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); + } + } + #endif /* if ( ipconfigHTTP_RX_BUFSIZE > 0 ) */ + + FreeRTOS_FD_SET( xSocket, xSocketSet, eSELECT_READ | eSELECT_EXCEPT ); + pxServer->xServers[ xIndex ].xSocket = xSocket; + pxServer->xServers[ xIndex ].eType = pxConfigs[ xIndex ].eType; + pxServer->xServers[ xIndex ].pcRootDir = strnew( pxConfigs[ xIndex ].pcRootDir ); + prvRemoveSlash( ( char * ) pxServer->xServers[ xIndex ].pcRootDir ); + } + } + } + } + else + { + /* Could not allocate the server, delete the socket set */ + FreeRTOS_DeleteSocketSet( xSocketSet ); + } + } + else + { + /* Could not create a socket set, return NULL */ + pxServer = NULL; + } + + return pxServer; + } +/*-----------------------------------------------------------*/ + + static void prvReceiveNewClient( TCPServer_t * pxServer, + BaseType_t xIndex, + Socket_t xNexSocket ) + { + TCPClient_t * pxClient = NULL; + BaseType_t xSize = 0; + FTCPWorkFunction fWorkFunc = NULL; + FTCPDeleteFunction fDeleteFunc = NULL; + const char * pcType = "Unknown"; + + /*_RB_ Can the work and delete functions be part of the xSERVER_CONFIG structure + * becomes generic, with no pre-processing required? */ + #if ( ipconfigUSE_HTTP != 0 ) + { + if( pxServer->xServers[ xIndex ].eType == eSERVER_HTTP ) + { + xSize = sizeof( HTTPClient_t ); + fWorkFunc = xHTTPClientWork; + fDeleteFunc = vHTTPClientDelete; + pcType = "HTTP"; + } + } + #endif /* ipconfigUSE_HTTP != 0 */ + + #if ( ipconfigUSE_FTP != 0 ) + { + if( pxServer->xServers[ xIndex ].eType == eSERVER_FTP ) + { + xSize = sizeof( FTPClient_t ); + fWorkFunc = xFTPClientWork; + fDeleteFunc = vFTPClientDelete; + pcType = "FTP"; + } + } + #endif /* ipconfigUSE_FTP != 0 */ + + /* Malloc enough space for a new HTTP-client */ + if( xSize ) + { + pxClient = ( TCPClient_t * ) pvPortMallocLarge( xSize ); + } + + if( pxClient != NULL ) + { + memset( pxClient, '\0', xSize ); + + /* Put the new client in front of the list. */ + pxClient->eType = pxServer->xServers[ xIndex ].eType; + pxClient->pcRootDir = pxServer->xServers[ xIndex ].pcRootDir; + pxClient->pxParent = pxServer; + pxClient->xSocket = xNexSocket; + pxClient->pxNextClient = pxServer->pxClients; + pxClient->fWorkFunction = fWorkFunc; + pxClient->fDeleteFunction = fDeleteFunc; + pxServer->pxClients = pxClient; + + FreeRTOS_FD_SET( xNexSocket, pxServer->xSocketSet, eSELECT_READ | eSELECT_EXCEPT ); + } + else + { + pcType = "closed"; + FreeRTOS_closesocket( xNexSocket ); + } + + { + struct freertos_sockaddr xRemoteAddress; + FreeRTOS_GetRemoteAddress( pxClient->xSocket, &xRemoteAddress ); + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + FreeRTOS_printf( ( "TPC-server: new %s client %xip\n", pcType, ( unsigned ) FreeRTOS_ntohl( xRemoteAddress.sin_address.ulIP_IPv4 ) ) ); + } + #else + { + FreeRTOS_printf( ( "TPC-server: new %s client %xip\n", pcType, ( unsigned ) FreeRTOS_ntohl( xRemoteAddress.sin_addr ) ) ); + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + } + + /* Remove compiler warnings in case FreeRTOS_printf() is not used. */ + ( void ) pcType; + } +/*-----------------------------------------------------------*/ + + void FreeRTOS_TCPServerWork( TCPServer_t * pxServer, + TickType_t xBlockingTime ) + { + TCPClient_t ** ppxClient; + BaseType_t xIndex; + BaseType_t xRc; + + /* Let the server do one working cycle */ + xRc = FreeRTOS_select( pxServer->xSocketSet, xBlockingTime ); + + if( xRc != 0 ) + { + for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ ) + { + struct freertos_sockaddr xAddress; + Socket_t xNexSocket; + socklen_t xSocketLength; + + if( pxServer->xServers[ xIndex ].xSocket == FREERTOS_NO_SOCKET ) + { + continue; + } + + xSocketLength = sizeof( xAddress ); + xNexSocket = FreeRTOS_accept( pxServer->xServers[ xIndex ].xSocket, &xAddress, &xSocketLength ); + + if( ( xNexSocket != FREERTOS_NO_SOCKET ) && ( xNexSocket != FREERTOS_INVALID_SOCKET ) ) + { + prvReceiveNewClient( pxServer, xIndex, xNexSocket ); + } + } + } + + ppxClient = &pxServer->pxClients; + + while( ( *ppxClient ) != NULL ) + { + TCPClient_t * pxThis = *ppxClient; + + /* Almost C++ */ + xRc = pxThis->fWorkFunction( pxThis ); + + if( xRc < 0 ) + { + *ppxClient = pxThis->pxNextClient; + /* Close handles, resources */ + pxThis->fDeleteFunction( pxThis ); + /* Free the space */ + vPortFreeLarge( pxThis ); + } + else + { + ppxClient = &( pxThis->pxNextClient ); + } + } + } +/*-----------------------------------------------------------*/ + + static char * strnew( const char * pcString ) + { + BaseType_t xLength; + char * pxBuffer; + + xLength = strlen( pcString ) + 1; + pxBuffer = ( char * ) pvPortMalloc( xLength ); + + if( pxBuffer != NULL ) + { + memcpy( pxBuffer, pcString, xLength ); + } + + return pxBuffer; + } +/*-----------------------------------------------------------*/ + + static void prvRemoveSlash( char * pcDir ) + { + BaseType_t xLength = strlen( pcDir ); + + while( ( xLength > 0 ) && ( pcDir[ xLength - 1 ] == '/' ) ) + { + pcDir[ --xLength ] = '\0'; + } + } +/*-----------------------------------------------------------*/ + + #if ( ipconfigSUPPORT_SIGNALS != 0 ) + +/* FreeRTOS_TCPServerWork() calls select(). + * The two functions below provide a possibility to interrupt + * the call to select(). After the interruption, resume + * by calling FreeRTOS_TCPServerWork() again. */ + BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t * pxServer ) + { + BaseType_t xIndex; + BaseType_t xResult = pdFALSE; + + for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ ) + { + if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET ) + { + FreeRTOS_SignalSocket( pxServer->xServers[ xIndex ].xSocket ); + xResult = pdTRUE; + break; + } + } + + return xResult; + } + + #endif /* ipconfigSUPPORT_SIGNALS */ +/*-----------------------------------------------------------*/ + + #if ( ipconfigSUPPORT_SIGNALS != 0 ) + +/* Same as above: this function may be called from an ISR, + * for instance a GPIO interrupt. */ + BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t * pxServer, + BaseType_t * pxHigherPriorityTaskWoken ) + { + BaseType_t xIndex; + BaseType_t xResult = pdFALSE; + + for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ ) + { + if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET ) + { + FreeRTOS_SignalSocketFromISR( pxServer->xServers[ xIndex ].xSocket, pxHigherPriorityTaskWoken ); + xResult = pdTRUE; + break; + } + } + + return xResult; + } + #endif /* ipconfigSUPPORT_SIGNALS */ +/*-----------------------------------------------------------*/ + +#endif /* ( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) ) */ diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_commands.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_commands.c index 0392fe87d..78a2f5af9 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_commands.c +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_commands.c @@ -1,74 +1,75 @@ -/* - * FreeRTOS+TCP V2.0.3 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://aws.amazon.com/freertos - * https://www.FreeRTOS.org - */ - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_FTP_commands.h" - -const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ] = -{ -/* cmdLen cmdName[7] cmdType checkLogin checkNullArg */ - { 4, "USER", ECMD_USER, pdFALSE, pdFALSE }, - { 4, "PASS", ECMD_PASS, pdFALSE, pdFALSE }, - { 4, "ACCT", ECMD_ACCT, pdTRUE, pdFALSE }, - { 3, "CWD", ECMD_CWD, pdTRUE, pdTRUE }, - { 4, "CDUP", ECMD_CDUP, pdTRUE, pdFALSE }, - { 4, "SMNT", ECMD_SMNT, pdTRUE, pdFALSE }, - { 4, "QUIT", ECMD_QUIT, pdTRUE, pdFALSE }, - { 4, "REIN", ECMD_REIN, pdTRUE, pdFALSE }, - { 4, "PORT", ECMD_PORT, pdTRUE, pdFALSE }, - { 4, "PASV", ECMD_PASV, pdTRUE, pdFALSE }, - { 4, "TYPE", ECMD_TYPE, pdTRUE, pdFALSE }, - { 4, "STRU", ECMD_STRU, pdTRUE, pdFALSE }, - { 4, "MODE", ECMD_MODE, pdTRUE, pdFALSE }, - { 4, "RETR", ECMD_RETR, pdTRUE, pdTRUE }, - { 4, "STOR", ECMD_STOR, pdTRUE, pdTRUE }, - { 4, "STOU", ECMD_STOU, pdTRUE, pdFALSE }, - { 4, "APPE", ECMD_APPE, pdTRUE, pdFALSE }, - { 4, "ALLO", ECMD_ALLO, pdTRUE, pdFALSE }, - { 4, "REST", ECMD_REST, pdTRUE, pdFALSE }, - { 4, "RNFR", ECMD_RNFR, pdTRUE, pdTRUE }, - { 4, "RNTO", ECMD_RNTO, pdTRUE, pdTRUE }, - { 4, "ABOR", ECMD_ABOR, pdTRUE, pdFALSE }, - { 4, "SIZE", ECMD_SIZE, pdTRUE, pdTRUE }, - { 4, "MDTM", ECMD_MDTM, pdTRUE, pdTRUE }, - { 4, "DELE", ECMD_DELE, pdTRUE, pdTRUE }, - { 3, "RMD", ECMD_RMD, pdTRUE, pdTRUE }, - { 3, "MKD", ECMD_MKD, pdTRUE, pdTRUE }, - { 3, "PWD", ECMD_PWD, pdTRUE, pdFALSE }, - { 4, "LIST", ECMD_LIST, pdTRUE, pdFALSE }, - { 4, "NLST", ECMD_NLST, pdTRUE, pdFALSE }, - { 4, "SITE", ECMD_SITE, pdTRUE, pdFALSE }, - { 4, "SYST", ECMD_SYST, pdFALSE, pdFALSE }, - { 4, "FEAT", ECMD_FEAT, pdFALSE, pdFALSE }, - { 4, "STAT", ECMD_STAT, pdTRUE, pdFALSE }, - { 4, "HELP", ECMD_HELP, pdFALSE, pdFALSE }, - { 4, "NOOP", ECMD_NOOP, pdFALSE, pdFALSE }, - { 4, "EMPT", ECMD_EMPTY, pdFALSE, pdFALSE }, - { 4, "CLOS", ECMD_CLOSE, pdTRUE, pdFALSE }, - { 4, "UNKN", ECMD_UNKNOWN, pdFALSE, pdFALSE }, -}; +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_FTP_commands.h" + +const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ] = +{ +/* cmdLen cmdName[7] cmdType checkLogin checkNullArg */ + { 4, "USER", ECMD_USER, pdFALSE, pdFALSE }, + { 4, "PASS", ECMD_PASS, pdFALSE, pdFALSE }, + { 4, "ACCT", ECMD_ACCT, pdTRUE, pdFALSE }, + { 3, "CWD", ECMD_CWD, pdTRUE, pdTRUE }, + { 4, "CDUP", ECMD_CDUP, pdTRUE, pdFALSE }, + { 4, "SMNT", ECMD_SMNT, pdTRUE, pdFALSE }, + { 4, "QUIT", ECMD_QUIT, pdTRUE, pdFALSE }, + { 4, "REIN", ECMD_REIN, pdTRUE, pdFALSE }, + { 4, "PORT", ECMD_PORT, pdTRUE, pdFALSE }, + { 4, "PASV", ECMD_PASV, pdTRUE, pdFALSE }, + { 4, "TYPE", ECMD_TYPE, pdTRUE, pdFALSE }, + { 4, "STRU", ECMD_STRU, pdTRUE, pdFALSE }, + { 4, "MODE", ECMD_MODE, pdTRUE, pdFALSE }, + { 4, "RETR", ECMD_RETR, pdTRUE, pdTRUE }, + { 4, "STOR", ECMD_STOR, pdTRUE, pdTRUE }, + { 4, "STOU", ECMD_STOU, pdTRUE, pdFALSE }, + { 4, "APPE", ECMD_APPE, pdTRUE, pdFALSE }, + { 4, "ALLO", ECMD_ALLO, pdTRUE, pdFALSE }, + { 4, "REST", ECMD_REST, pdTRUE, pdFALSE }, + { 4, "RNFR", ECMD_RNFR, pdTRUE, pdTRUE }, + { 4, "RNTO", ECMD_RNTO, pdTRUE, pdTRUE }, + { 4, "ABOR", ECMD_ABOR, pdTRUE, pdFALSE }, + { 4, "SIZE", ECMD_SIZE, pdTRUE, pdTRUE }, + { 4, "MDTM", ECMD_MDTM, pdTRUE, pdTRUE }, + { 4, "DELE", ECMD_DELE, pdTRUE, pdTRUE }, + { 3, "RMD", ECMD_RMD, pdTRUE, pdTRUE }, + { 3, "MKD", ECMD_MKD, pdTRUE, pdTRUE }, + { 3, "PWD", ECMD_PWD, pdTRUE, pdFALSE }, + { 4, "LIST", ECMD_LIST, pdTRUE, pdFALSE }, + { 4, "NLST", ECMD_NLST, pdTRUE, pdFALSE }, + { 4, "SITE", ECMD_SITE, pdTRUE, pdFALSE }, + { 4, "SYST", ECMD_SYST, pdFALSE, pdFALSE }, + { 4, "FEAT", ECMD_FEAT, pdFALSE, pdFALSE }, + { 4, "STAT", ECMD_STAT, pdTRUE, pdFALSE }, + { 4, "HELP", ECMD_HELP, pdFALSE, pdFALSE }, + { 4, "NOOP", ECMD_NOOP, pdFALSE, pdFALSE }, + { 4, "EMPT", ECMD_EMPTY, pdFALSE, pdFALSE }, + { 4, "CLOS", ECMD_CLOSE, pdTRUE, pdFALSE }, + { 4, "UNKN", ECMD_UNKNOWN, pdFALSE, pdFALSE }, +}; diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_server.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_server.c index f0f251beb..da66d5b01 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_server.c +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_server.c @@ -1,2684 +1,2905 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - *! - *! The protocols implemented in this file are intended to be demo quality only, - *! and not for production devices. - *! - */ - -/* Standard includes. */ -#include -#include -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "portmacro.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_TCP_IP.h" -#include "FreeRTOS_Sockets.h" -#include "FreeRTOS_Stream_Buffer.h" - -/* FreeRTOS Protocol includes. */ -#include "FreeRTOS_FTP_commands.h" -#include "FreeRTOS_TCP_server.h" -#include "FreeRTOS_server_private.h" - -/* Remove the whole file if FTP is not supported. */ -#if( ipconfigUSE_FTP == 1 ) - -#ifndef HTTP_SERVER_BACKLOG - #define HTTP_SERVER_BACKLOG ( 12 ) -#endif - -#if !defined( ARRAY_SIZE ) - #define ARRAY_SIZE( x ) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] ) -#endif - -#if defined(__WIN32__) && !defined(ipconfigFTP_FS_USES_BACKSLAH) - #define ipconfigFTP_FS_USES_BACKSLAH 1 -#endif - -/* Some defines to make the code more readbale */ -#define pcCOMMAND_BUFFER pxClient->pxParent->pcCommandBuffer -#define pcNEW_DIR pxClient->pxParent->pcNewDir -#define pcFILE_BUFFER pxClient->pxParent->pcFileBuffer - -/* This FTP server will only do binary transfers */ -#define TMODE_BINARY 1 -#define TMODE_ASCII 2 -#define TMODE_7BITS 3 -#define TMODE_8BITS 4 - -/* Ascii character definitions. */ -#define ftpASCII_CR 13 -#define ftpASCII_LF 10 - -#if defined( FTP_WRITES_ALIGNED ) || defined( ipconfigFTP_WRITES_ALIGNED ) - #error Name change : please rename the define to the new name 'ipconfigFTP_ZERO_COPY_ALIGNED_WRITES' -#endif - -/* - * ipconfigFTP_ZERO_COPY_ALIGNED_WRITES : experimental optimisation option. - * If non-zero, receiving data will be done with the zero-copy method and also - * writes to disk will be done with sector-alignment as much as possible. - */ -#ifndef ipconfigFTP_ZERO_COPY_ALIGNED_WRITES - #define ipconfigFTP_ZERO_COPY_ALIGNED_WRITES 0 -#endif - -/* - * This module only has 2 public functions: - */ -BaseType_t xFTPClientWork( TCPClient_t *pxClient ); -void vFTPClientDelete( TCPClient_t *pxClient ); - -/* - * Process a single command. - */ -static BaseType_t prvProcessCommand( FTPClient_t *pxClient, BaseType_t xIndex, char *pcRestCommand ); - -/* - * Create a socket for a data connection to the FTP client. - */ -static BaseType_t prvTransferConnect( FTPClient_t *pxClient, BaseType_t xDoListen ); - -/* - * Either call listen() or connect() to start the transfer connection. - */ -static BaseType_t prvTransferStart( FTPClient_t *pxClient ); - -/* - * See if the socket has got connected or disconnected. Close the socket if - * necessary. - */ -static void prvTransferCheck( FTPClient_t *pxClient ); - -/* - * Close the data socket and issue some informative logging. - */ -static void prvTransferCloseSocket( FTPClient_t *pxClient ); - -/* - * Close the file handle (pxReadHandle or pxWriteHandle). - */ -static void prvTransferCloseFile( FTPClient_t *pxClient ); - -/* - * Close a directory (-handle). - */ -static void prvTransferCloseDir( FTPClient_t *pxClient ); - -/* - * Translate a string (indicating a transfer type) to a number. - */ -static BaseType_t prvGetTransferType( const char *pcType ); - -#if( ipconfigHAS_PRINTF != 0 ) - /* - * For nice logging: write an amount (number of bytes), e.g. 3512200 as - * "3.45 MB" - */ - static const char *pcMkSize( uint32_t ulAmount, char *pcBuffer, BaseType_t xBufferSize ); -#endif - -#if( ipconfigHAS_PRINTF != 0 ) - /* - * Calculate the average as bytes-per-second, when amount and milliseconds - * are known. - */ - static uint32_t ulGetAverage( uint32_t ulAmount, TickType_t xDeltaMs ); -#endif - -/* - * A port command looks like: PORT h1,h2,h3,h4,p1,p2. Parse it and translate it - * to an IP-address and a port number. - */ -static UBaseType_t prvParsePortData( const char *pcCommand, uint32_t *pulIPAddress ); - -/* - * CWD: Change current working directory. - */ - -static BaseType_t prvChangeDir( FTPClient_t *pxClient, char *pcDirectory ); - -/* - * RNFR: Rename from ... - */ -static BaseType_t prvRenameFrom( FTPClient_t *pxClient, const char *pcFileName ); - -/* - * RNTO: Rename to ... - */ -static BaseType_t prvRenameTo( FTPClient_t *pxClient, const char *pcFileName ); - -/* - * SITE: Change file permissions. - */ -static BaseType_t prvSiteCmd( FTPClient_t *pxClient, char *pcRestCommand ); - -/* - * DELE: Delete a file. - */ -static BaseType_t prvDeleteFile( FTPClient_t *pxClient, char *pcFileName ); - -/* - * SIZE: get the size of a file (xSendDate = 0). - * MDTM: get data and time properties (xSendDate = 1). - */ -static BaseType_t prvSizeDateFile( FTPClient_t *pxClient, char *pcFileName, BaseType_t xSendDate ); - -/* - * MKD: Make / create a directory (xDoRemove = 0). - * RMD: Remove a directory (xDoRemove = 1). - */ -static BaseType_t prvMakeRemoveDir( FTPClient_t *pxClient, const char *pcDirectory, BaseType_t xDoRemove ); - -/* - * The next three commands: LIST, RETR and STOR all require a data socket. - * The data connection is either started with a 'PORT' or a 'PASV' command. - * Each of the commands has a prepare- (Prep) and a working- (Work) function. - * The Work function should be called as long as the data socket is open, and - * there is data to be transmitted. - */ - -/* - * LIST: Send a directory listing in Unix style. - */ -static BaseType_t prvListSendPrep( FTPClient_t *pxClient ); -static BaseType_t prvListSendWork( FTPClient_t *pxClient ); - -/* - * RETR: Send a file to the FTP client. - */ -static BaseType_t prvRetrieveFilePrep( FTPClient_t *pxClient, char *pcFileName ); -static BaseType_t prvRetrieveFileWork( FTPClient_t *pxClient ); - -/* - * STOR: Receive a file from the FTP client and store it. - */ -static BaseType_t prvStoreFilePrep( FTPClient_t *pxClient, char *pcFileName ); -static BaseType_t prvStoreFileWork( FTPClient_t *pxClient ); - -/* - * Print/format a single directory entry in Unix style. - */ -static BaseType_t prvGetFileInfoStat( FF_DirEnt_t *pxEntry, char *pcLine, BaseType_t xMaxLength ); - -/* - * Send a reply to a socket, either the command- or the data-socket. - */ -static BaseType_t prvSendReply( Socket_t xSocket, const char *pcBuffer, BaseType_t xLength ); - -/* - * Prepend the root directory (if any), plus the current working directory - * (always), to get an absolute path. - */ -BaseType_t xMakeAbsolute( FTPClient_t *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcPath ); - -/* - -####### ##### ###### # # ## - # ## # # # # # # # # - # # # # # # # - # # # # # # # #### ### ## # # - ##### # ##### # # # # # # # # # # - # # # # # # # # # ## # #### - # # # ## ## # # # # # - # # # ## ## # # # # # -#### #### #### ## ## #### #### ## ## - - * xFTPClientWork() - * will be called by FreeRTOS_TCPServerWork(), after select has expired(). - * FD_ISSET will not be used. This work function will always be called at - * regular intervals, and also after a select() event has occurred. - */ -BaseType_t xFTPClientWork( TCPClient_t *pxTCPClient ) -{ -FTPClient_t *pxClient = ( FTPClient_t * ) pxTCPClient; -BaseType_t xRc; - - if( pxClient->bits.bHelloSent == pdFALSE_UNSIGNED ) - { - BaseType_t xLength; - - pxClient->bits.bHelloSent = pdTRUE_UNSIGNED; - - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "220 Welcome to the FreeRTOS+TCP FTP server\r\n" ); - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - } - - /* Call recv() in a non-blocking way, to see if there is an FTP command - sent to this server. */ - xRc = FreeRTOS_recv( pxClient->xSocket, ( void * )pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), 0 ); - - if( xRc > 0 ) - { - BaseType_t xIndex; - const FTPCommand_t *pxCommand; - char *pcRestCommand; - - if( xRc < ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) ) - { - pcCOMMAND_BUFFER[ xRc ] = '\0'; - } - - while( xRc && ( ( pcCOMMAND_BUFFER[ xRc - 1 ] == ftpASCII_CR ) || ( pcCOMMAND_BUFFER[ xRc - 1 ] == ftpASCII_LF ) ) ) - { - pcCOMMAND_BUFFER[ --xRc ] = '\0'; - } - - /* Now iterate through a list of FTP commands, and look for a match. */ - pxCommand = xFTPCommands; - pcRestCommand = pcCOMMAND_BUFFER; - for( xIndex = 0; xIndex < FTP_CMD_COUNT - 1; xIndex++, pxCommand++ ) - { - BaseType_t xLength; - - /* The length of each command is stored as well, just to be a bit - quicker here. */ - xLength = pxCommand->xCommandLength; - - if( ( xRc >= xLength ) && ( memcmp( ( const void * ) pxCommand->pcCommandName, ( const void * ) pcCOMMAND_BUFFER, xLength ) == 0 ) ) - { - /* A match with an existing command is found. Skip any - whitespace to get the first parameter. */ - pcRestCommand += xLength; - while( ( *pcRestCommand == ' ' ) || ( *pcRestCommand == '\t' ) ) - { - pcRestCommand++; - } - break; - } - } - - /* If the command received was not recognised, xIndex will point to a - fake entry called 'ECMD_UNKNOWN'. */ - prvProcessCommand( pxClient, xIndex, pcRestCommand ); - } - else if( xRc < 0 ) - { - /* The connection will be closed and the client will be deleted. */ - FreeRTOS_printf( ( "xFTPClientWork: xRc = %ld\n", xRc ) ); - } - - /* Does it have an open data connection? */ - if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) - { - /* See if the connection has changed. */ - prvTransferCheck( pxClient ); - - /* "pcConnectionAck" contains a string like: - "Response: 150 Accepted data connection from 192.168.2.3:6789" - The socket can only be used once this acknowledgement has been sent. */ - if( ( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) && ( pxClient->pcConnectionAck[ 0 ] == '\0' ) ) - { - BaseType_t xClientRc = 0; - - if( pxClient->bits1.bDirHasEntry ) - { - /* Still listing a directory. */ - xClientRc = prvListSendWork( pxClient ); - } - else if( pxClient->pxReadHandle != NULL ) - { - /* Sending a file. */ - xClientRc = prvRetrieveFileWork( pxClient ); - } - else if( pxClient->pxWriteHandle != NULL ) - { - /* Receiving a file. */ - xClientRc = prvStoreFileWork( pxClient ); - } - - if( xClientRc < 0 ) - { - prvTransferCloseSocket( pxClient ); - prvTransferCloseFile( pxClient ); - } - } - } - - return xRc; -} -/*-----------------------------------------------------------*/ - -static void prvTransferCloseDir( FTPClient_t *pxClient ) -{ - /* Nothing to close for +FAT. */ - ( void ) pxClient; -} -/*-----------------------------------------------------------*/ - -void vFTPClientDelete( TCPClient_t *pxTCPClient ) -{ -FTPClient_t *pxClient = ( FTPClient_t * ) pxTCPClient; - - /* Close any directory-listing-handles (not used by +FAT ). */ - prvTransferCloseDir( pxClient ); - /* Close the data-socket. */ - prvTransferCloseSocket( pxClient ); - /* Close any open file handle. */ - prvTransferCloseFile( pxClient ); - - /* Close the FTP command socket */ - if( pxClient->xSocket != FREERTOS_NO_SOCKET ) - { - FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_ALL ); - FreeRTOS_closesocket( pxClient->xSocket ); - pxClient->xSocket = FREERTOS_NO_SOCKET; - } -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvProcessCommand( FTPClient_t *pxClient, BaseType_t xIndex, char *pcRestCommand ) -{ -const FTPCommand_t *pxFTPCommand = &( xFTPCommands[ xIndex ] ); -const char *pcMyReply = NULL; -BaseType_t xResult = 0; - - if( ( pxFTPCommand->ucCommandType != ECMD_PASS ) && ( pxFTPCommand->ucCommandType != ECMD_PORT ) ) - { - FreeRTOS_printf( ( " %s %s\n", pxFTPCommand->pcCommandName, pcRestCommand ) ); - } - - if( ( pxFTPCommand->checkLogin != pdFALSE ) && ( pxClient->bits.bLoggedIn == pdFALSE_UNSIGNED ) ) - { - pcMyReply = REPL_530; /* Please first log in. */ - } - else if( ( pxFTPCommand->checkNullArg != pdFALSE ) && ( ( pcRestCommand == NULL ) || ( pcRestCommand[ 0 ] == '\0' ) ) ) - { - pcMyReply = REPL_501; /* Command needs a parameter. */ - } - - if( pcMyReply == NULL ) - { - switch( pxFTPCommand->ucCommandType ) - { - case ECMD_USER: /* User. */ - /* User name has been entered, expect password. */ - pxClient->bits.bStatusUser = pdTRUE_UNSIGNED; - - #if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 )/*_RB_ Needs defaulting and adding to the web documentation. */ - { - /* Save the user name in 'pcFileName'. */ - snprintf( pxClient->pcFileName, sizeof( pxClient->pcFileName ), "%s", pcRestCommand ); - - /* The USER name is presented to the application. The function - may return a const string like "331 Please enter your - password\r\n". */ - pcMyReply = pcApplicationFTPUserHook( pxClient->pcFileName ); - if( pcMyReply == NULL ) - { - pcMyReply = REPL_331_ANON; - } - } - #else - { - /* No password checks, any password will be accepted. */ - pcMyReply = REPL_331_ANON; - } - #endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 */ - - #if( ipconfigFTP_HAS_USER_PROPERTIES_HOOK != 0 )/*_RB_ Needs defaulting and adding to the web documentation. */ - { - FTPUserProperties_t xProperties; - - xProperties.pcRootDir = pxClient->pcRootDir; - xProperties.xReadOnly = pdFALSE; - xProperties.usPortNumber = pxClient->usClientPort; - vApplicationFTPUserPropertiesHook( pxClient->pcFileName, &( xProperties ) ); - - if( xProperties.pcRootDir != NULL ) - { - pxClient->pcRootDir = xProperties.pcRootDir; - } - pxClient->bits.bReadOnly = ( xProperties.xReadOnly != pdFALSE_UNSIGNED ); - } - #endif /* ipconfigFTP_HAS_USER_PROPERTIES_HOOK */ - break; - - case ECMD_PASS: /* Password. */ - pxClient->ulRestartOffset = 0; - if( pxClient->bits.bStatusUser == pdFALSE_UNSIGNED ) - { - pcMyReply = REPL_503; /* "503 Bad sequence of commands.\r\n". */ - } - else - { - BaseType_t xAllow; - - pxClient->bits.bStatusUser = pdFALSE_UNSIGNED; - #if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 ) - { - xAllow = xApplicationFTPPasswordHook( pxClient->pcFileName, pcRestCommand ); - } - #else - { - xAllow = 1; - } - #endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */ - - if( xAllow > 0 ) - { - pxClient->bits.bLoggedIn = pdTRUE_UNSIGNED; /* Client has now logged in. */ - pcMyReply = "230 OK. Current directory is /\r\n"; - } - else - { - pcMyReply = "530 Login incorrect\r\n"; /* 530 Login incorrect. */ - } - - strcpy( pxClient->pcCurrentDir, ( const char * ) "/" ); - } - break; - - case ECMD_SYST: /* System. */ - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "215 UNIX Type: L8\r\n" ); - pcMyReply = pcCOMMAND_BUFFER; - break; - - case ECMD_PWD: /* Get working directory. */ - xMakeRelative( pxClient, pcFILE_BUFFER, sizeof( pcFILE_BUFFER ), pxClient->pcCurrentDir ); - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), REPL_257_PWD, pcFILE_BUFFER ); - pcMyReply = pcCOMMAND_BUFFER; - break; - - case ECMD_REST: - if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) - { - pcMyReply = REPL_553_READ_ONLY; - } - else - { - const char *pcPtr = pcRestCommand; - - while( *pcPtr == ' ' ) - { - pcPtr++; - } - - if( ( *pcPtr >= '0' ) && ( *pcPtr <= '9' ) ) - { - sscanf( pcPtr, "%lu", &pxClient->ulRestartOffset ); - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "350 Restarting at %lu. Send STORE or RETRIEVE\r\n", pxClient->ulRestartOffset ); - pcMyReply = pcCOMMAND_BUFFER; - } - else - { - pcMyReply = REPL_500; /* 500 Syntax error, command unrecognised. */ - } - } - break; - - case ECMD_NOOP: /* NOP operation */ - if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) - { - pcMyReply = REPL_200_PROGRESS; - } - else - { - pcMyReply = REPL_200; - } - break; - - case ECMD_TYPE: /* Ask or set transfer type. */ - { - /* e.g. "TYPE I" for Images (binary). */ - BaseType_t xType = prvGetTransferType( pcRestCommand ); - - if( xType < 0 ) - { - /* TYPE not recognised. */ - pcMyReply = REPL_500; - } - else - { - pxClient->xTransType = xType; - pcMyReply = REPL_200; - } - } - break; - - case ECMD_PASV: /* Enter passive mode. */ - /* Connect passive: Server will listen() and wait for a connection. - Start up a new data connection with 'xDoListen' set to true. */ - if( prvTransferConnect( pxClient, pdTRUE ) != pdTRUE ) - { - pcMyReply = REPL_502; - } - else - { - uint32_t ulIP; - uint16_t ulPort; - struct freertos_sockaddr xLocalAddress; - struct freertos_sockaddr xRemoteAddress; - - FreeRTOS_GetLocalAddress( pxClient->xTransferSocket, &xLocalAddress ); - FreeRTOS_GetRemoteAddress( pxClient->xSocket, &xRemoteAddress ); - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - ulIP = FreeRTOS_ntohl( xLocalAddress.sin_address.ulIP_IPv4 ); - pxClient->ulClientIP = FreeRTOS_ntohl( xRemoteAddress.sin_address.ulIP_IPv4 ); - } - #else - { - ulIP = FreeRTOS_ntohl( xLocalAddress.sin_addr ); - pxClient->ulClientIP = FreeRTOS_ntohl( xRemoteAddress.sin_addr ); - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - ulPort = FreeRTOS_ntohs( xLocalAddress.sin_port ); - - pxClient->usClientPort = FreeRTOS_ntohs( xRemoteAddress.sin_port ); - - /* REPL_227_D "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d). */ - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), REPL_227_D, - ( unsigned )ulIP >> 24, - ( unsigned )( ulIP >> 16 ) & 0xFF, - ( unsigned )( ulIP >> 8 ) & 0xFF, - ( unsigned )ulIP & 0xFF, - ( unsigned )ulPort >> 8, - ( unsigned )ulPort & 0xFF ); - - pcMyReply = pcCOMMAND_BUFFER; - } - break; - - case ECMD_PORT: /* Active connection to the client. */ - /* The client uses this command to tell the server to what - client-side port the server should contact; use of this command - indicates an active data transfer. e.g. PORT 192,168,1,2,4,19. */ - { - uint32_t ulIPAddress = 0; - UBaseType_t uxPort; - - uxPort = prvParsePortData( pcRestCommand, &ulIPAddress ); - FreeRTOS_printf( (" PORT %lxip:%ld\n", ulIPAddress, uxPort ) ); - - if( uxPort == 0u ) - { - pcMyReply = REPL_501; - } - else if( prvTransferConnect( pxClient, pdFALSE ) != pdTRUE ) - { - /* Call prvTransferConnect() with 'xDoListen' = false for an - active connect(). */ - pcMyReply = REPL_501; - } - else - { - pxClient->usClientPort = ( uint16_t ) uxPort; - pxClient->ulClientIP = ulIPAddress; - FreeRTOS_printf( ("Client address %lxip:%lu\n", ulIPAddress, uxPort ) ); - pcMyReply = REPL_200; - } - } - break; - - case ECMD_CWD: /* Change current working directory. */ - prvChangeDir( pxClient, pcRestCommand ); - break; - - case ECMD_RNFR: - if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) - { - pcMyReply = REPL_553_READ_ONLY; - } - else - { - prvRenameFrom( pxClient, pcRestCommand ); - } - break; - - case ECMD_RNTO: - if( pxClient->bits.bInRename == pdFALSE_UNSIGNED ) - { - pcMyReply = REPL_503; /* "503 Bad sequence of commands. */ - } - else - { - prvRenameTo( pxClient, pcRestCommand ); - } - break; - - case ECMD_SITE: /* Set file permissions */ - if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) - { - pcMyReply = REPL_553_READ_ONLY; - } - else if( prvSiteCmd( pxClient, pcRestCommand ) == pdFALSE ) - { - pcMyReply = REPL_202; - } - break; - - case ECMD_DELE: - if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) - { - pcMyReply = REPL_553_READ_ONLY; - } - else - { - prvDeleteFile( pxClient, pcRestCommand ); - } - break; - - case ECMD_MDTM: - prvSizeDateFile( pxClient, pcRestCommand, pdTRUE ); - break; - - case ECMD_SIZE: - if( pxClient->pxWriteHandle != NULL ) - { - /* This SIZE query is probably about a file which is now being - received. If so, return the value of pxClient->ulRecvBytes, - pcRestCommand points to 'pcCommandBuffer', make it free by - copying it to pcNewDir. */ - - xMakeAbsolute( pxClient, pcNEW_DIR, sizeof( pcNEW_DIR ), pcRestCommand ); - - if( strcmp( pcNEW_DIR, pcRestCommand ) == 0 ) - { - BaseType_t xCount; - for( xCount = 0; xCount < 3 && pxClient->pxWriteHandle; xCount++ ) - { - prvStoreFileWork( pxClient ); - } - if( pxClient->pxWriteHandle != NULL ) - { - /* File being queried is still open, return number of - bytes received until now. */ - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "213 %lu\r\n", pxClient->ulRecvBytes ); - pcMyReply = pcCOMMAND_BUFFER; - } /* otherwise, do a normal stat(). */ - } - strcpy( pcRestCommand, pcNEW_DIR ); - } - if( pcMyReply == NULL ) - { - prvSizeDateFile( pxClient, pcRestCommand, pdFALSE ); - } - break; - case ECMD_MKD: - case ECMD_RMD: - if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) - { - pcMyReply = REPL_553_READ_ONLY; - } - else - { - prvMakeRemoveDir( pxClient, pcRestCommand, pxFTPCommand->ucCommandType == ECMD_RMD ); - } - break; - case ECMD_CDUP: - prvChangeDir( pxClient, ".." ); - break; - - case ECMD_QUIT: - prvSendReply( pxClient->xSocket, REPL_221, 0 ); - pxClient->bits.bLoggedIn = pdFALSE_UNSIGNED; - break; - case ECMD_LIST: - case ECMD_RETR: - case ECMD_STOR: - if( ( pxClient->xTransferSocket == FREERTOS_NO_SOCKET ) && - ( ( pxFTPCommand->ucCommandType != ECMD_STOR ) || - ( pxClient->bits1.bEmptyFile == pdFALSE_UNSIGNED ) ) ) - { - /* Sending "425 Can't open data connection." : - Before receiving any of these commands, there must have been a - PORT or PASV command, which causes the creation of a data socket. */ - /* There is one exception: a STOR command is received while the - data connection has already been closed. This is tested with the - 'bEmptyFile' flag. */ - pcMyReply = REPL_425; - } - else - { - /* In case an empty file was received ( bits1.bEmptyFile ), the - transfer socket never delivered any data. Check if the transfer - socket is still open: */ - if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) - { - prvTransferCheck( pxClient ); - } - switch( pxFTPCommand->ucCommandType ) - { - case ECMD_LIST: - prvListSendPrep( pxClient ); - break; - case ECMD_RETR: - prvRetrieveFilePrep( pxClient, pcRestCommand ); - break; - case ECMD_STOR: - if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) - { - pcMyReply = REPL_553_READ_ONLY; - } - else - { - prvStoreFilePrep( pxClient, pcRestCommand ); - if( pxClient->bits1.bEmptyFile != pdFALSE_UNSIGNED ) - { - /* Although the 'xTransferSocket' is closed already, - call this function just for the logging. */ - prvTransferCloseSocket( pxClient ); - - /* Close an empty file. */ - prvTransferCloseFile( pxClient ); - } - } - break; - } - } - break; - - case ECMD_FEAT: - { - static const char pcFeatAnswer[] = - "211-Features:\x0a" - /* The MDTM command is only allowed when - there is support for date&time. */ - #if( ffconfigTIME_SUPPORT != 0 ) - " MDTM\x0a" - #endif - " REST STREAM\x0a" - " SIZE\x0d\x0a" - "211 End\x0d\x0a"; - pcMyReply = pcFeatAnswer; - } - break; - - case ECMD_UNKNOWN: - FreeRTOS_printf( ("ftp::processCmd: Cmd %s unknown\n", pcRestCommand ) ); - pcMyReply = REPL_500; - break; - } - } - if( pxFTPCommand->ucCommandType != ECMD_RNFR ) - { - pxClient->bits.bInRename = pdFALSE_UNSIGNED; - } - - if( pcMyReply != NULL ) - { - xResult = prvSendReply( pxClient->xSocket, pcMyReply, strlen( pcMyReply ) ); - } - - return xResult; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTransferConnect( FTPClient_t *pxClient, BaseType_t xDoListen ) -{ -Socket_t xSocket; -BaseType_t xResult; - - /* Open a socket for a data connection with the FTP client. - Happens after a PORT or a PASV command. */ - - /* Make sure the previous socket is deleted and flags reset */ - prvTransferCloseSocket( pxClient ); - - pxClient->bits1.bEmptyFile = pdFALSE_UNSIGNED; - - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); - - if( ( xSocket != FREERTOS_NO_SOCKET ) && ( xSocket != FREERTOS_INVALID_SOCKET ) ) - { - BaseType_t xSmallTimeout = pdMS_TO_TICKS( 100 ); - struct freertos_sockaddr xAddress; - - #if( ipconfigFTP_TX_BUFSIZE > 0 ) - WinProperties_t xWinProps; - #endif - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xAddress.sin_address.ulIP_IPv4 = FreeRTOS_GetIPAddress( ); /* Single NIC, currently not used */ - } - #else - { - xAddress.sin_addr = FreeRTOS_GetIPAddress( ); /* Single NIC, currently not used */ - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xAddress.sin_port = FreeRTOS_htons( 0 ); /* Bind to any available port number */ - xAddress.sin_family = FREERTOS_AF_INET; - - BaseType_t xBindResult; - xBindResult = FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) ); - if ( xBindResult != 0 ) - { - FreeRTOS_printf( ( "FreeRTOS_bind() failed\n" ) ); - return xBindResult; - } - - #if( ipconfigFTP_TX_BUFSIZE > 0 ) - { - /* Fill in the buffer and window sizes that will be used by the - socket. */ - xWinProps.lTxBufSize = ipconfigFTP_TX_BUFSIZE; - xWinProps.lTxWinSize = ipconfigFTP_TX_WINSIZE; - xWinProps.lRxBufSize = ipconfigFTP_RX_BUFSIZE; - xWinProps.lRxWinSize = ipconfigFTP_RX_WINSIZE; - - /* Set the window and buffer sizes. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); - } - #endif - - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xSmallTimeout, sizeof( BaseType_t ) ); - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xSmallTimeout, sizeof( BaseType_t ) ); - - /* The same instance of the socket will be used for the connection and - data transport. */ - if( xDoListen != pdFALSE ) - { - BaseType_t xTrueValue = pdTRUE; - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_REUSE_LISTEN_SOCKET, ( void * ) &xTrueValue, sizeof( xTrueValue ) ); - } - pxClient->bits1.bIsListen = xDoListen; - pxClient->xTransferSocket = xSocket; - - if( xDoListen != pdFALSE ) - { - FreeRTOS_FD_SET( xSocket, pxClient->pxParent->xSocketSet, eSELECT_EXCEPT | eSELECT_READ ); - /* Calling FreeRTOS_listen( ) */ - xResult = prvTransferStart( pxClient ); - if( xResult >= 0 ) - { - xResult = pdTRUE; - } - } - else - { - FreeRTOS_FD_SET( xSocket, pxClient->pxParent->xSocketSet, eSELECT_EXCEPT | eSELECT_READ | eSELECT_WRITE ); - xResult = pdTRUE; - } - } - else - { - FreeRTOS_printf( ( "FreeRTOS_socket() failed\n" ) ); - xResult = -pdFREERTOS_ERRNO_ENOMEM; - } - - /* An active socket (PORT) should connect() later. */ - return xResult; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTransferStart( FTPClient_t *pxClient ) -{ -BaseType_t xResult; - - /* A transfer socket has been opened, now either call listen() for 'PASV' - or connect() for the 'PORT' command. */ - if( pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ) - { - xResult = FreeRTOS_listen( pxClient->xTransferSocket, 1 ); - } - else - { - struct freertos_sockaddr xAddress; - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xAddress.sin_address.ulIP_IPv4 = FreeRTOS_htonl( pxClient->ulClientIP ); - } - #else - { - xAddress.sin_addr = FreeRTOS_htonl( pxClient->ulClientIP ); - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - - xAddress.sin_port = FreeRTOS_htons( pxClient->usClientPort ); - xAddress.sin_family = FREERTOS_AF_INET; - - /* Start an active connection for this data socket */ - xResult = FreeRTOS_connect( pxClient->xTransferSocket, &xAddress, sizeof( xAddress ) ); - } - - return xResult; -} -/*-----------------------------------------------------------*/ - -static void prvTransferCheck( FTPClient_t *pxClient ) -{ -BaseType_t xRxSize; - - /* A data transfer is busy. Check if there are changes in connectedness. */ - xRxSize = FreeRTOS_rx_size( pxClient->xTransferSocket ); - - if( pxClient->bits1.bClientConnected == pdFALSE_UNSIGNED ) - { - /* The time to receive a small file can be so short, that we don't even - see that the socket gets connected and disconnected. Therefore, check - the sizeof of the RX buffer. */ - { - struct freertos_sockaddr xAddress; - Socket_t xNexSocket; - socklen_t xSocketLength = sizeof( xAddress ); - - if( pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ) - { - xNexSocket = FreeRTOS_accept( pxClient->xTransferSocket, &xAddress, &xSocketLength); - if( ( ( xNexSocket != FREERTOS_NO_SOCKET ) && ( xNexSocket != FREERTOS_INVALID_SOCKET ) ) || - xRxSize > 0 ) - { - pxClient->bits1.bClientConnected = pdTRUE_UNSIGNED; - } - } - else - { - if( FreeRTOS_issocketconnected( pxClient->xTransferSocket ) > 0 || - xRxSize > 0 ) - { - pxClient->bits1.bClientConnected = pdTRUE_UNSIGNED; - } - } - if( pxClient->bits1.bClientConnected != pdFALSE_UNSIGNED ) - { - pxClient->bits1.bEmptyFile = pdFALSE_UNSIGNED; - #if( ipconfigHAS_PRINTF != 0 ) - { - struct freertos_sockaddr xRemoteAddress, xLocalAddress; - FreeRTOS_GetRemoteAddress( pxClient->xTransferSocket, &xRemoteAddress ); - FreeRTOS_GetLocalAddress( pxClient->xTransferSocket, &xLocalAddress ); - FreeRTOS_printf( ( "%s Connected from %u to %u\n", - pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ? "PASV" : "PORT", - ( unsigned ) FreeRTOS_ntohs( xLocalAddress.sin_port ), - ( unsigned ) FreeRTOS_ntohs( xRemoteAddress.sin_port ) ) ); - } - #endif /* ipconfigHAS_PRINTF */ - FreeRTOS_FD_CLR( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); - FreeRTOS_FD_SET( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_READ|eSELECT_EXCEPT ); - } - } - } - - if ( pxClient->bits1.bClientConnected != pdFALSE_UNSIGNED ) - { - if( pxClient->pcConnectionAck[ 0 ] != '\0' ) - { - BaseType_t xLength; - BaseType_t xRemotePort; - struct freertos_sockaddr xRemoteAddress; - - FreeRTOS_GetRemoteAddress( pxClient->xTransferSocket, &xRemoteAddress ); - xRemotePort = FreeRTOS_ntohs( xRemoteAddress.sin_port ); - - /* Tell on the command port 21 we have a data connection */ - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - pxClient->pcConnectionAck, pxClient->ulClientIP, xRemotePort ); - - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - pxClient->pcConnectionAck[ 0 ] = '\0'; - } - - if( ( FreeRTOS_issocketconnected( pxClient->xTransferSocket ) == pdFALSE ) && FreeRTOS_rx_size( pxClient->xTransferSocket ) == 0 ) - { - prvTransferCloseSocket( pxClient ); - prvTransferCloseFile( pxClient ); - } - } -} -/*-----------------------------------------------------------*/ - -static void prvTransferCloseSocket( FTPClient_t *pxClient ) -{ - if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) - { - /* DEBUGGING ONLY */ - BaseType_t xRxSize = FreeRTOS_rx_size( pxClient->xTransferSocket ); - if( xRxSize > 0 ) - { - BaseType_t xRxSize2; - BaseType_t xStatus; - prvStoreFileWork( pxClient ); - xStatus = FreeRTOS_connstatus( pxClient->xTransferSocket ); - xRxSize2 = FreeRTOS_rx_size( pxClient->xTransferSocket ); - FreeRTOS_printf( ( "FTP: WARNING: %s: RX size = %ld -> %ld (%s)\n", - FreeRTOS_GetTCPStateName( xStatus ), - xRxSize, xRxSize2, pxClient->pcFileName ) ); - if( xRxSize2 > 1 ) - { - return; - } - - /* Remove compiler warnings in case FreeRTOS_printf() is not - defined. */ - ( void ) xStatus; - } - } - - if( ( pxClient->pxWriteHandle != NULL ) || ( pxClient->pxReadHandle != NULL ) ) - { - BaseType_t xLength; - char pcStrBuf[ 32 ]; - - if( pxClient->bits1.bHadError == pdFALSE_UNSIGNED ) - { - xLength = snprintf( pxClient->pcClientAck, sizeof( pxClient->pcClientAck ), - "226 Closing connection %d bytes transmitted\r\n", ( int ) pxClient->ulRecvBytes ); - } - else - { - xLength = snprintf( pxClient->pcClientAck, sizeof( pxClient->pcClientAck ), - "451 Requested action aborted after %d bytes\r\n", ( int ) pxClient->ulRecvBytes ); - } - - /* Tell on the command socket the data connection is now closed. */ - prvSendReply( pxClient->xSocket, pxClient->pcClientAck, xLength ); - - #if( ipconfigHAS_PRINTF != 0 ) - { - TickType_t xDelta; - uint32_t ulAverage; - xDelta = xTaskGetTickCount( ) - pxClient->xStartTime; - ulAverage = ulGetAverage( pxClient->ulRecvBytes, xDelta ); - - FreeRTOS_printf( ("FTP: %s: '%s' %lu Bytes (%s/sec)\n", - pxClient->pxReadHandle ? "sent" : "recv", - pxClient->pcFileName, - pxClient->ulRecvBytes, - pcMkSize( ulAverage, pcStrBuf, sizeof( pcStrBuf ) ) ) ); - } - #endif - } - - if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) - { - FreeRTOS_FD_CLR( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_ALL ); - FreeRTOS_closesocket( pxClient->xTransferSocket ); - pxClient->xTransferSocket = FREERTOS_NO_SOCKET; - if( pxClient->ulRecvBytes == 0ul ) - { - /* Received zero bytes: an empty file */ - pxClient->bits1.bEmptyFile = pdTRUE_UNSIGNED; - } - else - { - pxClient->bits1.bEmptyFile = pdFALSE_UNSIGNED; - } - } - pxClient->bits1.bIsListen = pdFALSE_UNSIGNED; - pxClient->bits1.bDirHasEntry = pdFALSE_UNSIGNED; - pxClient->bits1.bClientConnected = pdFALSE_UNSIGNED; - pxClient->bits1.bHadError = pdFALSE_UNSIGNED; -} -/*-----------------------------------------------------------*/ - -static void prvTransferCloseFile( FTPClient_t *pxClient ) -{ - if( pxClient->pxWriteHandle != NULL ) - { - ff_fclose( pxClient->pxWriteHandle ); - pxClient->pxWriteHandle = NULL; - #if( ipconfigFTP_HAS_RECEIVED_HOOK != 0 ) - { - vApplicationFTPReceivedHook( pxClient->pcFileName, pxClient->ulRecvBytes, pxClient ); - } - #endif - - } - if( pxClient->pxReadHandle != NULL ) - { - ff_fclose( pxClient->pxReadHandle ); - pxClient->pxReadHandle = NULL; - } - /* These two field are only used for logging / file-statistics */ - pxClient->ulRecvBytes = 0ul; - pxClient->xStartTime = 0ul; -} -/*-----------------------------------------------------------*/ - -/** - * Guess the transfer type, given the client requested type. - * Actually in unix there is no difference between binary and - * ascii mode when we work with file descriptors. - * If #type is not recognized as a valid client request, -1 is returned. - */ -static BaseType_t prvGetTransferType( const char *pcType ) -{ -BaseType_t xResult = -1; - - if( pcType != NULL ) - { - BaseType_t xLength = strlen( pcType ); - if( xLength == 0 ) - { - return -1; - } - switch( pcType[ 0 ] ) { - case 'I': - xResult = TMODE_BINARY; - break; - case 'A': - xResult = TMODE_ASCII; - break; - case 'L': - if( xLength >= 3 ) - { - if( pcType[ 2 ] == '7' ) - { - xResult = TMODE_7BITS; - } - else if( pcType[ 2 ] == '8' ) - { - xResult = TMODE_7BITS; - } - } - break; - } - } - return xResult; -} -/*-----------------------------------------------------------*/ - -#if( ipconfigHAS_PRINTF != 0 ) - #define SIZE_1_GB ( 1024ul * 1024ul * 1024ul ) - #define SIZE_1_MB ( 1024ul * 1024ul ) - #define SIZE_1_KB ( 1024ul ) - - static const char *pcMkSize( uint32_t ulAmount, char *pcBuffer, BaseType_t xBufferSize ) - { - uint32_t ulGB, ulMB, ulKB, ulByte; - - ulGB = ( ulAmount / SIZE_1_GB ); - ulAmount -= ( ulGB * SIZE_1_GB ); - ulMB = ( ulAmount / SIZE_1_MB ); - ulAmount -= ( ulMB * SIZE_1_MB ); - ulKB = ( ulAmount / SIZE_1_KB ); - ulAmount -= ( ulKB * SIZE_1_KB ); - ulByte = ( ulAmount ); - - if (ulGB != 0ul ) - { - snprintf( pcBuffer, xBufferSize, "%lu.%02lu GB", ulGB, (100 * ulMB) / SIZE_1_KB ); - } - else if( ulMB != 0ul ) - { - snprintf( pcBuffer, xBufferSize, "%lu.%02lu MB", ulMB, (100 * ulKB) / SIZE_1_KB ); - } - else if( ulKB != 0ul ) - { - snprintf(pcBuffer, xBufferSize, "%lu.%02lu KB", ulKB, (100 * ulByte) / SIZE_1_KB ); - } - else - { - snprintf( pcBuffer, xBufferSize, "%lu bytes", ulByte ); - } - - return pcBuffer; - } - /*-----------------------------------------------------------*/ -#endif /* ipconfigHAS_PRINTF != 0 */ - -#if( ipconfigHAS_PRINTF != 0 ) - static uint32_t ulGetAverage( uint32_t ulAmount, TickType_t xDeltaMs ) - { - uint32_t ulAverage; - - /* Get the average amount of bytes per seconds. Ideally this is - calculated by Multiplying with 1000 and dividing by milliseconds: - ulAverage = ( 1000ul * ulAmount ) / xDeltaMs; - Now get a maximum precision, while avoiding an arithmetic overflow: - */ - if( xDeltaMs == 0ul ) - { - /* Time is zero, there is no average */ - ulAverage = 0ul; - } - else if( ulAmount >= ( ~0ul / 10ul ) ) - { - /* More than 409 MB has been transferred, do not multiply. */ - ulAverage = ( ulAmount / ( xDeltaMs / 1000ul ) ); - } - else if( ulAmount >= ( ~0ul / 100ul ) ) - { - /* Between 409 and 41 MB has been transferred, can multiply by 10. */ - ulAverage = ( ( ulAmount * 10ul ) / ( xDeltaMs / 100ul ) ); - } - else if( ulAmount >= ( ~0ul / 1000ul ) ) - { - /* Between 4.1 MB and 41 has been transferred, can multiply by 100. */ - ulAverage = ( ( ulAmount * 100ul ) / ( xDeltaMs / 10ul ) ); - } - else - { - /* Less than 4.1 MB: can multiply by 1000. */ - ulAverage = ( ( ulAmount * 1000ul ) / xDeltaMs ); - } - - return ulAverage; - } - /*-----------------------------------------------------------*/ -#endif /* ipconfigHAS_PRINTF != 0 */ - -static UBaseType_t prvParsePortData( const char *pcCommand, uint32_t *pulIPAddress ) -{ -/*_HT_ Using 'unsigned' here because when sscanf() sees '%u', it expects a pointer to 'unsigned'. -Not sure about the sscanf() format for UBaseType_t ? */ -unsigned h1, h2, h3, h4, p1, p2; -char sep; -UBaseType_t uxResult; - - /* Expect PORT h1,h2,h3,h4,p1,p2 */ - if (sscanf (pcCommand, "%u%c%u%c%u%c%u%c%u%c%u", &h1, &sep, &h2, &sep, &h3, &sep, &h4, &sep, &p1, &sep, &p2) != 11) - { - uxResult= 0u; - } - else - { - /* Put in network byte order. */ - *pulIPAddress = - ( ( uint32_t ) h1 << 24 ) | - ( ( uint32_t ) h2 << 16 ) | - ( ( uint32_t ) h3 << 8 ) | - ( ( uint32_t ) h4 ); - uxResult = ( p1 << 8 ) | p2; - } - return uxResult; -} -/*-----------------------------------------------------------*/ - -/* - - #### ####### # ### -# # # # ## # # -# # # # # # -# ###### #### ### ## #### # # ### # #### - ## # # # # # # # # ##### # # # # - ## # # # ## # ###### # # # # ###### -# # # # # # # # # # # -# # # ## # # # # ## # # # # ## - #### ## #### #### #### #### ##### ##### #### - -*/ - -static BaseType_t prvStoreFilePrep( FTPClient_t *pxClient, char *pcFileName ) -{ -BaseType_t xResult; -FF_FILE *pxNewHandle; -size_t uxFileSize = 0ul; -int iErrorNo; - - /* Close previous handle (if any) and reset file transfer parameters. */ - prvTransferCloseFile( pxClient ); - - xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); - - pxNewHandle = NULL; - - if( pxClient->ulRestartOffset != 0 ) - { - size_t uxOffset = pxClient->ulRestartOffset; - int32_t lRc; - - pxClient->ulRestartOffset = 0ul; /* Only use 1 time. */ - pxNewHandle = ff_fopen( pxClient->pcFileName, "ab" ); - - if( pxNewHandle != NULL ) - { - uxFileSize = pxNewHandle->ulFileSize; - - if( uxOffset <= uxFileSize ) - { - lRc = ff_fseek( pxNewHandle, uxOffset, FF_SEEK_SET ); - } - else - { - /* Won't even try to seek after EOF */ - lRc = -pdFREERTOS_ERRNO_EINVAL; - } - if( lRc != 0 ) - { - BaseType_t xLength; - - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "450 Seek invalid %u length %u\r\n", - ( unsigned ) uxOffset, ( unsigned ) uxFileSize ); - - /* "Requested file action not taken". */ - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - - FreeRTOS_printf( ( "ftp::storeFile: create %s: Seek %u length %u\n", - pxClient->pcFileName, ( unsigned ) uxOffset, ( unsigned ) uxFileSize ) ); - - ff_fclose( pxNewHandle ); - pxNewHandle = NULL; - } - } - } - else - { - pxNewHandle = ff_fopen( pxClient->pcFileName, "wb" ); - } - - if( pxNewHandle == NULL ) - { - iErrorNo = stdioGET_ERRNO(); - if( iErrorNo == pdFREERTOS_ERRNO_ENOSPC ) - { - prvSendReply( pxClient->xSocket, REPL_552, 0 ); - } - else - { - /* "Requested file action not taken". */ - prvSendReply( pxClient->xSocket, REPL_450, 0 ); - } - FreeRTOS_printf( ( "ftp::storeFile: create %s: %s (errno %d)\n", - pxClient->pcFileName, - ( const char* ) strerror( iErrorNo ), iErrorNo ) ); - - xResult = pdFALSE; - } - else - { - if( pxClient->bits1.bIsListen ) - { - /* True if PASV is used. */ - snprintf( pxClient->pcConnectionAck, sizeof( pxClient->pcConnectionAck ), - "150 Accepted data connection from %%xip:%%u\r\n" ); - prvTransferCheck( pxClient ); - } - else - { - BaseType_t xLength; - - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "150 Opening BIN connection to store file\r\n" ); - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - pxClient->pcConnectionAck[ 0 ] = '\0'; - prvTransferStart( pxClient ); /* Now active connect. */ - } - - pxClient->pxWriteHandle = pxNewHandle; - - /* To get some statistics about the performance. */ - pxClient->xStartTime = xTaskGetTickCount( ); - - xResult = pdTRUE; - } - - return xResult; -} -/*-----------------------------------------------------------*/ - -#if( ipconfigFTP_ZERO_COPY_ALIGNED_WRITES == 0 ) - - static BaseType_t prvStoreFileWork( FTPClient_t *pxClient ) - { - BaseType_t xRc, xWritten; - - /* Read from the data socket until all has been read or until a negative value - is returned. */ - for( ; ; ) - { - char *pcBuffer; - - /* The "zero-copy" method: */ - xRc = FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) &pcBuffer, - 0x20000u, FREERTOS_ZERO_COPY | FREERTOS_MSG_DONTWAIT ); - if( xRc <= 0 ) - { - break; - } - pxClient->ulRecvBytes += xRc; - xWritten = ff_fwrite( pcBuffer, 1, xRc, pxClient->pxWriteHandle ); - FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) NULL, xRc, 0 ); - if( xWritten != xRc ) - { - xRc = -1; - /* bHadError: a transfer got aborted because of an error. */ - pxClient->bits1.bHadError = pdTRUE_UNSIGNED; - break; - } - } - return xRc; - } - -#else /* ipconfigFTP_ZERO_COPY_ALIGNED_WRITES != 0 */ - - #if !defined( ipconfigFTP_PREFERRED_WRITE_SIZE ) - /* If you store data on flash, it may be profitable to give 'ipconfigFTP_PREFERRED_WRITE_SIZE' - the same size as the size of the flash' erase blocks, e.g. 4KB */ - #define ipconfigFTP_PREFERRED_WRITE_SIZE 512ul - #endif - - static BaseType_t prvStoreFileWork( FTPClient_t *pxClient ) - { - BaseType_t xRc, xWritten; - - /* Read from the data socket until all has been read or until a negative - value is returned. */ - for( ; ; ) - { - char *pcBuffer; - UBaseType_t xStatus; - - /* The "zero-copy" method: */ - xRc = FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) &pcBuffer, - 0x20000u, FREERTOS_ZERO_COPY | FREERTOS_MSG_DONTWAIT ); - - if( xRc <= 0 ) - { - /* There are no data or the connection is closed. */ - break; - } - xStatus = FreeRTOS_connstatus( pxClient->xTransferSocket ); - if( xStatus != eESTABLISHED ) - { - /* The connection is not established (any more), therefore - accept any amount of bytes, probably the last few bytes. */ - } - else - { - if( xRc >= ipconfigFTP_PREFERRED_WRITE_SIZE ) - { - /* More than a sector to write, round down to a multiple of - PREFERRED_WRITE_SIZE bytes. */ - xRc = ( xRc / ipconfigFTP_PREFERRED_WRITE_SIZE ) * ipconfigFTP_PREFERRED_WRITE_SIZE; - } - else - { - const StreamBuffer_t *pxBuffer = FreeRTOS_get_rx_buf( pxClient->xTransferSocket ); - size_t uxSpace = pxBuffer->LENGTH - pxBuffer->uxTail; - - if( uxSpace >= ipconfigFTP_PREFERRED_WRITE_SIZE ) - { - /* At this moment there are les than PREFERRED_WRITE_SIZE bytes in the RX - buffer, but there is space for more. Just return and - wait for more. */ - xRc = 0; - } - else - { - /* Now reading beyond the end of the circular buffer, - use a normal read. */ - pcBuffer = pcFILE_BUFFER; - xRc = FreeRTOS_recvcount( pxClient->xTransferSocket ); - xRc = ( xRc / ipconfigFTP_PREFERRED_WRITE_SIZE ) * ipconfigFTP_PREFERRED_WRITE_SIZE; - if( xRc > 0 ) - { - xRc = FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) pcBuffer, - sizeof( pcFILE_BUFFER ), FREERTOS_MSG_DONTWAIT ); - } - } - } - } - if( xRc == 0 ) - { - break; - } - pxClient->ulRecvBytes += xRc; - - xWritten = ff_fwrite( pcBuffer, 1, xRc, pxClient->pxWriteHandle ); - if( pcBuffer != pcFILE_BUFFER ) - { - FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) NULL, xRc, 0 ); - } - if( xWritten != xRc ) - { - xRc = -1; - /* bHadError: a transfer got aborted because of an error. */ - pxClient->bits1.bHadError = pdTRUE_UNSIGNED; - break; - } - } - return xRc; - } - -#endif /* ipconfigFTP_ZERO_COPY_ALIGNED_WRITES */ -/*-----------------------------------------------------------*/ - -/* -###### # ####### # ### - # # # # # ## # # - # # # # # # - # # #### ###### ### ## ### #### # # #### # # ### # #### - ###### # # # # # # # # # # # # # ##### # # # # - # ## ###### # ## # # ###### # # ###### # # # # ###### - # # # # # # # # # # # # # # - # # # ## # ## # # # ## # # # ## # # # # ## -### ## #### ## #### ##### #### ## #### #### ##### ##### #### -*/ -static BaseType_t prvRetrieveFilePrep( FTPClient_t *pxClient, char *pcFileName ) -{ -BaseType_t xResult = pdTRUE; -size_t uxFileSize; - - /* Close previous handle (if any) and reset file transfer parameters */ - prvTransferCloseFile( pxClient ); - - xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); - - pxClient->pxReadHandle = ff_fopen( pxClient->pcFileName, "rb" ); - if( pxClient->pxReadHandle == NULL ) - { - int iErrno = stdioGET_ERRNO(); - /* "Requested file action not taken". */ - prvSendReply( pxClient->xSocket, REPL_450, 0 ); - FreeRTOS_printf( ("prvRetrieveFilePrep: open '%s': errno %d: %s\n", - pxClient->pcFileName, iErrno, ( const char * ) strerror( iErrno ) ) ); - uxFileSize = 0ul; - xResult = pdFALSE; - } - else - { - uxFileSize = pxClient->pxReadHandle->ulFileSize; - pxClient->uxBytesLeft = uxFileSize; - if( pxClient->ulRestartOffset != 0ul ) - { - size_t uxOffset = pxClient->ulRestartOffset; - int32_t iRc; - - /* Only use 1 time. */ - pxClient->ulRestartOffset = 0; - - if( uxOffset < uxFileSize ) - { - iRc = ff_fseek( pxClient->pxReadHandle, uxOffset, FF_SEEK_SET ); - } - else - { - iRc = -pdFREERTOS_ERRNO_EINVAL; - } - if( iRc != 0 ) - { - BaseType_t xLength; - - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "450 Seek invalid %u length %u\r\n", ( unsigned ) uxOffset, ( unsigned ) uxFileSize ); - - /* "Requested file action not taken". */ - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - - FreeRTOS_printf( ( "prvRetrieveFilePrep: create %s: Seek %u length %u\n", - pxClient->pcFileName, ( unsigned ) uxOffset, ( unsigned ) uxFileSize ) ); - - ff_fclose( pxClient->pxReadHandle ); - pxClient->pxReadHandle = NULL; - xResult = pdFALSE; - } - else - { - pxClient->uxBytesLeft = uxFileSize - pxClient->ulRestartOffset; - } - } - } - if( xResult != pdFALSE ) - { - if( pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ) - { - /* True if PASV is used. */ - snprintf( pxClient->pcConnectionAck, sizeof( pxClient->pcConnectionAck ), - "150%cAccepted data connection from %%xip:%%u\r\n%s", - pxClient->xTransType == TMODE_ASCII ? '-' : ' ', - pxClient->xTransType == TMODE_ASCII ? "150 NOTE: ASCII mode requested, but binary mode used\r\n" : "" ); - } else { - BaseType_t xLength; - - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "150%cOpening data connection to %lxip:%u\r\n%s", - pxClient->xTransType == TMODE_ASCII ? '-' : ' ', - pxClient->ulClientIP, - pxClient->usClientPort, - pxClient->xTransType == TMODE_ASCII ? "150 NOTE: ASCII mode requested, but binary mode used\r\n" : "" ); - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - pxClient->pcConnectionAck[ 0 ] = '\0'; - prvTransferStart( pxClient ); - } - - /* Prepare the ACK which will be sent when all data has been sent. */ - snprintf( pxClient->pcClientAck, sizeof( pxClient->pcClientAck ), "%s", REPL_226 ); - - /* To get some statistics about the performance. */ - pxClient->xStartTime = xTaskGetTickCount( ); - if( uxFileSize == 0ul ) - { - FreeRTOS_shutdown( pxClient->xTransferSocket, FREERTOS_SHUT_RDWR ); - } - } - - return xResult; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvRetrieveFileWork( FTPClient_t *pxClient ) -{ -size_t uxSpace; -size_t uxCount, uxItemsRead; -BaseType_t xRc = 0; -BaseType_t xSetEvent = pdFALSE; - - do - { - #if( ipconfigFTP_TX_ZERO_COPY != 0 ) - char *pcBuffer; - BaseType_t xBufferLength; - #endif /* ipconfigFTP_TX_ZERO_COPY */ - - /* Take the lesser of the two: tx_space (number of bytes that can be - queued for transmission) and uxBytesLeft (the number of bytes left to - read from the file) */ - uxSpace = FreeRTOS_tx_space( pxClient->xTransferSocket ); - - if( uxSpace == 0 ) - { - FreeRTOS_FD_SET( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE | eSELECT_EXCEPT ); - xRc = FreeRTOS_select( pxClient->pxParent->xSocketSet, 200 ); - uxSpace = FreeRTOS_tx_space( pxClient->xTransferSocket ); - } - - uxCount = FreeRTOS_min_uint32( pxClient->uxBytesLeft, uxSpace ); - - if( uxCount == 0 ) - { - break; - } - - #if( ipconfigFTP_TX_ZERO_COPY == 0 ) - { - if( uxCount > sizeof( pcFILE_BUFFER ) ) - { - uxCount = sizeof( pcFILE_BUFFER ); - } - uxItemsRead = ff_fread( pcFILE_BUFFER, 1, uxCount, pxClient->pxReadHandle ); - if( uxItemsRead != uxCount ) - { - FreeRTOS_printf( ( "prvRetrieveFileWork: Got %u Expected %u\n", ( unsigned )uxItemsRead, ( unsigned ) uxCount ) ); - xRc = FreeRTOS_shutdown( pxClient->xTransferSocket, FREERTOS_SHUT_RDWR ); - pxClient->uxBytesLeft = 0u; - break; - } - pxClient->uxBytesLeft -= uxCount; - - if( pxClient->uxBytesLeft == 0u ) - { - BaseType_t xTrueValue = 1; - - FreeRTOS_setsockopt( pxClient->xTransferSocket, 0, FREERTOS_SO_CLOSE_AFTER_SEND, ( void * ) &xTrueValue, sizeof( xTrueValue ) ); - } - - xRc = FreeRTOS_send( pxClient->xTransferSocket, pcFILE_BUFFER, uxCount, 0 ); - } - #else /* ipconfigFTP_TX_ZERO_COPY != 0 */ - { - /* Use zero-copy transmission: - FreeRTOS_get_tx_head() returns a direct pointer to the TX stream and - set xBufferLength to know how much space there is left. */ - pcBuffer = ( char * )FreeRTOS_get_tx_head( pxClient->xTransferSocket, &xBufferLength ); - if( ( pcBuffer != NULL ) && ( xBufferLength >= 512 ) ) - { - /* Will read disk data directly to the TX stream of the socket. */ - uxCount = FreeRTOS_min_uint32( uxCount, ( uint32_t )xBufferLength ); - if( uxCount > ( size_t ) 0x40000u ) - { - uxCount = ( size_t ) 0x40000u; - } - } - else - { - /* Use the normal file i/o buffer. */ - pcBuffer = pcFILE_BUFFER; - if( uxCount > sizeof( pcFILE_BUFFER ) ) - { - uxCount = sizeof( pcFILE_BUFFER ); - } - } - - if ( pxClient->uxBytesLeft >= 1024u ) - { - uxCount &= ~( ( size_t ) 512u - 1u ); - } - - if( uxCount <= 0u ) - { - /* Nothing to send after rounding down to a multiple of a sector size. */ - break; - } - - uxItemsRead = ff_fread( pcBuffer, 1, uxCount, pxClient->pxReadHandle ); - - if( uxCount != uxItemsRead ) - { - FreeRTOS_printf( ( "prvRetrieveFileWork: Got %u Expected %u\n", ( unsigned )uxItemsRead, ( unsigned )uxCount ) ); - xRc = FreeRTOS_shutdown( pxClient->xTransferSocket, FREERTOS_SHUT_RDWR ); - pxClient->uxBytesLeft = 0u; - break; - } - pxClient->uxBytesLeft -= uxCount; - - if( pxClient->uxBytesLeft == 0u ) - { - BaseType_t xTrueValue = 1; - - FreeRTOS_setsockopt( pxClient->xTransferSocket, 0, FREERTOS_SO_CLOSE_AFTER_SEND, ( void * ) &xTrueValue, sizeof( xTrueValue ) ); - } - if( pcBuffer != pcFILE_BUFFER ) - { - pcBuffer = NULL; - } - xRc = FreeRTOS_send( pxClient->xTransferSocket, pcBuffer, uxCount, 0 ); - } - #endif /* ipconfigFTP_TX_ZERO_COPY */ - - if( xRc < 0 ) - { - break; - } - - pxClient->ulRecvBytes += xRc; - if( pxClient->uxBytesLeft == 0u ) - { - break; - } - } while( uxCount > 0u ); - - if( xRc < 0 ) - { - FreeRTOS_printf( ( "prvRetrieveFileWork: already disconnected\n" ) ); - } - else if( pxClient->uxBytesLeft <= 0u ) - { - BaseType_t x; - - for( x = 0; x < 5; x++ ) - { - xRc = FreeRTOS_recv( pxClient->xTransferSocket, pcFILE_BUFFER, sizeof( pcFILE_BUFFER ), 0 ); - if( xRc < 0 ) - { - break; - } - } -// FreeRTOS_printf( ( "prvRetrieveFileWork: %s all sent: xRc %ld\n", pxClient->pcFileName, xRc ) ); - } - else - { - FreeRTOS_FD_SET( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); - xSetEvent = pdTRUE; - } - if( xSetEvent == pdFALSE ) - { - FreeRTOS_FD_CLR( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); - } - return xRc; -} -/*-----------------------------------------------------------*/ - -/* -### ##### #### ##### - # # # # # # # - # # # # # - # # # # - # # ## # - # # # ## # - # # # # # # - # # # # # # -####### ##### #### #### -*/ -/* Prepare sending a directory LIST */ -static BaseType_t prvListSendPrep( FTPClient_t *pxClient ) -{ -BaseType_t xFindResult; -int iErrorNo; - - if( pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ) - { - /* True if PASV is used */ - snprintf( pxClient->pcConnectionAck, sizeof( pxClient->pcConnectionAck ), - "150 Accepted data connection from %%xip:%%u\r\n" ); - } - else - { - BaseType_t xLength; - - /* Here the FTP server is supposed to connect() */ - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "150 Opening ASCII mode data connection to for /bin/ls \r\n" ); - - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - /* Clear the current connection acknowledge message */ - pxClient->pcConnectionAck[ 0 ] = '\0'; - prvTransferStart( pxClient ); - } - - pxClient->xDirCount = 0; - xMakeAbsolute( pxClient, pcNEW_DIR, sizeof( pcNEW_DIR ), pxClient->pcCurrentDir ); - - xFindResult = ff_findfirst( pcNEW_DIR, &pxClient->xFindData ); - - pxClient->bits1.bDirHasEntry = ( xFindResult >= 0 ); - - iErrorNo = stdioGET_ERRNO(); - if( ( xFindResult < 0 ) && ( iErrorNo == pdFREERTOS_ERRNO_ENMFILE ) ) - { - FreeRTOS_printf( ("prvListSendPrep: Empty directory? (%s)\n", pxClient->pcCurrentDir ) ); - prvSendReply( pxClient->xTransferSocket, "total 0\r\n", 0 ); - pxClient->xDirCount++; - } - else if( xFindResult < 0 ) - { - FreeRTOS_printf( ( "prvListSendPrep: rc = %ld iErrorNo = %d\n", xFindResult, iErrorNo ) ); - prvSendReply( pxClient->xSocket, REPL_451, 0 ); - } - pxClient->pcClientAck[ 0 ] = '\0'; - - return pxClient->xDirCount; -} -/*-----------------------------------------------------------*/ - -#define MAX_DIR_LIST_ENTRY_SIZE 256 - -static BaseType_t prvListSendWork( FTPClient_t *pxClient ) -{ -BaseType_t xTxSpace; - - while( pxClient->bits1.bClientConnected != pdFALSE_UNSIGNED ) - { - char *pcWritePtr = pcCOMMAND_BUFFER; - BaseType_t xWriteLength; - - xTxSpace = FreeRTOS_tx_space( pxClient->xTransferSocket ); - - if( xTxSpace > ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) ) - { - xTxSpace = sizeof( pcCOMMAND_BUFFER ); - } - - while( ( xTxSpace >= MAX_DIR_LIST_ENTRY_SIZE ) && ( pxClient->bits1.bDirHasEntry != pdFALSE_UNSIGNED ) ) - { - BaseType_t xLength, xEndOfDir; - int32_t iRc; - int iErrorNo; - - xLength = prvGetFileInfoStat( &( pxClient->xFindData.xDirectoryEntry ), pcWritePtr, xTxSpace ); - - pxClient->xDirCount++; - pcWritePtr += xLength; - xTxSpace -= xLength; - - iRc = ff_findnext( &pxClient->xFindData ); - iErrorNo = stdioGET_ERRNO(); - - xEndOfDir = ( iRc < 0 ) && ( iErrorNo == pdFREERTOS_ERRNO_ENMFILE ); - - pxClient->bits1.bDirHasEntry = ( xEndOfDir == pdFALSE ) && ( iRc >= 0 ); - - if( ( iRc < 0 ) && ( xEndOfDir == pdFALSE ) ) - { - FreeRTOS_printf( ("prvListSendWork: %s (rc %08x)\n", - ( const char * ) strerror( iErrorNo ), - ( unsigned )iRc ) ); - } - } - xWriteLength = ( BaseType_t ) ( pcWritePtr - pcCOMMAND_BUFFER ); - - if( xWriteLength == 0 ) - { - break; - } - - if( pxClient->bits1.bDirHasEntry == pdFALSE_UNSIGNED ) - { - uint32_t ulTotalCount; - uint32_t ulFreeCount; - uint32_t ulPercentage; - - ulTotalCount = 1; - ulFreeCount = ff_diskfree( pxClient->pcCurrentDir, &ulTotalCount ); - ulPercentage = ( uint32_t ) ( ( 100ULL * ulFreeCount + ulTotalCount / 2 ) / ulTotalCount ); - - /* Prepare the ACK which will be sent when all data has been sent. */ - snprintf( pxClient->pcClientAck, sizeof( pxClient->pcClientAck ), - "226-Options: -l\r\n" - "226-%ld matches total\r\n" - "226 Total %lu KB (%lu %% free)\r\n", - pxClient->xDirCount, ulTotalCount /1024, ulPercentage ); - } - - if( xWriteLength ) - { - if( pxClient->bits1.bDirHasEntry == pdFALSE_UNSIGNED ) - { - BaseType_t xTrueValue = 1; - - FreeRTOS_setsockopt( pxClient->xTransferSocket, 0, FREERTOS_SO_CLOSE_AFTER_SEND, ( void * ) &xTrueValue, sizeof( xTrueValue ) ); - } - - prvSendReply( pxClient->xTransferSocket, pcCOMMAND_BUFFER, xWriteLength ); - } - - if( pxClient->bits1.bDirHasEntry == pdFALSE_UNSIGNED ) - { - prvSendReply( pxClient->xSocket, pxClient->pcClientAck, 0 ); - break; - } - - } /* while( pxClient->bits1.bClientConnected ) */ - - return 0; -} -/*-----------------------------------------------------------*/ - -static const char *pcMonthAbbrev( BaseType_t xMonth ) -{ -static const char pcMonthList[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; - - if( xMonth < 1 || xMonth > 12 ) - xMonth = 12; - - return pcMonthList + 3 * ( xMonth - 1 ); -}; -/*-----------------------------------------------------------*/ - -static BaseType_t prvGetFileInfoStat( FF_DirEnt_t *pxEntry, char *pcLine, BaseType_t xMaxLength ) -{ - char date[ 16 ]; - char mode[ 11 ] = "----------"; - BaseType_t st_nlink = 1; - const char user[ 9 ] = "freertos"; - const char group[ 8 ] = "plusfat"; - -/* - * Creates a unix-style listing, understood by most FTP clients: - * - * -rw-rw-r-- 1 freertos FreeRTOS+FAT 10564588 Sep 01 00:17 03. Metaharmoniks - Star (Instrumental).mp3 - * -rw-rw-r-- 1 freertos FreeRTOS+FAT 19087839 Sep 01 00:17 04. Simon Le Grec - Dimitri (Wherever U Are) (Cosmos Mix).mp3 - * -rw-rw-r-- 1 freertos FreeRTOS+FAT 11100621 Sep 01 00:16 05. D-Chill - Mistake (feat. Katy Blue).mp3 - */ - - #if ( ffconfigTIME_SUPPORT == 1 ) - const FF_SystemTime_t *pxCreateTime = &( pxEntry->xCreateTime ); - #else - #warning Do not use this. - FF_SystemTime_t xCreateTime; - const FF_SystemTime_t *pxCreateTime = &xCreateTime; - #endif - size_t ulSize = ( size_t )pxEntry->ulFileSize; - const char *pcFileName = pxEntry->pcFileName; - - mode[ 0 ] = ( ( pxEntry->ucAttrib & FF_FAT_ATTR_DIR ) != 0 ) ? 'd' : '-'; - #if( ffconfigDEV_SUPPORT != 0 ) - { - if( ( pxEntry->ucAttrib & FF_FAT_ATTR_DIR ) == 0 ) - { - switch( pxEntry->ucIsDeviceDir ) - { - case FF_DEV_CHAR_DEV: - mode[ 0 ] = 'c'; - break; - case FF_DEV_BLOCK_DEV: - mode[ 0 ] = 'b'; - break; - } - } - } - #endif /* ffconfigDEV_SUPPORT != 0 */ - - mode[ 1 ] = 'r'; /* Owner. */ - mode[ 2 ] = ( ( pxEntry->ucAttrib & FF_FAT_ATTR_READONLY ) != 0 ) ? '-' : 'w'; - mode[ 3 ] = '-'; /* x for executable. */ - - mode[ 4 ] = 'r'; /* group. */ - mode[ 5 ] = ( ( pxEntry->ucAttrib & FF_FAT_ATTR_READONLY ) != 0 ) ? '-' : 'w'; - mode[ 6 ] = '-'; /* x for executable. */ - - mode[ 7 ] = 'r'; /* world. */ - mode[ 8 ] = '-'; - mode[ 9 ] = '-'; /* x for executable. */ - - if( pxCreateTime->Month && pxCreateTime->Day ) - { - snprintf( date, sizeof( date ), "%-3.3s %02d %02d:%02d", - pcMonthAbbrev( pxCreateTime->Month ), - pxCreateTime->Day, - pxCreateTime->Hour, - pxCreateTime->Minute ); - } - else - { - snprintf (date, sizeof( date ), "Jan 01 1970"); - } - return snprintf( pcLine, xMaxLength, "%s %3ld %-4s %-4s %8d %12s %s\r\n", - mode, st_nlink, user, group, ( int ) ulSize, date, pcFileName ); -} -/*-----------------------------------------------------------*/ - -/* - #### # # ##### - # # # # # # -# # # # # # -# # # # # # -# # # # # # -# # # # # # -# # ## ## # # - # # ## ## # # - #### ## ## ##### -*/ -static BaseType_t prvChangeDir( FTPClient_t *pxClient, char *pcDirectory ) -{ -BaseType_t xResult; -BaseType_t xIsRootDir, xLength, xValid; -BaseType_t xIsDotDir = 0; - - if( pcDirectory[ 0 ] == '.' ) - { - if( ( pcDirectory[ 1 ] == '.' ) && - ( pcDirectory[ 2 ] == '\0' ) ) - { - xIsDotDir = 2; - } - else if( pcDirectory[ 1 ] == '\0' ) - { - xIsDotDir = 1; - } - } - - if( xIsDotDir != 0 ) - { - strcpy( pcFILE_BUFFER, pxClient->pcCurrentDir ); - - if( pcDirectory[ 1 ] == '.' ) - { - char *p = strrchr( pcFILE_BUFFER, '/' ); - if( p != NULL ) - { - if( p == pcFILE_BUFFER ) - { - p[ 1 ] = '\0'; - } - else - { - p[ 0 ] = '\0'; - } - } - } - } - else - { - if(pcDirectory[ 0 ] != '/' ) - { - BaseType_t xCurLength; - - xCurLength = strlen( pxClient->pcCurrentDir ); - snprintf( pcFILE_BUFFER, sizeof( pcFILE_BUFFER ), "%s%s%s", - pxClient->pcCurrentDir, - pxClient->pcCurrentDir[ xCurLength - 1 ] == '/' ? "" : "/", - pcDirectory ); - } - else - { - snprintf( pcFILE_BUFFER, sizeof( pcFILE_BUFFER ), "%s", pcDirectory ); - } - } - - xIsRootDir = ( pcFILE_BUFFER[ 0 ] == '/' ) && ( pcFILE_BUFFER[ 1 ] == '\0' ); - xMakeAbsolute( pxClient, pcNEW_DIR, sizeof( pcNEW_DIR ), pcFILE_BUFFER ); - - if( ( ( xIsRootDir == pdFALSE ) || ( FF_FS_Count() == 0 ) ) && ( ff_finddir( pcNEW_DIR ) == pdFALSE ) ) - { - xValid = pdFALSE; - } - else - { - xValid = pdTRUE; - } - - if( xValid == pdFALSE ) - { - /* Get the directory cluster, if it exists. */ - FreeRTOS_printf( ("FTP: chdir \"%s\": No such dir\n", pcNEW_DIR ) ); - //#define REPL_550 "550 Requested action not taken.\r\n" - //550 /home/hein/arch/h8300: No such file or directory - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "550 %s: No such file or directory\r\n", - pcNEW_DIR ); - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - xResult = pdFALSE; - } - else - { - memcpy( pxClient->pcCurrentDir, pcNEW_DIR, sizeof( pxClient->pcCurrentDir ) ); - - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "250 Changed to %s\r\n", pcNEW_DIR ); - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - xResult = pdTRUE; - } - - return xResult; -} -/*-----------------------------------------------------------*/ - -/* -###### ## # ####### ###### - # # ## # # ## # # - # # ## # # # # # - # # ### # # # # # - ###### # ## # ##### ###### - # ## # ## # # # # ## - # # # ### # # # - # # # ## # # # -### ## # ## #### ### ## -*/ -static BaseType_t prvRenameFrom( FTPClient_t *pxClient, const char *pcFileName ) -{ -const char *myReply; -FF_FILE *fh; - - xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); - - myReply = NULL; - - fh = ff_fopen( pxClient->pcFileName, "rb" ); - - if( fh != NULL ) - { - ff_fclose( fh ); - /* REPL_350; "350 Requested file action pending further information." */ - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "350 Rename '%s' ...\r\n", pxClient->pcFileName ); - myReply = pcCOMMAND_BUFFER; - pxClient->bits.bInRename = pdTRUE_UNSIGNED; - } - else if( stdioGET_ERRNO() == pdFREERTOS_ERRNO_EISDIR ) - { - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "350 Rename directory '%s' ...\r\n", pxClient->pcFileName ); - myReply = pcCOMMAND_BUFFER; - pxClient->bits.bInRename = pdTRUE_UNSIGNED; - } - else - { - FreeRTOS_printf( ("ftp::renameFrom[%s]\n%s\n", pxClient->pcFileName, strerror( stdioGET_ERRNO() ) ) ); - myReply = REPL_451; /* "451 Requested action aborted. Local error in processing." */ - } - if( myReply ) - { - prvSendReply( pxClient->xSocket, myReply, 0 ); - } - - return pdTRUE; -} -/*-----------------------------------------------------------*/ - -/* -###### ## # ##### ### - # # ## # # # # ## ## - # # ## # # ## ## - # # ### # # # # - ###### # ## # # # # - # ## # ## # # # # - # # # ### # ## ## - # # # ## # ## ## -### ## # ## #### ### -*/ -static BaseType_t prvRenameTo( FTPClient_t *pxClient, const char *pcFileName ) -{ -const char *myReply = NULL; -int iResult; - - xMakeAbsolute( pxClient, pcNEW_DIR, sizeof( pcNEW_DIR ), pcFileName ); - - /* FreeRTOS+FAT rename has an extra parameter: "remove target if already - exists". */ - iResult = ff_rename( pxClient->pcFileName, pcNEW_DIR, pdFALSE ); - - if( iResult < 0 ) - { - iResult = stdioGET_ERRNO(); - } - else - { - iResult = 0; - } - - switch( iResult ) - { - case 0: - FreeRTOS_printf( ( "ftp::renameTo[%s,%s]: Ok\n", pxClient->pcFileName, pcNEW_DIR ) ); - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "250 Rename successful to '%s'\r\n", pcNEW_DIR ); - myReply = pcCOMMAND_BUFFER; - break; - case pdFREERTOS_ERRNO_EEXIST: - /* the destination file already exists. - "450 Requested file action not taken.\r\n"*/ - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "450 Already exists '%s'\r\n", pcNEW_DIR ); - myReply = pcCOMMAND_BUFFER; - break; - case pdFREERTOS_ERRNO_EIO: /* FF_ERR_FILE_COULD_NOT_CREATE_DIRENT */ - /* if dirent creation failed (fatal error!). - "553 Requested action not taken.\r\n" */ - FreeRTOS_printf( ("ftp::renameTo[%s,%s]: Error creating DirEnt\n", - pxClient->pcFileName, pcNEW_DIR ) ); - myReply = REPL_553; - break; - case pdFREERTOS_ERRNO_ENXIO: - case pdFREERTOS_ERRNO_ENOENT: - /* if the source file was not found. - "450 Requested file action not taken.\r\n" */ - snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "450 No such file '%s'\r\n", pxClient->pcFileName ); - myReply = pcCOMMAND_BUFFER; - break; - default: - FreeRTOS_printf( ("ftp::renameTo[%s,%s]: %s\n", pxClient->pcFileName, pcNEW_DIR, - (const char*)strerror( stdioGET_ERRNO() ) ) ); - myReply = REPL_451; /* "451 Requested action aborted. Local error in processing." */ - break; - } - prvSendReply( pxClient->xSocket, myReply, 0 ); - - return pdTRUE; -} -/*-----------------------------------------------------------*/ - -/* - #### # -# # # # -# # # -# ### ###### #### - ## # # # # - ## # # ###### -# # # # # -# # # # ## # ## - #### ##### ## #### -*/ -static BaseType_t prvSiteCmd( FTPClient_t *pxClient, char *pcRestCommand ) -{ - ( void ) pxClient; - ( void ) pcRestCommand; - - return 0; -} -/*-----------------------------------------------------------*/ - -/* -##### ### - # # # # - # # # # - # # #### # #### ###### #### - # # # # # # # # # # - # # ###### # ###### # ###### - # # # # # # # - # # # ## # # ## # ## # ## -##### #### ##### #### ## #### -*/ -static BaseType_t prvDeleteFile( FTPClient_t *pxClient, char *pcFileName ) -{ -BaseType_t xResult, xLength; -int32_t iRc; -int iErrorNo; - - /* DELE: Delete a file. */ - xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); - - iRc = ff_remove( pxClient->pcFileName ); - - if (iRc >= 0 ) - { - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "250 File \"%s\" removed\r\n", pxClient->pcFileName ); - xResult = pdTRUE; - } - else - { - const char *errMsg = "other error"; - - iErrorNo = stdioGET_ERRNO(); - switch( iErrorNo ) - { /*_RB_ What do these negative numbers relate to? */ - case pdFREERTOS_ERRNO_ENOENT: errMsg = "No such file"; break; /* -31 File was not found. */ - case pdFREERTOS_ERRNO_EALREADY: errMsg = "File still open"; break; /* -30 File is in use. */ - case pdFREERTOS_ERRNO_EISDIR: errMsg = "Is a dir"; break; /* -32 Tried to FF_Open() a Directory. */ - case pdFREERTOS_ERRNO_EROFS: errMsg = "Read-only"; break; /* -33 Tried to FF_Open() a file marked read only. */ - case pdFREERTOS_ERRNO_ENOTDIR: errMsg = "Invalid path"; break; /* -34 The path of the file was not found. */ - } - FreeRTOS_printf( ( "ftp::delFile: '%s' because %s\n", - pxClient->pcFileName, strerror( iErrorNo ) ) ); - - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "521-\"%s\" %s;\r\n" - "521 taking no action\r\n", - pxClient->pcFileName, errMsg ); - - xResult = pdFALSE; - } - - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - - return xResult; -} -/*-----------------------------------------------------------*/ - -/* - #### # ##### -# # # # # # -# # # # # -# ### ###### #### # # #### ###### #### - ## # # # # # # # # # # # - ## # # ###### # # ##### # ###### -# # # # # # # # # # # -# # # # # ## # # # # # ## # ## - #### ##### ###### #### ##### ### ## ## #### -*/ -static BaseType_t prvSizeDateFile( FTPClient_t *pxClient, char *pcFileName, BaseType_t xSendDate ) -{ -BaseType_t xResult = pdFALSE; -char *pcPtr; - - /* SIZE: get the size of a file (xSendDate = 0) - MDTM: get data and time properties (xSendDate = 1) */ - xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); - - pcPtr = strrchr( pxClient->pcFileName, '/' ); - - if( ( pcPtr != NULL ) && ( pcPtr[ 1 ] != '\0' ) ) - { - FF_Stat_t xStatBuf; - int32_t iRc = ff_stat( pxClient->pcFileName, &xStatBuf ); - if (iRc < 0 ) - FreeRTOS_printf( ("In %s: %s\n", pxClient->pcFileName, - ( const char* )strerror( stdioGET_ERRNO() ) ) ); - - if( iRc == 0 ) - { - BaseType_t xLength; - /* "YYYYMMDDhhmmss" */ - if( xSendDate != pdFALSE ) - { - #if( ffconfigTIME_SUPPORT != 0 ) - { - FF_TimeStruct_t tmStruct; - time_t secs = xStatBuf.st_mtime; - FreeRTOS_gmtime_r( &secs, &tmStruct ); - - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "213 %04u%02u%02u%02u%02u%02u\r\n", - tmStruct.tm_year + 1900, - tmStruct.tm_mon+1, - tmStruct.tm_mday, - tmStruct.tm_hour, - tmStruct.tm_min, - tmStruct.tm_sec ); - } - #else - { - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "213 19700101000000\r\n", - } - #endif - } - else - { - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "213 %lu\r\n", xStatBuf.st_size ); - } - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - xResult = pdTRUE; - } - else - { - FreeRTOS_printf( ("ftp::sizeDateFile: No such file %s\n", pxClient->pcFileName ) ); - } - } else { - FreeRTOS_printf( ("ftp::sizeDateFile: Invalid file name: %s ?\n", pxClient->pcFileName ) ); - } - if( xResult == pdFALSE ) - { - prvSendReply( pxClient->xSocket, REPL_450, 0 ); /* "Requested file action not taken". */ - } - - return xResult; -} -/*-----------------------------------------------------------*/ - -/* -## ## ## ## ##### ###### ## ## ##### -### ### # # # # # # ### ### # # -# ### # # # # # # # # ### # # # -# # # # # # # # # # # # # # -# # # #### # # ###### # # # # # -# # # # # # # ## # # # # -# # # # # # # # # # # # -# # # # # # # # # # # # -# # ### ## ##### ### ## # # ##### -*/ -static BaseType_t prvMakeRemoveDir( FTPClient_t *pxClient, const char *pcDirectory, BaseType_t xDoRemove ) -{ -BaseType_t xResult; -BaseType_t xLength; -int32_t iRc; -int iErrorNo; - - /* MKD: Make / create a directory (xDoRemove = 0) - RMD: Remove a directory (xDoRemove = 1) */ - xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcDirectory ); - - if( xDoRemove ) - { - iRc = ff_rmdir( pxClient->pcFileName ); - } - else - { - #if( ffconfigMKDIR_RECURSIVE != 0 ) - { - iRc = ff_mkdir( pxClient->pcFileName, pdFALSE ); - } - #else - { - iRc = ff_mkdir( pxClient->pcFileName ); - } - #endif /* ffconfigMKDIR_RECURSIVE */ - } - xResult = pdTRUE; - - if( iRc >= 0 ) - { - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "257 \"%s\" directory %s\r\n", - pxClient->pcFileName, xDoRemove ? "removed" : "created" ); - } - else - { - const char *errMsg = "other error"; - BaseType_t xFTPCode = 521; - - xResult = pdFALSE; - iErrorNo = stdioGET_ERRNO(); - switch( iErrorNo ) - { - case pdFREERTOS_ERRNO_EEXIST: errMsg = "Directory already exists"; break; - case pdFREERTOS_ERRNO_ENOTDIR: errMsg = "Invalid path"; break; /* -34 The path of the file was not found. *//*_RB_ As before, what do these negative numbers relate to? */ - case pdFREERTOS_ERRNO_ENOTEMPTY:errMsg = "Dir not empty"; break; - case pdFREERTOS_ERRNO_EROFS: errMsg = "Read-only"; break; /* -33 Tried to FF_Open() a file marked read only. */ - default: errMsg = strerror( iErrorNo ); break; - } - if( iErrorNo == pdFREERTOS_ERRNO_ENOSPC ) - { - xFTPCode = 552; - } - xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), - "%ld-\"%s\" %s;\r\n" - "%ld taking no action\r\n", - xFTPCode, pxClient->pcFileName, errMsg, xFTPCode ); - FreeRTOS_printf( ( "%sdir '%s': %s\n", xDoRemove ? "rm" : "mk", pxClient->pcFileName, errMsg ) ); - } - prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); - - return xResult; -} -/*-----------------------------------------------------------*/ - -static portINLINE BaseType_t IsDigit( char cChar ) -{ -BaseType_t xResult; - - if( cChar >= '0' && cChar <= '9' ) - { - xResult = pdTRUE; - } - else - { - xResult = pdFALSE; - } - return xResult; -} - -static BaseType_t prvSendReply( Socket_t xSocket, const char *pcBuffer, BaseType_t xLength ) -{ -BaseType_t xResult; - - if( xLength == 0 ) - { - xLength = strlen( pcBuffer ); - } - xResult = FreeRTOS_send( xSocket, ( const void * )pcBuffer, ( size_t ) xLength, 0 ); - if( IsDigit( ( int ) pcBuffer[ 0 ] ) && - IsDigit( ( int ) pcBuffer[ 1 ] ) && - IsDigit( ( int ) pcBuffer[ 2 ] ) && - IsDigit( ( int ) pcBuffer[ 3 ] ) ) - { - const char *last = pcBuffer + strlen( pcBuffer ); - int iLength; - while( ( last > pcBuffer ) && ( ( last[ -1 ] == ftpASCII_CR ) || ( last[ -1 ] == ftpASCII_LF ) ) ) - { - last--; - } - iLength = ( int )( last - pcBuffer ); - FF_PRINTF( " %-*.*s", iLength, iLength, pcBuffer ); - } - return xResult; -} -/*-----------------------------------------------------------*/ - -#if( ipconfigFTP_HAS_RECEIVED_HOOK != 0 ) - - /* - * The following function is called for every file received: - * void vApplicationFTPReceivedHook( pcFileName, ulSize, pxFTPClient ); - * This callback function may do a callback to vFTPReplyMessage() to send messages - * to the FTP client like: - * 200-Please wait: Received new firmware - * 200-Please wait: Please wait a few seconds for reboot - */ - void vFTPReplyMessage( struct xFTP_CLIENT *pxFTPClient, const char *pcMessage ) - { - if( ( pxFTPClient != NULL ) && ( pxFTPClient->xSocket != NULL ) ) - { - prvSendReply( pxFTPClient->xSocket, pcMessage, 0 ); - } - } - /*-----------------------------------------------------------*/ - -#endif /* ipconfigFTP_HAS_RECEIVED_HOOK != 0 */ - -/* - * Some explanation: - * The FTP client may send: "DELE readme.txt" - * Here the complete path is constructed consisting of 3 parts: - * - * pxClient->pcRootDir + pxClient->pcCurrentDir + pcFileName - * - * 'pcCurrentDir' will not be applied for an absolute path like in "DELE /.htaccess" - */ -BaseType_t xMakeAbsolute( FTPClient_t *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName ) -{ -BaseType_t xLength = strlen( pxClient->pcRootDir ); - - if( pcFileName[ 0 ] != '/' ) - { - char *pcNewDirBuffer = pcNEW_DIR; - BaseType_t xCurLength; - - xCurLength = strlen( pxClient->pcCurrentDir ); - if( pcBuffer == pcNEW_DIR ) - { - /* In one call, the result already goes into pcNEW_DIR. - Use pcFILE_BUFFER in that case */ - pcNewDirBuffer = pcFILE_BUFFER; - } - snprintf( pcNewDirBuffer, sizeof( pcNEW_DIR ), "%s%s%s", - pxClient->pcCurrentDir, - pxClient->pcCurrentDir[ xCurLength - 1 ] == '/' ? "" : "/", - pcFileName ); - pcFileName = pcNewDirBuffer; - } - if( strncasecmp( pxClient->pcRootDir, pcFileName, xLength ) == 0 ) - { - xLength = snprintf( pcBuffer, xBufferLength, "%s", pcFileName ); - } - else - { - xLength = snprintf( pcBuffer, xBufferLength, "%s/%s", - pxClient->pcRootDir, - pcFileName[ 0 ] == '/' ? ( pcFileName + 1 ) : pcFileName ); - } - - #if( ipconfigFTP_FS_USES_BACKSLAH == 1 ) - for( pcPtr = pcBuffer; *pcPtr; pcPtr++ ) - { - if( pcPtr[ 0 ] == '/' ) - { - pcPtr[ 0 ] = '\\'; - } - } - #endif - - return xLength; -} -/*-----------------------------------------------------------*/ - -BaseType_t xMakeRelative( FTPClient_t *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName ) -{ -BaseType_t xLength = strlen( pxClient->pcRootDir ); - - if( strncasecmp ( pxClient->pcRootDir, pcFileName, xLength ) == 0 ) - { - xLength = snprintf( pcBuffer, xBufferLength, "%s", pcFileName + xLength ); - } - else - { - xLength = snprintf( pcBuffer, xBufferLength, "%s", pcFileName ); - } - - return xLength; -} -/*-----------------------------------------------------------*/ - -#endif /* ipconfigUSE_FTP */ - - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + *! + *! The protocols implemented in this file are intended to be demo quality only, + *! and not for production devices. + *! + */ + +/* Standard includes. */ +#include +#include +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "portmacro.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_TCP_IP.h" +#include "FreeRTOS_Sockets.h" +#include "FreeRTOS_Stream_Buffer.h" + +/* FreeRTOS Protocol includes. */ +#include "FreeRTOS_FTP_commands.h" +#include "FreeRTOS_TCP_server.h" +#include "FreeRTOS_server_private.h" + +/* Remove the whole file if FTP is not supported. */ +#if ( ipconfigUSE_FTP == 1 ) + + #ifndef HTTP_SERVER_BACKLOG + #define HTTP_SERVER_BACKLOG ( 12 ) + #endif + + #if !defined( ARRAY_SIZE ) + #define ARRAY_SIZE( x ) ( BaseType_t ) ( sizeof( x ) / sizeof( x )[ 0 ] ) + #endif + + #if defined( __WIN32__ ) && !defined( ipconfigFTP_FS_USES_BACKSLASH ) + #define ipconfigFTP_FS_USES_BACKSLASH 1 + #endif + +/* Some defines to make the code more readbale */ + #define pcCOMMAND_BUFFER pxClient->pxParent->pcCommandBuffer + #define pcNEW_DIR pxClient->pxParent->pcNewDir + #define pcFILE_BUFFER pxClient->pxParent->pcFileBuffer + +/* This FTP server will only do binary transfers */ + #define TMODE_BINARY 1 + #define TMODE_ASCII 2 + #define TMODE_7BITS 3 + #define TMODE_8BITS 4 + +/* Ascii character definitions. */ + #define ftpASCII_CR 13 + #define ftpASCII_LF 10 + + #if defined( FTP_WRITES_ALIGNED ) || defined( ipconfigFTP_WRITES_ALIGNED ) + #error Name change : please rename the define to the new name 'ipconfigFTP_ZERO_COPY_ALIGNED_WRITES' + #endif + +/* + * ipconfigFTP_ZERO_COPY_ALIGNED_WRITES : experimental optimisation option. + * If non-zero, receiving data will be done with the zero-copy method and also + * writes to disk will be done with sector-alignment as much as possible. + */ + #ifndef ipconfigFTP_ZERO_COPY_ALIGNED_WRITES + #define ipconfigFTP_ZERO_COPY_ALIGNED_WRITES 0 + #endif + +/* + * This module only has 2 public functions: + */ + BaseType_t xFTPClientWork( TCPClient_t * pxClient ); + void vFTPClientDelete( TCPClient_t * pxClient ); + +/* + * Process a single command. + */ + static BaseType_t prvProcessCommand( FTPClient_t * pxClient, + BaseType_t xIndex, + char * pcRestCommand ); + +/* + * Create a socket for a data connection to the FTP client. + */ + static BaseType_t prvTransferConnect( FTPClient_t * pxClient, + BaseType_t xDoListen ); + +/* + * Either call listen() or connect() to start the transfer connection. + */ + static BaseType_t prvTransferStart( FTPClient_t * pxClient ); + +/* + * See if the socket has got connected or disconnected. Close the socket if + * necessary. + */ + static void prvTransferCheck( FTPClient_t * pxClient ); + +/* + * Close the data socket and issue some informative logging. + */ + static void prvTransferCloseSocket( FTPClient_t * pxClient ); + +/* + * Close the file handle (pxReadHandle or pxWriteHandle). + */ + static void prvTransferCloseFile( FTPClient_t * pxClient ); + +/* + * Close a directory (-handle). + */ + static void prvTransferCloseDir( FTPClient_t * pxClient ); + +/* + * Translate a string (indicating a transfer type) to a number. + */ + static BaseType_t prvGetTransferType( const char * pcType ); + + #if ( ipconfigHAS_PRINTF != 0 ) + +/* + * For nice logging: write an amount (number of bytes), e.g. 3512200 as + * "3.45 MB" + */ + static const char * pcMkSize( uint32_t ulAmount, + char * pcBuffer, + BaseType_t xBufferSize ); + #endif + + #if ( ipconfigHAS_PRINTF != 0 ) + +/* + * Calculate the average as bytes-per-second, when amount and milliseconds + * are known. + */ + static uint32_t ulGetAverage( uint32_t ulAmount, + TickType_t xDeltaMs ); + #endif + +/* + * A port command looks like: PORT h1,h2,h3,h4,p1,p2. Parse it and translate it + * to an IP-address and a port number. + */ + static UBaseType_t prvParsePortData( const char * pcCommand, + uint32_t * pulIPAddress ); + +/* + * CWD: Change current working directory. + */ + + static BaseType_t prvChangeDir( FTPClient_t * pxClient, + char * pcDirectory ); + +/* + * RNFR: Rename from ... + */ + static BaseType_t prvRenameFrom( FTPClient_t * pxClient, + const char * pcFileName ); + +/* + * RNTO: Rename to ... + */ + static BaseType_t prvRenameTo( FTPClient_t * pxClient, + const char * pcFileName ); + +/* + * SITE: Change file permissions. + */ + static BaseType_t prvSiteCmd( FTPClient_t * pxClient, + char * pcRestCommand ); + +/* + * DELE: Delete a file. + */ + static BaseType_t prvDeleteFile( FTPClient_t * pxClient, + char * pcFileName ); + +/* + * SIZE: get the size of a file (xSendDate = 0). + * MDTM: get data and time properties (xSendDate = 1). + */ + static BaseType_t prvSizeDateFile( FTPClient_t * pxClient, + char * pcFileName, + BaseType_t xSendDate ); + +/* + * MKD: Make / create a directory (xDoRemove = 0). + * RMD: Remove a directory (xDoRemove = 1). + */ + static BaseType_t prvMakeRemoveDir( FTPClient_t * pxClient, + const char * pcDirectory, + BaseType_t xDoRemove ); + +/* + * The next three commands: LIST, RETR and STOR all require a data socket. + * The data connection is either started with a 'PORT' or a 'PASV' command. + * Each of the commands has a prepare- (Prep) and a working- (Work) function. + * The Work function should be called as long as the data socket is open, and + * there is data to be transmitted. + */ + +/* + * LIST: Send a directory listing in Unix style. + */ + static BaseType_t prvListSendPrep( FTPClient_t * pxClient ); + static BaseType_t prvListSendWork( FTPClient_t * pxClient ); + +/* + * RETR: Send a file to the FTP client. + */ + static BaseType_t prvRetrieveFilePrep( FTPClient_t * pxClient, + char * pcFileName ); + static BaseType_t prvRetrieveFileWork( FTPClient_t * pxClient ); + +/* + * STOR: Receive a file from the FTP client and store it. + */ + static BaseType_t prvStoreFilePrep( FTPClient_t * pxClient, + char * pcFileName ); + static BaseType_t prvStoreFileWork( FTPClient_t * pxClient ); + +/* + * Print/format a single directory entry in Unix style. + */ + static BaseType_t prvGetFileInfoStat( FF_DirEnt_t * pxEntry, + char * pcLine, + BaseType_t xMaxLength ); + +/* + * Send a reply to a socket, either the command- or the data-socket. + */ + static BaseType_t prvSendReply( Socket_t xSocket, + const char * pcBuffer, + BaseType_t xLength ); + +/* + * Prepend the root directory (if any), plus the current working directory + * (always), to get an absolute path. + */ + BaseType_t xMakeAbsolute( FTPClient_t * pxClient, + char * pcBuffer, + BaseType_t xBufferLength, + const char * pcPath ); + +/* + * + ####### ##### ###### # # ## + # ## # # # # # # # # + # # # # # # # + # # # # # # # #### ### ## # # + ##### # ##### # # # # # # # # # # + # # # # # # # # # ## # #### + # # # ## ## # # # # # + # # # ## ## # # # # # + #### #### #### ## ## #### #### ## ## + #### + * xFTPClientWork() + * will be called by FreeRTOS_TCPServerWork(), after select has expired(). + * FD_ISSET will not be used. This work function will always be called at + * regular intervals, and also after a select() event has occurred. + */ + BaseType_t xFTPClientWork( TCPClient_t * pxTCPClient ) + { + FTPClient_t * pxClient = ( FTPClient_t * ) pxTCPClient; + BaseType_t xRc; + + if( pxClient->bits.bHelloSent == pdFALSE_UNSIGNED ) + { + BaseType_t xLength; + + pxClient->bits.bHelloSent = pdTRUE_UNSIGNED; + + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "220 Welcome to the FreeRTOS+TCP FTP server\r\n" ); + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + } + + /* Call recv() in a non-blocking way, to see if there is an FTP command + * sent to this server. */ + xRc = FreeRTOS_recv( pxClient->xSocket, ( void * ) pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), 0 ); + + if( xRc > 0 ) + { + BaseType_t xIndex; + const FTPCommand_t * pxCommand; + char * pcRestCommand; + + if( xRc < ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) ) + { + pcCOMMAND_BUFFER[ xRc ] = '\0'; + } + + while( xRc && ( ( pcCOMMAND_BUFFER[ xRc - 1 ] == ftpASCII_CR ) || ( pcCOMMAND_BUFFER[ xRc - 1 ] == ftpASCII_LF ) ) ) + { + pcCOMMAND_BUFFER[ --xRc ] = '\0'; + } + + /* Now iterate through a list of FTP commands, and look for a match. */ + pxCommand = xFTPCommands; + pcRestCommand = pcCOMMAND_BUFFER; + + for( xIndex = 0; xIndex < FTP_CMD_COUNT - 1; xIndex++, pxCommand++ ) + { + BaseType_t xLength; + + /* The length of each command is stored as well, just to be a bit + * quicker here. */ + xLength = pxCommand->xCommandLength; + + if( ( xRc >= xLength ) && ( memcmp( ( const void * ) pxCommand->pcCommandName, ( const void * ) pcCOMMAND_BUFFER, xLength ) == 0 ) ) + { + /* A match with an existing command is found. Skip any + * whitespace to get the first parameter. */ + pcRestCommand += xLength; + + while( ( *pcRestCommand == ' ' ) || ( *pcRestCommand == '\t' ) ) + { + pcRestCommand++; + } + + break; + } + } + + /* If the command received was not recognised, xIndex will point to a + * fake entry called 'ECMD_UNKNOWN'. */ + prvProcessCommand( pxClient, xIndex, pcRestCommand ); + } + else if( xRc < 0 ) + { + /* The connection will be closed and the client will be deleted. */ + FreeRTOS_printf( ( "xFTPClientWork: xRc = %ld\n", xRc ) ); + } + + /* Does it have an open data connection? */ + if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) + { + /* See if the connection has changed. */ + prvTransferCheck( pxClient ); + + /* "pcConnectionAck" contains a string like: + * "Response: 150 Accepted data connection from 192.168.2.3:6789" + * The socket can only be used once this acknowledgement has been sent. */ + if( ( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) && ( pxClient->pcConnectionAck[ 0 ] == '\0' ) ) + { + BaseType_t xClientRc = 0; + + if( pxClient->bits1.bDirHasEntry ) + { + /* Still listing a directory. */ + xClientRc = prvListSendWork( pxClient ); + } + else if( pxClient->pxReadHandle != NULL ) + { + /* Sending a file. */ + xClientRc = prvRetrieveFileWork( pxClient ); + } + else if( pxClient->pxWriteHandle != NULL ) + { + /* Receiving a file. */ + xClientRc = prvStoreFileWork( pxClient ); + } + + if( xClientRc < 0 ) + { + prvTransferCloseSocket( pxClient ); + prvTransferCloseFile( pxClient ); + } + } + } + + return xRc; + } +/*-----------------------------------------------------------*/ + + static void prvTransferCloseDir( FTPClient_t * pxClient ) + { + /* Nothing to close for +FAT. */ + ( void ) pxClient; + } +/*-----------------------------------------------------------*/ + + void vFTPClientDelete( TCPClient_t * pxTCPClient ) + { + FTPClient_t * pxClient = ( FTPClient_t * ) pxTCPClient; + + /* Close any directory-listing-handles (not used by +FAT ). */ + prvTransferCloseDir( pxClient ); + /* Close the data-socket. */ + prvTransferCloseSocket( pxClient ); + /* Close any open file handle. */ + prvTransferCloseFile( pxClient ); + + /* Close the FTP command socket */ + if( pxClient->xSocket != FREERTOS_NO_SOCKET ) + { + FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_ALL ); + FreeRTOS_closesocket( pxClient->xSocket ); + pxClient->xSocket = FREERTOS_NO_SOCKET; + } + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvProcessCommand( FTPClient_t * pxClient, + BaseType_t xIndex, + char * pcRestCommand ) + { + const FTPCommand_t * pxFTPCommand = &( xFTPCommands[ xIndex ] ); + const char * pcMyReply = NULL; + BaseType_t xResult = 0; + + if( ( pxFTPCommand->ucCommandType != ECMD_PASS ) && ( pxFTPCommand->ucCommandType != ECMD_PORT ) ) + { + FreeRTOS_printf( ( " %s %s\n", pxFTPCommand->pcCommandName, pcRestCommand ) ); + } + + if( ( pxFTPCommand->checkLogin != pdFALSE ) && ( pxClient->bits.bLoggedIn == pdFALSE_UNSIGNED ) ) + { + pcMyReply = REPL_530; /* Please first log in. */ + } + else if( ( pxFTPCommand->checkNullArg != pdFALSE ) && ( ( pcRestCommand == NULL ) || ( pcRestCommand[ 0 ] == '\0' ) ) ) + { + pcMyReply = REPL_501; /* Command needs a parameter. */ + } + + if( pcMyReply == NULL ) + { + switch( pxFTPCommand->ucCommandType ) + { + case ECMD_USER: /* User. */ + /* User name has been entered, expect password. */ + pxClient->bits.bStatusUser = pdTRUE_UNSIGNED; + + #if ( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 ) /*_RB_ Needs defaulting and adding to the web documentation. */ + { + /* Save the user name in 'pcFileName'. */ + snprintf( pxClient->pcFileName, sizeof( pxClient->pcFileName ), "%s", pcRestCommand ); + + /* The USER name is presented to the application. The function + * may return a const string like "331 Please enter your + * password\r\n". */ + pcMyReply = pcApplicationFTPUserHook( pxClient->pcFileName ); + + if( pcMyReply == NULL ) + { + pcMyReply = REPL_331_ANON; + } + } + #else /* if ( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 ) */ + { + /* No password checks, any password will be accepted. */ + pcMyReply = REPL_331_ANON; + } + #endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 */ + + #if ( ipconfigFTP_HAS_USER_PROPERTIES_HOOK != 0 ) /*_RB_ Needs defaulting and adding to the web documentation. */ + { + FTPUserProperties_t xProperties; + + xProperties.pcRootDir = pxClient->pcRootDir; + xProperties.xReadOnly = pdFALSE; + xProperties.usPortNumber = pxClient->usClientPort; + vApplicationFTPUserPropertiesHook( pxClient->pcFileName, &( xProperties ) ); + + if( xProperties.pcRootDir != NULL ) + { + pxClient->pcRootDir = xProperties.pcRootDir; + } + + pxClient->bits.bReadOnly = ( xProperties.xReadOnly != pdFALSE_UNSIGNED ); + } + #endif /* ipconfigFTP_HAS_USER_PROPERTIES_HOOK */ + break; + + case ECMD_PASS: /* Password. */ + pxClient->ulRestartOffset = 0; + + if( pxClient->bits.bStatusUser == pdFALSE_UNSIGNED ) + { + pcMyReply = REPL_503; /* "503 Bad sequence of commands.\r\n". */ + } + else + { + BaseType_t xAllow; + + pxClient->bits.bStatusUser = pdFALSE_UNSIGNED; + #if ( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 ) + { + xAllow = xApplicationFTPPasswordHook( pxClient->pcFileName, pcRestCommand ); + } + #else + { + xAllow = 1; + } + #endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */ + + if( xAllow > 0 ) + { + pxClient->bits.bLoggedIn = pdTRUE_UNSIGNED; /* Client has now logged in. */ + pcMyReply = "230 OK. Current directory is /\r\n"; + } + else + { + pcMyReply = "530 Login incorrect\r\n"; /* 530 Login incorrect. */ + } + + strcpy( pxClient->pcCurrentDir, ( const char * ) "/" ); + } + + break; + + case ECMD_SYST: /* System. */ + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "215 UNIX Type: L8\r\n" ); + pcMyReply = pcCOMMAND_BUFFER; + break; + + case ECMD_PWD: /* Get working directory. */ + xMakeRelative( pxClient, pcFILE_BUFFER, sizeof( pcFILE_BUFFER ), pxClient->pcCurrentDir ); + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), REPL_257_PWD, pcFILE_BUFFER ); + pcMyReply = pcCOMMAND_BUFFER; + break; + + case ECMD_REST: + + if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) + { + pcMyReply = REPL_553_READ_ONLY; + } + else + { + const char * pcPtr = pcRestCommand; + + while( *pcPtr == ' ' ) + { + pcPtr++; + } + + if( ( *pcPtr >= '0' ) && ( *pcPtr <= '9' ) ) + { + sscanf( pcPtr, "%lu", &pxClient->ulRestartOffset ); + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "350 Restarting at %lu. Send STORE or RETRIEVE\r\n", pxClient->ulRestartOffset ); + pcMyReply = pcCOMMAND_BUFFER; + } + else + { + pcMyReply = REPL_500; /* 500 Syntax error, command unrecognised. */ + } + } + + break; + + case ECMD_NOOP: /* NOP operation */ + + if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) + { + pcMyReply = REPL_200_PROGRESS; + } + else + { + pcMyReply = REPL_200; + } + + break; + + case ECMD_TYPE: /* Ask or set transfer type. */ + { + /* e.g. "TYPE I" for Images (binary). */ + BaseType_t xType = prvGetTransferType( pcRestCommand ); + + if( xType < 0 ) + { + /* TYPE not recognised. */ + pcMyReply = REPL_500; + } + else + { + pxClient->xTransType = xType; + pcMyReply = REPL_200; + } + } + break; + + case ECMD_PASV: /* Enter passive mode. */ + + /* Connect passive: Server will listen() and wait for a connection. + * Start up a new data connection with 'xDoListen' set to true. */ + if( prvTransferConnect( pxClient, pdTRUE ) != pdTRUE ) + { + pcMyReply = REPL_502; + } + else + { + uint32_t ulIP; + uint16_t ulPort; + struct freertos_sockaddr xLocalAddress; + struct freertos_sockaddr xRemoteAddress; + + FreeRTOS_GetLocalAddress( pxClient->xTransferSocket, &xLocalAddress ); + FreeRTOS_GetRemoteAddress( pxClient->xSocket, &xRemoteAddress ); + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + ulIP = FreeRTOS_ntohl( xLocalAddress.sin_address.ulIP_IPv4 ); + pxClient->ulClientIP = FreeRTOS_ntohl( xRemoteAddress.sin_address.ulIP_IPv4 ); + } + #else + { + ulIP = FreeRTOS_ntohl( xLocalAddress.sin_addr ); + pxClient->ulClientIP = FreeRTOS_ntohl( xRemoteAddress.sin_addr ); + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + ulPort = FreeRTOS_ntohs( xLocalAddress.sin_port ); + + pxClient->usClientPort = FreeRTOS_ntohs( xRemoteAddress.sin_port ); + + /* REPL_227_D "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d). */ + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), REPL_227_D, + ( unsigned ) ulIP >> 24, + ( unsigned ) ( ulIP >> 16 ) & 0xFF, + ( unsigned ) ( ulIP >> 8 ) & 0xFF, + ( unsigned ) ulIP & 0xFF, + ( unsigned ) ulPort >> 8, + ( unsigned ) ulPort & 0xFF ); + + pcMyReply = pcCOMMAND_BUFFER; + } + + break; + + case ECMD_PORT: /* Active connection to the client. */ + + /* The client uses this command to tell the server to what + * client-side port the server should contact; use of this command + * indicates an active data transfer. e.g. PORT 192,168,1,2,4,19. */ + { + uint32_t ulIPAddress = 0; + UBaseType_t uxPort; + + uxPort = prvParsePortData( pcRestCommand, &ulIPAddress ); + FreeRTOS_printf( ( " PORT %lxip:%ld\n", ulIPAddress, uxPort ) ); + + if( uxPort == 0u ) + { + pcMyReply = REPL_501; + } + else if( prvTransferConnect( pxClient, pdFALSE ) != pdTRUE ) + { + /* Call prvTransferConnect() with 'xDoListen' = false for an + * active connect(). */ + pcMyReply = REPL_501; + } + else + { + pxClient->usClientPort = ( uint16_t ) uxPort; + pxClient->ulClientIP = ulIPAddress; + FreeRTOS_printf( ( "Client address %lxip:%lu\n", ulIPAddress, uxPort ) ); + pcMyReply = REPL_200; + } + } + break; + + case ECMD_CWD: /* Change current working directory. */ + prvChangeDir( pxClient, pcRestCommand ); + break; + + case ECMD_RNFR: + + if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) + { + pcMyReply = REPL_553_READ_ONLY; + } + else + { + prvRenameFrom( pxClient, pcRestCommand ); + } + + break; + + case ECMD_RNTO: + + if( pxClient->bits.bInRename == pdFALSE_UNSIGNED ) + { + pcMyReply = REPL_503; /* "503 Bad sequence of commands. */ + } + else + { + prvRenameTo( pxClient, pcRestCommand ); + } + + break; + + case ECMD_SITE: /* Set file permissions */ + + if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) + { + pcMyReply = REPL_553_READ_ONLY; + } + else if( prvSiteCmd( pxClient, pcRestCommand ) == pdFALSE ) + { + pcMyReply = REPL_202; + } + + break; + + case ECMD_DELE: + + if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) + { + pcMyReply = REPL_553_READ_ONLY; + } + else + { + prvDeleteFile( pxClient, pcRestCommand ); + } + + break; + + case ECMD_MDTM: + prvSizeDateFile( pxClient, pcRestCommand, pdTRUE ); + break; + + case ECMD_SIZE: + + if( pxClient->pxWriteHandle != NULL ) + { + /* This SIZE query is probably about a file which is now being + * received. If so, return the value of pxClient->ulRecvBytes, + * pcRestCommand points to 'pcCommandBuffer', make it free by + * copying it to pcNewDir. */ + + xMakeAbsolute( pxClient, pcNEW_DIR, sizeof( pcNEW_DIR ), pcRestCommand ); + + if( strcmp( pcNEW_DIR, pcRestCommand ) == 0 ) + { + BaseType_t xCount; + + for( xCount = 0; xCount < 3 && pxClient->pxWriteHandle; xCount++ ) + { + prvStoreFileWork( pxClient ); + } + + if( pxClient->pxWriteHandle != NULL ) + { + /* File being queried is still open, return number of + * bytes received until now. */ + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "213 %lu\r\n", pxClient->ulRecvBytes ); + pcMyReply = pcCOMMAND_BUFFER; + } /* otherwise, do a normal stat(). */ + } + + strcpy( pcRestCommand, pcNEW_DIR ); + } + + if( pcMyReply == NULL ) + { + prvSizeDateFile( pxClient, pcRestCommand, pdFALSE ); + } + + break; + + case ECMD_MKD: + case ECMD_RMD: + + if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) + { + pcMyReply = REPL_553_READ_ONLY; + } + else + { + prvMakeRemoveDir( pxClient, pcRestCommand, pxFTPCommand->ucCommandType == ECMD_RMD ); + } + + break; + + case ECMD_CDUP: + prvChangeDir( pxClient, ".." ); + break; + + case ECMD_QUIT: + prvSendReply( pxClient->xSocket, REPL_221, 0 ); + pxClient->bits.bLoggedIn = pdFALSE_UNSIGNED; + break; + + case ECMD_LIST: + case ECMD_RETR: + case ECMD_STOR: + + if( ( pxClient->xTransferSocket == FREERTOS_NO_SOCKET ) && + ( ( pxFTPCommand->ucCommandType != ECMD_STOR ) || + ( pxClient->bits1.bEmptyFile == pdFALSE_UNSIGNED ) ) ) + { + /* Sending "425 Can't open data connection." : + * Before receiving any of these commands, there must have been a + * PORT or PASV command, which causes the creation of a data socket. */ + + /* There is one exception: a STOR command is received while the + * data connection has already been closed. This is tested with the + * 'bEmptyFile' flag. */ + pcMyReply = REPL_425; + } + else + { + /* In case an empty file was received ( bits1.bEmptyFile ), the + * transfer socket never delivered any data. Check if the transfer + * socket is still open: */ + if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) + { + prvTransferCheck( pxClient ); + } + + switch( pxFTPCommand->ucCommandType ) + { + case ECMD_LIST: + prvListSendPrep( pxClient ); + break; + + case ECMD_RETR: + prvRetrieveFilePrep( pxClient, pcRestCommand ); + break; + + case ECMD_STOR: + + if( pxClient->bits.bReadOnly != pdFALSE_UNSIGNED ) + { + pcMyReply = REPL_553_READ_ONLY; + } + else + { + prvStoreFilePrep( pxClient, pcRestCommand ); + + if( pxClient->bits1.bEmptyFile != pdFALSE_UNSIGNED ) + { + /* Although the 'xTransferSocket' is closed already, + * call this function just for the logging. */ + prvTransferCloseSocket( pxClient ); + + /* Close an empty file. */ + prvTransferCloseFile( pxClient ); + } + } + + break; + } + } + + break; + + case ECMD_FEAT: + { + static const char pcFeatAnswer[] = + "211-Features:\x0a" + + /* The MDTM command is only allowed when + * there is support for date&time. */ + #if ( ffconfigTIME_SUPPORT != 0 ) + " MDTM\x0a" + #endif + " REST STREAM\x0a" + " SIZE\x0d\x0a" + "211 End\x0d\x0a"; + pcMyReply = pcFeatAnswer; + } + break; + + case ECMD_UNKNOWN: + FreeRTOS_printf( ( "ftp::processCmd: Cmd %s unknown\n", pcRestCommand ) ); + pcMyReply = REPL_500; + break; + } + } + + if( pxFTPCommand->ucCommandType != ECMD_RNFR ) + { + pxClient->bits.bInRename = pdFALSE_UNSIGNED; + } + + if( pcMyReply != NULL ) + { + xResult = prvSendReply( pxClient->xSocket, pcMyReply, strlen( pcMyReply ) ); + } + + return xResult; + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvTransferConnect( FTPClient_t * pxClient, + BaseType_t xDoListen ) + { + Socket_t xSocket; + BaseType_t xResult; + + /* Open a socket for a data connection with the FTP client. + * Happens after a PORT or a PASV command. */ + + /* Make sure the previous socket is deleted and flags reset */ + prvTransferCloseSocket( pxClient ); + + pxClient->bits1.bEmptyFile = pdFALSE_UNSIGNED; + + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); + + if( ( xSocket != FREERTOS_NO_SOCKET ) && ( xSocket != FREERTOS_INVALID_SOCKET ) ) + { + BaseType_t xSmallTimeout = pdMS_TO_TICKS( 100 ); + struct freertos_sockaddr xAddress; + + #if ( ipconfigFTP_TX_BUFSIZE > 0 ) + WinProperties_t xWinProps; + #endif + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xAddress.sin_address.ulIP_IPv4 = FreeRTOS_GetIPAddress(); /* Single NIC, currently not used */ + } + #else + { + xAddress.sin_addr = FreeRTOS_GetIPAddress(); /* Single NIC, currently not used */ + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xAddress.sin_port = FreeRTOS_htons( 0 ); /* Bind to any available port number */ + xAddress.sin_family = FREERTOS_AF_INET; + + BaseType_t xBindResult; + xBindResult = FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) ); + + if( xBindResult != 0 ) + { + FreeRTOS_printf( ( "FreeRTOS_bind() failed\n" ) ); + return xBindResult; + } + + #if ( ipconfigFTP_TX_BUFSIZE > 0 ) + { + /* Fill in the buffer and window sizes that will be used by the + * socket. */ + xWinProps.lTxBufSize = ipconfigFTP_TX_BUFSIZE; + xWinProps.lTxWinSize = ipconfigFTP_TX_WINSIZE; + xWinProps.lRxBufSize = ipconfigFTP_RX_BUFSIZE; + xWinProps.lRxWinSize = ipconfigFTP_RX_WINSIZE; + + /* Set the window and buffer sizes. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); + } + #endif /* if ( ipconfigFTP_TX_BUFSIZE > 0 ) */ + + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xSmallTimeout, sizeof( BaseType_t ) ); + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xSmallTimeout, sizeof( BaseType_t ) ); + + /* The same instance of the socket will be used for the connection and + * data transport. */ + if( xDoListen != pdFALSE ) + { + BaseType_t xTrueValue = pdTRUE; + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_REUSE_LISTEN_SOCKET, ( void * ) &xTrueValue, sizeof( xTrueValue ) ); + } + + pxClient->bits1.bIsListen = xDoListen; + pxClient->xTransferSocket = xSocket; + + if( xDoListen != pdFALSE ) + { + FreeRTOS_FD_SET( xSocket, pxClient->pxParent->xSocketSet, eSELECT_EXCEPT | eSELECT_READ ); + /* Calling FreeRTOS_listen( ) */ + xResult = prvTransferStart( pxClient ); + + if( xResult >= 0 ) + { + xResult = pdTRUE; + } + } + else + { + FreeRTOS_FD_SET( xSocket, pxClient->pxParent->xSocketSet, eSELECT_EXCEPT | eSELECT_READ | eSELECT_WRITE ); + xResult = pdTRUE; + } + } + else + { + FreeRTOS_printf( ( "FreeRTOS_socket() failed\n" ) ); + xResult = -pdFREERTOS_ERRNO_ENOMEM; + } + + /* An active socket (PORT) should connect() later. */ + return xResult; + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvTransferStart( FTPClient_t * pxClient ) + { + BaseType_t xResult; + + /* A transfer socket has been opened, now either call listen() for 'PASV' + * or connect() for the 'PORT' command. */ + if( pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ) + { + xResult = FreeRTOS_listen( pxClient->xTransferSocket, 1 ); + } + else + { + struct freertos_sockaddr xAddress; + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xAddress.sin_address.ulIP_IPv4 = FreeRTOS_htonl( pxClient->ulClientIP ); + } + #else + { + xAddress.sin_addr = FreeRTOS_htonl( pxClient->ulClientIP ); + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + + xAddress.sin_port = FreeRTOS_htons( pxClient->usClientPort ); + xAddress.sin_family = FREERTOS_AF_INET; + + /* Start an active connection for this data socket */ + xResult = FreeRTOS_connect( pxClient->xTransferSocket, &xAddress, sizeof( xAddress ) ); + } + + return xResult; + } +/*-----------------------------------------------------------*/ + + static void prvTransferCheck( FTPClient_t * pxClient ) + { + BaseType_t xRxSize; + + /* A data transfer is busy. Check if there are changes in connectedness. */ + xRxSize = FreeRTOS_rx_size( pxClient->xTransferSocket ); + + if( pxClient->bits1.bClientConnected == pdFALSE_UNSIGNED ) + { + /* The time to receive a small file can be so short, that we don't even + * see that the socket gets connected and disconnected. Therefore, check + * the sizeof of the RX buffer. */ + { + struct freertos_sockaddr xAddress; + Socket_t xNexSocket; + socklen_t xSocketLength = sizeof( xAddress ); + + if( pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ) + { + xNexSocket = FreeRTOS_accept( pxClient->xTransferSocket, &xAddress, &xSocketLength ); + + if( ( ( xNexSocket != FREERTOS_NO_SOCKET ) && ( xNexSocket != FREERTOS_INVALID_SOCKET ) ) || + ( xRxSize > 0 ) ) + { + pxClient->bits1.bClientConnected = pdTRUE_UNSIGNED; + } + } + else + { + if( ( FreeRTOS_issocketconnected( pxClient->xTransferSocket ) > 0 ) || + ( xRxSize > 0 ) ) + { + pxClient->bits1.bClientConnected = pdTRUE_UNSIGNED; + } + } + + if( pxClient->bits1.bClientConnected != pdFALSE_UNSIGNED ) + { + pxClient->bits1.bEmptyFile = pdFALSE_UNSIGNED; + #if ( ipconfigHAS_PRINTF != 0 ) + { + struct freertos_sockaddr xRemoteAddress, xLocalAddress; + FreeRTOS_GetRemoteAddress( pxClient->xTransferSocket, &xRemoteAddress ); + FreeRTOS_GetLocalAddress( pxClient->xTransferSocket, &xLocalAddress ); + FreeRTOS_printf( ( "%s Connected from %u to %u\n", + pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ? "PASV" : "PORT", + ( unsigned ) FreeRTOS_ntohs( xLocalAddress.sin_port ), + ( unsigned ) FreeRTOS_ntohs( xRemoteAddress.sin_port ) ) ); + } + #endif /* ipconfigHAS_PRINTF */ + FreeRTOS_FD_CLR( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); + FreeRTOS_FD_SET( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_READ | eSELECT_EXCEPT ); + } + } + } + + if( pxClient->bits1.bClientConnected != pdFALSE_UNSIGNED ) + { + if( pxClient->pcConnectionAck[ 0 ] != '\0' ) + { + BaseType_t xLength; + BaseType_t xRemotePort; + struct freertos_sockaddr xRemoteAddress; + + FreeRTOS_GetRemoteAddress( pxClient->xTransferSocket, &xRemoteAddress ); + xRemotePort = FreeRTOS_ntohs( xRemoteAddress.sin_port ); + + /* Tell on the command port 21 we have a data connection */ + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + pxClient->pcConnectionAck, pxClient->ulClientIP, xRemotePort ); + + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + pxClient->pcConnectionAck[ 0 ] = '\0'; + } + + if( ( FreeRTOS_issocketconnected( pxClient->xTransferSocket ) == pdFALSE ) && ( FreeRTOS_rx_size( pxClient->xTransferSocket ) == 0 ) ) + { + prvTransferCloseSocket( pxClient ); + prvTransferCloseFile( pxClient ); + } + } + } +/*-----------------------------------------------------------*/ + + static void prvTransferCloseSocket( FTPClient_t * pxClient ) + { + if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) + { + /* DEBUGGING ONLY */ + BaseType_t xRxSize = FreeRTOS_rx_size( pxClient->xTransferSocket ); + + if( xRxSize > 0 ) + { + BaseType_t xRxSize2; + BaseType_t xStatus; + prvStoreFileWork( pxClient ); + xStatus = FreeRTOS_connstatus( pxClient->xTransferSocket ); + xRxSize2 = FreeRTOS_rx_size( pxClient->xTransferSocket ); + FreeRTOS_printf( ( "FTP: WARNING: %s: RX size = %ld -> %ld (%s)\n", + FreeRTOS_GetTCPStateName( xStatus ), + xRxSize, xRxSize2, pxClient->pcFileName ) ); + + if( xRxSize2 > 1 ) + { + return; + } + + /* Remove compiler warnings in case FreeRTOS_printf() is not + * defined. */ + ( void ) xStatus; + } + } + + if( ( pxClient->pxWriteHandle != NULL ) || ( pxClient->pxReadHandle != NULL ) ) + { + BaseType_t xLength; + char pcStrBuf[ 32 ]; + + if( pxClient->bits1.bHadError == pdFALSE_UNSIGNED ) + { + xLength = snprintf( pxClient->pcClientAck, sizeof( pxClient->pcClientAck ), + "226 Closing connection %d bytes transmitted\r\n", ( int ) pxClient->ulRecvBytes ); + } + else + { + xLength = snprintf( pxClient->pcClientAck, sizeof( pxClient->pcClientAck ), + "451 Requested action aborted after %d bytes\r\n", ( int ) pxClient->ulRecvBytes ); + } + + /* Tell on the command socket the data connection is now closed. */ + prvSendReply( pxClient->xSocket, pxClient->pcClientAck, xLength ); + + #if ( ipconfigHAS_PRINTF != 0 ) + { + TickType_t xDelta; + uint32_t ulAverage; + xDelta = xTaskGetTickCount() - pxClient->xStartTime; + ulAverage = ulGetAverage( pxClient->ulRecvBytes, xDelta ); + + FreeRTOS_printf( ( "FTP: %s: '%s' %lu Bytes (%s/sec)\n", + pxClient->pxReadHandle ? "sent" : "recv", + pxClient->pcFileName, + pxClient->ulRecvBytes, + pcMkSize( ulAverage, pcStrBuf, sizeof( pcStrBuf ) ) ) ); + } + #endif /* if ( ipconfigHAS_PRINTF != 0 ) */ + } + + if( pxClient->xTransferSocket != FREERTOS_NO_SOCKET ) + { + FreeRTOS_FD_CLR( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_ALL ); + FreeRTOS_closesocket( pxClient->xTransferSocket ); + pxClient->xTransferSocket = FREERTOS_NO_SOCKET; + + if( pxClient->ulRecvBytes == 0ul ) + { + /* Received zero bytes: an empty file */ + pxClient->bits1.bEmptyFile = pdTRUE_UNSIGNED; + } + else + { + pxClient->bits1.bEmptyFile = pdFALSE_UNSIGNED; + } + } + + pxClient->bits1.bIsListen = pdFALSE_UNSIGNED; + pxClient->bits1.bDirHasEntry = pdFALSE_UNSIGNED; + pxClient->bits1.bClientConnected = pdFALSE_UNSIGNED; + pxClient->bits1.bHadError = pdFALSE_UNSIGNED; + } +/*-----------------------------------------------------------*/ + + static void prvTransferCloseFile( FTPClient_t * pxClient ) + { + if( pxClient->pxWriteHandle != NULL ) + { + ff_fclose( pxClient->pxWriteHandle ); + pxClient->pxWriteHandle = NULL; + #if ( ipconfigFTP_HAS_RECEIVED_HOOK != 0 ) + { + vApplicationFTPReceivedHook( pxClient->pcFileName, pxClient->ulRecvBytes, pxClient ); + } + #endif + } + + if( pxClient->pxReadHandle != NULL ) + { + ff_fclose( pxClient->pxReadHandle ); + pxClient->pxReadHandle = NULL; + } + + /* These two field are only used for logging / file-statistics */ + pxClient->ulRecvBytes = 0ul; + pxClient->xStartTime = 0ul; + } +/*-----------------------------------------------------------*/ + +/** + * Guess the transfer type, given the client requested type. + * Actually in unix there is no difference between binary and + * ascii mode when we work with file descriptors. + * If #type is not recognized as a valid client request, -1 is returned. + */ + static BaseType_t prvGetTransferType( const char * pcType ) + { + BaseType_t xResult = -1; + + if( pcType != NULL ) + { + BaseType_t xLength = strlen( pcType ); + + if( xLength == 0 ) + { + return -1; + } + + switch( pcType[ 0 ] ) + { + case 'I': + xResult = TMODE_BINARY; + break; + + case 'A': + xResult = TMODE_ASCII; + break; + + case 'L': + + if( xLength >= 3 ) + { + if( pcType[ 2 ] == '7' ) + { + xResult = TMODE_7BITS; + } + else if( pcType[ 2 ] == '8' ) + { + xResult = TMODE_7BITS; + } + } + + break; + } + } + + return xResult; + } +/*-----------------------------------------------------------*/ + + #if ( ipconfigHAS_PRINTF != 0 ) + #define SIZE_1_GB ( 1024ul * 1024ul * 1024ul ) + #define SIZE_1_MB ( 1024ul * 1024ul ) + #define SIZE_1_KB ( 1024ul ) + + static const char * pcMkSize( uint32_t ulAmount, + char * pcBuffer, + BaseType_t xBufferSize ) + { + uint32_t ulGB, ulMB, ulKB, ulByte; + + ulGB = ( ulAmount / SIZE_1_GB ); + ulAmount -= ( ulGB * SIZE_1_GB ); + ulMB = ( ulAmount / SIZE_1_MB ); + ulAmount -= ( ulMB * SIZE_1_MB ); + ulKB = ( ulAmount / SIZE_1_KB ); + ulAmount -= ( ulKB * SIZE_1_KB ); + ulByte = ( ulAmount ); + + if( ulGB != 0ul ) + { + snprintf( pcBuffer, xBufferSize, "%lu.%02lu GB", ulGB, ( 100 * ulMB ) / SIZE_1_KB ); + } + else if( ulMB != 0ul ) + { + snprintf( pcBuffer, xBufferSize, "%lu.%02lu MB", ulMB, ( 100 * ulKB ) / SIZE_1_KB ); + } + else if( ulKB != 0ul ) + { + snprintf( pcBuffer, xBufferSize, "%lu.%02lu KB", ulKB, ( 100 * ulByte ) / SIZE_1_KB ); + } + else + { + snprintf( pcBuffer, xBufferSize, "%lu bytes", ulByte ); + } + + return pcBuffer; + } + /*-----------------------------------------------------------*/ + #endif /* ipconfigHAS_PRINTF != 0 */ + + #if ( ipconfigHAS_PRINTF != 0 ) + static uint32_t ulGetAverage( uint32_t ulAmount, + TickType_t xDeltaMs ) + { + uint32_t ulAverage; + + /* Get the average amount of bytes per seconds. Ideally this is + * calculated by Multiplying with 1000 and dividing by milliseconds: + * ulAverage = ( 1000ul * ulAmount ) / xDeltaMs; + * Now get a maximum precision, while avoiding an arithmetic overflow: + */ + if( xDeltaMs == 0ul ) + { + /* Time is zero, there is no average */ + ulAverage = 0ul; + } + else if( ulAmount >= ( ~0ul / 10ul ) ) + { + /* More than 409 MB has been transferred, do not multiply. */ + ulAverage = ( ulAmount / ( xDeltaMs / 1000ul ) ); + } + else if( ulAmount >= ( ~0ul / 100ul ) ) + { + /* Between 409 and 41 MB has been transferred, can multiply by 10. */ + ulAverage = ( ( ulAmount * 10ul ) / ( xDeltaMs / 100ul ) ); + } + else if( ulAmount >= ( ~0ul / 1000ul ) ) + { + /* Between 4.1 MB and 41 has been transferred, can multiply by 100. */ + ulAverage = ( ( ulAmount * 100ul ) / ( xDeltaMs / 10ul ) ); + } + else + { + /* Less than 4.1 MB: can multiply by 1000. */ + ulAverage = ( ( ulAmount * 1000ul ) / xDeltaMs ); + } + + return ulAverage; + } + /*-----------------------------------------------------------*/ + #endif /* ipconfigHAS_PRINTF != 0 */ + + static UBaseType_t prvParsePortData( const char * pcCommand, + uint32_t * pulIPAddress ) + { +/*_HT_ Using 'unsigned' here because when sscanf() sees '%u', it expects a pointer to 'unsigned'. + * Not sure about the sscanf() format for UBaseType_t ? */ + unsigned h1, h2, h3, h4, p1, p2; + char sep; + UBaseType_t uxResult; + + /* Expect PORT h1,h2,h3,h4,p1,p2 */ + if( sscanf( pcCommand, "%u%c%u%c%u%c%u%c%u%c%u", &h1, &sep, &h2, &sep, &h3, &sep, &h4, &sep, &p1, &sep, &p2 ) != 11 ) + { + uxResult = 0u; + } + else + { + /* Put in network byte order. */ + *pulIPAddress = + ( ( uint32_t ) h1 << 24 ) | + ( ( uint32_t ) h2 << 16 ) | + ( ( uint32_t ) h3 << 8 ) | + ( ( uint32_t ) h4 ); + uxResult = ( p1 << 8 ) | p2; + } + + return uxResult; + } +/*-----------------------------------------------------------*/ + +/* + * + #### ####### # ### + # # # # ## # # + # # # # # # + # ###### #### ### ## #### # # ### # #### + ## # # # # # # # # ##### # # # # + ## # # # ## # ###### # # # # ###### + # # # # # # # # # # # + # # # ## # # # # ## # # # # ## + #### ## #### #### #### #### ##### ##### #### + #### + */ + + static BaseType_t prvStoreFilePrep( FTPClient_t * pxClient, + char * pcFileName ) + { + BaseType_t xResult; + FF_FILE * pxNewHandle; + size_t uxFileSize = 0ul; + int iErrorNo; + + /* Close previous handle (if any) and reset file transfer parameters. */ + prvTransferCloseFile( pxClient ); + + xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); + + pxNewHandle = NULL; + + if( pxClient->ulRestartOffset != 0 ) + { + size_t uxOffset = pxClient->ulRestartOffset; + int32_t lRc; + + pxClient->ulRestartOffset = 0ul; /* Only use 1 time. */ + pxNewHandle = ff_fopen( pxClient->pcFileName, "ab" ); + + if( pxNewHandle != NULL ) + { + uxFileSize = pxNewHandle->ulFileSize; + + if( uxOffset <= uxFileSize ) + { + lRc = ff_fseek( pxNewHandle, uxOffset, FF_SEEK_SET ); + } + else + { + /* Won't even try to seek after EOF */ + lRc = -pdFREERTOS_ERRNO_EINVAL; + } + + if( lRc != 0 ) + { + BaseType_t xLength; + + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "450 Seek invalid %u length %u\r\n", + ( unsigned ) uxOffset, ( unsigned ) uxFileSize ); + + /* "Requested file action not taken". */ + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + + FreeRTOS_printf( ( "ftp::storeFile: create %s: Seek %u length %u\n", + pxClient->pcFileName, ( unsigned ) uxOffset, ( unsigned ) uxFileSize ) ); + + ff_fclose( pxNewHandle ); + pxNewHandle = NULL; + } + } + } + else + { + pxNewHandle = ff_fopen( pxClient->pcFileName, "wb" ); + } + + if( pxNewHandle == NULL ) + { + iErrorNo = stdioGET_ERRNO(); + + if( iErrorNo == pdFREERTOS_ERRNO_ENOSPC ) + { + prvSendReply( pxClient->xSocket, REPL_552, 0 ); + } + else + { + /* "Requested file action not taken". */ + prvSendReply( pxClient->xSocket, REPL_450, 0 ); + } + + FreeRTOS_printf( ( "ftp::storeFile: create %s: %s (errno %d)\n", + pxClient->pcFileName, + ( const char * ) strerror( iErrorNo ), iErrorNo ) ); + + xResult = pdFALSE; + } + else + { + if( pxClient->bits1.bIsListen ) + { + /* True if PASV is used. */ + snprintf( pxClient->pcConnectionAck, sizeof( pxClient->pcConnectionAck ), + "150 Accepted data connection from %%xip:%%u\r\n" ); + prvTransferCheck( pxClient ); + } + else + { + BaseType_t xLength; + + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "150 Opening BIN connection to store file\r\n" ); + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + pxClient->pcConnectionAck[ 0 ] = '\0'; + prvTransferStart( pxClient ); /* Now active connect. */ + } + + pxClient->pxWriteHandle = pxNewHandle; + + /* To get some statistics about the performance. */ + pxClient->xStartTime = xTaskGetTickCount(); + + xResult = pdTRUE; + } + + return xResult; + } +/*-----------------------------------------------------------*/ + + #if ( ipconfigFTP_ZERO_COPY_ALIGNED_WRITES == 0 ) + + static BaseType_t prvStoreFileWork( FTPClient_t * pxClient ) + { + BaseType_t xRc, xWritten; + + /* Read from the data socket until all has been read or until a negative value + * is returned. */ + for( ; ; ) + { + char * pcBuffer; + + /* The "zero-copy" method: */ + xRc = FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) &pcBuffer, + 0x20000u, FREERTOS_ZERO_COPY | FREERTOS_MSG_DONTWAIT ); + + if( xRc <= 0 ) + { + break; + } + + pxClient->ulRecvBytes += xRc; + xWritten = ff_fwrite( pcBuffer, 1, xRc, pxClient->pxWriteHandle ); + FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) NULL, xRc, 0 ); + + if( xWritten != xRc ) + { + xRc = -1; + /* bHadError: a transfer got aborted because of an error. */ + pxClient->bits1.bHadError = pdTRUE_UNSIGNED; + break; + } + } + + return xRc; + } + + #else /* ipconfigFTP_ZERO_COPY_ALIGNED_WRITES != 0 */ + + #if !defined( ipconfigFTP_PREFERRED_WRITE_SIZE ) + +/* If you store data on flash, it may be profitable to give 'ipconfigFTP_PREFERRED_WRITE_SIZE' + * the same size as the size of the flash' erase blocks, e.g. 4KB */ + #define ipconfigFTP_PREFERRED_WRITE_SIZE 512ul + #endif + + static BaseType_t prvStoreFileWork( FTPClient_t * pxClient ) + { + BaseType_t xRc, xWritten; + + /* Read from the data socket until all has been read or until a negative + * value is returned. */ + for( ; ; ) + { + char * pcBuffer; + UBaseType_t xStatus; + + /* The "zero-copy" method: */ + xRc = FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) &pcBuffer, + 0x20000u, FREERTOS_ZERO_COPY | FREERTOS_MSG_DONTWAIT ); + + if( xRc <= 0 ) + { + /* There are no data or the connection is closed. */ + break; + } + + xStatus = FreeRTOS_connstatus( pxClient->xTransferSocket ); + + if( xStatus != eESTABLISHED ) + { + /* The connection is not established (any more), therefore + * accept any amount of bytes, probably the last few bytes. */ + } + else + { + if( xRc >= ipconfigFTP_PREFERRED_WRITE_SIZE ) + { + /* More than a sector to write, round down to a multiple of + * PREFERRED_WRITE_SIZE bytes. */ + xRc = ( xRc / ipconfigFTP_PREFERRED_WRITE_SIZE ) * ipconfigFTP_PREFERRED_WRITE_SIZE; + } + else + { + const StreamBuffer_t * pxBuffer = FreeRTOS_get_rx_buf( pxClient->xTransferSocket ); + size_t uxSpace = pxBuffer->LENGTH - pxBuffer->uxTail; + + if( uxSpace >= ipconfigFTP_PREFERRED_WRITE_SIZE ) + { + /* At this moment there are les than PREFERRED_WRITE_SIZE bytes in the RX + * buffer, but there is space for more. Just return and + * wait for more. */ + xRc = 0; + } + else + { + /* Now reading beyond the end of the circular buffer, + * use a normal read. */ + pcBuffer = pcFILE_BUFFER; + xRc = FreeRTOS_recvcount( pxClient->xTransferSocket ); + xRc = ( xRc / ipconfigFTP_PREFERRED_WRITE_SIZE ) * ipconfigFTP_PREFERRED_WRITE_SIZE; + + if( xRc > 0 ) + { + xRc = FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) pcBuffer, + sizeof( pcFILE_BUFFER ), FREERTOS_MSG_DONTWAIT ); + } + } + } + } + + if( xRc == 0 ) + { + break; + } + + pxClient->ulRecvBytes += xRc; + + xWritten = ff_fwrite( pcBuffer, 1, xRc, pxClient->pxWriteHandle ); + + if( pcBuffer != pcFILE_BUFFER ) + { + FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) NULL, xRc, 0 ); + } + + if( xWritten != xRc ) + { + xRc = -1; + /* bHadError: a transfer got aborted because of an error. */ + pxClient->bits1.bHadError = pdTRUE_UNSIGNED; + break; + } + } + + return xRc; + } + + #endif /* ipconfigFTP_ZERO_COPY_ALIGNED_WRITES */ +/*-----------------------------------------------------------*/ + +/* + ###### # ####### # ### + # # # # # ## # # + # # # # # # + # # #### ###### ### ## ### #### # # #### # # ### # #### + ###### # # # # # # # # # # # # # ##### # # # # + # ## ###### # ## # # ###### # # ###### # # # # ###### + # # # # # # # # # # # # # # + # # # ## # ## # # # ## # # # ## # # # # ## + ### ## #### ## #### ##### #### ## #### #### ##### ##### #### + */ + static BaseType_t prvRetrieveFilePrep( FTPClient_t * pxClient, + char * pcFileName ) + { + BaseType_t xResult = pdTRUE; + size_t uxFileSize; + + /* Close previous handle (if any) and reset file transfer parameters */ + prvTransferCloseFile( pxClient ); + + xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); + + pxClient->pxReadHandle = ff_fopen( pxClient->pcFileName, "rb" ); + + if( pxClient->pxReadHandle == NULL ) + { + int iErrno = stdioGET_ERRNO(); + /* "Requested file action not taken". */ + prvSendReply( pxClient->xSocket, REPL_450, 0 ); + FreeRTOS_printf( ( "prvRetrieveFilePrep: open '%s': errno %d: %s\n", + pxClient->pcFileName, iErrno, ( const char * ) strerror( iErrno ) ) ); + uxFileSize = 0ul; + xResult = pdFALSE; + } + else + { + uxFileSize = pxClient->pxReadHandle->ulFileSize; + pxClient->uxBytesLeft = uxFileSize; + + if( pxClient->ulRestartOffset != 0ul ) + { + size_t uxOffset = pxClient->ulRestartOffset; + int32_t iRc; + + /* Only use 1 time. */ + pxClient->ulRestartOffset = 0; + + if( uxOffset < uxFileSize ) + { + iRc = ff_fseek( pxClient->pxReadHandle, uxOffset, FF_SEEK_SET ); + } + else + { + iRc = -pdFREERTOS_ERRNO_EINVAL; + } + + if( iRc != 0 ) + { + BaseType_t xLength; + + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "450 Seek invalid %u length %u\r\n", ( unsigned ) uxOffset, ( unsigned ) uxFileSize ); + + /* "Requested file action not taken". */ + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + + FreeRTOS_printf( ( "prvRetrieveFilePrep: create %s: Seek %u length %u\n", + pxClient->pcFileName, ( unsigned ) uxOffset, ( unsigned ) uxFileSize ) ); + + ff_fclose( pxClient->pxReadHandle ); + pxClient->pxReadHandle = NULL; + xResult = pdFALSE; + } + else + { + pxClient->uxBytesLeft = uxFileSize - pxClient->ulRestartOffset; + } + } + } + + if( xResult != pdFALSE ) + { + if( pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ) + { + /* True if PASV is used. */ + snprintf( pxClient->pcConnectionAck, sizeof( pxClient->pcConnectionAck ), + "150%cAccepted data connection from %%xip:%%u\r\n%s", + pxClient->xTransType == TMODE_ASCII ? '-' : ' ', + pxClient->xTransType == TMODE_ASCII ? "150 NOTE: ASCII mode requested, but binary mode used\r\n" : "" ); + } + else + { + BaseType_t xLength; + + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "150%cOpening data connection to %lxip:%u\r\n%s", + pxClient->xTransType == TMODE_ASCII ? '-' : ' ', + pxClient->ulClientIP, + pxClient->usClientPort, + pxClient->xTransType == TMODE_ASCII ? "150 NOTE: ASCII mode requested, but binary mode used\r\n" : "" ); + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + pxClient->pcConnectionAck[ 0 ] = '\0'; + prvTransferStart( pxClient ); + } + + /* Prepare the ACK which will be sent when all data has been sent. */ + snprintf( pxClient->pcClientAck, sizeof( pxClient->pcClientAck ), "%s", REPL_226 ); + + /* To get some statistics about the performance. */ + pxClient->xStartTime = xTaskGetTickCount(); + + if( uxFileSize == 0ul ) + { + FreeRTOS_shutdown( pxClient->xTransferSocket, FREERTOS_SHUT_RDWR ); + } + } + + return xResult; + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvRetrieveFileWork( FTPClient_t * pxClient ) + { + size_t uxSpace; + size_t uxCount, uxItemsRead; + BaseType_t xRc = 0; + BaseType_t xSetEvent = pdFALSE; + + do + { + #if ( ipconfigFTP_TX_ZERO_COPY != 0 ) + char * pcBuffer; + BaseType_t xBufferLength; + #endif /* ipconfigFTP_TX_ZERO_COPY */ + + /* Take the lesser of the two: tx_space (number of bytes that can be + * queued for transmission) and uxBytesLeft (the number of bytes left to + * read from the file) */ + uxSpace = FreeRTOS_tx_space( pxClient->xTransferSocket ); + + if( uxSpace == 0 ) + { + FreeRTOS_FD_SET( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE | eSELECT_EXCEPT ); + xRc = FreeRTOS_select( pxClient->pxParent->xSocketSet, 200 ); + uxSpace = FreeRTOS_tx_space( pxClient->xTransferSocket ); + } + + uxCount = FreeRTOS_min_uint32( pxClient->uxBytesLeft, uxSpace ); + + if( uxCount == 0 ) + { + break; + } + + #if ( ipconfigFTP_TX_ZERO_COPY == 0 ) + { + if( uxCount > sizeof( pcFILE_BUFFER ) ) + { + uxCount = sizeof( pcFILE_BUFFER ); + } + + uxItemsRead = ff_fread( pcFILE_BUFFER, 1, uxCount, pxClient->pxReadHandle ); + + if( uxItemsRead != uxCount ) + { + FreeRTOS_printf( ( "prvRetrieveFileWork: Got %u Expected %u\n", ( unsigned ) uxItemsRead, ( unsigned ) uxCount ) ); + xRc = FreeRTOS_shutdown( pxClient->xTransferSocket, FREERTOS_SHUT_RDWR ); + pxClient->uxBytesLeft = 0u; + break; + } + + pxClient->uxBytesLeft -= uxCount; + + if( pxClient->uxBytesLeft == 0u ) + { + BaseType_t xTrueValue = 1; + + FreeRTOS_setsockopt( pxClient->xTransferSocket, 0, FREERTOS_SO_CLOSE_AFTER_SEND, ( void * ) &xTrueValue, sizeof( xTrueValue ) ); + } + + xRc = FreeRTOS_send( pxClient->xTransferSocket, pcFILE_BUFFER, uxCount, 0 ); + } + #else /* ipconfigFTP_TX_ZERO_COPY != 0 */ + { + /* Use zero-copy transmission: + * FreeRTOS_get_tx_head() returns a direct pointer to the TX stream and + * set xBufferLength to know how much space there is left. */ + pcBuffer = ( char * ) FreeRTOS_get_tx_head( pxClient->xTransferSocket, &xBufferLength ); + + if( ( pcBuffer != NULL ) && ( xBufferLength >= 512 ) ) + { + /* Will read disk data directly to the TX stream of the socket. */ + uxCount = FreeRTOS_min_uint32( uxCount, ( uint32_t ) xBufferLength ); + + if( uxCount > ( size_t ) 0x40000u ) + { + uxCount = ( size_t ) 0x40000u; + } + } + else + { + /* Use the normal file i/o buffer. */ + pcBuffer = pcFILE_BUFFER; + + if( uxCount > sizeof( pcFILE_BUFFER ) ) + { + uxCount = sizeof( pcFILE_BUFFER ); + } + } + + if( pxClient->uxBytesLeft >= 1024u ) + { + uxCount &= ~( ( size_t ) 512u - 1u ); + } + + if( uxCount <= 0u ) + { + /* Nothing to send after rounding down to a multiple of a sector size. */ + break; + } + + uxItemsRead = ff_fread( pcBuffer, 1, uxCount, pxClient->pxReadHandle ); + + if( uxCount != uxItemsRead ) + { + FreeRTOS_printf( ( "prvRetrieveFileWork: Got %u Expected %u\n", ( unsigned ) uxItemsRead, ( unsigned ) uxCount ) ); + xRc = FreeRTOS_shutdown( pxClient->xTransferSocket, FREERTOS_SHUT_RDWR ); + pxClient->uxBytesLeft = 0u; + break; + } + + pxClient->uxBytesLeft -= uxCount; + + if( pxClient->uxBytesLeft == 0u ) + { + BaseType_t xTrueValue = 1; + + FreeRTOS_setsockopt( pxClient->xTransferSocket, 0, FREERTOS_SO_CLOSE_AFTER_SEND, ( void * ) &xTrueValue, sizeof( xTrueValue ) ); + } + + if( pcBuffer != pcFILE_BUFFER ) + { + pcBuffer = NULL; + } + + xRc = FreeRTOS_send( pxClient->xTransferSocket, pcBuffer, uxCount, 0 ); + } + #endif /* ipconfigFTP_TX_ZERO_COPY */ + + if( xRc < 0 ) + { + break; + } + + pxClient->ulRecvBytes += xRc; + + if( pxClient->uxBytesLeft == 0u ) + { + break; + } + } while( uxCount > 0u ); + + if( xRc < 0 ) + { + FreeRTOS_printf( ( "prvRetrieveFileWork: already disconnected\n" ) ); + } + else if( pxClient->uxBytesLeft <= 0u ) + { + BaseType_t x; + + for( x = 0; x < 5; x++ ) + { + xRc = FreeRTOS_recv( pxClient->xTransferSocket, pcFILE_BUFFER, sizeof( pcFILE_BUFFER ), 0 ); + + if( xRc < 0 ) + { + break; + } + } + +/* FreeRTOS_printf( ( "prvRetrieveFileWork: %s all sent: xRc %ld\n", pxClient->pcFileName, xRc ) ); */ + } + else + { + FreeRTOS_FD_SET( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); + xSetEvent = pdTRUE; + } + + if( xSetEvent == pdFALSE ) + { + FreeRTOS_FD_CLR( pxClient->xTransferSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); + } + + return xRc; + } +/*-----------------------------------------------------------*/ + +/* + ### ##### #### ##### + # # # # # # # + # # # # # + # # # # + # # ## # + # # # ## # + # # # # # # + # # # # # # + ####### ##### #### #### + */ +/* Prepare sending a directory LIST */ + static BaseType_t prvListSendPrep( FTPClient_t * pxClient ) + { + BaseType_t xFindResult; + int iErrorNo; + + if( pxClient->bits1.bIsListen != pdFALSE_UNSIGNED ) + { + /* True if PASV is used */ + snprintf( pxClient->pcConnectionAck, sizeof( pxClient->pcConnectionAck ), + "150 Accepted data connection from %%xip:%%u\r\n" ); + } + else + { + BaseType_t xLength; + + /* Here the FTP server is supposed to connect() */ + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "150 Opening ASCII mode data connection to for /bin/ls \r\n" ); + + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + /* Clear the current connection acknowledge message */ + pxClient->pcConnectionAck[ 0 ] = '\0'; + prvTransferStart( pxClient ); + } + + pxClient->xDirCount = 0; + xMakeAbsolute( pxClient, pcNEW_DIR, sizeof( pcNEW_DIR ), pxClient->pcCurrentDir ); + + xFindResult = ff_findfirst( pcNEW_DIR, &pxClient->xFindData ); + + pxClient->bits1.bDirHasEntry = ( xFindResult >= 0 ); + + iErrorNo = stdioGET_ERRNO(); + + if( ( xFindResult < 0 ) && ( iErrorNo == pdFREERTOS_ERRNO_ENMFILE ) ) + { + FreeRTOS_printf( ( "prvListSendPrep: Empty directory? (%s)\n", pxClient->pcCurrentDir ) ); + prvSendReply( pxClient->xTransferSocket, "total 0\r\n", 0 ); + pxClient->xDirCount++; + } + else if( xFindResult < 0 ) + { + FreeRTOS_printf( ( "prvListSendPrep: rc = %ld iErrorNo = %d\n", xFindResult, iErrorNo ) ); + prvSendReply( pxClient->xSocket, REPL_451, 0 ); + } + + pxClient->pcClientAck[ 0 ] = '\0'; + + return pxClient->xDirCount; + } +/*-----------------------------------------------------------*/ + + #define MAX_DIR_LIST_ENTRY_SIZE 256 + + static BaseType_t prvListSendWork( FTPClient_t * pxClient ) + { + BaseType_t xTxSpace; + + while( pxClient->bits1.bClientConnected != pdFALSE_UNSIGNED ) + { + char * pcWritePtr = pcCOMMAND_BUFFER; + BaseType_t xWriteLength; + + xTxSpace = FreeRTOS_tx_space( pxClient->xTransferSocket ); + + if( xTxSpace > ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) ) + { + xTxSpace = sizeof( pcCOMMAND_BUFFER ); + } + + while( ( xTxSpace >= MAX_DIR_LIST_ENTRY_SIZE ) && ( pxClient->bits1.bDirHasEntry != pdFALSE_UNSIGNED ) ) + { + BaseType_t xLength, xEndOfDir; + int32_t iRc; + int iErrorNo; + + xLength = prvGetFileInfoStat( &( pxClient->xFindData.xDirectoryEntry ), pcWritePtr, xTxSpace ); + + pxClient->xDirCount++; + pcWritePtr += xLength; + xTxSpace -= xLength; + + iRc = ff_findnext( &pxClient->xFindData ); + iErrorNo = stdioGET_ERRNO(); + + xEndOfDir = ( iRc < 0 ) && ( iErrorNo == pdFREERTOS_ERRNO_ENMFILE ); + + pxClient->bits1.bDirHasEntry = ( xEndOfDir == pdFALSE ) && ( iRc >= 0 ); + + if( ( iRc < 0 ) && ( xEndOfDir == pdFALSE ) ) + { + FreeRTOS_printf( ( "prvListSendWork: %s (rc %08x)\n", + ( const char * ) strerror( iErrorNo ), + ( unsigned ) iRc ) ); + } + } + + xWriteLength = ( BaseType_t ) ( pcWritePtr - pcCOMMAND_BUFFER ); + + if( xWriteLength == 0 ) + { + break; + } + + if( pxClient->bits1.bDirHasEntry == pdFALSE_UNSIGNED ) + { + uint32_t ulTotalCount; + uint32_t ulFreeCount; + uint32_t ulPercentage; + + ulTotalCount = 1; + ulFreeCount = ff_diskfree( pxClient->pcCurrentDir, &ulTotalCount ); + ulPercentage = ( uint32_t ) ( ( 100ULL * ulFreeCount + ulTotalCount / 2 ) / ulTotalCount ); + + /* Prepare the ACK which will be sent when all data has been sent. */ + snprintf( pxClient->pcClientAck, sizeof( pxClient->pcClientAck ), + "226-Options: -l\r\n" + "226-%ld matches total\r\n" + "226 Total %lu KB (%lu %% free)\r\n", + pxClient->xDirCount, ulTotalCount / 1024, ulPercentage ); + } + + if( xWriteLength ) + { + if( pxClient->bits1.bDirHasEntry == pdFALSE_UNSIGNED ) + { + BaseType_t xTrueValue = 1; + + FreeRTOS_setsockopt( pxClient->xTransferSocket, 0, FREERTOS_SO_CLOSE_AFTER_SEND, ( void * ) &xTrueValue, sizeof( xTrueValue ) ); + } + + prvSendReply( pxClient->xTransferSocket, pcCOMMAND_BUFFER, xWriteLength ); + } + + if( pxClient->bits1.bDirHasEntry == pdFALSE_UNSIGNED ) + { + prvSendReply( pxClient->xSocket, pxClient->pcClientAck, 0 ); + break; + } + } /* while( pxClient->bits1.bClientConnected ) */ + + return 0; + } +/*-----------------------------------------------------------*/ + + static const char * pcMonthAbbrev( BaseType_t xMonth ) + { + static const char pcMonthList[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; + + if( ( xMonth < 1 ) || ( xMonth > 12 ) ) + { + xMonth = 12; + } + + return pcMonthList + 3 * ( xMonth - 1 ); + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvGetFileInfoStat( FF_DirEnt_t * pxEntry, + char * pcLine, + BaseType_t xMaxLength ) + { + char date[ 16 ]; + char mode[ 11 ] = "----------"; + BaseType_t st_nlink = 1; + const char user[ 9 ] = "freertos"; + const char group[ 8 ] = "plusfat"; + +/* + * Creates a unix-style listing, understood by most FTP clients: + * + * -rw-rw-r-- 1 freertos FreeRTOS+FAT 10564588 Sep 01 00:17 03. Metaharmoniks - Star (Instrumental).mp3 + * -rw-rw-r-- 1 freertos FreeRTOS+FAT 19087839 Sep 01 00:17 04. Simon Le Grec - Dimitri (Wherever U Are) (Cosmos Mix).mp3 + * -rw-rw-r-- 1 freertos FreeRTOS+FAT 11100621 Sep 01 00:16 05. D-Chill - Mistake (feat. Katy Blue).mp3 + */ + + #if ( ffconfigTIME_SUPPORT == 1 ) + const FF_SystemTime_t * pxCreateTime = &( pxEntry->xCreateTime ); + #else + #warning Do not use this. + FF_SystemTime_t xCreateTime; + const FF_SystemTime_t * pxCreateTime = &xCreateTime; + #endif + size_t ulSize = ( size_t ) pxEntry->ulFileSize; + const char * pcFileName = pxEntry->pcFileName; + + mode[ 0 ] = ( ( pxEntry->ucAttrib & FF_FAT_ATTR_DIR ) != 0 ) ? 'd' : '-'; + #if ( ffconfigDEV_SUPPORT != 0 ) + { + if( ( pxEntry->ucAttrib & FF_FAT_ATTR_DIR ) == 0 ) + { + switch( pxEntry->ucIsDeviceDir ) + { + case FF_DEV_CHAR_DEV: + mode[ 0 ] = 'c'; + break; + + case FF_DEV_BLOCK_DEV: + mode[ 0 ] = 'b'; + break; + } + } + } + #endif /* ffconfigDEV_SUPPORT != 0 */ + + mode[ 1 ] = 'r'; /* Owner. */ + mode[ 2 ] = ( ( pxEntry->ucAttrib & FF_FAT_ATTR_READONLY ) != 0 ) ? '-' : 'w'; + mode[ 3 ] = '-'; /* x for executable. */ + + mode[ 4 ] = 'r'; /* group. */ + mode[ 5 ] = ( ( pxEntry->ucAttrib & FF_FAT_ATTR_READONLY ) != 0 ) ? '-' : 'w'; + mode[ 6 ] = '-'; /* x for executable. */ + + mode[ 7 ] = 'r'; /* world. */ + mode[ 8 ] = '-'; + mode[ 9 ] = '-'; /* x for executable. */ + + if( pxCreateTime->Month && pxCreateTime->Day ) + { + snprintf( date, sizeof( date ), "%-3.3s %02d %02d:%02d", + pcMonthAbbrev( pxCreateTime->Month ), + pxCreateTime->Day, + pxCreateTime->Hour, + pxCreateTime->Minute ); + } + else + { + snprintf( date, sizeof( date ), "Jan 01 1970" ); + } + + return snprintf( pcLine, xMaxLength, "%s %3ld %-4s %-4s %8d %12s %s\r\n", + mode, st_nlink, user, group, ( int ) ulSize, date, pcFileName ); + } +/*-----------------------------------------------------------*/ + +/* + #### # # ##### + # # # # # # + # # # # # # + # # # # # # + # # # # # # + # # # # # # + # # ## ## # # + # # ## ## # # + #### ## ## ##### + */ + static BaseType_t prvChangeDir( FTPClient_t * pxClient, + char * pcDirectory ) + { + BaseType_t xResult; + BaseType_t xIsRootDir, xLength, xValid; + BaseType_t xIsDotDir = 0; + + if( pcDirectory[ 0 ] == '.' ) + { + if( ( pcDirectory[ 1 ] == '.' ) && + ( pcDirectory[ 2 ] == '\0' ) ) + { + xIsDotDir = 2; + } + else if( pcDirectory[ 1 ] == '\0' ) + { + xIsDotDir = 1; + } + } + + if( xIsDotDir != 0 ) + { + strcpy( pcFILE_BUFFER, pxClient->pcCurrentDir ); + + if( pcDirectory[ 1 ] == '.' ) + { + char * p = strrchr( pcFILE_BUFFER, '/' ); + + if( p != NULL ) + { + if( p == pcFILE_BUFFER ) + { + p[ 1 ] = '\0'; + } + else + { + p[ 0 ] = '\0'; + } + } + } + } + else + { + if( pcDirectory[ 0 ] != '/' ) + { + BaseType_t xCurLength; + + xCurLength = strlen( pxClient->pcCurrentDir ); + snprintf( pcFILE_BUFFER, sizeof( pcFILE_BUFFER ), "%s%s%s", + pxClient->pcCurrentDir, + pxClient->pcCurrentDir[ xCurLength - 1 ] == '/' ? "" : "/", + pcDirectory ); + } + else + { + snprintf( pcFILE_BUFFER, sizeof( pcFILE_BUFFER ), "%s", pcDirectory ); + } + } + + xIsRootDir = ( pcFILE_BUFFER[ 0 ] == '/' ) && ( pcFILE_BUFFER[ 1 ] == '\0' ); + xMakeAbsolute( pxClient, pcNEW_DIR, sizeof( pcNEW_DIR ), pcFILE_BUFFER ); + + if( ( ( xIsRootDir == pdFALSE ) || ( FF_FS_Count() == 0 ) ) && ( ff_finddir( pcNEW_DIR ) == pdFALSE ) ) + { + xValid = pdFALSE; + } + else + { + xValid = pdTRUE; + } + + if( xValid == pdFALSE ) + { + /* Get the directory cluster, if it exists. */ + FreeRTOS_printf( ( "FTP: chdir \"%s\": No such dir\n", pcNEW_DIR ) ); + /*#define REPL_550 "550 Requested action not taken.\r\n" */ + /*550 /home/hein/arch/h8300: No such file or directory */ + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "550 %s: No such file or directory\r\n", + pcNEW_DIR ); + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + xResult = pdFALSE; + } + else + { + memcpy( pxClient->pcCurrentDir, pcNEW_DIR, sizeof( pxClient->pcCurrentDir ) ); + + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "250 Changed to %s\r\n", pcNEW_DIR ); + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + xResult = pdTRUE; + } + + return xResult; + } +/*-----------------------------------------------------------*/ + +/* + ###### ## # ####### ###### + # # ## # # ## # # + # # ## # # # # # + # # ### # # # # # + ###### # ## # ##### ###### + # ## # ## # # # # ## + # # # ### # # # + # # # ## # # # + ### ## # ## #### ### ## + */ + static BaseType_t prvRenameFrom( FTPClient_t * pxClient, + const char * pcFileName ) + { + const char * myReply; + FF_FILE * fh; + + xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); + + myReply = NULL; + + fh = ff_fopen( pxClient->pcFileName, "rb" ); + + if( fh != NULL ) + { + ff_fclose( fh ); + /* REPL_350; "350 Requested file action pending further information." */ + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "350 Rename '%s' ...\r\n", pxClient->pcFileName ); + myReply = pcCOMMAND_BUFFER; + pxClient->bits.bInRename = pdTRUE_UNSIGNED; + } + else if( stdioGET_ERRNO() == pdFREERTOS_ERRNO_EISDIR ) + { + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "350 Rename directory '%s' ...\r\n", pxClient->pcFileName ); + myReply = pcCOMMAND_BUFFER; + pxClient->bits.bInRename = pdTRUE_UNSIGNED; + } + else + { + FreeRTOS_printf( ( "ftp::renameFrom[%s]\n%s\n", pxClient->pcFileName, strerror( stdioGET_ERRNO() ) ) ); + myReply = REPL_451; /* "451 Requested action aborted. Local error in processing." */ + } + + if( myReply ) + { + prvSendReply( pxClient->xSocket, myReply, 0 ); + } + + return pdTRUE; + } +/*-----------------------------------------------------------*/ + +/* + ###### ## # ##### ### + # # ## # # # # ## ## + # # ## # # ## ## + # # ### # # # # + ###### # ## # # # # + # ## # ## # # # # + # # # ### # ## ## + # # # ## # ## ## + ### ## # ## #### ### + */ + static BaseType_t prvRenameTo( FTPClient_t * pxClient, + const char * pcFileName ) + { + const char * myReply = NULL; + int iResult; + + xMakeAbsolute( pxClient, pcNEW_DIR, sizeof( pcNEW_DIR ), pcFileName ); + + /* FreeRTOS+FAT rename has an extra parameter: "remove target if already + * exists". */ + iResult = ff_rename( pxClient->pcFileName, pcNEW_DIR, pdFALSE ); + + if( iResult < 0 ) + { + iResult = stdioGET_ERRNO(); + } + else + { + iResult = 0; + } + + switch( iResult ) + { + case 0: + FreeRTOS_printf( ( "ftp::renameTo[%s,%s]: Ok\n", pxClient->pcFileName, pcNEW_DIR ) ); + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "250 Rename successful to '%s'\r\n", pcNEW_DIR ); + myReply = pcCOMMAND_BUFFER; + break; + + case pdFREERTOS_ERRNO_EEXIST: + + /* the destination file already exists. + * "450 Requested file action not taken.\r\n"*/ + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "450 Already exists '%s'\r\n", pcNEW_DIR ); + myReply = pcCOMMAND_BUFFER; + break; + + case pdFREERTOS_ERRNO_EIO: /* FF_ERR_FILE_COULD_NOT_CREATE_DIRENT */ + + /* if dirent creation failed (fatal error!). + * "553 Requested action not taken.\r\n" */ + FreeRTOS_printf( ( "ftp::renameTo[%s,%s]: Error creating DirEnt\n", + pxClient->pcFileName, pcNEW_DIR ) ); + myReply = REPL_553; + break; + + case pdFREERTOS_ERRNO_ENXIO: + case pdFREERTOS_ERRNO_ENOENT: + + /* if the source file was not found. + * "450 Requested file action not taken.\r\n" */ + snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "450 No such file '%s'\r\n", pxClient->pcFileName ); + myReply = pcCOMMAND_BUFFER; + break; + + default: + FreeRTOS_printf( ( "ftp::renameTo[%s,%s]: %s\n", pxClient->pcFileName, pcNEW_DIR, + ( const char * ) strerror( stdioGET_ERRNO() ) ) ); + myReply = REPL_451; /* "451 Requested action aborted. Local error in processing." */ + break; + } + + prvSendReply( pxClient->xSocket, myReply, 0 ); + + return pdTRUE; + } +/*-----------------------------------------------------------*/ + +/* + #### # + # # # # + # # # + # ### ###### #### + ## # # # # + ## # # ###### + # # # # # + # # # # ## # ## + #### ##### ## #### + */ + static BaseType_t prvSiteCmd( FTPClient_t * pxClient, + char * pcRestCommand ) + { + ( void ) pxClient; + ( void ) pcRestCommand; + + return 0; + } +/*-----------------------------------------------------------*/ + +/* + ##### ### + # # # # + # # # # + # # #### # #### ###### #### + # # # # # # # # # # + # # ###### # ###### # ###### + # # # # # # # + # # # ## # # ## # ## # ## + ##### #### ##### #### ## #### + */ + static BaseType_t prvDeleteFile( FTPClient_t * pxClient, + char * pcFileName ) + { + BaseType_t xResult, xLength; + int32_t iRc; + int iErrorNo; + + /* DELE: Delete a file. */ + xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); + + iRc = ff_remove( pxClient->pcFileName ); + + if( iRc >= 0 ) + { + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "250 File \"%s\" removed\r\n", pxClient->pcFileName ); + xResult = pdTRUE; + } + else + { + const char * errMsg = "other error"; + + iErrorNo = stdioGET_ERRNO(); + + switch( iErrorNo ) + { /*_RB_ What do these negative numbers relate to? */ + case pdFREERTOS_ERRNO_ENOENT: + errMsg = "No such file"; + break; /* -31 File was not found. */ + + case pdFREERTOS_ERRNO_EALREADY: + errMsg = "File still open"; + break; /* -30 File is in use. */ + + case pdFREERTOS_ERRNO_EISDIR: + errMsg = "Is a dir"; + break; /* -32 Tried to FF_Open() a Directory. */ + + case pdFREERTOS_ERRNO_EROFS: + errMsg = "Read-only"; + break; /* -33 Tried to FF_Open() a file marked read only. */ + + case pdFREERTOS_ERRNO_ENOTDIR: + errMsg = "Invalid path"; + break; /* -34 The path of the file was not found. */ + } + + FreeRTOS_printf( ( "ftp::delFile: '%s' because %s\n", + pxClient->pcFileName, strerror( iErrorNo ) ) ); + + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "521-\"%s\" %s;\r\n" + "521 taking no action\r\n", + pxClient->pcFileName, errMsg ); + + xResult = pdFALSE; + } + + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + + return xResult; + } +/*-----------------------------------------------------------*/ + +/* + #### # ##### + # # # # # # + # # # # # + # ### ###### #### # # #### ###### #### + ## # # # # # # # # # # # + ## # # ###### # # ##### # ###### + # # # # # # # # # # # + # # # # # ## # # # # # ## # ## + #### ##### ###### #### ##### ### ## ## #### + */ + static BaseType_t prvSizeDateFile( FTPClient_t * pxClient, + char * pcFileName, + BaseType_t xSendDate ) + { + BaseType_t xResult = pdFALSE; + char * pcPtr; + + /* SIZE: get the size of a file (xSendDate = 0) + * MDTM: get data and time properties (xSendDate = 1) */ + xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName ); + + pcPtr = strrchr( pxClient->pcFileName, '/' ); + + if( ( pcPtr != NULL ) && ( pcPtr[ 1 ] != '\0' ) ) + { + FF_Stat_t xStatBuf; + int32_t iRc = ff_stat( pxClient->pcFileName, &xStatBuf ); + + if( iRc < 0 ) + { + FreeRTOS_printf( ( "In %s: %s\n", pxClient->pcFileName, + ( const char * ) strerror( stdioGET_ERRNO() ) ) ); + } + + if( iRc == 0 ) + { + BaseType_t xLength; + + /* "YYYYMMDDhhmmss" */ + if( xSendDate != pdFALSE ) + { + #if ( ffconfigTIME_SUPPORT != 0 ) + { + FF_TimeStruct_t tmStruct; + time_t secs = xStatBuf.st_mtime; + FreeRTOS_gmtime_r( &secs, &tmStruct ); + + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "213 %04u%02u%02u%02u%02u%02u\r\n", + tmStruct.tm_year + 1900, + tmStruct.tm_mon + 1, + tmStruct.tm_mday, + tmStruct.tm_hour, + tmStruct.tm_min, + tmStruct.tm_sec ); + } + #else /* if ( ffconfigTIME_SUPPORT != 0 ) */ + { + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "213 19700101000000\r\n", +} + #endif /* if ( ffconfigTIME_SUPPORT != 0 ) */ + } + else + { + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "213 %lu\r\n", xStatBuf.st_size ); + } + + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + xResult = pdTRUE; + } + else + { + FreeRTOS_printf( ( "ftp::sizeDateFile: No such file %s\n", pxClient->pcFileName ) ); + } + } + else + { + FreeRTOS_printf( ( "ftp::sizeDateFile: Invalid file name: %s ?\n", pxClient->pcFileName ) ); + } + + if( xResult == pdFALSE ) + { + prvSendReply( pxClient->xSocket, REPL_450, 0 ); /* "Requested file action not taken". */ + } + + return xResult; + } +/*-----------------------------------------------------------*/ + +/* +## ## ## ## ##### ###### ## ## ##### +### ### # # # # # # ### ### # # +# ### # # # # # # # # ### # # # +# # # # # # # # # # # # # # +# # # #### # # ###### # # # # # +# # # # # # # ## # # # # +# # # # # # # # # # # # +# # # # # # # # # # # # +# # ### ## ##### ### ## # # ##### +*/ + static BaseType_t prvMakeRemoveDir( FTPClient_t * pxClient, + const char * pcDirectory, + BaseType_t xDoRemove ) + { + BaseType_t xResult; + BaseType_t xLength; + int32_t iRc; + int iErrorNo; + + /* MKD: Make / create a directory (xDoRemove = 0) + * RMD: Remove a directory (xDoRemove = 1) */ + xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcDirectory ); + + if( xDoRemove ) + { + iRc = ff_rmdir( pxClient->pcFileName ); + } + else + { + #if ( ffconfigMKDIR_RECURSIVE != 0 ) + { + iRc = ff_mkdir( pxClient->pcFileName, pdFALSE ); + } + #else + { + iRc = ff_mkdir( pxClient->pcFileName ); + } + #endif /* ffconfigMKDIR_RECURSIVE */ + } + + xResult = pdTRUE; + + if( iRc >= 0 ) + { + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "257 \"%s\" directory %s\r\n", + pxClient->pcFileName, xDoRemove ? "removed" : "created" ); + } + else + { + const char * errMsg = "other error"; + BaseType_t xFTPCode = 521; + + xResult = pdFALSE; + iErrorNo = stdioGET_ERRNO(); + + switch( iErrorNo ) + { + case pdFREERTOS_ERRNO_EEXIST: + errMsg = "Directory already exists"; + break; + + case pdFREERTOS_ERRNO_ENOTDIR: + errMsg = "Invalid path"; + break; /* -34 The path of the file was not found. *//*_RB_ As before, what do these negative numbers relate to? */ + + case pdFREERTOS_ERRNO_ENOTEMPTY: + errMsg = "Dir not empty"; + break; + + case pdFREERTOS_ERRNO_EROFS: + errMsg = "Read-only"; + break; /* -33 Tried to FF_Open() a file marked read only. */ + + default: + errMsg = strerror( iErrorNo ); + break; + } + + if( iErrorNo == pdFREERTOS_ERRNO_ENOSPC ) + { + xFTPCode = 552; + } + + xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), + "%ld-\"%s\" %s;\r\n" + "%ld taking no action\r\n", + xFTPCode, pxClient->pcFileName, errMsg, xFTPCode ); + FreeRTOS_printf( ( "%sdir '%s': %s\n", xDoRemove ? "rm" : "mk", pxClient->pcFileName, errMsg ) ); + } + + prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength ); + + return xResult; + } +/*-----------------------------------------------------------*/ + + static portINLINE BaseType_t IsDigit( char cChar ) + { + BaseType_t xResult; + + if( ( cChar >= '0' ) && ( cChar <= '9' ) ) + { + xResult = pdTRUE; + } + else + { + xResult = pdFALSE; + } + + return xResult; + } + + static BaseType_t prvSendReply( Socket_t xSocket, + const char * pcBuffer, + BaseType_t xLength ) + { + BaseType_t xResult; + + if( xLength == 0 ) + { + xLength = strlen( pcBuffer ); + } + + xResult = FreeRTOS_send( xSocket, ( const void * ) pcBuffer, ( size_t ) xLength, 0 ); + + if( IsDigit( ( int ) pcBuffer[ 0 ] ) && + IsDigit( ( int ) pcBuffer[ 1 ] ) && + IsDigit( ( int ) pcBuffer[ 2 ] ) && + IsDigit( ( int ) pcBuffer[ 3 ] ) ) + { + const char * last = pcBuffer + strlen( pcBuffer ); + int iLength; + + while( ( last > pcBuffer ) && ( ( last[ -1 ] == ftpASCII_CR ) || ( last[ -1 ] == ftpASCII_LF ) ) ) + { + last--; + } + + iLength = ( int ) ( last - pcBuffer ); + FF_PRINTF( " %-*.*s", iLength, iLength, pcBuffer ); + } + + return xResult; + } +/*-----------------------------------------------------------*/ + + #if ( ipconfigFTP_HAS_RECEIVED_HOOK != 0 ) + +/* + * The following function is called for every file received: + * void vApplicationFTPReceivedHook( pcFileName, ulSize, pxFTPClient ); + * This callback function may do a callback to vFTPReplyMessage() to send messages + * to the FTP client like: + * 200-Please wait: Received new firmware + * 200-Please wait: Please wait a few seconds for reboot + */ + void vFTPReplyMessage( struct xFTP_CLIENT * pxFTPClient, + const char * pcMessage ) + { + if( ( pxFTPClient != NULL ) && ( pxFTPClient->xSocket != NULL ) ) + { + prvSendReply( pxFTPClient->xSocket, pcMessage, 0 ); + } + } + /*-----------------------------------------------------------*/ + + #endif /* ipconfigFTP_HAS_RECEIVED_HOOK != 0 */ + +/* + * Some explanation: + * The FTP client may send: "DELE readme.txt" + * Here the complete path is constructed consisting of 3 parts: + * + * pxClient->pcRootDir + pxClient->pcCurrentDir + pcFileName + * + * 'pcCurrentDir' will not be applied for an absolute path like in "DELE /.htaccess" + */ + BaseType_t xMakeAbsolute( FTPClient_t * pxClient, + char * pcBuffer, + BaseType_t xBufferLength, + const char * pcFileName ) + { + BaseType_t xLength = strlen( pxClient->pcRootDir ); + + if( pcFileName[ 0 ] != '/' ) + { + char * pcNewDirBuffer = pcNEW_DIR; + BaseType_t xCurLength; + + xCurLength = strlen( pxClient->pcCurrentDir ); + + if( pcBuffer == pcNEW_DIR ) + { + /* In one call, the result already goes into pcNEW_DIR. + * Use pcFILE_BUFFER in that case */ + pcNewDirBuffer = pcFILE_BUFFER; + } + + snprintf( pcNewDirBuffer, sizeof( pcNEW_DIR ), "%s%s%s", + pxClient->pcCurrentDir, + pxClient->pcCurrentDir[ xCurLength - 1 ] == '/' ? "" : "/", + pcFileName ); + pcFileName = pcNewDirBuffer; + } + + if( strncasecmp( pxClient->pcRootDir, pcFileName, xLength ) == 0 ) + { + xLength = snprintf( pcBuffer, xBufferLength, "%s", pcFileName ); + } + else + { + xLength = snprintf( pcBuffer, xBufferLength, "%s/%s", + pxClient->pcRootDir, + pcFileName[ 0 ] == '/' ? ( pcFileName + 1 ) : pcFileName ); + } + + #if ( ipconfigFTP_FS_USES_BACKSLASH == 1 ) + for( pcPtr = pcBuffer; *pcPtr; pcPtr++ ) + { + if( pcPtr[ 0 ] == '/' ) + { + pcPtr[ 0 ] = '\\'; + } + } + #endif + + return xLength; + } +/*-----------------------------------------------------------*/ + + BaseType_t xMakeRelative( FTPClient_t * pxClient, + char * pcBuffer, + BaseType_t xBufferLength, + const char * pcFileName ) + { + BaseType_t xLength = strlen( pxClient->pcRootDir ); + + if( strncasecmp( pxClient->pcRootDir, pcFileName, xLength ) == 0 ) + { + xLength = snprintf( pcBuffer, xBufferLength, "%s", pcFileName + xLength ); + } + else + { + xLength = snprintf( pcBuffer, xBufferLength, "%s", pcFileName ); + } + + return xLength; + } +/*-----------------------------------------------------------*/ + +#endif /* ipconfigUSE_FTP */ diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP_Server/FreeRTOS_HTTP_commands.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP_Server/FreeRTOS_HTTP_commands.c index f7118a604..faaa7b5c7 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP_Server/FreeRTOS_HTTP_commands.c +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP_Server/FreeRTOS_HTTP_commands.c @@ -1,76 +1,87 @@ -/* - *! - *! The protocols implemented in this file are intended to be demo quality only, - *! and not for production devices. - *! - * - * FreeRTOS+TCP V2.0.3 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://aws.amazon.com/freertos - * https://www.FreeRTOS.org - */ - - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" - -#include "FreeRTOS_HTTP_commands.h" - -const struct xWEB_COMMAND xWebCommands[ WEB_CMD_COUNT ] = -{ - { 3, "GET", ECMD_GET }, - { 4, "HEAD", ECMD_HEAD }, - { 4, "POST", ECMD_POST }, - { 3, "PUT", ECMD_PUT }, - { 6, "DELETE", ECMD_DELETE }, - { 5, "TRACE", ECMD_TRACE }, - { 7, "OPTIONS", ECMD_OPTIONS }, - { 7, "CONNECT", ECMD_CONNECT }, - { 5, "PATCH", ECMD_PATCH }, - { 4, "UNKN", ECMD_UNK }, -}; - -const char *webCodename (int aCode) -{ - switch (aCode) { - case WEB_REPLY_OK: // = 200, - return "OK"; - case WEB_NO_CONTENT: // 204 - return "No content"; - case WEB_BAD_REQUEST: // = 400, - return "Bad request"; - case WEB_UNAUTHORIZED: // = 401, - return "Authorization Required"; - case WEB_NOT_FOUND: // = 404, - return "Not Found"; - case WEB_GONE: // = 410, - return "Done"; - case WEB_PRECONDITION_FAILED: // = 412, - return "Precondition Failed"; - case WEB_INTERNAL_SERVER_ERROR: // = 500, - return "Internal Server Error"; - } - return "Unknown"; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + *! + *! The protocols implemented in this file are intended to be demo quality only, + *! and not for production devices. + *! + */ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" + +#include "FreeRTOS_HTTP_commands.h" + +const struct xWEB_COMMAND xWebCommands[ WEB_CMD_COUNT ] = +{ + { 3, "GET", ECMD_GET }, + { 4, "HEAD", ECMD_HEAD }, + { 4, "POST", ECMD_POST }, + { 3, "PUT", ECMD_PUT }, + { 6, "DELETE", ECMD_DELETE }, + { 5, "TRACE", ECMD_TRACE }, + { 7, "OPTIONS", ECMD_OPTIONS }, + { 7, "CONNECT", ECMD_CONNECT }, + { 5, "PATCH", ECMD_PATCH }, + { 4, "UNKN", ECMD_UNK }, +}; + +const char * webCodename( int aCode ) +{ + switch( aCode ) + { + case WEB_REPLY_OK: /* = 200, */ + return "OK"; + + case WEB_NO_CONTENT: /* 204 */ + return "No content"; + + case WEB_BAD_REQUEST: /* = 400, */ + return "Bad request"; + + case WEB_UNAUTHORIZED: /* = 401, */ + return "Authorization Required"; + + case WEB_NOT_FOUND: /* = 404, */ + return "Not Found"; + + case WEB_GONE: /* = 410, */ + return "Done"; + + case WEB_PRECONDITION_FAILED: /* = 412, */ + return "Precondition Failed"; + + case WEB_INTERNAL_SERVER_ERROR: /* = 500, */ + return "Internal Server Error"; + } + + return "Unknown"; +} diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP_Server/FreeRTOS_HTTP_server.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP_Server/FreeRTOS_HTTP_server.c index 39a124365..d61f241ec 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP_Server/FreeRTOS_HTTP_server.c +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP_Server/FreeRTOS_HTTP_server.c @@ -1,433 +1,464 @@ -/* - *! - *! The protocols implemented in this file are intended to be demo quality only, - *! and not for production devices. - *! - * - * FreeRTOS+TCP V2.0.3 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://aws.amazon.com/freertos - * https://www.FreeRTOS.org - */ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" - -/* FreeRTOS Protocol includes. */ -#include "FreeRTOS_HTTP_commands.h" -#include "FreeRTOS_TCP_server.h" -#include "FreeRTOS_server_private.h" - -/* Remove the whole file if HTTP is not supported. */ -#if( ipconfigUSE_HTTP == 1 ) - -/* FreeRTOS+FAT includes. */ -#include "ff_stdio.h" - -#ifndef HTTP_SERVER_BACKLOG - #define HTTP_SERVER_BACKLOG ( 12 ) -#endif - -#ifndef USE_HTML_CHUNKS - #define USE_HTML_CHUNKS ( 0 ) -#endif - -#if !defined( ARRAY_SIZE ) - #define ARRAY_SIZE(x) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] ) -#endif - -/* Some defines to make the code more readbale */ -#define pcCOMMAND_BUFFER pxClient->pxParent->pcCommandBuffer -#define pcNEW_DIR pxClient->pxParent->pcNewDir -#define pcFILE_BUFFER pxClient->pxParent->pcFileBuffer - -#ifndef ipconfigHTTP_REQUEST_CHARACTER - #define ipconfigHTTP_REQUEST_CHARACTER '?' -#endif - -/*_RB_ Need comment block, although fairly self evident. */ -static void prvFileClose( HTTPClient_t *pxClient ); -static BaseType_t prvProcessCmd( HTTPClient_t *pxClient, BaseType_t xIndex ); -static const char *pcGetContentsType( const char *apFname ); -static BaseType_t prvOpenURL( HTTPClient_t *pxClient ); -static BaseType_t prvSendFile( HTTPClient_t *pxClient ); -static BaseType_t prvSendReply( HTTPClient_t *pxClient, BaseType_t xCode ); - -static const char pcEmptyString[1] = { '\0' }; - -typedef struct xTYPE_COUPLE -{ - const char *pcExtension; - const char *pcType; -} TypeCouple_t; - -static TypeCouple_t pxTypeCouples[ ] = -{ - { "html", "text/html" }, - { "css", "text/css" }, - { "js", "text/javascript" }, - { "png", "image/png" }, - { "jpg", "image/jpeg" }, - { "gif", "image/gif" }, - { "txt", "text/plain" }, - { "mp3", "audio/mpeg3" }, - { "wav", "audio/wav" }, - { "flac", "audio/ogg" }, - { "pdf", "application/pdf" }, - { "ttf", "application/x-font-ttf" }, - { "ttc", "application/x-font-ttf" } -}; - -void vHTTPClientDelete( TCPClient_t *pxTCPClient ) -{ -HTTPClient_t *pxClient = ( HTTPClient_t * ) pxTCPClient; - - /* This HTTP client stops, close / release all resources. */ - if( pxClient->xSocket != FREERTOS_NO_SOCKET ) - { - FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_ALL ); - FreeRTOS_closesocket( pxClient->xSocket ); - pxClient->xSocket = FREERTOS_NO_SOCKET; - } - prvFileClose( pxClient ); -} -/*-----------------------------------------------------------*/ - -static void prvFileClose( HTTPClient_t *pxClient ) -{ - if( pxClient->pxFileHandle != NULL ) - { - FreeRTOS_printf( ( "Closing file: %s\n", pxClient->pcCurrentFilename ) ); - ff_fclose( pxClient->pxFileHandle ); - pxClient->pxFileHandle = NULL; - } -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvSendReply( HTTPClient_t *pxClient, BaseType_t xCode ) -{ -struct xTCP_SERVER *pxParent = pxClient->pxParent; -BaseType_t xRc; - - /* A normal command reply on the main socket (port 21). */ - char *pcBuffer = pxParent->pcFileBuffer; - - xRc = snprintf( pcBuffer, sizeof( pxParent->pcFileBuffer ), - "HTTP/1.1 %d %s\r\n" -#if USE_HTML_CHUNKS - "Transfer-Encoding: chunked\r\n" -#endif - "Content-Type: %s\r\n" - "Connection: keep-alive\r\n" - "%s\r\n", - ( int ) xCode, - webCodename (xCode), - pxParent->pcContentsType[0] ? pxParent->pcContentsType : "text/html", - pxParent->pcExtraContents ); - - pxParent->pcContentsType[0] = '\0'; - pxParent->pcExtraContents[0] = '\0'; - - xRc = FreeRTOS_send( pxClient->xSocket, ( const void * ) pcBuffer, xRc, 0 ); - pxClient->bits.bReplySent = pdTRUE_UNSIGNED; - - return xRc; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvSendFile( HTTPClient_t *pxClient ) -{ -size_t uxSpace; -size_t uxCount; -BaseType_t xRc = 0; - - if( pxClient->bits.bReplySent == pdFALSE_UNSIGNED ) - { - pxClient->bits.bReplySent = pdTRUE_UNSIGNED; - - strcpy( pxClient->pxParent->pcContentsType, pcGetContentsType( pxClient->pcCurrentFilename ) ); - snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ), - "Content-Length: %d\r\n", ( int ) pxClient->uxBytesLeft ); - - /* "Requested file action OK". */ - xRc = prvSendReply( pxClient, WEB_REPLY_OK ); - } - - if( xRc >= 0 ) do - { - uxSpace = FreeRTOS_tx_space( pxClient->xSocket ); - - if( pxClient->uxBytesLeft < uxSpace ) - { - uxCount = pxClient->uxBytesLeft; - } - else - { - uxCount = uxSpace; - } - - if( uxCount > 0u ) - { - if( uxCount > sizeof( pxClient->pxParent->pcFileBuffer ) ) - { - uxCount = sizeof( pxClient->pxParent->pcFileBuffer ); - } - ff_fread( pxClient->pxParent->pcFileBuffer, 1, uxCount, pxClient->pxFileHandle ); - pxClient->uxBytesLeft -= uxCount; - - xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pxParent->pcFileBuffer, uxCount, 0 ); - if( xRc < 0 ) - { - break; - } - } - } while( uxCount > 0u ); - - if( pxClient->uxBytesLeft == 0u ) - { - /* Writing is ready, no need for further 'eSELECT_WRITE' events. */ - FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); - prvFileClose( pxClient ); - } - else - { - /* Wake up the TCP task as soon as this socket may be written to. */ - FreeRTOS_FD_SET( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); - } - - return xRc; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvOpenURL( HTTPClient_t *pxClient ) -{ -BaseType_t xRc; -char pcSlash[ 2 ]; - - pxClient->bits.ulFlags = 0; - - #if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 ) - { - if( strchr( pxClient->pcUrlData, ipconfigHTTP_REQUEST_CHARACTER ) != NULL ) - { - size_t xResult; - - xResult = uxApplicationHTTPHandleRequestHook( pxClient->pcUrlData, pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ) ); - if( xResult > 0 ) - { - strcpy( pxClient->pxParent->pcContentsType, "text/html" ); - snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ), - "Content-Length: %d\r\n", ( int ) xResult ); - xRc = prvSendReply( pxClient, WEB_REPLY_OK ); /* "Requested file action OK" */ - if( xRc > 0 ) - { - xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pcCurrentFilename, xResult, 0 ); - } - /* Although against the coding standard of FreeRTOS, a return is - done here to simplify this conditional code. */ - return xRc; - } - } - } - #endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */ - - if( pxClient->pcUrlData[ 0 ] != '/' ) - { - /* Insert a slash before the file name. */ - pcSlash[ 0 ] = '/'; - pcSlash[ 1 ] = '\0'; - } - else - { - /* The browser provided a starting '/' already. */ - pcSlash[ 0 ] = '\0'; - } - snprintf( pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ), "%s%s%s", - pxClient->pcRootDir, - pcSlash, - pxClient->pcUrlData); - - pxClient->pxFileHandle = ff_fopen( pxClient->pcCurrentFilename, "rb" ); - - FreeRTOS_printf( ( "Open file '%s': %s\n", pxClient->pcCurrentFilename, - pxClient->pxFileHandle != NULL ? "Ok" : strerror( stdioGET_ERRNO() ) ) ); - - if( pxClient->pxFileHandle == NULL ) - { - /* "404 File not found". */ - xRc = prvSendReply( pxClient, WEB_NOT_FOUND ); - } - else - { - pxClient->uxBytesLeft = ( size_t ) pxClient->pxFileHandle->ulFileSize; - xRc = prvSendFile( pxClient ); - } - - return xRc; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvProcessCmd( HTTPClient_t *pxClient, BaseType_t xIndex ) -{ -BaseType_t xResult = 0; - - /* A new command has been received. Process it. */ - switch( xIndex ) - { - case ECMD_GET: - xResult = prvOpenURL( pxClient ); - break; - - case ECMD_HEAD: - case ECMD_POST: - case ECMD_PUT: - case ECMD_DELETE: - case ECMD_TRACE: - case ECMD_OPTIONS: - case ECMD_CONNECT: - case ECMD_PATCH: - case ECMD_UNK: - { - FreeRTOS_printf( ( "prvProcessCmd: Not implemented: %s\n", - xWebCommands[xIndex].pcCommandName ) ); - } - break; - } - - return xResult; -} -/*-----------------------------------------------------------*/ - -BaseType_t xHTTPClientWork( TCPClient_t *pxTCPClient ) -{ -BaseType_t xRc; -HTTPClient_t *pxClient = ( HTTPClient_t * ) pxTCPClient; - - if( pxClient->pxFileHandle != NULL ) - { - prvSendFile( pxClient ); - } - - xRc = FreeRTOS_recv( pxClient->xSocket, ( void * )pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), 0 ); - - if( xRc > 0 ) - { - BaseType_t xIndex; - const char *pcEndOfCmd; - const struct xWEB_COMMAND *curCmd; - char *pcBuffer = pcCOMMAND_BUFFER; - - if( xRc < ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) ) - { - pcBuffer[ xRc ] = '\0'; - } - while( xRc && ( pcBuffer[ xRc - 1 ] == 13 || pcBuffer[ xRc - 1 ] == 10 ) ) - { - pcBuffer[ --xRc ] = '\0'; - } - pcEndOfCmd = pcBuffer + xRc; - - curCmd = xWebCommands; - - /* Pointing to "/index.html HTTP/1.1". */ - pxClient->pcUrlData = pcBuffer; - - /* Pointing to "HTTP/1.1". */ - pxClient->pcRestData = pcEmptyString; - - /* Last entry is "ECMD_UNK". */ - for( xIndex = 0; xIndex < WEB_CMD_COUNT - 1; xIndex++, curCmd++ ) - { - BaseType_t xLength; - - xLength = curCmd->xCommandLength; - if( ( xRc >= xLength ) && ( memcmp( curCmd->pcCommandName, pcBuffer, xLength ) == 0 ) ) - { - char *pcLastPtr; - - pxClient->pcUrlData += xLength + 1; - for( pcLastPtr = (char *)pxClient->pcUrlData; pcLastPtr < pcEndOfCmd; pcLastPtr++ ) - { - char ch = *pcLastPtr; - if( ( ch == '\0' ) || ( strchr( "\n\r \t", ch ) != NULL ) ) - { - *pcLastPtr = '\0'; - pxClient->pcRestData = pcLastPtr + 1; - break; - } - } - break; - } - } - - if( xIndex < ( WEB_CMD_COUNT - 1 ) ) - { - xRc = prvProcessCmd( pxClient, xIndex ); - } - } - else if( xRc < 0 ) - { - /* The connection will be closed and the client will be deleted. */ - FreeRTOS_printf( ( "xHTTPClientWork: rc = %ld\n", xRc ) ); - } - return xRc; -} -/*-----------------------------------------------------------*/ - -static const char *pcGetContentsType (const char *apFname) -{ - const char *slash = NULL; - const char *dot = NULL; - const char *ptr; - const char *pcResult = "text/html"; - BaseType_t x; - - for( ptr = apFname; *ptr; ptr++ ) - { - if (*ptr == '.') dot = ptr; - if (*ptr == '/') slash = ptr; - } - if( dot > slash ) - { - dot++; - for( x = 0; x < ARRAY_SIZE( pxTypeCouples ); x++ ) - { - if( strcasecmp( dot, pxTypeCouples[ x ].pcExtension ) == 0 ) - { - pcResult = pxTypeCouples[ x ].pcType; - break; - } - } - } - return pcResult; -} - -#endif /* ipconfigUSE_HTTP */ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + *! + *! The protocols implemented in this file are intended to be demo quality only, + *! and not for production devices. + *! + */ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" + +/* FreeRTOS Protocol includes. */ +#include "FreeRTOS_HTTP_commands.h" +#include "FreeRTOS_TCP_server.h" +#include "FreeRTOS_server_private.h" + +/* Remove the whole file if HTTP is not supported. */ +#if ( ipconfigUSE_HTTP == 1 ) + +/* FreeRTOS+FAT includes. */ + #include "ff_stdio.h" + + #ifndef HTTP_SERVER_BACKLOG + #define HTTP_SERVER_BACKLOG ( 12 ) + #endif + + #ifndef USE_HTML_CHUNKS + #define USE_HTML_CHUNKS ( 0 ) + #endif + + #if !defined( ARRAY_SIZE ) + #define ARRAY_SIZE( x ) ( BaseType_t ) ( sizeof( x ) / sizeof( x )[ 0 ] ) + #endif + +/* Some defines to make the code more readbale */ + #define pcCOMMAND_BUFFER pxClient->pxParent->pcCommandBuffer + #define pcNEW_DIR pxClient->pxParent->pcNewDir + #define pcFILE_BUFFER pxClient->pxParent->pcFileBuffer + + #ifndef ipconfigHTTP_REQUEST_CHARACTER + #define ipconfigHTTP_REQUEST_CHARACTER '?' + #endif + +/*_RB_ Need comment block, although fairly self evident. */ + static void prvFileClose( HTTPClient_t * pxClient ); + static BaseType_t prvProcessCmd( HTTPClient_t * pxClient, + BaseType_t xIndex ); + static const char * pcGetContentsType( const char * apFname ); + static BaseType_t prvOpenURL( HTTPClient_t * pxClient ); + static BaseType_t prvSendFile( HTTPClient_t * pxClient ); + static BaseType_t prvSendReply( HTTPClient_t * pxClient, + BaseType_t xCode ); + + static const char pcEmptyString[ 1 ] = { '\0' }; + + typedef struct xTYPE_COUPLE + { + const char * pcExtension; + const char * pcType; + } TypeCouple_t; + + static TypeCouple_t pxTypeCouples[] = + { + { "html", "text/html" }, + { "css", "text/css" }, + { "js", "text/javascript" }, + { "png", "image/png" }, + { "jpg", "image/jpeg" }, + { "gif", "image/gif" }, + { "txt", "text/plain" }, + { "mp3", "audio/mpeg3" }, + { "wav", "audio/wav" }, + { "flac", "audio/ogg" }, + { "pdf", "application/pdf" }, + { "ttf", "application/x-font-ttf" }, + { "ttc", "application/x-font-ttf" } + }; + + void vHTTPClientDelete( TCPClient_t * pxTCPClient ) + { + HTTPClient_t * pxClient = ( HTTPClient_t * ) pxTCPClient; + + /* This HTTP client stops, close / release all resources. */ + if( pxClient->xSocket != FREERTOS_NO_SOCKET ) + { + FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_ALL ); + FreeRTOS_closesocket( pxClient->xSocket ); + pxClient->xSocket = FREERTOS_NO_SOCKET; + } + + prvFileClose( pxClient ); + } +/*-----------------------------------------------------------*/ + + static void prvFileClose( HTTPClient_t * pxClient ) + { + if( pxClient->pxFileHandle != NULL ) + { + FreeRTOS_printf( ( "Closing file: %s\n", pxClient->pcCurrentFilename ) ); + ff_fclose( pxClient->pxFileHandle ); + pxClient->pxFileHandle = NULL; + } + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvSendReply( HTTPClient_t * pxClient, + BaseType_t xCode ) + { + struct xTCP_SERVER * pxParent = pxClient->pxParent; + BaseType_t xRc; + + /* A normal command reply on the main socket (port 21). */ + char * pcBuffer = pxParent->pcFileBuffer; + + xRc = snprintf( pcBuffer, sizeof( pxParent->pcFileBuffer ), + "HTTP/1.1 %d %s\r\n" + #if USE_HTML_CHUNKS + "Transfer-Encoding: chunked\r\n" + #endif + "Content-Type: %s\r\n" + "Connection: keep-alive\r\n" + "%s\r\n", + ( int ) xCode, + webCodename( xCode ), + pxParent->pcContentsType[ 0 ] ? pxParent->pcContentsType : "text/html", + pxParent->pcExtraContents ); + + pxParent->pcContentsType[ 0 ] = '\0'; + pxParent->pcExtraContents[ 0 ] = '\0'; + + xRc = FreeRTOS_send( pxClient->xSocket, ( const void * ) pcBuffer, xRc, 0 ); + pxClient->bits.bReplySent = pdTRUE_UNSIGNED; + + return xRc; + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvSendFile( HTTPClient_t * pxClient ) + { + size_t uxSpace; + size_t uxCount; + BaseType_t xRc = 0; + + if( pxClient->bits.bReplySent == pdFALSE_UNSIGNED ) + { + pxClient->bits.bReplySent = pdTRUE_UNSIGNED; + + strcpy( pxClient->pxParent->pcContentsType, pcGetContentsType( pxClient->pcCurrentFilename ) ); + snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ), + "Content-Length: %d\r\n", ( int ) pxClient->uxBytesLeft ); + + /* "Requested file action OK". */ + xRc = prvSendReply( pxClient, WEB_REPLY_OK ); + } + + if( xRc >= 0 ) + { + do + { + uxSpace = FreeRTOS_tx_space( pxClient->xSocket ); + + if( pxClient->uxBytesLeft < uxSpace ) + { + uxCount = pxClient->uxBytesLeft; + } + else + { + uxCount = uxSpace; + } + + if( uxCount > 0u ) + { + if( uxCount > sizeof( pxClient->pxParent->pcFileBuffer ) ) + { + uxCount = sizeof( pxClient->pxParent->pcFileBuffer ); + } + + ff_fread( pxClient->pxParent->pcFileBuffer, 1, uxCount, pxClient->pxFileHandle ); + pxClient->uxBytesLeft -= uxCount; + + xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pxParent->pcFileBuffer, uxCount, 0 ); + + if( xRc < 0 ) + { + break; + } + } + } while( uxCount > 0u ); + } + + if( pxClient->uxBytesLeft == 0u ) + { + /* Writing is ready, no need for further 'eSELECT_WRITE' events. */ + FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); + prvFileClose( pxClient ); + } + else + { + /* Wake up the TCP task as soon as this socket may be written to. */ + FreeRTOS_FD_SET( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE ); + } + + return xRc; + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvOpenURL( HTTPClient_t * pxClient ) + { + BaseType_t xRc; + char pcSlash[ 2 ]; + + pxClient->bits.ulFlags = 0; + + #if ( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 ) + { + if( strchr( pxClient->pcUrlData, ipconfigHTTP_REQUEST_CHARACTER ) != NULL ) + { + size_t xResult; + + xResult = uxApplicationHTTPHandleRequestHook( pxClient->pcUrlData, pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ) ); + + if( xResult > 0 ) + { + strcpy( pxClient->pxParent->pcContentsType, "text/html" ); + snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ), + "Content-Length: %d\r\n", ( int ) xResult ); + xRc = prvSendReply( pxClient, WEB_REPLY_OK ); /* "Requested file action OK" */ + + if( xRc > 0 ) + { + xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pcCurrentFilename, xResult, 0 ); + } + + /* Although against the coding standard of FreeRTOS, a return is + * done here to simplify this conditional code. */ + return xRc; + } + } + } + #endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */ + + if( pxClient->pcUrlData[ 0 ] != '/' ) + { + /* Insert a slash before the file name. */ + pcSlash[ 0 ] = '/'; + pcSlash[ 1 ] = '\0'; + } + else + { + /* The browser provided a starting '/' already. */ + pcSlash[ 0 ] = '\0'; + } + + snprintf( pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ), "%s%s%s", + pxClient->pcRootDir, + pcSlash, + pxClient->pcUrlData ); + + pxClient->pxFileHandle = ff_fopen( pxClient->pcCurrentFilename, "rb" ); + + FreeRTOS_printf( ( "Open file '%s': %s\n", pxClient->pcCurrentFilename, + pxClient->pxFileHandle != NULL ? "Ok" : strerror( stdioGET_ERRNO() ) ) ); + + if( pxClient->pxFileHandle == NULL ) + { + /* "404 File not found". */ + xRc = prvSendReply( pxClient, WEB_NOT_FOUND ); + } + else + { + pxClient->uxBytesLeft = ( size_t ) pxClient->pxFileHandle->ulFileSize; + xRc = prvSendFile( pxClient ); + } + + return xRc; + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvProcessCmd( HTTPClient_t * pxClient, + BaseType_t xIndex ) + { + BaseType_t xResult = 0; + + /* A new command has been received. Process it. */ + switch( xIndex ) + { + case ECMD_GET: + xResult = prvOpenURL( pxClient ); + break; + + case ECMD_HEAD: + case ECMD_POST: + case ECMD_PUT: + case ECMD_DELETE: + case ECMD_TRACE: + case ECMD_OPTIONS: + case ECMD_CONNECT: + case ECMD_PATCH: + case ECMD_UNK: + FreeRTOS_printf( ( "prvProcessCmd: Not implemented: %s\n", + xWebCommands[ xIndex ].pcCommandName ) ); + break; + } + + return xResult; + } +/*-----------------------------------------------------------*/ + + BaseType_t xHTTPClientWork( TCPClient_t * pxTCPClient ) + { + BaseType_t xRc; + HTTPClient_t * pxClient = ( HTTPClient_t * ) pxTCPClient; + + if( pxClient->pxFileHandle != NULL ) + { + prvSendFile( pxClient ); + } + + xRc = FreeRTOS_recv( pxClient->xSocket, ( void * ) pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), 0 ); + + if( xRc > 0 ) + { + BaseType_t xIndex; + const char * pcEndOfCmd; + const struct xWEB_COMMAND * curCmd; + char * pcBuffer = pcCOMMAND_BUFFER; + + if( xRc < ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) ) + { + pcBuffer[ xRc ] = '\0'; + } + + while( xRc && ( pcBuffer[ xRc - 1 ] == 13 || pcBuffer[ xRc - 1 ] == 10 ) ) + { + pcBuffer[ --xRc ] = '\0'; + } + + pcEndOfCmd = pcBuffer + xRc; + + curCmd = xWebCommands; + + /* Pointing to "/index.html HTTP/1.1". */ + pxClient->pcUrlData = pcBuffer; + + /* Pointing to "HTTP/1.1". */ + pxClient->pcRestData = pcEmptyString; + + /* Last entry is "ECMD_UNK". */ + for( xIndex = 0; xIndex < WEB_CMD_COUNT - 1; xIndex++, curCmd++ ) + { + BaseType_t xLength; + + xLength = curCmd->xCommandLength; + + if( ( xRc >= xLength ) && ( memcmp( curCmd->pcCommandName, pcBuffer, xLength ) == 0 ) ) + { + char * pcLastPtr; + + pxClient->pcUrlData += xLength + 1; + + for( pcLastPtr = ( char * ) pxClient->pcUrlData; pcLastPtr < pcEndOfCmd; pcLastPtr++ ) + { + char ch = *pcLastPtr; + + if( ( ch == '\0' ) || ( strchr( "\n\r \t", ch ) != NULL ) ) + { + *pcLastPtr = '\0'; + pxClient->pcRestData = pcLastPtr + 1; + break; + } + } + + break; + } + } + + if( xIndex < ( WEB_CMD_COUNT - 1 ) ) + { + xRc = prvProcessCmd( pxClient, xIndex ); + } + } + else if( xRc < 0 ) + { + /* The connection will be closed and the client will be deleted. */ + FreeRTOS_printf( ( "xHTTPClientWork: rc = %ld\n", xRc ) ); + } + + return xRc; + } +/*-----------------------------------------------------------*/ + + static const char * pcGetContentsType( const char * apFname ) + { + const char * slash = NULL; + const char * dot = NULL; + const char * ptr; + const char * pcResult = "text/html"; + BaseType_t x; + + for( ptr = apFname; *ptr; ptr++ ) + { + if( *ptr == '.' ) + { + dot = ptr; + } + + if( *ptr == '/' ) + { + slash = ptr; + } + } + + if( dot > slash ) + { + dot++; + + for( x = 0; x < ARRAY_SIZE( pxTypeCouples ); x++ ) + { + if( strcasecmp( dot, pxTypeCouples[ x ].pcExtension ) == 0 ) + { + pcResult = pxTypeCouples[ x ].pcType; + break; + } + } + } + + return pcResult; + } + +#endif /* ipconfigUSE_HTTP */ diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/NTPDemo.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/NTPDemo.c index 93d90e5bf..100c39bb7 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/NTPDemo.c +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/NTPDemo.c @@ -1,469 +1,498 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - *! - *! The protocols implemented in this file are intended to be demo quality only, - *! and not for production devices. - *! - * - * NTPDemo.c - * - * An example of how to lookup a domain using DNS - * And also how to send and receive UDP messages to get the NTP time - * - */ - -/* Standard includes. */ -#include -#include -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "semphr.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" -#include "FreeRTOS_DNS.h" -#include "FreeRTOS_Stream_Buffer.h" - -/* Use the date & time functions from +FAT. */ -#include "ff_time.h" - -#include "NTPDemo.h" -#include "ntpClient.h" - -#include "date_and_time.h" - -enum EStatus { - EStatusLookup, - EStatusAsking, - EStatusPause, - EStatusFailed, -}; - -static struct SNtpPacket xNTPPacket; - -#if( ipconfigUSE_CALLBACKS == 0 ) - static char cRecvBuffer[ sizeof( struct SNtpPacket ) + 64 ]; -#endif - -static enum EStatus xStatus = EStatusLookup; - -static const char *pcTimeServers[] = { - "0.asia.pool.ntp.org", - "0.europe.pool.ntp.org", - "0.id.pool.ntp.org", - "0.south-america.pool.ntp.org", - "0.oceania.pool.ntp.org", - "0.north-america.pool.ntp.org" -}; - -static SemaphoreHandle_t xNTPWakeupSem = NULL; -static uint32_t ulIPAddressFound; -static Socket_t xUDPSocket = NULL; -static TaskHandle_t xNTPTaskhandle = NULL; -static TickType_t uxSendTime; - -static void prvNTPTask( void *pvParameters ); - -static void vSignalTask( void ) -{ - #if( ipconfigUSE_CALLBACKS == 0 ) - if( xUDPSocket != NULL ) - { - /* Send a signal to the socket so that the - FreeRTOS_recvfrom will get interrupted. */ - FreeRTOS_SignalSocket( xUDPSocket ); - } - else - #endif - if( xNTPWakeupSem != NULL ) - { - xSemaphoreGive( xNTPWakeupSem ); - } -} - -void vStartNTPTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority ) -{ - /* The only public function in this module: start a task to contact - some NTP server. */ - - if( xNTPTaskhandle != NULL ) - { - switch( xStatus ) - { - case EStatusPause: - xStatus = EStatusAsking; - vSignalTask(); - break; - case EStatusLookup: - FreeRTOS_printf( ( "NTP looking up server\n" ) ); - break; - case EStatusAsking: - FreeRTOS_printf( ( "NTP still asking\n" ) ); - break; - case EStatusFailed: - FreeRTOS_printf( ( "NTP failed somehow\n" ) ); - ulIPAddressFound = 0ul; - xStatus = EStatusLookup; - vSignalTask(); - break; - } - } - else - { - xUDPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - if( xUDPSocket != FREERTOS_INVALID_SOCKET ) - { - struct freertos_sockaddr xAddress; - #if( ipconfigUSE_CALLBACKS != 0 ) - BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 0 ); - #else - BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 ); - #endif - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xAddress.sin_address.ulIP_IPv4 = 0ul; - } - #else - { - xAddress.sin_addr = 0ul; - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xAddress.sin_port = FreeRTOS_htons( NTP_PORT ); - xAddress.sin_family = FREERTOS_AF_INET; - - FreeRTOS_bind( xUDPSocket, &xAddress, sizeof( xAddress ) ); - FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); - xTaskCreate( prvNTPTask, /* The function that implements the task. */ - ( const char * ) "NTP client", /* Just a text name for the task to aid debugging. */ - usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ - NULL, /* The task parameter, not used in this case. */ - uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ - &xNTPTaskhandle ); /* The task handle. */ - } - else - { - FreeRTOS_printf( ( "Creating socket failed\n" ) ); - } - } -} -/*-----------------------------------------------------------*/ - -static void vDNS_callback( const char *pcName, void *pvSearchID, uint32_t ulIPAddress ) -{ -char pcBuf[16]; - - /* The DNS lookup has a result, or it has reached the time-out. */ - FreeRTOS_inet_ntoa( ulIPAddress, pcBuf ); - FreeRTOS_printf( ( "IP address of %s found: %s\n", pcName, pcBuf ) ); - if( ulIPAddressFound == 0ul ) - { - ulIPAddressFound = ulIPAddress; - } - /* For testing: in case DNS doen't respond, still try some NTP server - with a known IP-address. */ - if( ulIPAddressFound == 0ul ) - { - ulIPAddressFound = FreeRTOS_inet_addr_quick( 184, 105, 182, 7 ); -/* ulIPAddressFound = FreeRTOS_inet_addr_quick( 103, 242, 70, 4 ); */ - } - xStatus = EStatusAsking; - - vSignalTask(); -} -/*-----------------------------------------------------------*/ - -static void prvSwapFields( struct SNtpPacket *pxPacket) -{ - /* NTP messages are big-endian */ - pxPacket->rootDelay = FreeRTOS_htonl( pxPacket->rootDelay ); - pxPacket->rootDispersion = FreeRTOS_htonl( pxPacket->rootDispersion ); - - pxPacket->referenceTimestamp.seconds = FreeRTOS_htonl( pxPacket->referenceTimestamp.seconds ); - pxPacket->referenceTimestamp.fraction = FreeRTOS_htonl( pxPacket->referenceTimestamp.fraction ); - - pxPacket->originateTimestamp.seconds = FreeRTOS_htonl( pxPacket->originateTimestamp.seconds ); - pxPacket->originateTimestamp.fraction = FreeRTOS_htonl( pxPacket->originateTimestamp.fraction ); - - pxPacket->receiveTimestamp.seconds = FreeRTOS_htonl( pxPacket->receiveTimestamp.seconds ); - pxPacket->receiveTimestamp.fraction = FreeRTOS_htonl( pxPacket->receiveTimestamp.fraction ); - - pxPacket->transmitTimestamp.seconds = FreeRTOS_htonl( pxPacket->transmitTimestamp.seconds ); - pxPacket->transmitTimestamp.fraction = FreeRTOS_htonl( pxPacket->transmitTimestamp.fraction ); -} -/*-----------------------------------------------------------*/ - -static void prvNTPPacketInit( ) -{ - memset (&xNTPPacket, '\0', sizeof( xNTPPacket ) ); - - xNTPPacket.flags = 0xDB; /* value 0xDB : mode 3 (client), version 3, leap indicator unknown 3 */ - xNTPPacket.poll = 10; /* 10 means 1 << 10 = 1024 seconds */ - xNTPPacket.precision = 0xFA; /* = 250 = 0.015625 seconds */ - xNTPPacket.rootDelay = 0x5D2E; /* 0x5D2E = 23854 or (23854/65535)= 0.3640 sec */ - xNTPPacket.rootDispersion = 0x0008CAC8; /* 0x0008CAC8 = 8.7912 seconds */ - - /* use the recorded NTP time */ - time_t uxSecs = FreeRTOS_time( NULL );/* apTime may be NULL, returns seconds */ - - xNTPPacket.referenceTimestamp.seconds = uxSecs; /* Current time */ - xNTPPacket.transmitTimestamp.seconds = uxSecs + 3; - - /* Transform the contents of the fields from native to big endian. */ - prvSwapFields( &xNTPPacket ); -} -/*-----------------------------------------------------------*/ - -static void prvReadTime( struct SNtpPacket * pxPacket ) -{ - FF_TimeStruct_t xTimeStruct; - time_t uxPreviousSeconds; - time_t uxPreviousMS; - - time_t uxCurrentSeconds; - time_t uxCurrentMS; - - const char *pcTimeUnit; - int32_t ilDiff; - TickType_t uxTravelTime; - - uxTravelTime = xTaskGetTickCount() - uxSendTime; - - /* Transform the contents of the fields from big to native endian. */ - prvSwapFields( pxPacket ); - - uxCurrentSeconds = pxPacket->receiveTimestamp.seconds - TIME1970; - uxCurrentMS = pxPacket->receiveTimestamp.fraction / 4294967; - uxCurrentSeconds += uxCurrentMS / 1000; - uxCurrentMS = uxCurrentMS % 1000; - - // Get the last time recorded - uxPreviousSeconds = FreeRTOS_get_secs_msec( &uxPreviousMS ); - - // Set the new time with precision in msec. */ - FreeRTOS_set_secs_msec( &uxCurrentSeconds, &uxCurrentMS ); - - if( uxCurrentSeconds >= uxPreviousSeconds ) - { - ilDiff = ( int32_t ) ( uxCurrentSeconds - uxPreviousSeconds ); - } - else - { - ilDiff = 0 - ( int32_t ) ( uxPreviousSeconds - uxCurrentSeconds ); - } - - if( ( ilDiff < -5 ) || ( ilDiff > 5 ) ) - { - /* More than 5 seconds difference. */ - pcTimeUnit = "sec"; - } - else - { - /* Less than or equal to 5 second difference. */ - pcTimeUnit = "ms"; - uint32_t ulLowest = ( uxCurrentSeconds <= uxPreviousSeconds ) ? uxCurrentSeconds : uxPreviousSeconds; - int32_t iCurMS = 1000 * ( uxCurrentSeconds - ulLowest ) + uxCurrentMS; - int32_t iPrevMS = 1000 * ( uxPreviousSeconds - ulLowest ) + uxPreviousMS; - ilDiff = iCurMS - iPrevMS; - } - uxCurrentSeconds -= iTimeZone; - - FreeRTOS_gmtime_r( &uxCurrentSeconds, &xTimeStruct ); - - /* - 378.067 [NTP client] NTP time: 9/11/2015 16:11:19.559 Diff -20 ms (289 ms) - 379.441 [NTP client] NTP time: 9/11/2015 16:11:20.933 Diff 0 ms (263 ms) - */ - - FreeRTOS_printf( ("NTP time: %d/%d/%02d %2d:%02d:%02d.%03u Diff %d %s (%lu ms)\n", - xTimeStruct.tm_mday, - xTimeStruct.tm_mon + 1, - xTimeStruct.tm_year + 1900, - xTimeStruct.tm_hour, - xTimeStruct.tm_min, - xTimeStruct.tm_sec, - ( unsigned )uxCurrentMS, - ( unsigned )ilDiff, - pcTimeUnit, - uxTravelTime ) ); - - /* Remove compiler warnings in case FreeRTOS_printf() is not used. */ - ( void ) pcTimeUnit; - ( void ) uxTravelTime; -} -/*-----------------------------------------------------------*/ - -#if( ipconfigUSE_CALLBACKS != 0 ) - - static BaseType_t xOnUDPReceive( Socket_t xSocket, void * pvData, size_t xLength, - const struct freertos_sockaddr *pxFrom, const struct freertos_sockaddr *pxDest ) - { - if( xLength >= sizeof( xNTPPacket ) ) - { - prvReadTime( ( struct SNtpPacket *)pvData ); - if( xStatus != EStatusPause ) - { - xStatus = EStatusPause; - } - } - vSignalTask(); - /* Tell the driver not to store the RX data */ - return 1; - } - /*-----------------------------------------------------------*/ - -#endif /* ipconfigUSE_CALLBACKS != 0 */ - -static void prvNTPTask( void *pvParameters ) -{ -BaseType_t xServerIndex = 3; -struct freertos_sockaddr xAddress; -#if( ipconfigUSE_CALLBACKS != 0 ) - F_TCP_UDP_Handler_t xHandler; -#endif /* ipconfigUSE_CALLBACKS != 0 */ - - xStatus = EStatusLookup; - #if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) || ( ipconfigUSE_CALLBACKS != 0 ) - { - xNTPWakeupSem = xSemaphoreCreateBinary(); - } - #endif - - #if( ipconfigUSE_CALLBACKS != 0 ) - { - memset( &xHandler, '\0', sizeof( xHandler ) ); - xHandler.pxOnUDPReceive = xOnUDPReceive; - FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) ); - } - #endif - #if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) - { - FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SET_SEMAPHORE, ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) ); - } - #endif - for( ; ; ) - { - switch( xStatus ) - { - case EStatusLookup: - if( ( ulIPAddressFound == 0ul ) || ( ulIPAddressFound == ~0ul ) ) - { - if( ++xServerIndex == sizeof( pcTimeServers ) / sizeof( pcTimeServers[ 0 ] ) ) - { - xServerIndex = 0; - } - FreeRTOS_printf( ( "Looking up server '%s'\n", pcTimeServers[ xServerIndex ] ) ); - FreeRTOS_gethostbyname_a( pcTimeServers[ xServerIndex ], vDNS_callback, (void *)NULL, 1200 ); - } - else - { - xStatus = EStatusAsking; - } - break; - - case EStatusAsking: - { - char pcBuf[16]; - - prvNTPPacketInit( ); - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xAddress.sin_address.ulIP_IPv4 = ulIPAddressFound; - xAddress.sin_port = FreeRTOS_htons( NTP_PORT ); - FreeRTOS_inet_ntoa( xAddress.sin_address.ulIP_IPv4, pcBuf ); - } - #else - { - xAddress.sin_addr = ulIPAddressFound; - xAddress.sin_port = FreeRTOS_htons( NTP_PORT ); - FreeRTOS_inet_ntoa( xAddress.sin_addr, pcBuf ); - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xAddress.sin_family = FREERTOS_AF_INET; - - FreeRTOS_printf( ( "Sending UDP message to %s:%u\n", - pcBuf, - FreeRTOS_ntohs( xAddress.sin_port ) ) ); - - uxSendTime = xTaskGetTickCount( ); - FreeRTOS_sendto( xUDPSocket, ( void * )&xNTPPacket, sizeof( xNTPPacket ), 0, &xAddress, sizeof( xAddress ) ); - } - break; - - case EStatusPause: - break; - - case EStatusFailed: - break; - } - - #if( ipconfigUSE_CALLBACKS != 0 ) - { - xSemaphoreTake( xNTPWakeupSem, 5000 ); - } - #else - { - uint32_t xAddressSize; - BaseType_t xReturned; - - xAddressSize = sizeof( xAddress ); - xReturned = FreeRTOS_recvfrom( xUDPSocket, ( void * ) cRecvBuffer, sizeof( cRecvBuffer ), 0, &xAddress, &xAddressSize ); - switch( xReturned ) - { - case 0: - case -pdFREERTOS_ERRNO_EAGAIN: - case -pdFREERTOS_ERRNO_EINTR: - break; - default: - if( xReturned < sizeof( xNTPPacket ) ) - { - FreeRTOS_printf( ( "FreeRTOS_recvfrom: returns %ld\n", xReturned ) ); - } - else - { - prvReadTime( ( struct SNtpPacket *)cRecvBuffer ); - if( xStatus != EStatusPause ) - { - xStatus = EStatusPause; - } - } - break; - } - } - #endif - } -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + *! + *! The protocols implemented in this file are intended to be demo quality only, + *! and not for production devices. + *! + * + * NTPDemo.c + * + * An example of how to lookup a domain using DNS + * And also how to send and receive UDP messages to get the NTP time + * + */ + +/* Standard includes. */ +#include +#include +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" +#include "FreeRTOS_DNS.h" +#include "FreeRTOS_Stream_Buffer.h" + +/* Use the date & time functions from +FAT. */ +#include "ff_time.h" + +#include "NTPDemo.h" +#include "ntpClient.h" + +#include "date_and_time.h" + +enum EStatus +{ + EStatusLookup, + EStatusAsking, + EStatusPause, + EStatusFailed, +}; + +static struct SNtpPacket xNTPPacket; + +#if ( ipconfigUSE_CALLBACKS == 0 ) + static char cRecvBuffer[ sizeof( struct SNtpPacket ) + 64 ]; +#endif + +static enum EStatus xStatus = EStatusLookup; + +static const char * pcTimeServers[] = +{ + "0.asia.pool.ntp.org", + "0.europe.pool.ntp.org", + "0.id.pool.ntp.org", + "0.south-america.pool.ntp.org", + "0.oceania.pool.ntp.org", + "0.north-america.pool.ntp.org" +}; + +static SemaphoreHandle_t xNTPWakeupSem = NULL; +static uint32_t ulIPAddressFound; +static Socket_t xUDPSocket = NULL; +static TaskHandle_t xNTPTaskhandle = NULL; +static TickType_t uxSendTime; + +static void prvNTPTask( void * pvParameters ); + +static void vSignalTask( void ) +{ + #if ( ipconfigUSE_CALLBACKS == 0 ) + if( xUDPSocket != NULL ) + { + /* Send a signal to the socket so that the + * FreeRTOS_recvfrom will get interrupted. */ + FreeRTOS_SignalSocket( xUDPSocket ); + } + else + #endif + + if( xNTPWakeupSem != NULL ) + { + xSemaphoreGive( xNTPWakeupSem ); + } +} + +void vStartNTPTask( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ) +{ + /* The only public function in this module: start a task to contact + * some NTP server. */ + + if( xNTPTaskhandle != NULL ) + { + switch( xStatus ) + { + case EStatusPause: + xStatus = EStatusAsking; + vSignalTask(); + break; + + case EStatusLookup: + FreeRTOS_printf( ( "NTP looking up server\n" ) ); + break; + + case EStatusAsking: + FreeRTOS_printf( ( "NTP still asking\n" ) ); + break; + + case EStatusFailed: + FreeRTOS_printf( ( "NTP failed somehow\n" ) ); + ulIPAddressFound = 0ul; + xStatus = EStatusLookup; + vSignalTask(); + break; + } + } + else + { + xUDPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + + if( xUDPSocket != FREERTOS_INVALID_SOCKET ) + { + struct freertos_sockaddr xAddress; + #if ( ipconfigUSE_CALLBACKS != 0 ) + BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 0 ); + #else + BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 ); + #endif + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xAddress.sin_address.ulIP_IPv4 = 0ul; + } + #else + { + xAddress.sin_addr = 0ul; + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xAddress.sin_port = FreeRTOS_htons( NTP_PORT ); + xAddress.sin_family = FREERTOS_AF_INET; + + FreeRTOS_bind( xUDPSocket, &xAddress, sizeof( xAddress ) ); + FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); + xTaskCreate( prvNTPTask, /* The function that implements the task. */ + ( const char * ) "NTP client", /* Just a text name for the task to aid debugging. */ + usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ + NULL, /* The task parameter, not used in this case. */ + uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ + &xNTPTaskhandle ); /* The task handle. */ + } + else + { + FreeRTOS_printf( ( "Creating socket failed\n" ) ); + } + } +} +/*-----------------------------------------------------------*/ + +static void vDNS_callback( const char * pcName, + void * pvSearchID, + uint32_t ulIPAddress ) +{ + char pcBuf[ 16 ]; + + /* The DNS lookup has a result, or it has reached the time-out. */ + FreeRTOS_inet_ntoa( ulIPAddress, pcBuf ); + FreeRTOS_printf( ( "IP address of %s found: %s\n", pcName, pcBuf ) ); + + if( ulIPAddressFound == 0ul ) + { + ulIPAddressFound = ulIPAddress; + } + + /* For testing: in case DNS doesn't respond, still try some NTP server + * with a known IP-address. */ + if( ulIPAddressFound == 0ul ) + { + ulIPAddressFound = FreeRTOS_inet_addr_quick( 184, 105, 182, 7 ); +/* ulIPAddressFound = FreeRTOS_inet_addr_quick( 103, 242, 70, 4 ); */ + } + + xStatus = EStatusAsking; + + vSignalTask(); +} +/*-----------------------------------------------------------*/ + +static void prvSwapFields( struct SNtpPacket * pxPacket ) +{ + /* NTP messages are big-endian */ + pxPacket->rootDelay = FreeRTOS_htonl( pxPacket->rootDelay ); + pxPacket->rootDispersion = FreeRTOS_htonl( pxPacket->rootDispersion ); + + pxPacket->referenceTimestamp.seconds = FreeRTOS_htonl( pxPacket->referenceTimestamp.seconds ); + pxPacket->referenceTimestamp.fraction = FreeRTOS_htonl( pxPacket->referenceTimestamp.fraction ); + + pxPacket->originateTimestamp.seconds = FreeRTOS_htonl( pxPacket->originateTimestamp.seconds ); + pxPacket->originateTimestamp.fraction = FreeRTOS_htonl( pxPacket->originateTimestamp.fraction ); + + pxPacket->receiveTimestamp.seconds = FreeRTOS_htonl( pxPacket->receiveTimestamp.seconds ); + pxPacket->receiveTimestamp.fraction = FreeRTOS_htonl( pxPacket->receiveTimestamp.fraction ); + + pxPacket->transmitTimestamp.seconds = FreeRTOS_htonl( pxPacket->transmitTimestamp.seconds ); + pxPacket->transmitTimestamp.fraction = FreeRTOS_htonl( pxPacket->transmitTimestamp.fraction ); +} +/*-----------------------------------------------------------*/ + +static void prvNTPPacketInit() +{ + memset( &xNTPPacket, '\0', sizeof( xNTPPacket ) ); + + xNTPPacket.flags = 0xDB; /* value 0xDB : mode 3 (client), version 3, leap indicator unknown 3 */ + xNTPPacket.poll = 10; /* 10 means 1 << 10 = 1024 seconds */ + xNTPPacket.precision = 0xFA; /* = 250 = 0.015625 seconds */ + xNTPPacket.rootDelay = 0x5D2E; /* 0x5D2E = 23854 or (23854/65535)= 0.3640 sec */ + xNTPPacket.rootDispersion = 0x0008CAC8; /* 0x0008CAC8 = 8.7912 seconds */ + + /* use the recorded NTP time */ + time_t uxSecs = FreeRTOS_time( NULL ); /* apTime may be NULL, returns seconds */ + + xNTPPacket.referenceTimestamp.seconds = uxSecs; /* Current time */ + xNTPPacket.transmitTimestamp.seconds = uxSecs + 3; + + /* Transform the contents of the fields from native to big endian. */ + prvSwapFields( &xNTPPacket ); +} +/*-----------------------------------------------------------*/ + +static void prvReadTime( struct SNtpPacket * pxPacket ) +{ + FF_TimeStruct_t xTimeStruct; + time_t uxPreviousSeconds; + time_t uxPreviousMS; + + time_t uxCurrentSeconds; + time_t uxCurrentMS; + + const char * pcTimeUnit; + int32_t ilDiff; + TickType_t uxTravelTime; + + uxTravelTime = xTaskGetTickCount() - uxSendTime; + + /* Transform the contents of the fields from big to native endian. */ + prvSwapFields( pxPacket ); + + uxCurrentSeconds = pxPacket->receiveTimestamp.seconds - TIME1970; + uxCurrentMS = pxPacket->receiveTimestamp.fraction / 4294967; + uxCurrentSeconds += uxCurrentMS / 1000; + uxCurrentMS = uxCurrentMS % 1000; + + /* Get the last time recorded */ + uxPreviousSeconds = FreeRTOS_get_secs_msec( &uxPreviousMS ); + + /* Set the new time with precision in msec. * / */ + FreeRTOS_set_secs_msec( &uxCurrentSeconds, &uxCurrentMS ); + + if( uxCurrentSeconds >= uxPreviousSeconds ) + { + ilDiff = ( int32_t ) ( uxCurrentSeconds - uxPreviousSeconds ); + } + else + { + ilDiff = 0 - ( int32_t ) ( uxPreviousSeconds - uxCurrentSeconds ); + } + + if( ( ilDiff < -5 ) || ( ilDiff > 5 ) ) + { + /* More than 5 seconds difference. */ + pcTimeUnit = "sec"; + } + else + { + /* Less than or equal to 5 second difference. */ + pcTimeUnit = "ms"; + uint32_t ulLowest = ( uxCurrentSeconds <= uxPreviousSeconds ) ? uxCurrentSeconds : uxPreviousSeconds; + int32_t iCurMS = 1000 * ( uxCurrentSeconds - ulLowest ) + uxCurrentMS; + int32_t iPrevMS = 1000 * ( uxPreviousSeconds - ulLowest ) + uxPreviousMS; + ilDiff = iCurMS - iPrevMS; + } + + uxCurrentSeconds -= iTimeZone; + + FreeRTOS_gmtime_r( &uxCurrentSeconds, &xTimeStruct ); + + /* + * 378.067 [NTP client] NTP time: 9/11/2015 16:11:19.559 Diff -20 ms (289 ms) + * 379.441 [NTP client] NTP time: 9/11/2015 16:11:20.933 Diff 0 ms (263 ms) + */ + + FreeRTOS_printf( ( "NTP time: %d/%d/%02d %2d:%02d:%02d.%03u Diff %d %s (%lu ms)\n", + xTimeStruct.tm_mday, + xTimeStruct.tm_mon + 1, + xTimeStruct.tm_year + 1900, + xTimeStruct.tm_hour, + xTimeStruct.tm_min, + xTimeStruct.tm_sec, + ( unsigned ) uxCurrentMS, + ( unsigned ) ilDiff, + pcTimeUnit, + uxTravelTime ) ); + + /* Remove compiler warnings in case FreeRTOS_printf() is not used. */ + ( void ) pcTimeUnit; + ( void ) uxTravelTime; +} +/*-----------------------------------------------------------*/ + +#if ( ipconfigUSE_CALLBACKS != 0 ) + + static BaseType_t xOnUDPReceive( Socket_t xSocket, + void * pvData, + size_t xLength, + const struct freertos_sockaddr * pxFrom, + const struct freertos_sockaddr * pxDest ) + { + if( xLength >= sizeof( xNTPPacket ) ) + { + prvReadTime( ( struct SNtpPacket * ) pvData ); + + if( xStatus != EStatusPause ) + { + xStatus = EStatusPause; + } + } + + vSignalTask(); + /* Tell the driver not to store the RX data */ + return 1; + } + /*-----------------------------------------------------------*/ + +#endif /* ipconfigUSE_CALLBACKS != 0 */ + +static void prvNTPTask( void * pvParameters ) +{ + BaseType_t xServerIndex = 3; + struct freertos_sockaddr xAddress; + + #if ( ipconfigUSE_CALLBACKS != 0 ) + F_TCP_UDP_Handler_t xHandler; + #endif /* ipconfigUSE_CALLBACKS != 0 */ + + xStatus = EStatusLookup; + #if ( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) || ( ipconfigUSE_CALLBACKS != 0 ) + { + xNTPWakeupSem = xSemaphoreCreateBinary(); + } + #endif + + #if ( ipconfigUSE_CALLBACKS != 0 ) + { + memset( &xHandler, '\0', sizeof( xHandler ) ); + xHandler.pxOnUDPReceive = xOnUDPReceive; + FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) ); + } + #endif + #if ( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) + { + FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SET_SEMAPHORE, ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) ); + } + #endif + + for( ; ; ) + { + switch( xStatus ) + { + case EStatusLookup: + + if( ( ulIPAddressFound == 0ul ) || ( ulIPAddressFound == ~0ul ) ) + { + if( ++xServerIndex == sizeof( pcTimeServers ) / sizeof( pcTimeServers[ 0 ] ) ) + { + xServerIndex = 0; + } + + FreeRTOS_printf( ( "Looking up server '%s'\n", pcTimeServers[ xServerIndex ] ) ); + FreeRTOS_gethostbyname_a( pcTimeServers[ xServerIndex ], vDNS_callback, ( void * ) NULL, 1200 ); + } + else + { + xStatus = EStatusAsking; + } + + break; + + case EStatusAsking: + { + char pcBuf[ 16 ]; + + prvNTPPacketInit(); + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xAddress.sin_address.ulIP_IPv4 = ulIPAddressFound; + xAddress.sin_port = FreeRTOS_htons( NTP_PORT ); + FreeRTOS_inet_ntoa( xAddress.sin_address.ulIP_IPv4, pcBuf ); + } + #else + { + xAddress.sin_addr = ulIPAddressFound; + xAddress.sin_port = FreeRTOS_htons( NTP_PORT ); + FreeRTOS_inet_ntoa( xAddress.sin_addr, pcBuf ); + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xAddress.sin_family = FREERTOS_AF_INET; + + FreeRTOS_printf( ( "Sending UDP message to %s:%u\n", + pcBuf, + FreeRTOS_ntohs( xAddress.sin_port ) ) ); + + uxSendTime = xTaskGetTickCount(); + FreeRTOS_sendto( xUDPSocket, ( void * ) &xNTPPacket, sizeof( xNTPPacket ), 0, &xAddress, sizeof( xAddress ) ); + } + break; + + case EStatusPause: + break; + + case EStatusFailed: + break; + } + + #if ( ipconfigUSE_CALLBACKS != 0 ) + { + xSemaphoreTake( xNTPWakeupSem, 5000 ); + } + #else + { + uint32_t xAddressSize; + BaseType_t xReturned; + + xAddressSize = sizeof( xAddress ); + xReturned = FreeRTOS_recvfrom( xUDPSocket, ( void * ) cRecvBuffer, sizeof( cRecvBuffer ), 0, &xAddress, &xAddressSize ); + + switch( xReturned ) + { + case 0: + case -pdFREERTOS_ERRNO_EAGAIN: + case -pdFREERTOS_ERRNO_EINTR: + break; + + default: + + if( xReturned < sizeof( xNTPPacket ) ) + { + FreeRTOS_printf( ( "FreeRTOS_recvfrom: returns %ld\n", xReturned ) ); + } + else + { + prvReadTime( ( struct SNtpPacket * ) cRecvBuffer ); + + if( xStatus != EStatusPause ) + { + xStatus = EStatusPause; + } + } + + break; + } + } + #endif /* if ( ipconfigUSE_CALLBACKS != 0 ) */ + } +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/readme.md b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/readme.md index 36003fcfd..74a357765 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/readme.md +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/readme.md @@ -1,5 +1,5 @@ FreeRTOS 2020107.00 adds a new SNTPv4 client library, [FreeRTOS/coreSNTP](https://github.com/FreeRTOS/coreSNTP), -and an [accompanying demo](..\..\..\coreSNTP_Windows_Simulator) to showcase the setup of an SNTP client and system -wall-clock time using the library. Refer to +and an [accompanying demo](..\..\..\coreSNTP_Windows_Simulator) to showcase the setup of an SNTP client and system +wall-clock time using the library. Refer to The protocols implemented in this directory are intended to be demo quality examples only. They are not intended for inclusion in production devices. diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_FTP_commands.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_FTP_commands.h index b25ecaee3..bbacf3f7e 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_FTP_commands.h +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_FTP_commands.h @@ -1,133 +1,136 @@ -/* - * FreeRTOS+TCP V2.0.1 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://aws.amazon.com/freertos - * https://www.FreeRTOS.org - */ - -#ifndef __FTPCMD_H__ - -#define __FTPCMD_H__ - -#define REPL_110 "110 Restart marker reply.\r\n" -#define REPL_120 "120 Try again in 2 minutes.\r\n" -#define REPL_125 "125 Data connection already open; transfer starting.\r\n" -#define REPL_150 "150 File status okay; about to open data connection.\r\n" -#define REPL_200 "200 NOOP command successful.\r\n" -#define REPL_200_PROGRESS "200 NOOP: data transfer in progress.\r\n" -#define REPL_202 "202 Command not implemented, superfluous at this site.\r\n" -#define REPL_211 "221 System status, or system help reply.\r\n" -#define REPL_211_STATUS "221-status of %s.\r\n" -#define REPL_211_END "221 End of status.\r\n" -#define REPL_212 "212 Directory status.\r\n" -#define REPL_213 "213 File status.\r\n" -#define REPL_214 "214 Help message.\r\n" -#define REPL_214_END "214 End Help message.\r\n" -#define REPL_215 "215 %s system type.\r\n" -#define REPL_220 "220 Service ready for new user.\r\n" -#define REPL_221 "221 Service closing control connection.\r\n" -#define REPL_225 "225 Data connection open; no transfer in progress.\r\n" -#define REPL_226 "226 Closing data connection.\r\n" -#define REPL_227 "227 Entering Passive Mode (%s,%s,%s,%s,%s,%s).\r\n" -#define REPL_227_D "227 Entering Passive Mode (%u,%u,%u,%u,%u,%u).\r\n" -#define REPL_230 "230 User logged in, proceed.\r\n" -#define REPL_250 "250 Requested file action okay, completed.\r\n" -#define REPL_257 "257 %s created.\r\n" -// #define REPL_257_PWD "257 \"%s\" is current working dir.\r\n" -#define REPL_257_PWD "257 \"%s\"\r\n" -#define REPL_331 "331 Only anonymous user is accepted.\r\n" -#define REPL_331_ANON "331 Anonymous login okay\r\n" -#define REPL_332 "332 Need account for login.\r\n" -#define REPL_350 "350 Requested file action pending further information.\r\n" -#define REPL_421 "421 Service not available, closing control connection.\r\n" -#define REPL_425 "425 Can't open data connection.\r\n" -#define REPL_426 "426 Connection closed; transfer aborted.\r\n" -#define REPL_450 "450 Requested file action not taken.\r\n" -#define REPL_451 "451 Requested action aborted. Local error in processing.\r\n" -#define REPL_452 "452 Requested action not taken.\r\n" -#define REPL_500 "500 Syntax error, command unrecognized.\r\n" -#define REPL_501 "501 Syntax error in parameters or arguments.\r\n" -#define REPL_502 "502 Command not implemented.\r\n" -#define REPL_503 "503 Bad sequence of commands.\r\n" -#define REPL_504 "504 Command not implemented for that parameter.\r\n" -#define REPL_530 "530 Not logged in.\r\n" -#define REPL_532 "532 Need account for storing files.\r\n" -#define REPL_550 "550 Requested action not taken.\r\n" -#define REPL_551 "551 Requested action aborted. Page type unknown.\r\n" -#define REPL_552 "552 Requested file action aborted.\r\n" -#define REPL_553 "553 Requested action not taken.\r\n" -#define REPL_553_READ_ONLY "553 Read-only file-system.\r\n" - -enum EFTPCommand { - ECMD_USER, - ECMD_PASS, - ECMD_ACCT, - ECMD_CWD, - ECMD_CDUP, - ECMD_SMNT, - ECMD_QUIT, - ECMD_REIN, - ECMD_PORT, - ECMD_PASV, - ECMD_TYPE, - ECMD_STRU, - ECMD_MODE, - ECMD_RETR, - ECMD_STOR, - ECMD_STOU, - ECMD_APPE, - ECMD_ALLO, - ECMD_REST, - ECMD_RNFR, - ECMD_RNTO, - ECMD_ABOR, - ECMD_SIZE, - ECMD_MDTM, - ECMD_DELE, - ECMD_RMD, - ECMD_MKD, - ECMD_PWD, - ECMD_LIST, - ECMD_NLST, - ECMD_SITE, - ECMD_SYST, - ECMD_FEAT, - ECMD_STAT, - ECMD_HELP, - ECMD_NOOP, - ECMD_EMPTY, - ECMD_CLOSE, - ECMD_UNKNOWN, -}; - -typedef struct xFTP_COMMAND { - BaseType_t xCommandLength; - const char pcCommandName[7]; - const unsigned char ucCommandType; - const unsigned char checkLogin; - const unsigned char checkNullArg; -} FTPCommand_t; - -#define FTP_CMD_COUNT (ECMD_UNKNOWN+1) - -extern const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ]; - -#endif // __FTPCMD_H__ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef __FTPCMD_H__ + +#define __FTPCMD_H__ + +#define REPL_110 "110 Restart marker reply.\r\n" +#define REPL_120 "120 Try again in 2 minutes.\r\n" +#define REPL_125 "125 Data connection already open; transfer starting.\r\n" +#define REPL_150 "150 File status okay; about to open data connection.\r\n" +#define REPL_200 "200 NOOP command successful.\r\n" +#define REPL_200_PROGRESS "200 NOOP: data transfer in progress.\r\n" +#define REPL_202 "202 Command not implemented, superfluous at this site.\r\n" +#define REPL_211 "221 System status, or system help reply.\r\n" +#define REPL_211_STATUS "221-status of %s.\r\n" +#define REPL_211_END "221 End of status.\r\n" +#define REPL_212 "212 Directory status.\r\n" +#define REPL_213 "213 File status.\r\n" +#define REPL_214 "214 Help message.\r\n" +#define REPL_214_END "214 End Help message.\r\n" +#define REPL_215 "215 %s system type.\r\n" +#define REPL_220 "220 Service ready for new user.\r\n" +#define REPL_221 "221 Service closing control connection.\r\n" +#define REPL_225 "225 Data connection open; no transfer in progress.\r\n" +#define REPL_226 "226 Closing data connection.\r\n" +#define REPL_227 "227 Entering Passive Mode (%s,%s,%s,%s,%s,%s).\r\n" +#define REPL_227_D "227 Entering Passive Mode (%u,%u,%u,%u,%u,%u).\r\n" +#define REPL_230 "230 User logged in, proceed.\r\n" +#define REPL_250 "250 Requested file action okay, completed.\r\n" +#define REPL_257 "257 %s created.\r\n" +/* #define REPL_257_PWD "257 \"%s\" is current working dir.\r\n" */ +#define REPL_257_PWD "257 \"%s\"\r\n" +#define REPL_331 "331 Only anonymous user is accepted.\r\n" +#define REPL_331_ANON "331 Anonymous login okay\r\n" +#define REPL_332 "332 Need account for login.\r\n" +#define REPL_350 "350 Requested file action pending further information.\r\n" +#define REPL_421 "421 Service not available, closing control connection.\r\n" +#define REPL_425 "425 Can't open data connection.\r\n" +#define REPL_426 "426 Connection closed; transfer aborted.\r\n" +#define REPL_450 "450 Requested file action not taken.\r\n" +#define REPL_451 "451 Requested action aborted. Local error in processing.\r\n" +#define REPL_452 "452 Requested action not taken.\r\n" +#define REPL_500 "500 Syntax error, command unrecognized.\r\n" +#define REPL_501 "501 Syntax error in parameters or arguments.\r\n" +#define REPL_502 "502 Command not implemented.\r\n" +#define REPL_503 "503 Bad sequence of commands.\r\n" +#define REPL_504 "504 Command not implemented for that parameter.\r\n" +#define REPL_530 "530 Not logged in.\r\n" +#define REPL_532 "532 Need account for storing files.\r\n" +#define REPL_550 "550 Requested action not taken.\r\n" +#define REPL_551 "551 Requested action aborted. Page type unknown.\r\n" +#define REPL_552 "552 Requested file action aborted.\r\n" +#define REPL_553 "553 Requested action not taken.\r\n" +#define REPL_553_READ_ONLY "553 Read-only file-system.\r\n" + +enum EFTPCommand +{ + ECMD_USER, + ECMD_PASS, + ECMD_ACCT, + ECMD_CWD, + ECMD_CDUP, + ECMD_SMNT, + ECMD_QUIT, + ECMD_REIN, + ECMD_PORT, + ECMD_PASV, + ECMD_TYPE, + ECMD_STRU, + ECMD_MODE, + ECMD_RETR, + ECMD_STOR, + ECMD_STOU, + ECMD_APPE, + ECMD_ALLO, + ECMD_REST, + ECMD_RNFR, + ECMD_RNTO, + ECMD_ABOR, + ECMD_SIZE, + ECMD_MDTM, + ECMD_DELE, + ECMD_RMD, + ECMD_MKD, + ECMD_PWD, + ECMD_LIST, + ECMD_NLST, + ECMD_SITE, + ECMD_SYST, + ECMD_FEAT, + ECMD_STAT, + ECMD_HELP, + ECMD_NOOP, + ECMD_EMPTY, + ECMD_CLOSE, + ECMD_UNKNOWN, +}; + +typedef struct xFTP_COMMAND +{ + BaseType_t xCommandLength; + const char pcCommandName[ 7 ]; + const unsigned char ucCommandType; + const unsigned char checkLogin; + const unsigned char checkNullArg; +} FTPCommand_t; + +#define FTP_CMD_COUNT ( ECMD_UNKNOWN + 1 ) + +extern const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ]; + +#endif // __FTPCMD_H__ diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_HTTP_commands.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_HTTP_commands.h index e40f09421..641c749c2 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_HTTP_commands.h +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_HTTP_commands.h @@ -1,67 +1,68 @@ -/* - * FreeRTOS+TCP V2.0.3 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://aws.amazon.com/freertos - * https://www.FreeRTOS.org - */ -#ifndef FREERTOS_HTTP_COMMANDS_H -#define FREERTOS_HTTP_COMMANDS_H - -enum { - WEB_REPLY_OK = 200, - WEB_NO_CONTENT = 204, - WEB_BAD_REQUEST = 400, - WEB_UNAUTHORIZED = 401, - WEB_NOT_FOUND = 404, - WEB_GONE = 410, - WEB_PRECONDITION_FAILED = 412, - WEB_INTERNAL_SERVER_ERROR = 500, -}; - -enum EWebCommand { - ECMD_GET, - ECMD_HEAD, - ECMD_POST, - ECMD_PUT, - ECMD_DELETE, - ECMD_TRACE, - ECMD_OPTIONS, - ECMD_CONNECT, - ECMD_PATCH, - ECMD_UNK, -}; - -struct xWEB_COMMAND -{ - BaseType_t xCommandLength; - const char *pcCommandName; - const unsigned char ucCommandType; -}; - -#define WEB_CMD_COUNT (ECMD_UNK+1) - -extern const struct xWEB_COMMAND xWebCommands[WEB_CMD_COUNT]; - -extern const char *webCodename (int aCode); - -#endif /* FREERTOS_HTTP_COMMANDS_H */ - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ +#ifndef FREERTOS_HTTP_COMMANDS_H +#define FREERTOS_HTTP_COMMANDS_H + +enum +{ + WEB_REPLY_OK = 200, + WEB_NO_CONTENT = 204, + WEB_BAD_REQUEST = 400, + WEB_UNAUTHORIZED = 401, + WEB_NOT_FOUND = 404, + WEB_GONE = 410, + WEB_PRECONDITION_FAILED = 412, + WEB_INTERNAL_SERVER_ERROR = 500, +}; + +enum EWebCommand +{ + ECMD_GET, + ECMD_HEAD, + ECMD_POST, + ECMD_PUT, + ECMD_DELETE, + ECMD_TRACE, + ECMD_OPTIONS, + ECMD_CONNECT, + ECMD_PATCH, + ECMD_UNK, +}; + +struct xWEB_COMMAND +{ + BaseType_t xCommandLength; + const char * pcCommandName; + const unsigned char ucCommandType; +}; + +#define WEB_CMD_COUNT ( ECMD_UNK + 1 ) + +extern const struct xWEB_COMMAND xWebCommands[ WEB_CMD_COUNT ]; + +extern const char * webCodename( int aCode ); + +#endif /* FREERTOS_HTTP_COMMANDS_H */ diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_TCP_server.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_TCP_server.h index 913cdcfc8..5308cd4a6 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_TCP_server.h +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_TCP_server.h @@ -1,125 +1,141 @@ -/* - * FreeRTOS+TCP V2.0.3 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://aws.amazon.com/freertos - * https://www.FreeRTOS.org - */ - -/* - Some code which is common to TCP servers like HTTP en FTP -*/ - -#ifndef FREERTOS_TCP_SERVER_H -#define FREERTOS_TCP_SERVER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef FTP_SERVER_USES_RELATIVE_DIRECTORY - #define FTP_SERVER_USES_RELATIVE_DIRECTORY 0 -#endif - -enum eSERVER_TYPE -{ - eSERVER_NONE, - eSERVER_HTTP, - eSERVER_FTP, -}; - -struct xFTP_CLIENT; - -#if( ipconfigFTP_HAS_RECEIVED_HOOK != 0 ) - extern void vApplicationFTPReceivedHook( const char *pcFileName, uint32_t ulSize, struct xFTP_CLIENT *pxFTPClient ); - extern void vFTPReplyMessage( struct xFTP_CLIENT *pxFTPClient, const char *pcMessage ); -#endif /* ipconfigFTP_HAS_RECEIVED_HOOK != 0 */ - -#if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 ) - /* - * Function is called when a user name has been submitted. - * The function may return a string such as: "331 Please enter your password" - * or return NULL to use the default reply. - */ - extern const char *pcApplicationFTPUserHook( const char *pcUserName ); -#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */ - -#if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 ) - /* - * Function is called when a password was received. - * Return positive value to allow the user - */ - extern BaseType_t xApplicationFTPPasswordHook( const char *pcUserName, const char *pcPassword ); -#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */ - -#if( ipconfigFTP_HAS_USER_PROPERTIES_HOOK != 0 ) - /* - * The FTP server is asking for user-specific properties - */ - typedef struct - { - uint16_t usPortNumber; /* For reference only. Host-endian. */ - const char *pcRootDir; - BaseType_t xReadOnly; - } - FTPUserProperties_t; - extern void vApplicationFTPUserPropertiesHook( const char *pcUserName, FTPUserProperties_t *pxProperties ); -#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */ - -#if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 ) - /* - * A GET request is received containing a special character, - * usually a question mark. - * const char *pcURLData; // A request, e.g. "/request?limit=75" - * char *pcBuffer; // Here the answer can be written - * size_t uxBufferLength; // Size of the buffer - * - */ - extern size_t uxApplicationHTTPHandleRequestHook( const char *pcURLData, char *pcBuffer, size_t uxBufferLength ); -#endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */ - -struct xSERVER_CONFIG -{ - enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */ - BaseType_t xPortNumber; /* e.g. 80, 8080, 21 */ - BaseType_t xBackLog; /* e.g. 10, maximum number of connected TCP clients */ - const char * const pcRootDir; /* Treat this directory as the root directory */ -}; - -struct xTCP_SERVER; -typedef struct xTCP_SERVER TCPServer_t; - -TCPServer_t *FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG *pxConfigs, BaseType_t xCount ); -void FreeRTOS_TCPServerWork( TCPServer_t *pxServer, TickType_t xBlockingTime ); - -#if( ipconfigSUPPORT_SIGNALS != 0 ) - /* FreeRTOS_TCPServerWork() calls select(). - The two functions below provide a possibility to interrupt - the call to select(). After the interruption, resume - by calling FreeRTOS_TCPServerWork() again. */ - BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t *pxServer ); - BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t *pxServer, BaseType_t *pxHigherPriorityTaskWoken ); -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* FREERTOS_TCP_SERVER_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Some code which is common to TCP servers like HTTP en FTP + */ + +#ifndef FREERTOS_TCP_SERVER_H + #define FREERTOS_TCP_SERVER_H + + #ifdef __cplusplus + extern "C" { + #endif + + #ifndef FTP_SERVER_USES_RELATIVE_DIRECTORY + #define FTP_SERVER_USES_RELATIVE_DIRECTORY 0 + #endif + + enum eSERVER_TYPE + { + eSERVER_NONE, + eSERVER_HTTP, + eSERVER_FTP, + }; + + struct xFTP_CLIENT; + + #if ( ipconfigFTP_HAS_RECEIVED_HOOK != 0 ) + extern void vApplicationFTPReceivedHook( const char * pcFileName, + uint32_t ulSize, + struct xFTP_CLIENT * pxFTPClient ); + extern void vFTPReplyMessage( struct xFTP_CLIENT * pxFTPClient, + const char * pcMessage ); + #endif /* ipconfigFTP_HAS_RECEIVED_HOOK != 0 */ + + #if ( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 ) + +/* + * Function is called when a user name has been submitted. + * The function may return a string such as: "331 Please enter your password" + * or return NULL to use the default reply. + */ + extern const char * pcApplicationFTPUserHook( const char * pcUserName ); + #endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */ + + #if ( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 ) + +/* + * Function is called when a password was received. + * Return positive value to allow the user + */ + extern BaseType_t xApplicationFTPPasswordHook( const char * pcUserName, + const char * pcPassword ); + #endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */ + + #if ( ipconfigFTP_HAS_USER_PROPERTIES_HOOK != 0 ) + +/* + * The FTP server is asking for user-specific properties + */ + typedef struct + { + uint16_t usPortNumber; /* For reference only. Host-endian. */ + const char * pcRootDir; + BaseType_t xReadOnly; + } + FTPUserProperties_t; + extern void vApplicationFTPUserPropertiesHook( const char * pcUserName, + FTPUserProperties_t * pxProperties ); + #endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */ + + #if ( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 ) + +/* + * A GET request is received containing a special character, + * usually a question mark. + * const char *pcURLData; // A request, e.g. "/request?limit=75" + * char *pcBuffer; // Here the answer can be written + * size_t uxBufferLength; // Size of the buffer + * + */ + extern size_t uxApplicationHTTPHandleRequestHook( const char * pcURLData, + char * pcBuffer, + size_t uxBufferLength ); + #endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */ + + struct xSERVER_CONFIG + { + enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */ + BaseType_t xPortNumber; /* e.g. 80, 8080, 21 */ + BaseType_t xBackLog; /* e.g. 10, maximum number of connected TCP clients */ + const char * const pcRootDir; /* Treat this directory as the root directory */ + }; + + struct xTCP_SERVER; + typedef struct xTCP_SERVER TCPServer_t; + + TCPServer_t * FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG * pxConfigs, + BaseType_t xCount ); + void FreeRTOS_TCPServerWork( TCPServer_t * pxServer, + TickType_t xBlockingTime ); + + #if ( ipconfigSUPPORT_SIGNALS != 0 ) + +/* FreeRTOS_TCPServerWork() calls select(). + * The two functions below provide a possibility to interrupt + * the call to select(). After the interruption, resume + * by calling FreeRTOS_TCPServerWork() again. */ + BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t * pxServer ); + BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t * pxServer, + BaseType_t * pxHigherPriorityTaskWoken ); + #endif + + #ifdef __cplusplus +} /* extern "C" */ + #endif + +#endif /* FREERTOS_TCP_SERVER_H */ diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_server_private.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_server_private.h index ef4e12b7c..e29fcb674 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_server_private.h +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_server_private.h @@ -1,185 +1,201 @@ -/* - * FreeRTOS+TCP V2.0.3 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://aws.amazon.com/freertos - * https://www.FreeRTOS.org - */ - - /* - Some code which is common to TCP servers like HTTP and FTP -*/ - -#ifndef FREERTOS_SERVER_PRIVATE_H -#define FREERTOS_SERVER_PRIVATE_H - -#define FREERTOS_NO_SOCKET NULL - -/* FreeRTOS+FAT */ -#include "ff_stdio.h" - -/* Each HTTP server has 1, at most 2 sockets */ -#define HTTP_SOCKET_COUNT 2 - -/* - * ipconfigTCP_COMMAND_BUFFER_SIZE sets the size of: - * pcCommandBuffer': a buffer to receive and send TCP commands - * - * ipconfigTCP_FILE_BUFFER_SIZE sets the size of: - * pcFileBuffer' : a buffer to access the file system: read or write data. - * - * The buffers are both used for FTP as well as HTTP. - */ - -#ifndef ipconfigTCP_COMMAND_BUFFER_SIZE - #define ipconfigTCP_COMMAND_BUFFER_SIZE ( 2048 ) -#endif - -#ifndef ipconfigTCP_FILE_BUFFER_SIZE - #define ipconfigTCP_FILE_BUFFER_SIZE ( 2048 ) -#endif - -struct xTCP_CLIENT; - -typedef BaseType_t ( * FTCPWorkFunction ) ( struct xTCP_CLIENT * /* pxClient */ ); -typedef void ( * FTCPDeleteFunction ) ( struct xTCP_CLIENT * /* pxClient */ ); - -#define TCP_CLIENT_FIELDS \ - enum eSERVER_TYPE eType; \ - struct xTCP_SERVER *pxParent; \ - Socket_t xSocket; \ - const char *pcRootDir; \ - FTCPWorkFunction fWorkFunction; \ - FTCPDeleteFunction fDeleteFunction; \ - struct xTCP_CLIENT *pxNextClient - -typedef struct xTCP_CLIENT -{ - /* This define contains fields which must come first within each of the client structs */ - TCP_CLIENT_FIELDS; - /* --- Keep at the top --- */ - -} TCPClient_t; - -struct xHTTP_CLIENT -{ - /* This define contains fields which must come first within each of the client structs */ - TCP_CLIENT_FIELDS; - /* --- Keep at the top --- */ - - const char *pcUrlData; - const char *pcRestData; - char pcCurrentFilename[ ffconfigMAX_FILENAME ]; - size_t uxBytesLeft; - FF_FILE *pxFileHandle; - union { - struct { - uint32_t - bReplySent : 1; - }; - uint32_t ulFlags; - } bits; -}; - -typedef struct xHTTP_CLIENT HTTPClient_t; - -struct xFTP_CLIENT -{ - /* This define contains fields which must come first within each of the client structs */ - TCP_CLIENT_FIELDS; - /* --- Keep at the top --- */ - - uint32_t ulRestartOffset; - uint32_t ulRecvBytes; - size_t uxBytesLeft; /* Bytes left to send */ - uint32_t ulClientIP; - TickType_t xStartTime; - uint16_t usClientPort; - Socket_t xTransferSocket; - BaseType_t xTransType; - BaseType_t xDirCount; - FF_FindData_t xFindData; - FF_FILE *pxReadHandle; - FF_FILE *pxWriteHandle; - char pcCurrentDir[ ffconfigMAX_FILENAME ]; - char pcFileName[ ffconfigMAX_FILENAME ]; - char pcConnectionAck[ 128 ]; - char pcClientAck[ 128 ]; - union { - struct { - uint32_t - bHelloSent : 1, - bLoggedIn : 1, - bStatusUser : 1, - bInRename : 1, - bReadOnly : 1; - }; - uint32_t ulFTPFlags; - } bits; - union { - struct { - uint32_t - bIsListen : 1, /* pdTRUE for passive data connections (using list()). */ - bDirHasEntry : 1, /* pdTRUE if ff_findfirst() was successful. */ - bClientConnected : 1, /* pdTRUE after connect() or accept() has succeeded. */ - bEmptyFile : 1, /* pdTRUE if a connection-without-data was received. */ - bHadError : 1; /* pdTRUE if a transfer got aborted because of an error. */ - }; - uint32_t ulConnFlags; - } bits1; -}; - -typedef struct xFTP_CLIENT FTPClient_t; - -BaseType_t xHTTPClientWork( TCPClient_t *pxClient ); -BaseType_t xFTPClientWork( TCPClient_t *pxClient ); - -void vHTTPClientDelete( TCPClient_t *pxClient ); -void vFTPClientDelete( TCPClient_t *pxClient ); - -BaseType_t xMakeAbsolute( struct xFTP_CLIENT *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName ); -BaseType_t xMakeRelative( FTPClient_t *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName ); - -struct xTCP_SERVER -{ - SocketSet_t xSocketSet; - /* A buffer to receive and send TCP commands, either HTTP of FTP. */ - char pcCommandBuffer[ ipconfigTCP_COMMAND_BUFFER_SIZE ]; - /* A buffer to access the file system: read or write data. */ - char pcFileBuffer[ ipconfigTCP_FILE_BUFFER_SIZE ]; - - #if( ipconfigUSE_FTP != 0 ) - char pcNewDir[ ffconfigMAX_FILENAME ]; - #endif - #if( ipconfigUSE_HTTP != 0 ) - char pcContentsType[40]; /* Space for the msg: "text/javascript" */ - char pcExtraContents[40]; /* Space for the msg: "Content-Length: 346500" */ - #endif - BaseType_t xServerCount; - TCPClient_t *pxClients; - struct xSERVER - { - enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */ - const char *pcRootDir; - Socket_t xSocket; - } xServers[ 1 ]; -}; - -#endif /* FREERTOS_SERVER_PRIVATE_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Some code which is common to TCP servers like HTTP and FTP + */ + +#ifndef FREERTOS_SERVER_PRIVATE_H +#define FREERTOS_SERVER_PRIVATE_H + +#define FREERTOS_NO_SOCKET NULL + +/* FreeRTOS+FAT */ +#include "ff_stdio.h" + +/* Each HTTP server has 1, at most 2 sockets */ +#define HTTP_SOCKET_COUNT 2 + +/* + * ipconfigTCP_COMMAND_BUFFER_SIZE sets the size of: + * pcCommandBuffer': a buffer to receive and send TCP commands + * + * ipconfigTCP_FILE_BUFFER_SIZE sets the size of: + * pcFileBuffer' : a buffer to access the file system: read or write data. + * + * The buffers are both used for FTP as well as HTTP. + */ + +#ifndef ipconfigTCP_COMMAND_BUFFER_SIZE + #define ipconfigTCP_COMMAND_BUFFER_SIZE ( 2048 ) +#endif + +#ifndef ipconfigTCP_FILE_BUFFER_SIZE + #define ipconfigTCP_FILE_BUFFER_SIZE ( 2048 ) +#endif + +struct xTCP_CLIENT; + +typedef BaseType_t ( * FTCPWorkFunction ) ( struct xTCP_CLIENT * /* pxClient */ ); +typedef void ( * FTCPDeleteFunction ) ( struct xTCP_CLIENT * /* pxClient */ ); + +#define TCP_CLIENT_FIELDS \ + enum eSERVER_TYPE eType; \ + struct xTCP_SERVER * pxParent; \ + Socket_t xSocket; \ + const char * pcRootDir; \ + FTCPWorkFunction fWorkFunction; \ + FTCPDeleteFunction fDeleteFunction; \ + struct xTCP_CLIENT * pxNextClient + +typedef struct xTCP_CLIENT +{ + /* This define contains fields which must come first within each of the client structs */ + TCP_CLIENT_FIELDS; + /* --- Keep at the top --- */ +} TCPClient_t; + +struct xHTTP_CLIENT +{ + /* This define contains fields which must come first within each of the client structs */ + TCP_CLIENT_FIELDS; + /* --- Keep at the top --- */ + + const char * pcUrlData; + const char * pcRestData; + char pcCurrentFilename[ ffconfigMAX_FILENAME ]; + size_t uxBytesLeft; + FF_FILE * pxFileHandle; + union + { + struct + { + uint32_t + bReplySent : 1; + }; + uint32_t ulFlags; + } + bits; +}; + +typedef struct xHTTP_CLIENT HTTPClient_t; + +struct xFTP_CLIENT +{ + /* This define contains fields which must come first within each of the client structs */ + TCP_CLIENT_FIELDS; + /* --- Keep at the top --- */ + + uint32_t ulRestartOffset; + uint32_t ulRecvBytes; + size_t uxBytesLeft; /* Bytes left to send */ + uint32_t ulClientIP; + TickType_t xStartTime; + uint16_t usClientPort; + Socket_t xTransferSocket; + BaseType_t xTransType; + BaseType_t xDirCount; + FF_FindData_t xFindData; + FF_FILE * pxReadHandle; + FF_FILE * pxWriteHandle; + char pcCurrentDir[ ffconfigMAX_FILENAME ]; + char pcFileName[ ffconfigMAX_FILENAME ]; + char pcConnectionAck[ 128 ]; + char pcClientAck[ 128 ]; + union + { + struct + { + uint32_t + bHelloSent : 1, + bLoggedIn : 1, + bStatusUser : 1, + bInRename : 1, + bReadOnly : 1; + }; + uint32_t ulFTPFlags; + } + bits; + union + { + struct + { + uint32_t + bIsListen : 1, /* pdTRUE for passive data connections (using list()). */ + bDirHasEntry : 1, /* pdTRUE if ff_findfirst() was successful. */ + bClientConnected : 1, /* pdTRUE after connect() or accept() has succeeded. */ + bEmptyFile : 1, /* pdTRUE if a connection-without-data was received. */ + bHadError : 1; /* pdTRUE if a transfer got aborted because of an error. */ + }; + uint32_t ulConnFlags; + } + bits1; +}; + +typedef struct xFTP_CLIENT FTPClient_t; + +BaseType_t xHTTPClientWork( TCPClient_t * pxClient ); +BaseType_t xFTPClientWork( TCPClient_t * pxClient ); + +void vHTTPClientDelete( TCPClient_t * pxClient ); +void vFTPClientDelete( TCPClient_t * pxClient ); + +BaseType_t xMakeAbsolute( struct xFTP_CLIENT * pxClient, + char * pcBuffer, + BaseType_t xBufferLength, + const char * pcFileName ); +BaseType_t xMakeRelative( FTPClient_t * pxClient, + char * pcBuffer, + BaseType_t xBufferLength, + const char * pcFileName ); + +struct xTCP_SERVER +{ + SocketSet_t xSocketSet; + /* A buffer to receive and send TCP commands, either HTTP of FTP. */ + char pcCommandBuffer[ ipconfigTCP_COMMAND_BUFFER_SIZE ]; + /* A buffer to access the file system: read or write data. */ + char pcFileBuffer[ ipconfigTCP_FILE_BUFFER_SIZE ]; + + #if ( ipconfigUSE_FTP != 0 ) + char pcNewDir[ ffconfigMAX_FILENAME ]; + #endif + #if ( ipconfigUSE_HTTP != 0 ) + char pcContentsType[ 40 ]; /* Space for the msg: "text/javascript" */ + char pcExtraContents[ 40 ]; /* Space for the msg: "Content-Length: 346500" */ + #endif + BaseType_t xServerCount; + TCPClient_t * pxClients; + struct xSERVER + { + enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */ + const char * pcRootDir; + Socket_t xSocket; + } + xServers[ 1 ]; +}; + +#endif /* FREERTOS_SERVER_PRIVATE_H */ diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPClient.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPClient.h index 813539e6e..49e4837d0 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPClient.h +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPClient.h @@ -1,71 +1,98 @@ -// -// ntpClient.h -// - -#ifndef __NTPCLIENT_H__ - -#define __NTPCLIENT_H__ - -#define NTP_PORT 123 - -typedef uint32_t quint32; -typedef int32_t qint32; -typedef uint8_t quint8; -typedef int8_t qint8; - -typedef union _SNtpFlags SNtpFlags; - -/** - * 64-bit NTP timestamp. - */ -struct __attribute__ ((__packed__)) _SNtpTimestamp { - /** Number of seconds passed since Jan 1 1900, in big-endian format. */ - quint32 seconds; - - /** Fractional time part, in 1/0xFFFFFFFFs of a second. */ - quint32 fraction; -}; - -typedef struct _SNtpTimestamp SNtpTimestamp; -/** - * Mandatory part of an NTP packet - */ -struct SNtpPacket { - /** Flags. */ - unsigned char flags; // value 0xDB : mode 3 (client), version 3, leap indicator unknown 3 - - /** Stratum of the clock. */ - quint8 stratum; // value 0 : unspecified - - /** Maximum interval between successive messages, in log2 seconds. Note that the value is signed. */ - qint8 poll; // 10 means 1 << 10 = 1024 seconds - - /** Precision of the clock, in log2 seconds. Note that the value is signed. */ - qint8 precision; // 0xFA = 250 = 0.015625 seconds - - /** Round trip time to the primary reference source, in NTP short format. */ - qint32 rootDelay; // 0x5D2E = 23854 or (23854/65535)= 0.3640 sec - - /** Nominal error relative to the primary reference source. */ - qint32 rootDispersion; // 0x0008 CAC8 = 8.7912 seconds - - /** Reference identifier (either a 4 character string or an IP address). */ - qint8 referenceID[4]; // or just 0000 - - /** The time at which the clock was last set or corrected. */ - SNtpTimestamp referenceTimestamp; // Current time - - /** The time at which the request departed the client for the server. */ - SNtpTimestamp originateTimestamp; // Keep 0 - - /** The time at which the request arrived at the server. */ - SNtpTimestamp receiveTimestamp; // Keep 0 - - /** The time at which the reply departed the server for client. */ - SNtpTimestamp transmitTimestamp; -}; - -/* Add this number to get secs since 1-1-1900 */ -#define TIME1970 2208988800UL - -#endif // __NTPCLIENT_H__ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* ntpClient.h */ + +#ifndef __NTPCLIENT_H__ + +#define __NTPCLIENT_H__ + +#define NTP_PORT 123 + +typedef uint32_t quint32; +typedef int32_t qint32; +typedef uint8_t quint8; +typedef int8_t qint8; + +typedef union _SNtpFlags SNtpFlags; + +/** + * 64-bit NTP timestamp. + */ +struct __attribute__( ( __packed__ ) ) _SNtpTimestamp +{ + /** Number of seconds passed since Jan 1 1900, in big-endian format. */ + quint32 seconds; + + /** Fractional time part, in 1/0xFFFFFFFFs of a second. */ + quint32 fraction; +}; + +typedef struct _SNtpTimestamp SNtpTimestamp; + +/** + * Mandatory part of an NTP packet + */ +struct SNtpPacket +{ + /** Flags. */ + unsigned char flags; /* value 0xDB : mode 3 (client), version 3, leap indicator unknown 3 */ + + /** Stratum of the clock. */ + quint8 stratum; /* value 0 : unspecified */ + + /** Maximum interval between successive messages, in log2 seconds. Note that the value is signed. */ + qint8 poll; /* 10 means 1 << 10 = 1024 seconds */ + + /** Precision of the clock, in log2 seconds. Note that the value is signed. */ + qint8 precision; /* 0xFA = 250 = 0.015625 seconds */ + + /** Round trip time to the primary reference source, in NTP short format. */ + qint32 rootDelay; /* 0x5D2E = 23854 or (23854/65535)= 0.3640 sec */ + + /** Nominal error relative to the primary reference source. */ + qint32 rootDispersion; /* 0x0008 CAC8 = 8.7912 seconds */ + + /** Reference identifier (either a 4 character string or an IP address). */ + qint8 referenceID[ 4 ]; /* or just 0000 */ + + /** The time at which the clock was last set or corrected. */ + SNtpTimestamp referenceTimestamp; /* Current time */ + + /** The time at which the request departed the client for the server. */ + SNtpTimestamp originateTimestamp; /* Keep 0 */ + + /** The time at which the request arrived at the server. */ + SNtpTimestamp receiveTimestamp; /* Keep 0 */ + + /** The time at which the reply departed the server for client. */ + SNtpTimestamp transmitTimestamp; +}; + +/* Add this number to get secs since 1-1-1900 */ +#define TIME1970 2208988800UL + +#endif // __NTPCLIENT_H__ diff --git a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPDemo.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPDemo.h index e75fb76aa..384df8d60 100644 --- a/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPDemo.h +++ b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPDemo.h @@ -1,11 +1,34 @@ -/* - * A simple demo for NTP using FreeRTOS+TCP - */ - -#ifndef NTPDEMO_H - -#define NTPDEMO_H - -void vStartNTPTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority ); - -#endif \ No newline at end of file +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef NTPDEMO_H + +#define NTPDEMO_H + +void vStartNTPTask( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ); + +#endif diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c index 3796eafb3..cb9dca95f 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c @@ -1,529 +1,553 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* Standard includes. */ -#include -#include -#include -#include - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -/* File system includes. */ -#include "fat_sl.h" -#include "api_mdriver_ram.h" - -#ifdef _WINDOWS_ - #define snprintf _snprintf -#endif - -#define cliNEW_LINE "\r\n" - -/******************************************************************************* - * See the URL in the comments within main.c for the location of the online - * documentation. - ******************************************************************************/ - -/* - * Print out information on a single file. - */ -static void prvCreateFileInfoString( char *pcBuffer, F_FIND *pxFindStruct ); - -/* - * Copies an existing file into a newly created file. - */ -static BaseType_t prvPerformCopy( const char *pcSourceFile, - int32_t lSourceFileLength, - const char *pcDestinationFile, - char *pxWriteBuffer, - size_t xWriteBufferLen ); - -/* - * Implements the DIR command. - */ -static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the CD command. - */ -static BaseType_t prvCDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the DEL command. - */ -static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the TYPE command. - */ -static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the COPY command. - */ -static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* Structure that defines the DIR command line command, which lists all the -files in the current directory. */ -static const CLI_Command_Definition_t xDIR = -{ - "dir", /* The command string to type. */ - "\r\ndir:\r\n Lists the files in the current directory\r\n", - prvDIRCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the CD command line command, which changes the -working directory. */ -static const CLI_Command_Definition_t xCD = -{ - "cd", /* The command string to type. */ - "\r\ncd :\r\n Changes the working directory\r\n", - prvCDCommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the TYPE command line command, which prints the -contents of a file to the console. */ -static const CLI_Command_Definition_t xTYPE = -{ - "type", /* The command string to type. */ - "\r\ntype :\r\n Prints file contents to the terminal\r\n", - prvTYPECommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the DEL command line command, which deletes a file. */ -static const CLI_Command_Definition_t xDEL = -{ - "del", /* The command string to type. */ - "\r\ndel :\r\n deletes a file or directory\r\n", - prvDELCommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the COPY command line command, which deletes a file. */ -static const CLI_Command_Definition_t xCOPY = -{ - "copy", /* The command string to type. */ - "\r\ncopy :\r\n Copies to \r\n", - prvCOPYCommand, /* The function to run. */ - 2 /* Two parameters are expected. */ -}; - - -/*-----------------------------------------------------------*/ - -void vRegisterFileSystemCLICommands( void ) -{ - /* Register all the command line commands defined immediately above. */ - FreeRTOS_CLIRegisterCommand( &xDIR ); - FreeRTOS_CLIRegisterCommand( &xCD ); - FreeRTOS_CLIRegisterCommand( &xTYPE ); - FreeRTOS_CLIRegisterCommand( &xDEL ); - FreeRTOS_CLIRegisterCommand( &xCOPY ); -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength, xReturn = pdTRUE; -static F_FILE *pxFile = NULL; -int iChar; -size_t xByte; -size_t xColumns = 50U; - - /* Ensure there is always a null terminator after each character written. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - - /* Ensure the buffer leaves space for the \r\n. */ - configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); - xWriteBufferLen -= strlen( cliNEW_LINE ); - - if( xWriteBufferLen < xColumns ) - { - /* Ensure the loop that uses xColumns as an end condition does not - write off the end of the buffer. */ - xColumns = xWriteBufferLen; - } - - if( pxFile == NULL ) - { - /* The file has not been opened yet. Find the file name. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to open the requested file. */ - pxFile = f_open( pcParameter, "r" ); - } - - if( pxFile != NULL ) - { - /* Read the next chunk of data from the file. */ - for( xByte = 0; xByte < xColumns; xByte++ ) - { - iChar = f_getc( pxFile ); - - if( iChar == -1 ) - { - /* No more characters to return. */ - f_close( pxFile ); - pxFile = NULL; - break; - } - else - { - pcWriteBuffer[ xByte ] = ( char ) iChar; - } - } - } - - if( pxFile == NULL ) - { - /* Either the file was not opened, or all the data from the file has - been returned and the file is now closed. */ - xReturn = pdFALSE; - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvCDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength; -unsigned char ucReturned; -size_t xStringLength; - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to move to the requested directory. */ - ucReturned = f_chdir( pcParameter ); - - if( ucReturned == F_NO_ERROR ) - { - sprintf( pcWriteBuffer, "In: " ); - xStringLength = strlen( pcWriteBuffer ); - f_getcwd( &( pcWriteBuffer[ xStringLength ] ), ( unsigned char ) ( xWriteBufferLen - xStringLength ) ); - } - else - { - sprintf( pcWriteBuffer, "Error" ); - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -static F_FIND *pxFindStruct = NULL; -unsigned char ucReturned; -BaseType_t xReturn = pdFALSE; - - /* This assumes pcWriteBuffer is long enough. */ - ( void ) pcCommandString; - - /* Ensure the buffer leaves space for the \r\n. */ - configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); - xWriteBufferLen -= strlen( cliNEW_LINE ); - - if( pxFindStruct == NULL ) - { - /* This is the first time this function has been executed since the Dir - command was run. Create the find structure. */ - pxFindStruct = ( F_FIND * ) pvPortMalloc( sizeof( F_FIND ) ); - - if( pxFindStruct != NULL ) - { - ucReturned = f_findfirst( "*.*", pxFindStruct ); - - if( ucReturned == F_NO_ERROR ) - { - prvCreateFileInfoString( pcWriteBuffer, pxFindStruct ); - xReturn = pdPASS; - } - else - { - snprintf( pcWriteBuffer, xWriteBufferLen, "Error: f_findfirst() failed." ); - } - } - else - { - snprintf( pcWriteBuffer, xWriteBufferLen, "Failed to allocate RAM (using heap_4.c will prevent fragmentation)." ); - } - } - else - { - /* The find struct has already been created. Find the next file in - the directory. */ - ucReturned = f_findnext( pxFindStruct ); - - if( ucReturned == F_NO_ERROR ) - { - prvCreateFileInfoString( pcWriteBuffer, pxFindStruct ); - xReturn = pdPASS; - } - else - { - /* There are no more files. Free the find structure. */ - vPortFree( pxFindStruct ); - pxFindStruct = NULL; - - /* No string to return. */ - pcWriteBuffer[ 0 ] = 0x00; - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength; -unsigned char ucReturned; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to delete the file. */ - ucReturned = f_delete( pcParameter ); - - if( ucReturned == F_NO_ERROR ) - { - sprintf( pcWriteBuffer, "%s was deleted", pcParameter ); - } - else - { - sprintf( pcWriteBuffer, "Error" ); - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -char *pcSourceFile, *pcDestinationFile; -BaseType_t xParameterStringLength; -long lSourceLength, lDestinationLength = 0; - - /* Obtain the name of the destination file. */ - pcDestinationFile = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 2, /* Return the second parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcDestinationFile ); - - /* Obtain the name of the source file. */ - pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcSourceFile ); - - /* Terminate the string. */ - pcSourceFile[ xParameterStringLength ] = 0x00; - - /* See if the source file exists, obtain its length if it does. */ - lSourceLength = f_filelength( pcSourceFile ); - - if( lSourceLength == 0 ) - { - sprintf( pcWriteBuffer, "Source file does not exist" ); - } - else - { - /* See if the destination file exists. */ - lDestinationLength = f_filelength( pcDestinationFile ); - - if( lDestinationLength != 0 ) - { - sprintf( pcWriteBuffer, "Error: Destination file already exists" ); - } - } - - /* Continue only if the source file exists and the destination file does - not exist. */ - if( ( lSourceLength != 0 ) && ( lDestinationLength == 0 ) ) - { - if( prvPerformCopy( pcSourceFile, lSourceLength, pcDestinationFile, pcWriteBuffer, xWriteBufferLen ) == pdPASS ) - { - sprintf( pcWriteBuffer, "Copy made" ); - } - else - { - sprintf( pcWriteBuffer, "Error during copy" ); - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvPerformCopy( const char *pcSourceFile, - int32_t lSourceFileLength, - const char *pcDestinationFile, - char *pxWriteBuffer, - size_t xWriteBufferLen ) -{ -int32_t lBytesRead = 0, lBytesToRead, lBytesRemaining; -F_FILE *pxFile; -BaseType_t xReturn = pdPASS; - - /* NOTE: Error handling has been omitted for clarity. */ - - while( lBytesRead < lSourceFileLength ) - { - /* How many bytes are left? */ - lBytesRemaining = lSourceFileLength - lBytesRead; - - /* How many bytes should be read this time around the loop. Can't - read more bytes than will fit into the buffer. */ - if( lBytesRemaining > ( long ) xWriteBufferLen ) - { - lBytesToRead = ( long ) xWriteBufferLen; - } - else - { - lBytesToRead = lBytesRemaining; - } - - /* Open the source file, seek past the data that has already been - read from the file, read the next block of data, then close the - file again so the destination file can be opened. */ - pxFile = f_open( pcSourceFile, "r" ); - if( pxFile != NULL ) - { - f_seek( pxFile, lBytesRead, F_SEEK_SET ); - f_read( pxWriteBuffer, lBytesToRead, 1, pxFile ); - f_close( pxFile ); - } - else - { - xReturn = pdFAIL; - break; - } - - /* Open the destination file and write the block of data to the end of - the file. */ - pxFile = f_open( pcDestinationFile, "a" ); - if( pxFile != NULL ) - { - f_write( pxWriteBuffer, lBytesToRead, 1, pxFile ); - f_close( pxFile ); - } - else - { - xReturn = pdFAIL; - break; - } - - lBytesRead += lBytesToRead; - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static void prvCreateFileInfoString( char *pcBuffer, F_FIND *pxFindStruct ) -{ -const char *pcWritableFile = "writable file", *pcReadOnlyFile = "read only file", *pcDirectory = "directory"; -const char * pcAttrib; - - /* Point pcAttrib to a string that describes the file. */ - if( ( pxFindStruct->attr & F_ATTR_DIR ) != 0 ) - { - pcAttrib = pcDirectory; - } - else if( pxFindStruct->attr & F_ATTR_READONLY ) - { - pcAttrib = pcReadOnlyFile; - } - else - { - pcAttrib = pcWritableFile; - } - - /* Create a string that includes the file name, the file size and the - attributes string. */ - sprintf( pcBuffer, "%s [%s] [size=%d]", pxFindStruct->filename, pcAttrib, ( int ) pxFindStruct->filesize ); -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* File system includes. */ +#include "fat_sl.h" +#include "api_mdriver_ram.h" + +#ifdef _WINDOWS_ + #define snprintf _snprintf +#endif + +#define cliNEW_LINE "\r\n" + +/******************************************************************************* + * See the URL in the comments within main.c for the location of the online + * documentation. + ******************************************************************************/ + +/* + * Print out information on a single file. + */ +static void prvCreateFileInfoString( char * pcBuffer, + F_FIND * pxFindStruct ); + +/* + * Copies an existing file into a newly created file. + */ +static BaseType_t prvPerformCopy( const char * pcSourceFile, + int32_t lSourceFileLength, + const char * pcDestinationFile, + char * pxWriteBuffer, + size_t xWriteBufferLen ); + +/* + * Implements the DIR command. + */ +static BaseType_t prvDIRCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the CD command. + */ +static BaseType_t prvCDCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the DEL command. + */ +static BaseType_t prvDELCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the TYPE command. + */ +static BaseType_t prvTYPECommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the COPY command. + */ +static BaseType_t prvCOPYCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* Structure that defines the DIR command line command, which lists all the + * files in the current directory. */ +static const CLI_Command_Definition_t xDIR = +{ + "dir", /* The command string to type. */ + "\r\ndir:\r\n Lists the files in the current directory\r\n", + prvDIRCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the CD command line command, which changes the + * working directory. */ +static const CLI_Command_Definition_t xCD = +{ + "cd", /* The command string to type. */ + "\r\ncd :\r\n Changes the working directory\r\n", + prvCDCommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the TYPE command line command, which prints the + * contents of a file to the console. */ +static const CLI_Command_Definition_t xTYPE = +{ + "type", /* The command string to type. */ + "\r\ntype :\r\n Prints file contents to the terminal\r\n", + prvTYPECommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the DEL command line command, which deletes a file. */ +static const CLI_Command_Definition_t xDEL = +{ + "del", /* The command string to type. */ + "\r\ndel :\r\n deletes a file or directory\r\n", + prvDELCommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the COPY command line command, which deletes a file. */ +static const CLI_Command_Definition_t xCOPY = +{ + "copy", /* The command string to type. */ + "\r\ncopy :\r\n Copies to \r\n", + prvCOPYCommand, /* The function to run. */ + 2 /* Two parameters are expected. */ +}; + + +/*-----------------------------------------------------------*/ + +void vRegisterFileSystemCLICommands( void ) +{ + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xDIR ); + FreeRTOS_CLIRegisterCommand( &xCD ); + FreeRTOS_CLIRegisterCommand( &xTYPE ); + FreeRTOS_CLIRegisterCommand( &xDEL ); + FreeRTOS_CLIRegisterCommand( &xCOPY ); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTYPECommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength, xReturn = pdTRUE; + static F_FILE * pxFile = NULL; + int iChar; + size_t xByte; + size_t xColumns = 50U; + + /* Ensure there is always a null terminator after each character written. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + if( xWriteBufferLen < xColumns ) + { + /* Ensure the loop that uses xColumns as an end condition does not + * write off the end of the buffer. */ + xColumns = xWriteBufferLen; + } + + if( pxFile == NULL ) + { + /* The file has not been opened yet. Find the file name. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to open the requested file. */ + pxFile = f_open( pcParameter, "r" ); + } + + if( pxFile != NULL ) + { + /* Read the next chunk of data from the file. */ + for( xByte = 0; xByte < xColumns; xByte++ ) + { + iChar = f_getc( pxFile ); + + if( iChar == -1 ) + { + /* No more characters to return. */ + f_close( pxFile ); + pxFile = NULL; + break; + } + else + { + pcWriteBuffer[ xByte ] = ( char ) iChar; + } + } + } + + if( pxFile == NULL ) + { + /* Either the file was not opened, or all the data from the file has + * been returned and the file is now closed. */ + xReturn = pdFALSE; + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvCDCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength; + unsigned char ucReturned; + size_t xStringLength; + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to move to the requested directory. */ + ucReturned = f_chdir( pcParameter ); + + if( ucReturned == F_NO_ERROR ) + { + sprintf( pcWriteBuffer, "In: " ); + xStringLength = strlen( pcWriteBuffer ); + f_getcwd( &( pcWriteBuffer[ xStringLength ] ), ( unsigned char ) ( xWriteBufferLen - xStringLength ) ); + } + else + { + sprintf( pcWriteBuffer, "Error" ); + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvDIRCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + static F_FIND * pxFindStruct = NULL; + unsigned char ucReturned; + BaseType_t xReturn = pdFALSE; + + /* This assumes pcWriteBuffer is long enough. */ + ( void ) pcCommandString; + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + if( pxFindStruct == NULL ) + { + /* This is the first time this function has been executed since the Dir + * command was run. Create the find structure. */ + pxFindStruct = ( F_FIND * ) pvPortMalloc( sizeof( F_FIND ) ); + + if( pxFindStruct != NULL ) + { + ucReturned = f_findfirst( "*.*", pxFindStruct ); + + if( ucReturned == F_NO_ERROR ) + { + prvCreateFileInfoString( pcWriteBuffer, pxFindStruct ); + xReturn = pdPASS; + } + else + { + snprintf( pcWriteBuffer, xWriteBufferLen, "Error: f_findfirst() failed." ); + } + } + else + { + snprintf( pcWriteBuffer, xWriteBufferLen, "Failed to allocate RAM (using heap_4.c will prevent fragmentation)." ); + } + } + else + { + /* The find struct has already been created. Find the next file in + * the directory. */ + ucReturned = f_findnext( pxFindStruct ); + + if( ucReturned == F_NO_ERROR ) + { + prvCreateFileInfoString( pcWriteBuffer, pxFindStruct ); + xReturn = pdPASS; + } + else + { + /* There are no more files. Free the find structure. */ + vPortFree( pxFindStruct ); + pxFindStruct = NULL; + + /* No string to return. */ + pcWriteBuffer[ 0 ] = 0x00; + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvDELCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength; + unsigned char ucReturned; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to delete the file. */ + ucReturned = f_delete( pcParameter ); + + if( ucReturned == F_NO_ERROR ) + { + sprintf( pcWriteBuffer, "%s was deleted", pcParameter ); + } + else + { + sprintf( pcWriteBuffer, "Error" ); + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvCOPYCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + char * pcSourceFile, * pcDestinationFile; + BaseType_t xParameterStringLength; + long lSourceLength, lDestinationLength = 0; + + /* Obtain the name of the destination file. */ + pcDestinationFile = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 2, /* Return the second parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcDestinationFile ); + + /* Obtain the name of the source file. */ + pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcSourceFile ); + + /* Terminate the string. */ + pcSourceFile[ xParameterStringLength ] = 0x00; + + /* See if the source file exists, obtain its length if it does. */ + lSourceLength = f_filelength( pcSourceFile ); + + if( lSourceLength == 0 ) + { + sprintf( pcWriteBuffer, "Source file does not exist" ); + } + else + { + /* See if the destination file exists. */ + lDestinationLength = f_filelength( pcDestinationFile ); + + if( lDestinationLength != 0 ) + { + sprintf( pcWriteBuffer, "Error: Destination file already exists" ); + } + } + + /* Continue only if the source file exists and the destination file does + * not exist. */ + if( ( lSourceLength != 0 ) && ( lDestinationLength == 0 ) ) + { + if( prvPerformCopy( pcSourceFile, lSourceLength, pcDestinationFile, pcWriteBuffer, xWriteBufferLen ) == pdPASS ) + { + sprintf( pcWriteBuffer, "Copy made" ); + } + else + { + sprintf( pcWriteBuffer, "Error during copy" ); + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvPerformCopy( const char * pcSourceFile, + int32_t lSourceFileLength, + const char * pcDestinationFile, + char * pxWriteBuffer, + size_t xWriteBufferLen ) +{ + int32_t lBytesRead = 0, lBytesToRead, lBytesRemaining; + F_FILE * pxFile; + BaseType_t xReturn = pdPASS; + + /* NOTE: Error handling has been omitted for clarity. */ + + while( lBytesRead < lSourceFileLength ) + { + /* How many bytes are left? */ + lBytesRemaining = lSourceFileLength - lBytesRead; + + /* How many bytes should be read this time around the loop. Can't + * read more bytes than will fit into the buffer. */ + if( lBytesRemaining > ( long ) xWriteBufferLen ) + { + lBytesToRead = ( long ) xWriteBufferLen; + } + else + { + lBytesToRead = lBytesRemaining; + } + + /* Open the source file, seek past the data that has already been + * read from the file, read the next block of data, then close the + * file again so the destination file can be opened. */ + pxFile = f_open( pcSourceFile, "r" ); + + if( pxFile != NULL ) + { + f_seek( pxFile, lBytesRead, F_SEEK_SET ); + f_read( pxWriteBuffer, lBytesToRead, 1, pxFile ); + f_close( pxFile ); + } + else + { + xReturn = pdFAIL; + break; + } + + /* Open the destination file and write the block of data to the end of + * the file. */ + pxFile = f_open( pcDestinationFile, "a" ); + + if( pxFile != NULL ) + { + f_write( pxWriteBuffer, lBytesToRead, 1, pxFile ); + f_close( pxFile ); + } + else + { + xReturn = pdFAIL; + break; + } + + lBytesRead += lBytesToRead; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvCreateFileInfoString( char * pcBuffer, + F_FIND * pxFindStruct ) +{ + const char * pcWritableFile = "writable file", * pcReadOnlyFile = "read only file", * pcDirectory = "directory"; + const char * pcAttrib; + + /* Point pcAttrib to a string that describes the file. */ + if( ( pxFindStruct->attr & F_ATTR_DIR ) != 0 ) + { + pcAttrib = pcDirectory; + } + else if( pxFindStruct->attr & F_ATTR_READONLY ) + { + pcAttrib = pcReadOnlyFile; + } + else + { + pcAttrib = pcWritableFile; + } + + /* Create a string that includes the file name, the file size and the + * attributes string. */ + sprintf( pcBuffer, "%s [%s] [size=%d]", pxFindStruct->filename, pcAttrib, ( int ) pxFindStruct->filesize ); +} diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c index c4fc0e8cc..5d30e790d 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c @@ -1,479 +1,507 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - - - /****************************************************************************** - * - * https://www.FreeRTOS.org/cli - * - ******************************************************************************/ - - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* Standard includes. */ -#include -#include -#include -#include - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS - #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0 -#endif - -#ifndef configINCLUDE_QUERY_HEAP_COMMAND - #define configINCLUDE_QUERY_HEAP_COMMAND 0 -#endif - -/* - * The function that registers the commands that are defined within this file. - */ -void vRegisterSampleCLICommands( void ); - -/* - * Implements the task-stats command. - */ -static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the run-time-stats command. - */ -#if( configGENERATE_RUN_TIME_STATS == 1 ) - static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); -#endif /* configGENERATE_RUN_TIME_STATS */ - -/* - * Implements the echo-three-parameters command. - */ -static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the echo-parameters command. - */ -static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the "query heap" command. - */ -#if( configINCLUDE_QUERY_HEAP_COMMAND == 1 ) - static BaseType_t prvQueryHeapCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); -#endif - -/* - * Implements the "trace start" and "trace stop" commands; - */ -#if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 ) - static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); -#endif - -/* Structure that defines the "task-stats" command line command. This generates -a table that gives information on each task in the system. */ -static const CLI_Command_Definition_t xTaskStats = -{ - "task-stats", /* The command string to type. */ - "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n", - prvTaskStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the "echo_3_parameters" command line command. This -takes exactly three parameters that the command simply echos back one at a -time. */ -static const CLI_Command_Definition_t xThreeParameterEcho = -{ - "echo-3-parameters", - "\r\necho-3-parameters :\r\n Expects three parameters, echos each in turn\r\n", - prvThreeParameterEchoCommand, /* The function to run. */ - 3 /* Three parameters are expected, which can take any value. */ -}; - -/* Structure that defines the "echo_parameters" command line command. This -takes a variable number of parameters that the command simply echos back one at -a time. */ -static const CLI_Command_Definition_t xParameterEcho = -{ - "echo-parameters", - "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n", - prvParameterEchoCommand, /* The function to run. */ - -1 /* The user can enter any number of commands. */ -}; - -#if( configGENERATE_RUN_TIME_STATS == 1 ) - /* Structure that defines the "run-time-stats" command line command. This - generates a table that shows how much run time each task has */ - static const CLI_Command_Definition_t xRunTimeStats = - { - "run-time-stats", /* The command string to type. */ - "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n", - prvRunTimeStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ - }; -#endif /* configGENERATE_RUN_TIME_STATS */ - -#if( configINCLUDE_QUERY_HEAP_COMMAND == 1 ) - /* Structure that defines the "query_heap" command line command. */ - static const CLI_Command_Definition_t xQueryHeap = - { - "query-heap", - "\r\nquery-heap:\r\n Displays the free heap space, and minimum ever free heap space.\r\n", - prvQueryHeapCommand, /* The function to run. */ - 0 /* The user can enter any number of commands. */ - }; -#endif /* configQUERY_HEAP_COMMAND */ - -#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - /* Structure that defines the "trace" command line command. This takes a single - parameter, which can be either "start" or "stop". */ - static const CLI_Command_Definition_t xStartStopTrace = - { - "trace", - "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n", - prvStartStopTraceCommand, /* The function to run. */ - 1 /* One parameter is expected. Valid values are "start" and "stop". */ - }; -#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ - -/*-----------------------------------------------------------*/ - -void vRegisterSampleCLICommands( void ) -{ - /* Register all the command line commands defined immediately above. */ - FreeRTOS_CLIRegisterCommand( &xTaskStats ); - FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); - FreeRTOS_CLIRegisterCommand( &xParameterEcho ); - - #if( configGENERATE_RUN_TIME_STATS == 1 ) - { - FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); - } - #endif - - #if( configINCLUDE_QUERY_HEAP_COMMAND == 1 ) - { - FreeRTOS_CLIRegisterCommand( &xQueryHeap ); - } - #endif - - #if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 ) - { - FreeRTOS_CLIRegisterCommand( &xStartStopTrace ); - } - #endif -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *const pcHeader = " State Priority Stack #\r\n************************************************\r\n"; -BaseType_t xSpacePadding; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Generate a table of task stats. */ - strcpy( pcWriteBuffer, "Task" ); - pcWriteBuffer += strlen( pcWriteBuffer ); - - /* Minus three for the null terminator and half the number of characters in - "Task" so the column lines up with the centre of the heading. */ - configASSERT( configMAX_TASK_NAME_LEN > 3 ); - for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ ) - { - /* Add a space to align columns after the task's name. */ - *pcWriteBuffer = ' '; - pcWriteBuffer++; - - /* Ensure always terminated. */ - *pcWriteBuffer = 0x00; - } - strcpy( pcWriteBuffer, pcHeader ); - vTaskList( pcWriteBuffer + strlen( pcHeader ) ); - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -#if( configINCLUDE_QUERY_HEAP_COMMAND == 1 ) - - static BaseType_t prvQueryHeapCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) - { - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - sprintf( pcWriteBuffer, "Current free heap %d bytes, minimum ever free heap %d bytes\r\n", ( int ) xPortGetFreeHeapSize(), ( int ) xPortGetMinimumEverFreeHeapSize() ); - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; - } - -#endif /* configINCLUDE_QUERY_HEAP */ -/*-----------------------------------------------------------*/ - -#if( configGENERATE_RUN_TIME_STATS == 1 ) - - static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) - { - const char * const pcHeader = " Abs Time % Time\r\n****************************************\r\n"; - BaseType_t xSpacePadding; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Generate a table of task stats. */ - strcpy( pcWriteBuffer, "Task" ); - pcWriteBuffer += strlen( pcWriteBuffer ); - - /* Pad the string "task" with however many bytes necessary to make it the - length of a task name. Minus three for the null terminator and half the - number of characters in "Task" so the column lines up with the centre of - the heading. */ - for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ ) - { - /* Add a space to align columns after the task's name. */ - *pcWriteBuffer = ' '; - pcWriteBuffer++; - - /* Ensure always terminated. */ - *pcWriteBuffer = 0x00; - } - - strcpy( pcWriteBuffer, pcHeader ); - vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) ); - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; - } - -#endif /* configGENERATE_RUN_TIME_STATS */ -/*-----------------------------------------------------------*/ - -static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength, xReturn; -static UBaseType_t uxParameterNumber = 0; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - if( uxParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( pcWriteBuffer, "The three parameters were:\r\n" ); - - /* Next time the function is called the first parameter will be echoed - back. */ - uxParameterNumber = 1U; - - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - uxParameterNumber, /* Return the next parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( pcWriteBuffer, "%d: ", ( int ) uxParameterNumber ); - strncat( pcWriteBuffer, pcParameter, ( size_t ) xParameterStringLength ); - strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - if( uxParameterNumber == 3U ) - { - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - xReturn = pdFALSE; - uxParameterNumber = 0; - } - else - { - /* There are more parameters to return after this one. */ - xReturn = pdTRUE; - uxParameterNumber++; - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength, xReturn; -static UBaseType_t uxParameterNumber = 0; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - if( uxParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( pcWriteBuffer, "The parameters were:\r\n" ); - - /* Next time the function is called the first parameter will be echoed - back. */ - uxParameterNumber = 1U; - - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - uxParameterNumber, /* Return the next parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - if( pcParameter != NULL ) - { - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( pcWriteBuffer, "%d: ", ( int ) uxParameterNumber ); - strncat( pcWriteBuffer, ( char * ) pcParameter, ( size_t ) xParameterStringLength ); - strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - - /* There might be more parameters to return after this one. */ - xReturn = pdTRUE; - uxParameterNumber++; - } - else - { - /* No more parameters were found. Make sure the write buffer does - not contain a valid string. */ - pcWriteBuffer[ 0 ] = 0x00; - - /* No more data to return. */ - xReturn = pdFALSE; - - /* Start over the next time this command is executed. */ - uxParameterNumber = 0; - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - - static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) - { - const char *pcParameter; - BaseType_t lParameterStringLength; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* There are only two valid parameter values. */ - if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 ) - { - /* Start or restart the trace. */ - vTraceStop(); - vTraceClear(); - vTraceStart(); - - sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" ); - } - else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 ) - { - /* End the trace, if one is running. */ - vTraceStop(); - sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" ); - } - else - { - sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); - } - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; - } - -#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/****************************************************************************** +* +* https://www.FreeRTOS.org/cli +* +******************************************************************************/ + + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS + #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0 +#endif + +#ifndef configINCLUDE_QUERY_HEAP_COMMAND + #define configINCLUDE_QUERY_HEAP_COMMAND 0 +#endif + +/* + * The function that registers the commands that are defined within this file. + */ +void vRegisterSampleCLICommands( void ); + +/* + * Implements the task-stats command. + */ +static BaseType_t prvTaskStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the run-time-stats command. + */ +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + static BaseType_t prvRunTimeStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); +#endif /* configGENERATE_RUN_TIME_STATS */ + +/* + * Implements the echo-three-parameters command. + */ +static BaseType_t prvThreeParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the echo-parameters command. + */ +static BaseType_t prvParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the "query heap" command. + */ +#if ( configINCLUDE_QUERY_HEAP_COMMAND == 1 ) + static BaseType_t prvQueryHeapCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); +#endif + +/* + * Implements the "trace start" and "trace stop" commands; + */ +#if ( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 ) + static BaseType_t prvStartStopTraceCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); +#endif + +/* Structure that defines the "task-stats" command line command. This generates + * a table that gives information on each task in the system. */ +static const CLI_Command_Definition_t xTaskStats = +{ + "task-stats", /* The command string to type. */ + "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n", + prvTaskStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the "echo_3_parameters" command line command. This + * takes exactly three parameters that the command simply echos back one at a + * time. */ +static const CLI_Command_Definition_t xThreeParameterEcho = +{ + "echo-3-parameters", + "\r\necho-3-parameters :\r\n Expects three parameters, echos each in turn\r\n", + prvThreeParameterEchoCommand, /* The function to run. */ + 3 /* Three parameters are expected, which can take any value. */ +}; + +/* Structure that defines the "echo_parameters" command line command. This + * takes a variable number of parameters that the command simply echos back one at + * a time. */ +static const CLI_Command_Definition_t xParameterEcho = +{ + "echo-parameters", + "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n", + prvParameterEchoCommand, /* The function to run. */ + -1 /* The user can enter any number of commands. */ +}; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +/* Structure that defines the "run-time-stats" command line command. This + * generates a table that shows how much run time each task has */ + static const CLI_Command_Definition_t xRunTimeStats = + { + "run-time-stats", /* The command string to type. */ + "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n", + prvRunTimeStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ + }; +#endif /* configGENERATE_RUN_TIME_STATS */ + +#if ( configINCLUDE_QUERY_HEAP_COMMAND == 1 ) + /* Structure that defines the "query_heap" command line command. */ + static const CLI_Command_Definition_t xQueryHeap = + { + "query-heap", + "\r\nquery-heap:\r\n Displays the free heap space, and minimum ever free heap space.\r\n", + prvQueryHeapCommand, /* The function to run. */ + 0 /* The user can enter any number of commands. */ + }; +#endif /* configQUERY_HEAP_COMMAND */ + +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + +/* Structure that defines the "trace" command line command. This takes a single + * parameter, which can be either "start" or "stop". */ + static const CLI_Command_Definition_t xStartStopTrace = + { + "trace", + "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n", + prvStartStopTraceCommand, /* The function to run. */ + 1 /* One parameter is expected. Valid values are "start" and "stop". */ + }; +#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ + +/*-----------------------------------------------------------*/ + +void vRegisterSampleCLICommands( void ) +{ + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xTaskStats ); + FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); + FreeRTOS_CLIRegisterCommand( &xParameterEcho ); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); + } + #endif + + #if ( configINCLUDE_QUERY_HEAP_COMMAND == 1 ) + { + FreeRTOS_CLIRegisterCommand( &xQueryHeap ); + } + #endif + + #if ( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 ) + { + FreeRTOS_CLIRegisterCommand( &xStartStopTrace ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTaskStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * const pcHeader = " State Priority Stack #\r\n************************************************\r\n"; + BaseType_t xSpacePadding; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( pcWriteBuffer, "Task" ); + pcWriteBuffer += strlen( pcWriteBuffer ); + + /* Minus three for the null terminator and half the number of characters in + * "Task" so the column lines up with the centre of the heading. */ + configASSERT( configMAX_TASK_NAME_LEN > 3 ); + + for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ ) + { + /* Add a space to align columns after the task's name. */ + *pcWriteBuffer = ' '; + pcWriteBuffer++; + + /* Ensure always terminated. */ + *pcWriteBuffer = 0x00; + } + + strcpy( pcWriteBuffer, pcHeader ); + vTaskList( pcWriteBuffer + strlen( pcHeader ) ); + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +#if ( configINCLUDE_QUERY_HEAP_COMMAND == 1 ) + + static BaseType_t prvQueryHeapCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) + { + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + sprintf( pcWriteBuffer, "Current free heap %d bytes, minimum ever free heap %d bytes\r\n", ( int ) xPortGetFreeHeapSize(), ( int ) xPortGetMinimumEverFreeHeapSize() ); + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; + } + +#endif /* configINCLUDE_QUERY_HEAP */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + static BaseType_t prvRunTimeStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) + { + const char * const pcHeader = " Abs Time % Time\r\n****************************************\r\n"; + BaseType_t xSpacePadding; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( pcWriteBuffer, "Task" ); + pcWriteBuffer += strlen( pcWriteBuffer ); + + /* Pad the string "task" with however many bytes necessary to make it the + * length of a task name. Minus three for the null terminator and half the + * number of characters in "Task" so the column lines up with the centre of + * the heading. */ + for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ ) + { + /* Add a space to align columns after the task's name. */ + *pcWriteBuffer = ' '; + pcWriteBuffer++; + + /* Ensure always terminated. */ + *pcWriteBuffer = 0x00; + } + + strcpy( pcWriteBuffer, pcHeader ); + vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) ); + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; + } + +#endif /* configGENERATE_RUN_TIME_STATS */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvThreeParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength, xReturn; + static UBaseType_t uxParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( uxParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( pcWriteBuffer, "The three parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + * back. */ + uxParameterNumber = 1U; + + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + uxParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( pcWriteBuffer, "%d: ", ( int ) uxParameterNumber ); + strncat( pcWriteBuffer, pcParameter, ( size_t ) xParameterStringLength ); + strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + if( uxParameterNumber == 3U ) + { + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + xReturn = pdFALSE; + uxParameterNumber = 0; + } + else + { + /* There are more parameters to return after this one. */ + xReturn = pdTRUE; + uxParameterNumber++; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength, xReturn; + static UBaseType_t uxParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( uxParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( pcWriteBuffer, "The parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + * back. */ + uxParameterNumber = 1U; + + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + uxParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + if( pcParameter != NULL ) + { + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( pcWriteBuffer, "%d: ", ( int ) uxParameterNumber ); + strncat( pcWriteBuffer, ( char * ) pcParameter, ( size_t ) xParameterStringLength ); + strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* There might be more parameters to return after this one. */ + xReturn = pdTRUE; + uxParameterNumber++; + } + else + { + /* No more parameters were found. Make sure the write buffer does + * not contain a valid string. */ + pcWriteBuffer[ 0 ] = 0x00; + + /* No more data to return. */ + xReturn = pdFALSE; + + /* Start over the next time this command is executed. */ + uxParameterNumber = 0; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + + static BaseType_t prvStartStopTraceCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) + { + const char * pcParameter; + BaseType_t lParameterStringLength; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* There are only two valid parameter values. */ + if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 ) + { + /* Start or restart the trace. */ + vTraceStop(); + vTraceClear(); + vTraceStart(); + + sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" ); + } + else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 ) + { + /* End the trace, if one is running. */ + vTraceStop(); + sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" ); + } + else + { + sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); + } + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; + } + +#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c index 6c742d041..5249a0cad 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c @@ -1,225 +1,227 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -/* - * NOTE: This file uses a third party USB CDC driver. - */ - -/* Standard includes. */ -#include "string.h" -#include "stdio.h" - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "semphr.h" - -/* Example includes. */ -#include "FreeRTOS_CLI.h" - -/* Demo application includes. */ -#include "serial.h" - -/* Dimensions the buffer into which input characters are placed. */ -#define cmdMAX_INPUT_SIZE 50 - -/* Dimentions a buffer to be used by the UART driver, if the UART driver uses a -buffer at all. */ -#define cmdQUEUE_LENGTH 25 - -/* DEL acts as a backspace. */ -#define cmdASCII_DEL ( 0x7F ) - -/* The maximum time to wait for the mutex that guards the UART to become -available. */ -#define cmdMAX_MUTEX_WAIT pdMS_TO_TICKS( 300 ) - -#ifndef configCLI_BAUD_RATE - #define configCLI_BAUD_RATE 115200 -#endif - -/*-----------------------------------------------------------*/ - -/* - * The task that implements the command console processing. - */ -static void prvUARTCommandConsoleTask( void *pvParameters ); -void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority ); - -/*-----------------------------------------------------------*/ - -/* Const messages output by the command console. */ -static const char * const pcWelcomeMessage = "FreeRTOS command server.\r\nType Help to view a list of registered commands.\r\n\r\n>"; -static const char * const pcEndOfOutputMessage = "\r\n[Press ENTER to execute the previous command again]\r\n>"; -static const char * const pcNewLine = "\r\n"; - -/* Used to guard access to the UART in case messages are sent to the UART from -more than one task. */ -static SemaphoreHandle_t xTxMutex = NULL; - -/* The handle to the UART port, which is not used by all ports. */ -static xComPortHandle xPort = 0; - -/*-----------------------------------------------------------*/ - -void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority ) -{ - /* Create the semaphore used to access the UART Tx. */ - xTxMutex = xSemaphoreCreateMutex(); - configASSERT( xTxMutex ); - - /* Create that task that handles the console itself. */ - xTaskCreate( prvUARTCommandConsoleTask, /* The task that implements the command console. */ - "CLI", /* Text name assigned to the task. This is just to assist debugging. The kernel does not use this name itself. */ - usStackSize, /* The size of the stack allocated to the task. */ - NULL, /* The parameter is not used, so NULL is passed. */ - uxPriority, /* The priority allocated to the task. */ - NULL ); /* A handle is not required, so just pass NULL. */ -} -/*-----------------------------------------------------------*/ - -static void prvUARTCommandConsoleTask( void *pvParameters ) -{ -signed char cRxedChar; -uint8_t ucInputIndex = 0; -char *pcOutputString; -static char cInputString[ cmdMAX_INPUT_SIZE ], cLastInputString[ cmdMAX_INPUT_SIZE ]; -BaseType_t xReturned; -xComPortHandle xPort; - - ( void ) pvParameters; - - /* Obtain the address of the output buffer. Note there is no mutual - exclusion on this buffer as it is assumed only one command console interface - will be used at any one time. */ - pcOutputString = FreeRTOS_CLIGetOutputBuffer(); - - /* Initialise the UART. */ - xPort = xSerialPortInitMinimal( configCLI_BAUD_RATE, cmdQUEUE_LENGTH ); - - /* Send the welcome message. */ - vSerialPutString( xPort, ( signed char * ) pcWelcomeMessage, ( unsigned short ) strlen( pcWelcomeMessage ) ); - - for( ;; ) - { - /* Wait for the next character. The while loop is used in case - INCLUDE_vTaskSuspend is not set to 1 - in which case portMAX_DELAY will - be a genuine block time rather than an infinite block time. */ - while( xSerialGetChar( xPort, &cRxedChar, portMAX_DELAY ) != pdPASS ); - - /* Ensure exclusive access to the UART Tx. */ - if( xSemaphoreTake( xTxMutex, cmdMAX_MUTEX_WAIT ) == pdPASS ) - { - /* Echo the character back. */ - xSerialPutChar( xPort, cRxedChar, portMAX_DELAY ); - - /* Was it the end of the line? */ - if( cRxedChar == '\n' || cRxedChar == '\r' ) - { - /* Just to space the output from the input. */ - vSerialPutString( xPort, ( signed char * ) pcNewLine, ( unsigned short ) strlen( pcNewLine ) ); - - /* See if the command is empty, indicating that the last command - is to be executed again. */ - if( ucInputIndex == 0 ) - { - /* Copy the last command back into the input string. */ - strcpy( cInputString, cLastInputString ); - } - - /* Pass the received command to the command interpreter. The - command interpreter is called repeatedly until it returns - pdFALSE (indicating there is no more output) as it might - generate more than one string. */ - do - { - /* Get the next output string from the command interpreter. */ - xReturned = FreeRTOS_CLIProcessCommand( cInputString, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE ); - - /* Write the generated string to the UART. */ - vSerialPutString( xPort, ( signed char * ) pcOutputString, ( unsigned short ) strlen( pcOutputString ) ); - - } while( xReturned != pdFALSE ); - - /* All the strings generated by the input command have been - sent. Clear the input string ready to receive the next command. - Remember the command that was just processed first in case it is - to be processed again. */ - strcpy( cLastInputString, cInputString ); - ucInputIndex = 0; - memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); - - vSerialPutString( xPort, ( signed char * ) pcEndOfOutputMessage, ( unsigned short ) strlen( pcEndOfOutputMessage ) ); - } - else - { - if( cRxedChar == '\r' ) - { - /* Ignore the character. */ - } - else if( ( cRxedChar == '\b' ) || ( cRxedChar == cmdASCII_DEL ) ) - { - /* Backspace was pressed. Erase the last character in the - string - if any. */ - if( ucInputIndex > 0 ) - { - ucInputIndex--; - cInputString[ ucInputIndex ] = '\0'; - } - } - else - { - /* A character was entered. Add it to the string entered so - far. When a \n is entered the complete string will be - passed to the command interpreter. */ - if( ( cRxedChar >= ' ' ) && ( cRxedChar <= '~' ) ) - { - if( ucInputIndex < cmdMAX_INPUT_SIZE ) - { - cInputString[ ucInputIndex ] = cRxedChar; - ucInputIndex++; - } - } - } - } - - /* Must ensure to give the mutex back. */ - xSemaphoreGive( xTxMutex ); - } - } -} -/*-----------------------------------------------------------*/ - -void vOutputString( const char * const pcMessage ) -{ - if( xSemaphoreTake( xTxMutex, cmdMAX_MUTEX_WAIT ) == pdPASS ) - { - vSerialPutString( xPort, ( signed char * ) pcMessage, ( unsigned short ) strlen( pcMessage ) ); - xSemaphoreGive( xTxMutex ); - } -} -/*-----------------------------------------------------------*/ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * NOTE: This file uses a third party USB CDC driver. + */ + +/* Standard includes. */ +#include "string.h" +#include "stdio.h" + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Example includes. */ +#include "FreeRTOS_CLI.h" + +/* Demo application includes. */ +#include "serial.h" + +/* Dimensions the buffer into which input characters are placed. */ +#define cmdMAX_INPUT_SIZE 50 + +/* Dimensions a buffer to be used by the UART driver, if the UART driver uses a + * buffer at all. */ +#define cmdQUEUE_LENGTH 25 + +/* DEL acts as a backspace. */ +#define cmdASCII_DEL ( 0x7F ) + +/* The maximum time to wait for the mutex that guards the UART to become + * available. */ +#define cmdMAX_MUTEX_WAIT pdMS_TO_TICKS( 300 ) + +#ifndef configCLI_BAUD_RATE + #define configCLI_BAUD_RATE 115200 +#endif + +/*-----------------------------------------------------------*/ + +/* + * The task that implements the command console processing. + */ +static void prvUARTCommandConsoleTask( void * pvParameters ); +void vUARTCommandConsoleStart( uint16_t usStackSize, + UBaseType_t uxPriority ); + +/*-----------------------------------------------------------*/ + +/* Const messages output by the command console. */ +static const char * const pcWelcomeMessage = "FreeRTOS command server.\r\nType Help to view a list of registered commands.\r\n\r\n>"; +static const char * const pcEndOfOutputMessage = "\r\n[Press ENTER to execute the previous command again]\r\n>"; +static const char * const pcNewLine = "\r\n"; + +/* Used to guard access to the UART in case messages are sent to the UART from + * more than one task. */ +static SemaphoreHandle_t xTxMutex = NULL; + +/* The handle to the UART port, which is not used by all ports. */ +static xComPortHandle xPort = 0; + +/*-----------------------------------------------------------*/ + +void vUARTCommandConsoleStart( uint16_t usStackSize, + UBaseType_t uxPriority ) +{ + /* Create the semaphore used to access the UART Tx. */ + xTxMutex = xSemaphoreCreateMutex(); + configASSERT( xTxMutex ); + + /* Create that task that handles the console itself. */ + xTaskCreate( prvUARTCommandConsoleTask, /* The task that implements the command console. */ + "CLI", /* Text name assigned to the task. This is just to assist debugging. The kernel does not use this name itself. */ + usStackSize, /* The size of the stack allocated to the task. */ + NULL, /* The parameter is not used, so NULL is passed. */ + uxPriority, /* The priority allocated to the task. */ + NULL ); /* A handle is not required, so just pass NULL. */ +} +/*-----------------------------------------------------------*/ + +static void prvUARTCommandConsoleTask( void * pvParameters ) +{ + signed char cRxedChar; + uint8_t ucInputIndex = 0; + char * pcOutputString; + static char cInputString[ cmdMAX_INPUT_SIZE ], cLastInputString[ cmdMAX_INPUT_SIZE ]; + BaseType_t xReturned; + xComPortHandle xPort; + + ( void ) pvParameters; + + /* Obtain the address of the output buffer. Note there is no mutual + * exclusion on this buffer as it is assumed only one command console interface + * will be used at any one time. */ + pcOutputString = FreeRTOS_CLIGetOutputBuffer(); + + /* Initialise the UART. */ + xPort = xSerialPortInitMinimal( configCLI_BAUD_RATE, cmdQUEUE_LENGTH ); + + /* Send the welcome message. */ + vSerialPutString( xPort, ( signed char * ) pcWelcomeMessage, ( unsigned short ) strlen( pcWelcomeMessage ) ); + + for( ; ; ) + { + /* Wait for the next character. The while loop is used in case + * INCLUDE_vTaskSuspend is not set to 1 - in which case portMAX_DELAY will + * be a genuine block time rather than an infinite block time. */ + while( xSerialGetChar( xPort, &cRxedChar, portMAX_DELAY ) != pdPASS ) + { + } + + /* Ensure exclusive access to the UART Tx. */ + if( xSemaphoreTake( xTxMutex, cmdMAX_MUTEX_WAIT ) == pdPASS ) + { + /* Echo the character back. */ + xSerialPutChar( xPort, cRxedChar, portMAX_DELAY ); + + /* Was it the end of the line? */ + if( ( cRxedChar == '\n' ) || ( cRxedChar == '\r' ) ) + { + /* Just to space the output from the input. */ + vSerialPutString( xPort, ( signed char * ) pcNewLine, ( unsigned short ) strlen( pcNewLine ) ); + + /* See if the command is empty, indicating that the last command + * is to be executed again. */ + if( ucInputIndex == 0 ) + { + /* Copy the last command back into the input string. */ + strcpy( cInputString, cLastInputString ); + } + + /* Pass the received command to the command interpreter. The + * command interpreter is called repeatedly until it returns + * pdFALSE (indicating there is no more output) as it might + * generate more than one string. */ + do + { + /* Get the next output string from the command interpreter. */ + xReturned = FreeRTOS_CLIProcessCommand( cInputString, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE ); + + /* Write the generated string to the UART. */ + vSerialPutString( xPort, ( signed char * ) pcOutputString, ( unsigned short ) strlen( pcOutputString ) ); + } while( xReturned != pdFALSE ); + + /* All the strings generated by the input command have been + * sent. Clear the input string ready to receive the next command. + * Remember the command that was just processed first in case it is + * to be processed again. */ + strcpy( cLastInputString, cInputString ); + ucInputIndex = 0; + memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); + + vSerialPutString( xPort, ( signed char * ) pcEndOfOutputMessage, ( unsigned short ) strlen( pcEndOfOutputMessage ) ); + } + else + { + if( cRxedChar == '\r' ) + { + /* Ignore the character. */ + } + else if( ( cRxedChar == '\b' ) || ( cRxedChar == cmdASCII_DEL ) ) + { + /* Backspace was pressed. Erase the last character in the + * string - if any. */ + if( ucInputIndex > 0 ) + { + ucInputIndex--; + cInputString[ ucInputIndex ] = '\0'; + } + } + else + { + /* A character was entered. Add it to the string entered so + * far. When a \n is entered the complete string will be + * passed to the command interpreter. */ + if( ( cRxedChar >= ' ' ) && ( cRxedChar <= '~' ) ) + { + if( ucInputIndex < cmdMAX_INPUT_SIZE ) + { + cInputString[ ucInputIndex ] = cRxedChar; + ucInputIndex++; + } + } + } + } + + /* Must ensure to give the mutex back. */ + xSemaphoreGive( xTxMutex ); + } + } +} +/*-----------------------------------------------------------*/ + +void vOutputString( const char * const pcMessage ) +{ + if( xSemaphoreTake( xTxMutex, cmdMAX_MUTEX_WAIT ) == pdPASS ) + { + vSerialPutString( xPort, ( signed char * ) pcMessage, ( unsigned short ) strlen( pcMessage ) ); + xSemaphoreGive( xTxMutex ); + } +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c index 02d4eeadf..5d6f908e9 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c @@ -1,328 +1,339 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - /****************************************************************************** - * - * See the following URL for information on the commands defined in this file: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml - * - ******************************************************************************/ - - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* Standard includes. */ -#include -#include -#include - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -/* FreeRTOS+UDP includes, just to make the stats available to the CLI -commands. */ -#include "FreeRTOS_UDP_IP.h" -#include "FreeRTOS_Sockets.h" - -/* - * Defines a command that prints out IP address information. - */ -static BaseType_t prvDisplayIPConfig( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Defines a command that prints out the gathered demo debug stats. - */ -static BaseType_t prvDisplayIPDebugStats( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Defines a command that sends an ICMP ping request to an IP address. - */ -static BaseType_t prvPingCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* Structure that defines the "ip-config" command line command. */ -static const CLI_Command_Definition_t xIPConfig = -{ - "ip-config", - "ip-config:\r\n Displays IP address configuration\r\n\r\n", - prvDisplayIPConfig, - 0 -}; - -#if configINCLUDE_DEMO_DEBUG_STATS != 0 - /* Structure that defines the "ip-debug-stats" command line command. */ - static const CLI_Command_Definition_t xIPDebugStats = - { - "ip-debug-stats", /* The command string to type. */ - "ip-debug-stats:\r\n Shows some IP stack stats useful for debug - an example only.\r\n\r\n", - prvDisplayIPDebugStats, /* The function to run. */ - 0 /* No parameters are expected. */ - }; -#endif /* configINCLUDE_DEMO_DEBUG_STATS */ - -#if ipconfigSUPPORT_OUTGOING_PINGS == 1 - - /* Structure that defines the "ping" command line command. This takes an IP - address or host name and (optionally) the number of bytes to ping as - parameters. */ - static const CLI_Command_Definition_t xPing = - { - "ping", - "ping :\r\n for example, ping 192.168.0.3 8, or ping www.example.com\r\n\r\n", - prvPingCommand, /* The function to run. */ - -1 /* Ping can take either one or two parameter, so the number of parameters has to be determined by the ping command implementation. */ - }; - -#endif /* ipconfigSUPPORT_OUTGOING_PINGS */ - - -/*-----------------------------------------------------------*/ - -void vRegisterUDPCLICommands( void ) -{ - /* Register all the command line commands defined immediately above. */ - FreeRTOS_CLIRegisterCommand( &xIPConfig ); - - #if configINCLUDE_DEMO_DEBUG_STATS == 1 - { - FreeRTOS_CLIRegisterCommand( &xIPDebugStats ); - } - #endif /* configINCLUDE_DEMO_DEBUG_STATS */ - - #if ipconfigSUPPORT_OUTGOING_PINGS == 1 - { - FreeRTOS_CLIRegisterCommand( &xPing ); - } - #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ -} -/*-----------------------------------------------------------*/ - -#if ipconfigSUPPORT_OUTGOING_PINGS == 1 - - static BaseType_t prvPingCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) - { - char * pcParameter; - BaseType_t lParameterStringLength, xReturn; - uint32_t ulIPAddress, ulBytesToPing; - const uint32_t ulDefaultBytesToPing = 8UL; - char cBuffer[ 16 ]; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Start with an empty string. */ - pcWriteBuffer[ 0 ] = 0x00; - - /* Obtain the number of bytes to ping. */ - pcParameter = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 2, /* Return the second parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - if( pcParameter == NULL ) - { - /* The number of bytes was not specified, so default it. */ - ulBytesToPing = ulDefaultBytesToPing; - } - else - { - ulBytesToPing = atol( pcParameter ); - } - - /* Obtain the IP address string. */ - pcParameter = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to obtain the IP address. If the first character is not a - digit, assume the host name has been passed in. */ - if( ( *pcParameter >= '0' ) && ( *pcParameter <= '9' ) ) - { - ulIPAddress = FreeRTOS_inet_addr( pcParameter ); - } - else - { - /* Terminate the host name. */ - pcParameter[ lParameterStringLength ] = 0x00; - - /* Attempt to resolve host. */ - ulIPAddress = FreeRTOS_gethostbyname( pcParameter ); - } - - /* Convert IP address, which may have come from a DNS lookup, to string. */ - FreeRTOS_inet_ntoa( ulIPAddress, cBuffer ); - - if( ulIPAddress != 0 ) - { - xReturn = FreeRTOS_SendPingRequest( ulIPAddress, ( uint16_t ) ulBytesToPing, portMAX_DELAY ); - } - else - { - xReturn = pdFALSE; - } - - if( xReturn == pdFALSE ) - { - sprintf( pcWriteBuffer, "%s", "Could not send ping request\r\n" ); - } - else - { - sprintf( pcWriteBuffer, "Ping sent to %s with identifier %d\r\n", cBuffer, ( int ) xReturn ); - } - - return pdFALSE; - } - /*-----------------------------------------------------------*/ - -#endif /* ipconfigSUPPORT_OUTGOING_PINGS */ - -#if configINCLUDE_DEMO_DEBUG_STATS != 0 - - static BaseType_t prvDisplayIPDebugStats( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) - { - static BaseType_t xIndex = -1; - extern xExampleDebugStatEntry_t xIPTraceValues[]; - BaseType_t xReturn; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - xIndex++; - - if( xIndex < xExampleDebugStatEntries() ) - { - sprintf( pcWriteBuffer, "%s %d\r\n", ( char * ) xIPTraceValues[ xIndex ].pucDescription, ( int ) xIPTraceValues[ xIndex ].ulData ); - xReturn = pdPASS; - } - else - { - /* Reset the index for the next time it is called. */ - xIndex = -1; - - /* Ensure nothing remains in the write buffer. */ - pcWriteBuffer[ 0 ] = 0x00; - xReturn = pdFALSE; - } - - return xReturn; - } - /*-----------------------------------------------------------*/ - -#endif /* configINCLUDE_DEMO_DEBUG_STATS */ - -static BaseType_t prvDisplayIPConfig( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -static BaseType_t xIndex = 0; -BaseType_t xReturn; -uint32_t ulAddress; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - switch( xIndex ) - { - case 0 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( &ulAddress, NULL, NULL, NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( pcWriteBuffer, "\r\nIP address " ); - xReturn = pdTRUE; - xIndex++; - break; - - case 1 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( NULL, &ulAddress, NULL, NULL, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( NULL, &ulAddress, NULL, NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( pcWriteBuffer, "\r\nNet mask " ); - xReturn = pdTRUE; - xIndex++; - break; - - case 2 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( NULL, NULL, &ulAddress, NULL, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( NULL, NULL, &ulAddress, NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( pcWriteBuffer, "\r\nGateway address " ); - xReturn = pdTRUE; - xIndex++; - break; - - case 3 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( NULL, NULL, NULL, &ulAddress, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulAddress ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( pcWriteBuffer, "\r\nDNS server address " ); - xReturn = pdTRUE; - xIndex++; - break; - - default : - ulAddress = 0; - sprintf( pcWriteBuffer, "\r\n\r\n" ); - xReturn = pdFALSE; - xIndex = 0; - break; - } - - if( ulAddress != 0 ) - { - FreeRTOS_inet_ntoa( ulAddress, ( &( pcWriteBuffer[ strlen( pcWriteBuffer ) ] ) ) ); - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/****************************************************************************** +* +* See the following URL for information on the commands defined in this file: +* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml +* +******************************************************************************/ + + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* FreeRTOS+UDP includes, just to make the stats available to the CLI + * commands. */ +#include "FreeRTOS_UDP_IP.h" +#include "FreeRTOS_Sockets.h" + +/* + * Defines a command that prints out IP address information. + */ +static BaseType_t prvDisplayIPConfig( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Defines a command that prints out the gathered demo debug stats. + */ +static BaseType_t prvDisplayIPDebugStats( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Defines a command that sends an ICMP ping request to an IP address. + */ +static BaseType_t prvPingCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* Structure that defines the "ip-config" command line command. */ +static const CLI_Command_Definition_t xIPConfig = +{ + "ip-config", + "ip-config:\r\n Displays IP address configuration\r\n\r\n", + prvDisplayIPConfig, + 0 +}; + +#if configINCLUDE_DEMO_DEBUG_STATS != 0 + /* Structure that defines the "ip-debug-stats" command line command. */ + static const CLI_Command_Definition_t xIPDebugStats = + { + "ip-debug-stats", /* The command string to type. */ + "ip-debug-stats:\r\n Shows some IP stack stats useful for debug - an example only.\r\n\r\n", + prvDisplayIPDebugStats, /* The function to run. */ + 0 /* No parameters are expected. */ + }; +#endif /* configINCLUDE_DEMO_DEBUG_STATS */ + +#if ipconfigSUPPORT_OUTGOING_PINGS == 1 + +/* Structure that defines the "ping" command line command. This takes an IP + * address or host name and (optionally) the number of bytes to ping as + * parameters. */ + static const CLI_Command_Definition_t xPing = + { + "ping", + "ping :\r\n for example, ping 192.168.0.3 8, or ping www.example.com\r\n\r\n", + prvPingCommand, /* The function to run. */ + -1 /* Ping can take either one or two parameter, so the number of parameters has to be determined by the ping command implementation. */ + }; + +#endif /* ipconfigSUPPORT_OUTGOING_PINGS */ + + +/*-----------------------------------------------------------*/ + +void vRegisterUDPCLICommands( void ) +{ + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xIPConfig ); + + #if configINCLUDE_DEMO_DEBUG_STATS == 1 + { + FreeRTOS_CLIRegisterCommand( &xIPDebugStats ); + } + #endif /* configINCLUDE_DEMO_DEBUG_STATS */ + + #if ipconfigSUPPORT_OUTGOING_PINGS == 1 + { + FreeRTOS_CLIRegisterCommand( &xPing ); + } + #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ +} +/*-----------------------------------------------------------*/ + +#if ipconfigSUPPORT_OUTGOING_PINGS == 1 + + static BaseType_t prvPingCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) + { + char * pcParameter; + BaseType_t lParameterStringLength, xReturn; + uint32_t ulIPAddress, ulBytesToPing; + const uint32_t ulDefaultBytesToPing = 8UL; + char cBuffer[ 16 ]; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Start with an empty string. */ + pcWriteBuffer[ 0 ] = 0x00; + + /* Obtain the number of bytes to ping. */ + pcParameter = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 2, /* Return the second parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + if( pcParameter == NULL ) + { + /* The number of bytes was not specified, so default it. */ + ulBytesToPing = ulDefaultBytesToPing; + } + else + { + ulBytesToPing = atol( pcParameter ); + } + + /* Obtain the IP address string. */ + pcParameter = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to obtain the IP address. If the first character is not a + * digit, assume the host name has been passed in. */ + if( ( *pcParameter >= '0' ) && ( *pcParameter <= '9' ) ) + { + ulIPAddress = FreeRTOS_inet_addr( pcParameter ); + } + else + { + /* Terminate the host name. */ + pcParameter[ lParameterStringLength ] = 0x00; + + /* Attempt to resolve host. */ + ulIPAddress = FreeRTOS_gethostbyname( pcParameter ); + } + + /* Convert IP address, which may have come from a DNS lookup, to string. */ + FreeRTOS_inet_ntoa( ulIPAddress, cBuffer ); + + if( ulIPAddress != 0 ) + { + xReturn = FreeRTOS_SendPingRequest( ulIPAddress, ( uint16_t ) ulBytesToPing, portMAX_DELAY ); + } + else + { + xReturn = pdFALSE; + } + + if( xReturn == pdFALSE ) + { + sprintf( pcWriteBuffer, "%s", "Could not send ping request\r\n" ); + } + else + { + sprintf( pcWriteBuffer, "Ping sent to %s with identifier %d\r\n", cBuffer, ( int ) xReturn ); + } + + return pdFALSE; + } + /*-----------------------------------------------------------*/ + +#endif /* ipconfigSUPPORT_OUTGOING_PINGS */ + +#if configINCLUDE_DEMO_DEBUG_STATS != 0 + + static BaseType_t prvDisplayIPDebugStats( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) + { + static BaseType_t xIndex = -1; + extern xExampleDebugStatEntry_t xIPTraceValues[]; + BaseType_t xReturn; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + xIndex++; + + if( xIndex < xExampleDebugStatEntries() ) + { + sprintf( pcWriteBuffer, "%s %d\r\n", ( char * ) xIPTraceValues[ xIndex ].pucDescription, ( int ) xIPTraceValues[ xIndex ].ulData ); + xReturn = pdPASS; + } + else + { + /* Reset the index for the next time it is called. */ + xIndex = -1; + + /* Ensure nothing remains in the write buffer. */ + pcWriteBuffer[ 0 ] = 0x00; + xReturn = pdFALSE; + } + + return xReturn; + } + /*-----------------------------------------------------------*/ + +#endif /* configINCLUDE_DEMO_DEBUG_STATS */ + +static BaseType_t prvDisplayIPConfig( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + static BaseType_t xIndex = 0; + BaseType_t xReturn; + uint32_t ulAddress; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + switch( xIndex ) + { + case 0: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulAddress, NULL, NULL, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( &ulAddress, NULL, NULL, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( pcWriteBuffer, "\r\nIP address " ); + xReturn = pdTRUE; + xIndex++; + break; + + case 1: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( NULL, &ulAddress, NULL, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( NULL, &ulAddress, NULL, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( pcWriteBuffer, "\r\nNet mask " ); + xReturn = pdTRUE; + xIndex++; + break; + + case 2: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( NULL, NULL, &ulAddress, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( NULL, NULL, &ulAddress, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( pcWriteBuffer, "\r\nGateway address " ); + xReturn = pdTRUE; + xIndex++; + break; + + case 3: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( NULL, NULL, NULL, &ulAddress, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulAddress ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( pcWriteBuffer, "\r\nDNS server address " ); + xReturn = pdTRUE; + xIndex++; + break; + + default: + ulAddress = 0; + sprintf( pcWriteBuffer, "\r\n\r\n" ); + xReturn = pdFALSE; + xIndex = 0; + break; + } + + if( ulAddress != 0 ) + { + FreeRTOS_inet_ntoa( ulAddress, ( &( pcWriteBuffer[ strlen( pcWriteBuffer ) ] ) ) ); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_FAT_SL_Demos/CreateExampleFiles/File-system-demo.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_FAT_SL_Demos/CreateExampleFiles/File-system-demo.c index 2fa71aa66..41d75d114 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_FAT_SL_Demos/CreateExampleFiles/File-system-demo.c +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_FAT_SL_Demos/CreateExampleFiles/File-system-demo.c @@ -1,320 +1,316 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -/******************************************************************************* - * See the URL in the comments within main.c for the location of the online - * documentation. - ******************************************************************************/ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" - -/* File system includes. */ -#include "fat_sl.h" -#include "api_mdriver_ram.h" - -/* 8.3 format, plus null terminator. */ -#define fsMAX_FILE_NAME_LEN 13 - -/* The number of bytes read/written to the example files at a time. */ -#define fsRAM_BUFFER_SIZE 200 - -/* The number of bytes written to the file that uses f_putc() and f_getc(). */ -#define fsPUTC_FILE_SIZE 100 - -/*-----------------------------------------------------------*/ - -/* - * Creates and verifies different files on the volume, demonstrating the use of - * various different API functions. - */ -void vCreateAndVerifySampleFiles( void ); - -/* - * Create a set of example files in the root directory of the volume using - * f_write(). - */ -static void prvCreateDemoFilesUsing_f_write( void ); - -/* - * Use f_read() to read back and verify the files that were created by - * prvCreateDemoFilesUsing_f_write(). - */ -static void prvVerifyDemoFileUsing_f_read( void ); - -/* - * Create an example file in a sub-directory using f_putc(). - */ -static void prvCreateDemoFileUsing_f_putc( void ); - -/* - * Use f_getc() to read back and verify the file that was created by - * prvCreateDemoFileUsing_f_putc(). - */ -static void prvVerifyDemoFileUsing_f_getc( void ); - -/*-----------------------------------------------------------*/ - -/* A buffer used to both create content to write to disk, and read content back -from a disk. Note there is no mutual exclusion on this buffer. */ -static char cRAMBuffer[ fsRAM_BUFFER_SIZE ]; - -/* Names of directories that are created. */ -static const char *pcRoot = "/", *pcDirectory1 = "SUB1", *pcDirectory2 = "SUB2", *pcFullPath = "/SUB1/SUB2"; - -/*-----------------------------------------------------------*/ - -void vCreateAndVerifySampleFiles( void ) -{ -unsigned char ucStatus; - - /* First create the volume. */ - ucStatus = f_initvolume( ram_initfunc ); - - /* It is expected that the volume is not formatted. */ - if( ucStatus == F_ERR_NOTFORMATTED ) - { - /* Format the created volume. */ - ucStatus = f_format( F_FAT12_MEDIA ); - } - - if( ucStatus == F_NO_ERROR ) - { - /* Create a set of files using f_write(). */ - prvCreateDemoFilesUsing_f_write(); - - /* Read back and verify the files that were created using f_write(). */ - prvVerifyDemoFileUsing_f_read(); - - /* Create sub directories two deep then create a file using putc. */ - prvCreateDemoFileUsing_f_putc(); - - /* Read back and verify the file created by - prvCreateDemoFileUsing_f_putc(). */ - prvVerifyDemoFileUsing_f_getc(); - } -} -/*-----------------------------------------------------------*/ - -static void prvCreateDemoFilesUsing_f_write( void ) -{ -BaseType_t xFileNumber, xWriteNumber; -char cFileName[ fsMAX_FILE_NAME_LEN ]; -const BaseType_t xMaxFiles = 5; -long lItemsWritten; -F_FILE *pxFile; - - /* Create xMaxFiles files. Each created file will be - ( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled - with a different repeating character. */ - for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) - { - /* Generate a file name. */ - sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber ); - - /* Obtain the current working directory and print out the file name and - the directory into which the file is being written. */ - f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); - - /* Open the file, creating the file if it does not already exist. */ - pxFile = f_open( cFileName, "w" ); - configASSERT( pxFile ); - - /* Fill the RAM buffer with data that will be written to the file. This - is just a repeating ascii character that indicates the file number. */ - memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE ); - - /* Write the RAM buffer to the opened file a number of times. The - number of times the RAM buffer is written to the file depends on the - file number, so the length of each created file will be different. */ - for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ ) - { - lItemsWritten = f_write( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile ); - configASSERT( lItemsWritten == 1 ); - } - - /* Close the file so another file can be created. */ - f_close( pxFile ); - } -} -/*-----------------------------------------------------------*/ - -static void prvVerifyDemoFileUsing_f_read( void ) -{ -BaseType_t xFileNumber, xReadNumber; -char cFileName[ fsMAX_FILE_NAME_LEN ]; -const BaseType_t xMaxFiles = 5; -long lItemsRead, lChar; -F_FILE *pxFile; - - /* Read back the files that were created by - prvCreateDemoFilesUsing_f_write(). */ - for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) - { - /* Generate the file name. */ - sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber ); - - /* Obtain the current working directory and print out the file name and - the directory from which the file is being read. */ - f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); - - /* Open the file for reading. */ - pxFile = f_open( cFileName, "r" ); - configASSERT( pxFile ); - - /* Read the file into the RAM buffer, checking the file contents are as - expected. The size of the file depends on the file number. */ - for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ ) - { - /* Start with the RAM buffer clear. */ - memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE ); - - lItemsRead = f_read( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile ); - configASSERT( lItemsRead == 1 ); - - /* Check the RAM buffer is filled with the expected data. Each - file contains a different repeating ascii character that indicates - the number of the file. */ - for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ ) - { - configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) ); - } - } - - /* Close the file. */ - f_close( pxFile ); - } -} -/*-----------------------------------------------------------*/ - -static void prvCreateDemoFileUsing_f_putc( void ) -{ -unsigned char ucReturn; -int iByte, iReturned; -F_FILE *pxFile; -char cFileName[ fsMAX_FILE_NAME_LEN ]; - - /* Obtain and print out the working directory. */ - f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); - - /* Create a sub directory. */ - ucReturn = f_mkdir( pcDirectory1 ); - configASSERT( ucReturn == F_NO_ERROR ); - - /* Move into the created sub-directory. */ - ucReturn = f_chdir( pcDirectory1 ); - configASSERT( ucReturn == F_NO_ERROR ); - - /* Obtain and print out the working directory. */ - f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); - - /* Create a subdirectory in the new directory. */ - ucReturn = f_mkdir( pcDirectory2 ); - configASSERT( ucReturn == F_NO_ERROR ); - - /* Move into the directory just created - now two directories down from - the root. */ - ucReturn = f_chdir( pcDirectory2 ); - configASSERT( ucReturn == F_NO_ERROR ); - - /* Obtain and print out the working directory. */ - f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); - configASSERT( strcmp( cRAMBuffer, pcFullPath ) == 0 ); - - /* Generate the file name. */ - sprintf( cFileName, "%s.txt", pcDirectory2 ); - - /* Print out the file name and the directory into which the file is being - written. */ - pxFile = f_open( cFileName, "w" ); - - /* Create a file 1 byte at a time. The file is filled with incrementing - ascii characters starting from '0'. */ - for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ ) - { - iReturned = f_putc( ( ( int ) '0' + iByte ), pxFile ); - configASSERT( iReturned == ( ( int ) '0' + iByte ) ); - } - - /* Finished so close the file. */ - f_close( pxFile ); - - /* Move back to the root directory. */ - ucReturn = f_chdir( "../.." ); - configASSERT( ucReturn == F_NO_ERROR ); - - /* Obtain and print out the working directory. */ - f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); - configASSERT( strcmp( cRAMBuffer, pcRoot ) == 0 ); -} -/*-----------------------------------------------------------*/ - -static void prvVerifyDemoFileUsing_f_getc( void ) -{ -unsigned char ucReturn; -int iByte, iReturned; -F_FILE *pxFile; -char cFileName[ fsMAX_FILE_NAME_LEN ]; - - /* Move into the directory in which the file was created. */ - ucReturn = f_chdir( pcFullPath ); - configASSERT( ucReturn == F_NO_ERROR ); - - /* Obtain and print out the working directory. */ - f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); - configASSERT( strcmp( cRAMBuffer, pcFullPath ) == 0 ); - - /* Generate the file name. */ - sprintf( cFileName, "%s.txt", pcDirectory2 ); - - /* This time the file is opened for reading. */ - pxFile = f_open( cFileName, "r" ); - - /* Read the file 1 byte at a time. */ - for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ ) - { - iReturned = f_getc( pxFile ); - configASSERT( iReturned == ( ( int ) '0' + iByte ) ); - } - - /* Finished so close the file. */ - f_close( pxFile ); - - /* Move back to the root directory. */ - ucReturn = f_chdir( "../.." ); - configASSERT( ucReturn == F_NO_ERROR ); - - /* Obtain and print out the working directory. */ - f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); -} - - - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/******************************************************************************* + * See the URL in the comments within main.c for the location of the online + * documentation. + ******************************************************************************/ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" + +/* File system includes. */ +#include "fat_sl.h" +#include "api_mdriver_ram.h" + +/* 8.3 format, plus null terminator. */ +#define fsMAX_FILE_NAME_LEN 13 + +/* The number of bytes read/written to the example files at a time. */ +#define fsRAM_BUFFER_SIZE 200 + +/* The number of bytes written to the file that uses f_putc() and f_getc(). */ +#define fsPUTC_FILE_SIZE 100 + +/*-----------------------------------------------------------*/ + +/* + * Creates and verifies different files on the volume, demonstrating the use of + * various different API functions. + */ +void vCreateAndVerifySampleFiles( void ); + +/* + * Create a set of example files in the root directory of the volume using + * f_write(). + */ +static void prvCreateDemoFilesUsing_f_write( void ); + +/* + * Use f_read() to read back and verify the files that were created by + * prvCreateDemoFilesUsing_f_write(). + */ +static void prvVerifyDemoFileUsing_f_read( void ); + +/* + * Create an example file in a sub-directory using f_putc(). + */ +static void prvCreateDemoFileUsing_f_putc( void ); + +/* + * Use f_getc() to read back and verify the file that was created by + * prvCreateDemoFileUsing_f_putc(). + */ +static void prvVerifyDemoFileUsing_f_getc( void ); + +/*-----------------------------------------------------------*/ + +/* A buffer used to both create content to write to disk, and read content back + * from a disk. Note there is no mutual exclusion on this buffer. */ +static char cRAMBuffer[ fsRAM_BUFFER_SIZE ]; + +/* Names of directories that are created. */ +static const char * pcRoot = "/", * pcDirectory1 = "SUB1", * pcDirectory2 = "SUB2", * pcFullPath = "/SUB1/SUB2"; + +/*-----------------------------------------------------------*/ + +void vCreateAndVerifySampleFiles( void ) +{ + unsigned char ucStatus; + + /* First create the volume. */ + ucStatus = f_initvolume( ram_initfunc ); + + /* It is expected that the volume is not formatted. */ + if( ucStatus == F_ERR_NOTFORMATTED ) + { + /* Format the created volume. */ + ucStatus = f_format( F_FAT12_MEDIA ); + } + + if( ucStatus == F_NO_ERROR ) + { + /* Create a set of files using f_write(). */ + prvCreateDemoFilesUsing_f_write(); + + /* Read back and verify the files that were created using f_write(). */ + prvVerifyDemoFileUsing_f_read(); + + /* Create sub directories two deep then create a file using putc. */ + prvCreateDemoFileUsing_f_putc(); + + /* Read back and verify the file created by + * prvCreateDemoFileUsing_f_putc(). */ + prvVerifyDemoFileUsing_f_getc(); + } +} +/*-----------------------------------------------------------*/ + +static void prvCreateDemoFilesUsing_f_write( void ) +{ + BaseType_t xFileNumber, xWriteNumber; + char cFileName[ fsMAX_FILE_NAME_LEN ]; + const BaseType_t xMaxFiles = 5; + long lItemsWritten; + F_FILE * pxFile; + + /* Create xMaxFiles files. Each created file will be + * ( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled + * with a different repeating character. */ + for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) + { + /* Generate a file name. */ + sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber ); + + /* Obtain the current working directory and print out the file name and + * the directory into which the file is being written. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + + /* Open the file, creating the file if it does not already exist. */ + pxFile = f_open( cFileName, "w" ); + configASSERT( pxFile ); + + /* Fill the RAM buffer with data that will be written to the file. This + * is just a repeating ascii character that indicates the file number. */ + memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE ); + + /* Write the RAM buffer to the opened file a number of times. The + * number of times the RAM buffer is written to the file depends on the + * file number, so the length of each created file will be different. */ + for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ ) + { + lItemsWritten = f_write( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile ); + configASSERT( lItemsWritten == 1 ); + } + + /* Close the file so another file can be created. */ + f_close( pxFile ); + } +} +/*-----------------------------------------------------------*/ + +static void prvVerifyDemoFileUsing_f_read( void ) +{ + BaseType_t xFileNumber, xReadNumber; + char cFileName[ fsMAX_FILE_NAME_LEN ]; + const BaseType_t xMaxFiles = 5; + long lItemsRead, lChar; + F_FILE * pxFile; + + /* Read back the files that were created by + * prvCreateDemoFilesUsing_f_write(). */ + for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) + { + /* Generate the file name. */ + sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber ); + + /* Obtain the current working directory and print out the file name and + * the directory from which the file is being read. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + + /* Open the file for reading. */ + pxFile = f_open( cFileName, "r" ); + configASSERT( pxFile ); + + /* Read the file into the RAM buffer, checking the file contents are as + * expected. The size of the file depends on the file number. */ + for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ ) + { + /* Start with the RAM buffer clear. */ + memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE ); + + lItemsRead = f_read( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile ); + configASSERT( lItemsRead == 1 ); + + /* Check the RAM buffer is filled with the expected data. Each + * file contains a different repeating ascii character that indicates + * the number of the file. */ + for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ ) + { + configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) ); + } + } + + /* Close the file. */ + f_close( pxFile ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCreateDemoFileUsing_f_putc( void ) +{ + unsigned char ucReturn; + int iByte, iReturned; + F_FILE * pxFile; + char cFileName[ fsMAX_FILE_NAME_LEN ]; + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + + /* Create a sub directory. */ + ucReturn = f_mkdir( pcDirectory1 ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Move into the created sub-directory. */ + ucReturn = f_chdir( pcDirectory1 ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + + /* Create a subdirectory in the new directory. */ + ucReturn = f_mkdir( pcDirectory2 ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Move into the directory just created - now two directories down from + * the root. */ + ucReturn = f_chdir( pcDirectory2 ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + configASSERT( strcmp( cRAMBuffer, pcFullPath ) == 0 ); + + /* Generate the file name. */ + sprintf( cFileName, "%s.txt", pcDirectory2 ); + + /* Print out the file name and the directory into which the file is being + * written. */ + pxFile = f_open( cFileName, "w" ); + + /* Create a file 1 byte at a time. The file is filled with incrementing + * ascii characters starting from '0'. */ + for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ ) + { + iReturned = f_putc( ( ( int ) '0' + iByte ), pxFile ); + configASSERT( iReturned == ( ( int ) '0' + iByte ) ); + } + + /* Finished so close the file. */ + f_close( pxFile ); + + /* Move back to the root directory. */ + ucReturn = f_chdir( "../.." ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + configASSERT( strcmp( cRAMBuffer, pcRoot ) == 0 ); +} +/*-----------------------------------------------------------*/ + +static void prvVerifyDemoFileUsing_f_getc( void ) +{ + unsigned char ucReturn; + int iByte, iReturned; + F_FILE * pxFile; + char cFileName[ fsMAX_FILE_NAME_LEN ]; + + /* Move into the directory in which the file was created. */ + ucReturn = f_chdir( pcFullPath ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + configASSERT( strcmp( cRAMBuffer, pcFullPath ) == 0 ); + + /* Generate the file name. */ + sprintf( cFileName, "%s.txt", pcDirectory2 ); + + /* This time the file is opened for reading. */ + pxFile = f_open( cFileName, "r" ); + + /* Read the file 1 byte at a time. */ + for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ ) + { + iReturned = f_getc( pxFile ); + configASSERT( iReturned == ( ( int ) '0' + iByte ) ); + } + + /* Finished so close the file. */ + f_close( pxFile ); + + /* Move back to the root directory. */ + ucReturn = f_chdir( "../.." ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); +} diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c index 293baab26..e5c7f1ed4 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c @@ -1,679 +1,713 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - /****************************************************************************** - * - * See the following URL for information on the commands defined in this file: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml - * - ******************************************************************************/ - - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* Standard includes. */ -#include -#include -#include - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -/* FreeRTOS+UDP includes, just to make the stats available to the CLI -commands. */ -#include "FreeRTOS_UDP_IP.h" -#include "FreeRTOS_Sockets.h" - -#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS - #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0 -#endif - - -/* - * Implements the run-time-stats command. - */ -static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the task-stats command. - */ -static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the echo-three-parameters command. - */ -static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the echo-parameters command. - */ -static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Defines a command that prints out IP address information. - */ -static BaseType_t prvDisplayIPConfig( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Defines a command that prints out the gathered demo debug stats. - */ -static BaseType_t prvDisplayIPDebugStats( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Defines a command that sends an ICMP ping request to an IP address. - */ -static BaseType_t prvPingCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the "trace start" and "trace stop" commands; - */ -#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); -#endif - -/* Structure that defines the "ip-config" command line command. */ -static const CLI_Command_Definition_t xIPConfig = -{ - "ip-config", - "ip-config:\r\n Displays IP address configuration\r\n\r\n", - prvDisplayIPConfig, - 0 -}; - -#if configINCLUDE_DEMO_DEBUG_STATS != 0 - /* Structure that defines the "ip-debug-stats" command line command. */ - static const CLI_Command_Definition_t xIPDebugStats = - { - "ip-debug-stats", /* The command string to type. */ - "ip-debug-stats:\r\n Shows some IP stack stats useful for debug - an example only.\r\n\r\n", - prvDisplayIPDebugStats, /* The function to run. */ - 0 /* No parameters are expected. */ - }; -#endif /* configINCLUDE_DEMO_DEBUG_STATS */ - -/* Structure that defines the "run-time-stats" command line command. This -generates a table that shows how much run time each task has */ -static const CLI_Command_Definition_t xRunTimeStats = -{ - "run-time-stats", /* The command string to type. */ - "run-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n", - prvRunTimeStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the "task-stats" command line command. This generates -a table that gives information on each task in the system. */ -static const CLI_Command_Definition_t xTaskStats = -{ - "task-stats", /* The command string to type. */ - "task-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n\r\n", - prvTaskStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the "echo_3_parameters" command line command. This -takes exactly three parameters that the command simply echos back one at a -time. */ -static const CLI_Command_Definition_t xThreeParameterEcho = -{ - "echo-3-parameters", - "echo-3-parameters :\r\n Expects three parameters, echos each in turn\r\n\r\n", - prvThreeParameterEchoCommand, /* The function to run. */ - 3 /* Three parameters are expected, which can take any value. */ -}; - -/* Structure that defines the "echo_parameters" command line command. This -takes a variable number of parameters that the command simply echos back one at -a time. */ -static const CLI_Command_Definition_t xParameterEcho = -{ - "echo-parameters", - "echo-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n\r\n", - prvParameterEchoCommand, /* The function to run. */ - -1 /* The user can enter any number of commands. */ -}; - -#if ipconfigSUPPORT_OUTGOING_PINGS == 1 - - /* Structure that defines the "ping" command line command. This takes an IP - address or host name and (optionally) the number of bytes to ping as - parameters. */ - static const CLI_Command_Definition_t xPing = - { - "ping", - "ping :\r\n for example, ping 192.168.0.3 8, or ping www.example.com\r\n\r\n", - prvPingCommand, /* The function to run. */ - -1 /* Ping can take either one or two parameter, so the number of parameters has to be determined by the ping command implementation. */ - }; - -#endif /* ipconfigSUPPORT_OUTGOING_PINGS */ - -#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - /* Structure that defines the "trace" command line command. This takes a single - parameter, which can be either "start" or "stop". */ - static const CLI_Command_Definition_t xStartStopTrace = - { - "trace", - "trace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n\r\n", - prvStartStopTraceCommand, /* The function to run. */ - 1 /* One parameter is expected. Valid values are "start" and "stop". */ - }; -#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ - -/*-----------------------------------------------------------*/ - -void vRegisterCLICommands( void ) -{ - /* Register all the command line commands defined immediately above. */ - FreeRTOS_CLIRegisterCommand( &xTaskStats ); - FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); - FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); - FreeRTOS_CLIRegisterCommand( &xParameterEcho ); - FreeRTOS_CLIRegisterCommand( &xIPDebugStats ); - FreeRTOS_CLIRegisterCommand( &xIPConfig ); - - #if ipconfigSUPPORT_OUTGOING_PINGS == 1 - { - FreeRTOS_CLIRegisterCommand( &xPing ); - } - #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ - - #if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - FreeRTOS_CLIRegisterCommand( & xStartStopTrace ); - #endif -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *const pcHeader = " State\tPriority\tStack\t#\r\n************************************************\r\n"; -BaseType_t xSpacePadding; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Generate a table of task stats. */ - strcpy( pcWriteBuffer, "Task" ); - pcWriteBuffer += strlen( pcWriteBuffer ); - - /* Pad the string "task" with however many bytes necessary to make it the - length of a task name. Minus three for the null terminator and half the - number of characters in "Task" so the column lines up with the centre of - the heading. */ - for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ ) - { - /* Add a space to align columns after the task's name. */ - *pcWriteBuffer = ' '; - pcWriteBuffer++; - - /* Ensure always terminated. */ - *pcWriteBuffer = 0x00; - } - strcpy( pcWriteBuffer, pcHeader ); - vTaskList( pcWriteBuffer + strlen( pcHeader ) ); - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char * const pcHeader = " Abs Time % Time\r\n****************************************\r\n"; -BaseType_t xSpacePadding; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Generate a table of task stats. */ - strcpy( pcWriteBuffer, "Task" ); - pcWriteBuffer += strlen( pcWriteBuffer ); - - /* Pad the string "task" with however many bytes necessary to make it the - length of a task name. Minus three for the null terminator and half the - number of characters in "Task" so the column lines up with the centre of - the heading. */ - for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ ) - { - /* Add a space to align columns after the task's name. */ - *pcWriteBuffer = ' '; - pcWriteBuffer++; - - /* Ensure always terminated. */ - *pcWriteBuffer = 0x00; - } - - strcpy( pcWriteBuffer, pcHeader ); - vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) ); - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength, xReturn; -static BaseType_t lParameterNumber = 0; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - if( lParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( pcWriteBuffer, "The three parameters were:\r\n" ); - - /* Next time the function is called the first parameter will be echoed - back. */ - lParameterNumber = 1L; - - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - lParameterNumber, /* Return the next parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); - strncat( pcWriteBuffer, pcParameter, xParameterStringLength ); - strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - if( lParameterNumber == 3L ) - { - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - xReturn = pdFALSE; - lParameterNumber = 0L; - } - else - { - /* There are more parameters to return after this one. */ - xReturn = pdTRUE; - lParameterNumber++; - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength, xReturn; -static BaseType_t lParameterNumber = 0; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - if( lParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( pcWriteBuffer, "The parameters were:\r\n" ); - - /* Next time the function is called the first parameter will be echoed - back. */ - lParameterNumber = 1L; - - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - lParameterNumber, /* Return the next parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - if( pcParameter != NULL ) - { - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); - strncat( pcWriteBuffer, pcParameter, xParameterStringLength ); - strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - - /* There might be more parameters to return after this one. */ - xReturn = pdTRUE; - lParameterNumber++; - } - else - { - /* No more parameters were found. Make sure the write buffer does - not contain a valid string. */ - pcWriteBuffer[ 0 ] = 0x00; - - /* No more data to return. */ - xReturn = pdFALSE; - - /* Start over the next time this command is executed. */ - lParameterNumber = 0; - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -#if ipconfigSUPPORT_OUTGOING_PINGS == 1 - - static BaseType_t prvPingCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) - { - char * pcParameter; - BaseType_t lParameterStringLength, xReturn; - uint32_t ulIPAddress, ulBytesToPing; - const uint32_t ulDefaultBytesToPing = 8UL; - char cBuffer[ 16 ]; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Start with an empty string. */ - pcWriteBuffer[ 0 ] = 0x00; - - /* Obtain the number of bytes to ping. */ - pcParameter = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 2, /* Return the second parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - if( pcParameter == NULL ) - { - /* The number of bytes was not specified, so default it. */ - ulBytesToPing = ulDefaultBytesToPing; - } - else - { - ulBytesToPing = atol( pcParameter ); - } - - /* Obtain the IP address string. */ - pcParameter = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to obtain the IP address. If the first character is not a - digit, assume the host name has been passed in. */ - if( ( *pcParameter >= '0' ) && ( *pcParameter <= '9' ) ) - { - ulIPAddress = FreeRTOS_inet_addr( pcParameter ); - } - else - { - /* Terminate the host name. */ - pcParameter[ lParameterStringLength ] = 0x00; - - /* Attempt to resolve host. */ - ulIPAddress = FreeRTOS_gethostbyname( pcParameter ); - } - - /* Convert IP address, which may have come from a DNS lookup, to string. */ - FreeRTOS_inet_ntoa( ulIPAddress, cBuffer ); - - if( ulIPAddress != 0 ) - { - xReturn = FreeRTOS_SendPingRequest( ulIPAddress, ( uint16_t ) ulBytesToPing, portMAX_DELAY ); - } - else - { - xReturn = pdFALSE; - } - - if( xReturn == pdFALSE ) - { - sprintf( pcWriteBuffer, "%s", "Could not send ping request\r\n" ); - } - else - { - sprintf( pcWriteBuffer, "Ping sent to %s with identifier %d\r\n", cBuffer, xReturn ); - } - - return pdFALSE; - } - /*-----------------------------------------------------------*/ - -#endif /* ipconfigSUPPORT_OUTGOING_PINGS */ - -#if configINCLUDE_DEMO_DEBUG_STATS != 0 - - static BaseType_t prvDisplayIPDebugStats( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) - { - static BaseType_t xIndex = -1; - extern xExampleDebugStatEntry_t xIPTraceValues[]; - BaseType_t xReturn; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - xIndex++; - - if( xIndex < xExampleDebugStatEntries() ) - { - sprintf( pcWriteBuffer, "%s %d\r\n", xIPTraceValues[ xIndex ].pucDescription, ( int ) xIPTraceValues[ xIndex ].ulData ); - xReturn = pdPASS; - } - else - { - /* Reset the index for the next time it is called. */ - xIndex = -1; - - /* Ensure nothing remains in the write buffer. */ - pcWriteBuffer[ 0 ] = 0x00; - xReturn = pdFALSE; - } - - return xReturn; - } - /*-----------------------------------------------------------*/ - -#endif /* configINCLUDE_DEMO_DEBUG_STATS */ - -static BaseType_t prvDisplayIPConfig( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -static BaseType_t xIndex = 0; -BaseType_t xReturn; -uint32_t ulAddress; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - switch( xIndex ) - { - case 0 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( &ulAddress, NULL, NULL, NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( pcWriteBuffer, "\r\nIP address " ); - xReturn = pdTRUE; - xIndex++; - break; - - case 1 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( NULL, &ulAddress, NULL, NULL, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( NULL, &ulAddress, NULL, NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( pcWriteBuffer, "\r\nNet mask " ); - xReturn = pdTRUE; - xIndex++; - break; - - case 2 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( NULL, NULL, &ulAddress, NULL, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( NULL, NULL, &ulAddress, NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( pcWriteBuffer, "\r\nGateway address " ); - xReturn = pdTRUE; - xIndex++; - break; - - case 3 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( NULL, NULL, NULL, &ulAddress, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulAddress ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( pcWriteBuffer, "\r\nDNS server address " ); - xReturn = pdTRUE; - xIndex++; - break; - - default : - ulAddress = 0; - sprintf( pcWriteBuffer, "\r\n\r\n" ); - xReturn = pdFALSE; - xIndex = 0; - break; - } - - if( ulAddress != 0 ) - { - FreeRTOS_inet_ntoa( ulAddress, &( pcWriteBuffer[ strlen( pcWriteBuffer ) ] ) ); - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - - static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) - { - const char *pcParameter; - BaseType_t lParameterStringLength; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* There are only two valid parameter values. */ - if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 ) - { - /* Start or restart the trace. */ - vTraceStop(); - vTraceClear(); - vTraceStart(); - - sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" ); - } - else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 ) - { - /* End the trace, if one is running. */ - vTraceStop(); - sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" ); - } - else - { - sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); - } - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; - } - -#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/****************************************************************************** +* +* See the following URL for information on the commands defined in this file: +* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml +* +******************************************************************************/ + + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* FreeRTOS+UDP includes, just to make the stats available to the CLI + * commands. */ +#include "FreeRTOS_UDP_IP.h" +#include "FreeRTOS_Sockets.h" + +#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS + #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0 +#endif + + +/* + * Implements the run-time-stats command. + */ +static BaseType_t prvTaskStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the task-stats command. + */ +static BaseType_t prvRunTimeStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the echo-three-parameters command. + */ +static BaseType_t prvThreeParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the echo-parameters command. + */ +static BaseType_t prvParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Defines a command that prints out IP address information. + */ +static BaseType_t prvDisplayIPConfig( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Defines a command that prints out the gathered demo debug stats. + */ +static BaseType_t prvDisplayIPDebugStats( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Defines a command that sends an ICMP ping request to an IP address. + */ +static BaseType_t prvPingCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the "trace start" and "trace stop" commands; + */ +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + static BaseType_t prvStartStopTraceCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); +#endif + +/* Structure that defines the "ip-config" command line command. */ +static const CLI_Command_Definition_t xIPConfig = +{ + "ip-config", + "ip-config:\r\n Displays IP address configuration\r\n\r\n", + prvDisplayIPConfig, + 0 +}; + +#if configINCLUDE_DEMO_DEBUG_STATS != 0 + /* Structure that defines the "ip-debug-stats" command line command. */ + static const CLI_Command_Definition_t xIPDebugStats = + { + "ip-debug-stats", /* The command string to type. */ + "ip-debug-stats:\r\n Shows some IP stack stats useful for debug - an example only.\r\n\r\n", + prvDisplayIPDebugStats, /* The function to run. */ + 0 /* No parameters are expected. */ + }; +#endif /* configINCLUDE_DEMO_DEBUG_STATS */ + +/* Structure that defines the "run-time-stats" command line command. This + * generates a table that shows how much run time each task has */ +static const CLI_Command_Definition_t xRunTimeStats = +{ + "run-time-stats", /* The command string to type. */ + "run-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n", + prvRunTimeStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the "task-stats" command line command. This generates + * a table that gives information on each task in the system. */ +static const CLI_Command_Definition_t xTaskStats = +{ + "task-stats", /* The command string to type. */ + "task-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n\r\n", + prvTaskStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the "echo_3_parameters" command line command. This + * takes exactly three parameters that the command simply echos back one at a + * time. */ +static const CLI_Command_Definition_t xThreeParameterEcho = +{ + "echo-3-parameters", + "echo-3-parameters :\r\n Expects three parameters, echos each in turn\r\n\r\n", + prvThreeParameterEchoCommand, /* The function to run. */ + 3 /* Three parameters are expected, which can take any value. */ +}; + +/* Structure that defines the "echo_parameters" command line command. This + * takes a variable number of parameters that the command simply echos back one at + * a time. */ +static const CLI_Command_Definition_t xParameterEcho = +{ + "echo-parameters", + "echo-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n\r\n", + prvParameterEchoCommand, /* The function to run. */ + -1 /* The user can enter any number of commands. */ +}; + +#if ipconfigSUPPORT_OUTGOING_PINGS == 1 + +/* Structure that defines the "ping" command line command. This takes an IP + * address or host name and (optionally) the number of bytes to ping as + * parameters. */ + static const CLI_Command_Definition_t xPing = + { + "ping", + "ping :\r\n for example, ping 192.168.0.3 8, or ping www.example.com\r\n\r\n", + prvPingCommand, /* The function to run. */ + -1 /* Ping can take either one or two parameter, so the number of parameters has to be determined by the ping command implementation. */ + }; + +#endif /* ipconfigSUPPORT_OUTGOING_PINGS */ + +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + +/* Structure that defines the "trace" command line command. This takes a single + * parameter, which can be either "start" or "stop". */ + static const CLI_Command_Definition_t xStartStopTrace = + { + "trace", + "trace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n\r\n", + prvStartStopTraceCommand, /* The function to run. */ + 1 /* One parameter is expected. Valid values are "start" and "stop". */ + }; +#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ + +/*-----------------------------------------------------------*/ + +void vRegisterCLICommands( void ) +{ + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xTaskStats ); + FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); + FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); + FreeRTOS_CLIRegisterCommand( &xParameterEcho ); + FreeRTOS_CLIRegisterCommand( &xIPDebugStats ); + FreeRTOS_CLIRegisterCommand( &xIPConfig ); + + #if ipconfigSUPPORT_OUTGOING_PINGS == 1 + { + FreeRTOS_CLIRegisterCommand( &xPing ); + } + #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ + + #if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + FreeRTOS_CLIRegisterCommand( &xStartStopTrace ); + #endif +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTaskStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * const pcHeader = " State\tPriority\tStack\t#\r\n************************************************\r\n"; + BaseType_t xSpacePadding; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( pcWriteBuffer, "Task" ); + pcWriteBuffer += strlen( pcWriteBuffer ); + + /* Pad the string "task" with however many bytes necessary to make it the + * length of a task name. Minus three for the null terminator and half the + * number of characters in "Task" so the column lines up with the centre of + * the heading. */ + for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ ) + { + /* Add a space to align columns after the task's name. */ + *pcWriteBuffer = ' '; + pcWriteBuffer++; + + /* Ensure always terminated. */ + *pcWriteBuffer = 0x00; + } + + strcpy( pcWriteBuffer, pcHeader ); + vTaskList( pcWriteBuffer + strlen( pcHeader ) ); + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvRunTimeStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * const pcHeader = " Abs Time % Time\r\n****************************************\r\n"; + BaseType_t xSpacePadding; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( pcWriteBuffer, "Task" ); + pcWriteBuffer += strlen( pcWriteBuffer ); + + /* Pad the string "task" with however many bytes necessary to make it the + * length of a task name. Minus three for the null terminator and half the + * number of characters in "Task" so the column lines up with the centre of + * the heading. */ + for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ ) + { + /* Add a space to align columns after the task's name. */ + *pcWriteBuffer = ' '; + pcWriteBuffer++; + + /* Ensure always terminated. */ + *pcWriteBuffer = 0x00; + } + + strcpy( pcWriteBuffer, pcHeader ); + vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) ); + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvThreeParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength, xReturn; + static BaseType_t lParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( pcWriteBuffer, "The three parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + * back. */ + lParameterNumber = 1L; + + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); + strncat( pcWriteBuffer, pcParameter, xParameterStringLength ); + strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + if( lParameterNumber == 3L ) + { + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + xReturn = pdFALSE; + lParameterNumber = 0L; + } + else + { + /* There are more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength, xReturn; + static BaseType_t lParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( pcWriteBuffer, "The parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + * back. */ + lParameterNumber = 1L; + + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + if( pcParameter != NULL ) + { + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); + strncat( pcWriteBuffer, pcParameter, xParameterStringLength ); + strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* There might be more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + else + { + /* No more parameters were found. Make sure the write buffer does + * not contain a valid string. */ + pcWriteBuffer[ 0 ] = 0x00; + + /* No more data to return. */ + xReturn = pdFALSE; + + /* Start over the next time this command is executed. */ + lParameterNumber = 0; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ipconfigSUPPORT_OUTGOING_PINGS == 1 + + static BaseType_t prvPingCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) + { + char * pcParameter; + BaseType_t lParameterStringLength, xReturn; + uint32_t ulIPAddress, ulBytesToPing; + const uint32_t ulDefaultBytesToPing = 8UL; + char cBuffer[ 16 ]; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Start with an empty string. */ + pcWriteBuffer[ 0 ] = 0x00; + + /* Obtain the number of bytes to ping. */ + pcParameter = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 2, /* Return the second parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + if( pcParameter == NULL ) + { + /* The number of bytes was not specified, so default it. */ + ulBytesToPing = ulDefaultBytesToPing; + } + else + { + ulBytesToPing = atol( pcParameter ); + } + + /* Obtain the IP address string. */ + pcParameter = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to obtain the IP address. If the first character is not a + * digit, assume the host name has been passed in. */ + if( ( *pcParameter >= '0' ) && ( *pcParameter <= '9' ) ) + { + ulIPAddress = FreeRTOS_inet_addr( pcParameter ); + } + else + { + /* Terminate the host name. */ + pcParameter[ lParameterStringLength ] = 0x00; + + /* Attempt to resolve host. */ + ulIPAddress = FreeRTOS_gethostbyname( pcParameter ); + } + + /* Convert IP address, which may have come from a DNS lookup, to string. */ + FreeRTOS_inet_ntoa( ulIPAddress, cBuffer ); + + if( ulIPAddress != 0 ) + { + xReturn = FreeRTOS_SendPingRequest( ulIPAddress, ( uint16_t ) ulBytesToPing, portMAX_DELAY ); + } + else + { + xReturn = pdFALSE; + } + + if( xReturn == pdFALSE ) + { + sprintf( pcWriteBuffer, "%s", "Could not send ping request\r\n" ); + } + else + { + sprintf( pcWriteBuffer, "Ping sent to %s with identifier %d\r\n", cBuffer, xReturn ); + } + + return pdFALSE; + } + /*-----------------------------------------------------------*/ + +#endif /* ipconfigSUPPORT_OUTGOING_PINGS */ + +#if configINCLUDE_DEMO_DEBUG_STATS != 0 + + static BaseType_t prvDisplayIPDebugStats( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) + { + static BaseType_t xIndex = -1; + extern xExampleDebugStatEntry_t xIPTraceValues[]; + BaseType_t xReturn; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + xIndex++; + + if( xIndex < xExampleDebugStatEntries() ) + { + sprintf( pcWriteBuffer, "%s %d\r\n", xIPTraceValues[ xIndex ].pucDescription, ( int ) xIPTraceValues[ xIndex ].ulData ); + xReturn = pdPASS; + } + else + { + /* Reset the index for the next time it is called. */ + xIndex = -1; + + /* Ensure nothing remains in the write buffer. */ + pcWriteBuffer[ 0 ] = 0x00; + xReturn = pdFALSE; + } + + return xReturn; + } + /*-----------------------------------------------------------*/ + +#endif /* configINCLUDE_DEMO_DEBUG_STATS */ + +static BaseType_t prvDisplayIPConfig( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + static BaseType_t xIndex = 0; + BaseType_t xReturn; + uint32_t ulAddress; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + switch( xIndex ) + { + case 0: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulAddress, NULL, NULL, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( &ulAddress, NULL, NULL, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( pcWriteBuffer, "\r\nIP address " ); + xReturn = pdTRUE; + xIndex++; + break; + + case 1: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( NULL, &ulAddress, NULL, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( NULL, &ulAddress, NULL, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( pcWriteBuffer, "\r\nNet mask " ); + xReturn = pdTRUE; + xIndex++; + break; + + case 2: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( NULL, NULL, &ulAddress, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( NULL, NULL, &ulAddress, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( pcWriteBuffer, "\r\nGateway address " ); + xReturn = pdTRUE; + xIndex++; + break; + + case 3: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( NULL, NULL, NULL, &ulAddress, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulAddress ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( pcWriteBuffer, "\r\nDNS server address " ); + xReturn = pdTRUE; + xIndex++; + break; + + default: + ulAddress = 0; + sprintf( pcWriteBuffer, "\r\n\r\n" ); + xReturn = pdFALSE; + xIndex = 0; + break; + } + + if( ulAddress != 0 ) + { + FreeRTOS_inet_ntoa( ulAddress, &( pcWriteBuffer[ strlen( pcWriteBuffer ) ] ) ); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + + static BaseType_t prvStartStopTraceCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) + { + const char * pcParameter; + BaseType_t lParameterStringLength; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* There are only two valid parameter values. */ + if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 ) + { + /* Start or restart the trace. */ + vTraceStop(); + vTraceClear(); + vTraceStart(); + + sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" ); + } + else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 ) + { + /* End the trace, if one is running. */ + vTraceStop(); + sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" ); + } + else + { + sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); + } + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; + } + +#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandInterpreter.h b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandInterpreter.h index d4309fd8b..25f2228c3 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandInterpreter.h +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandInterpreter.h @@ -1,32 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -#ifndef UDP_COMMAND_INTERPRETER_H -#define UDP_COMMAND_INTERPRETER_H - -void vStartUDPCommandInterpreterTask( uint16_t usStackSize, uint32_t ulPort, UBaseType_t uxPriority ); - -#endif /* UDP_COMMAND_INTERPRETER_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef UDP_COMMAND_INTERPRETER_H +#define UDP_COMMAND_INTERPRETER_H + +void vStartUDPCommandInterpreterTask( uint16_t usStackSize, + uint32_t ulPort, + UBaseType_t uxPriority ); + +#endif /* UDP_COMMAND_INTERPRETER_H */ diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c index 10730610a..73e031b17 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c @@ -1,206 +1,207 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -/* FreeRTOS+UDP includes. */ -#include "FreeRTOS_UDP_IP.h" -#include "FreeRTOS_Sockets.h" - -/* Demo app includes. */ -#include "UDPCommandInterpreter.h" - -/* Dimensions the buffer into which input characters are placed. */ -#define cmdMAX_INPUT_SIZE 60 - -/* Dimensions the buffer into which string outputs can be placed. */ -#define cmdMAX_OUTPUT_SIZE 1250 - -/* Dimensions the buffer passed to the recvfrom() call. */ -#define cmdSOCKET_INPUT_BUFFER_SIZE 60 - -/* - * The task that runs FreeRTOS+CLI. - */ -void vUDPCommandInterpreterTask( void *pvParameters ); - -/* - * Open and configure the UDP socket. - */ -static xSocket_t prvOpenUDPServerSocket( uint16_t usPort ); - -/*-----------------------------------------------------------*/ - -void vStartUDPCommandInterpreterTask( uint16_t usStackSize, uint32_t ulPort, UBaseType_t uxPriority ) -{ - xTaskCreate( vUDPCommandInterpreterTask, "CLI", usStackSize, ( void * ) ulPort, uxPriority, NULL ); -} -/*-----------------------------------------------------------*/ - -/* - * Task that provides the input and output for the FreeRTOS+CLI command - * interpreter. In this case a UDP port is used. See the URL in the comments - * within main.c for the location of the online documentation. - */ -void vUDPCommandInterpreterTask( void *pvParameters ) -{ -long lBytes, lByte; -signed char cInChar, cInputIndex = 0; -static char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ]; -BaseType_t xMoreDataToFollow; -struct freertos_sockaddr xClient; -socklen_t xClientAddressLength = 0; /* This is required as a parameter to maintain the sendto() Berkeley sockets API - but it is not actually used so can take any value. */ -xSocket_t xSocket; - - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; - - /* Attempt to open the socket. The port number is passed in the task - parameter. The strange casting is to remove compiler warnings on 32-bit - machines. */ - xSocket = prvOpenUDPServerSocket( ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL ); - - if( xSocket != FREERTOS_INVALID_SOCKET ) - { - for( ;; ) - { - /* Wait for incoming data on the opened socket. */ - lBytes = FreeRTOS_recvfrom( xSocket, ( void * ) cLocalBuffer, sizeof( cLocalBuffer ), 0, &xClient, &xClientAddressLength ); - - if( lBytes != FREERTOS_SOCKET_ERROR ) - { - /* Process each received byte in turn. */ - lByte = 0; - while( lByte < lBytes ) - { - /* The next character in the input buffer. */ - cInChar = cLocalBuffer[ lByte ]; - lByte++; - - /* Newline characters are taken as the end of the command - string. */ - if( cInChar == '\n' ) - { - /* Process the input string received prior to the - newline. */ - do - { - /* Pass the string to FreeRTOS+CLI. */ - xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE ); - - /* Send the output generated by the command's - implementation. */ - FreeRTOS_sendto( xSocket, cOutputString, strlen( cOutputString ), 0, &xClient, xClientAddressLength ); - - } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */ - - /* All the strings generated by the command processing - have been sent. Clear the input string ready to receive - the next command. */ - cInputIndex = 0; - memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); - - /* Transmit a spacer, just to make the command console - easier to read. */ - FreeRTOS_sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, &xClient, xClientAddressLength ); - } - else - { - if( cInChar == '\r' ) - { - /* Ignore the character. Newlines are used to - detect the end of the input string. */ - } - else if( cInChar == '\b' ) - { - /* Backspace was pressed. Erase the last character - in the string - if any. */ - if( cInputIndex > 0 ) - { - cInputIndex--; - cInputString[ cInputIndex ] = '\0'; - } - } - else - { - /* A character was entered. Add it to the string - entered so far. When a \n is entered the complete - string will be passed to the command interpreter. */ - if( cInputIndex < cmdMAX_INPUT_SIZE ) - { - cInputString[ cInputIndex ] = cInChar; - cInputIndex++; - } - } - } - } - } - } - } - else - { - /* The socket could not be opened. */ - vTaskDelete( NULL ); - } -} -/*-----------------------------------------------------------*/ - -static xSocket_t prvOpenUDPServerSocket( uint16_t usPort ) -{ -struct freertos_sockaddr xServer; -xSocket_t xSocket = FREERTOS_INVALID_SOCKET; - - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - if( xSocket != FREERTOS_INVALID_SOCKET) - { - /* Zero out the server structure. */ - memset( ( void * ) &xServer, 0x00, sizeof( xServer ) ); - - /* Set family and port. */ - xServer.sin_port = FreeRTOS_htons( usPort ); - xServer.sin_family = FREERTOS_AF_INET; - - /* Bind the address to the socket. */ - if( FreeRTOS_bind( xSocket, &xServer, sizeof( xServer ) ) == -1 ) - { - FreeRTOS_closesocket( xSocket ); - xSocket = FREERTOS_INVALID_SOCKET; - } - } - - return xSocket; -} - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* FreeRTOS+UDP includes. */ +#include "FreeRTOS_UDP_IP.h" +#include "FreeRTOS_Sockets.h" + +/* Demo app includes. */ +#include "UDPCommandInterpreter.h" + +/* Dimensions the buffer into which input characters are placed. */ +#define cmdMAX_INPUT_SIZE 60 + +/* Dimensions the buffer into which string outputs can be placed. */ +#define cmdMAX_OUTPUT_SIZE 1250 + +/* Dimensions the buffer passed to the recvfrom() call. */ +#define cmdSOCKET_INPUT_BUFFER_SIZE 60 + +/* + * The task that runs FreeRTOS+CLI. + */ +void vUDPCommandInterpreterTask( void * pvParameters ); + +/* + * Open and configure the UDP socket. + */ +static xSocket_t prvOpenUDPServerSocket( uint16_t usPort ); + +/*-----------------------------------------------------------*/ + +void vStartUDPCommandInterpreterTask( uint16_t usStackSize, + uint32_t ulPort, + UBaseType_t uxPriority ) +{ + xTaskCreate( vUDPCommandInterpreterTask, "CLI", usStackSize, ( void * ) ulPort, uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +/* + * Task that provides the input and output for the FreeRTOS+CLI command + * interpreter. In this case a UDP port is used. See the URL in the comments + * within main.c for the location of the online documentation. + */ +void vUDPCommandInterpreterTask( void * pvParameters ) +{ + long lBytes, lByte; + signed char cInChar, cInputIndex = 0; + static char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ]; + BaseType_t xMoreDataToFollow; + struct freertos_sockaddr xClient; + socklen_t xClientAddressLength = 0; /* This is required as a parameter to maintain the sendto() Berkeley sockets API - but it is not actually used so can take any value. */ + xSocket_t xSocket; + + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; + + /* Attempt to open the socket. The port number is passed in the task + * parameter. The strange casting is to remove compiler warnings on 32-bit + * machines. */ + xSocket = prvOpenUDPServerSocket( ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL ); + + if( xSocket != FREERTOS_INVALID_SOCKET ) + { + for( ; ; ) + { + /* Wait for incoming data on the opened socket. */ + lBytes = FreeRTOS_recvfrom( xSocket, ( void * ) cLocalBuffer, sizeof( cLocalBuffer ), 0, &xClient, &xClientAddressLength ); + + if( lBytes != FREERTOS_SOCKET_ERROR ) + { + /* Process each received byte in turn. */ + lByte = 0; + + while( lByte < lBytes ) + { + /* The next character in the input buffer. */ + cInChar = cLocalBuffer[ lByte ]; + lByte++; + + /* Newline characters are taken as the end of the command + * string. */ + if( cInChar == '\n' ) + { + /* Process the input string received prior to the + * newline. */ + do + { + /* Pass the string to FreeRTOS+CLI. */ + xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE ); + + /* Send the output generated by the command's + * implementation. */ + FreeRTOS_sendto( xSocket, cOutputString, strlen( cOutputString ), 0, &xClient, xClientAddressLength ); + } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */ + + /* All the strings generated by the command processing + * have been sent. Clear the input string ready to receive + * the next command. */ + cInputIndex = 0; + memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); + + /* Transmit a spacer, just to make the command console + * easier to read. */ + FreeRTOS_sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, &xClient, xClientAddressLength ); + } + else + { + if( cInChar == '\r' ) + { + /* Ignore the character. Newlines are used to + * detect the end of the input string. */ + } + else if( cInChar == '\b' ) + { + /* Backspace was pressed. Erase the last character + * in the string - if any. */ + if( cInputIndex > 0 ) + { + cInputIndex--; + cInputString[ cInputIndex ] = '\0'; + } + } + else + { + /* A character was entered. Add it to the string + * entered so far. When a \n is entered the complete + * string will be passed to the command interpreter. */ + if( cInputIndex < cmdMAX_INPUT_SIZE ) + { + cInputString[ cInputIndex ] = cInChar; + cInputIndex++; + } + } + } + } + } + } + } + else + { + /* The socket could not be opened. */ + vTaskDelete( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static xSocket_t prvOpenUDPServerSocket( uint16_t usPort ) +{ + struct freertos_sockaddr xServer; + xSocket_t xSocket = FREERTOS_INVALID_SOCKET; + + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + + if( xSocket != FREERTOS_INVALID_SOCKET ) + { + /* Zero out the server structure. */ + memset( ( void * ) &xServer, 0x00, sizeof( xServer ) ); + + /* Set family and port. */ + xServer.sin_port = FreeRTOS_htons( usPort ); + xServer.sin_family = FREERTOS_AF_INET; + + /* Bind the address to the socket. */ + if( FreeRTOS_bind( xSocket, &xServer, sizeof( xServer ) ) == -1 ) + { + FreeRTOS_closesocket( xSocket ); + xSocket = FREERTOS_INVALID_SOCKET; + } + } + + return xSocket; +} diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c index c40e350e2..8b7215cbb 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c @@ -1,386 +1,388 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/****************************************************************************** - * - * See the following web page for essential TwoEchoClient.c usage and - * configuration details: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Common_Echo_Clients.shtml - * - ******************************************************************************/ - - -/* Standard includes. */ -#include -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* FreeRTOS+UDP includes. */ -#include "FreeRTOS_UDP_IP.h" -#include "FreeRTOS_Sockets.h" - -/* Small delay used between attempts to obtain a zero copy buffer. */ -#define echoTINY_DELAY ( ( TickType_t ) 2 ) - -/* The echo tasks create a socket, send out a number of echo requests -(listening for each echo reply), then close the socket again before -starting over. This delay is used between each iteration to ensure the -network does not get too congested. */ -#define echoLOOP_DELAY ( ( TickType_t ) 250 / portTICK_RATE_MS ) - -#if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 - /* When the trace recorder code is included user events are generated to - mark the sending and receiving of the echoed data (only in the zero copy - task. */ - #define echoMARK_SEND_IN_TRACE_BUFFER( x ) vTraceUserEvent( x ) - traceLabel xZeroCopySendEvent, xZeroCopyReceiveEvent; - -#else - /* When the trace recorder code is not included just #define away the call - to post the user event. */ - #define echoMARK_SEND_IN_TRACE_BUFFER( x ) - #define xZeroCopySendEvent 0 - #define xZeroCopyReceiveEvent 0 -#endif - -/* The echo server is assumed to be on port 7, which is the standard echo -protocol port. */ -#define echoECHO_PORT ( 7 ) - -/* - * Uses a socket to send data to, then receive data from, the standard echo - * port number 7. prvEchoClientTask() uses the standard interface. - * prvZeroCopyEchoClientTask() uses the zero copy interface. - */ -static void prvEchoClientTask( void *pvParameters ); -static void prvZeroCopyEchoClientTask( void *pvParameters ); - -/* The receive timeout is set shorter when the windows simulator is used -because simulated time is slower than real time. */ -#ifdef _WINDOWS_ - const TickType_t xReceiveTimeOut = 50 / portTICK_RATE_MS; -#else - const TickType_t xReceiveTimeOut = 500 / portTICK_RATE_MS; -#endif - -/*-----------------------------------------------------------*/ - -void vStartEchoClientTasks( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority ) -{ - /* Create the echo client task that does not use the zero copy interface. */ - xTaskCreate( prvEchoClientTask, /* The function that implements the task. */ - "Echo0", /* Just a text name for the task to aid debugging. */ - usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ - NULL, /* The task parameter, not used in this case. */ - uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ - NULL ); /* The task handle is not used. */ - - /* Create the echo client task that does use the zero copy interface. */ - xTaskCreate( prvZeroCopyEchoClientTask, /* The function that implements the task. */ - "Echo1", /* Just a text name for the task to aid debugging. */ - usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ - NULL, /* The task parameter, not used in this case. */ - uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ - NULL ); /* The task handle is not used. */ -} -/*-----------------------------------------------------------*/ - -static void prvEchoClientTask( void *pvParameters ) -{ -xSocket_t xSocket; -struct freertos_sockaddr xEchoServerAddress; -char cTxString[ 25 ], cRxString[ 25 ]; /* Make sure the stack is large enough to hold these. Turn on stack overflow checking during debug to be sure. */ -int32_t lLoopCount = 0UL; -const int32_t lMaxLoopCount = 50; -volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL; -uint32_t xAddressLength = sizeof( xEchoServerAddress ); - - /* Remove compiler warning about unused parameters. */ - ( void ) pvParameters; - - /* Echo requests are sent to the echo server. The address of the echo - server is configured by the constants configECHO_SERVER_ADDR0 to - configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ - xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); - } - #else - { - xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xEchoServerAddress.sin_family = FREERTOS_AF_INET; - - for( ;; ) - { - /* Create a socket. */ - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); - - /* Set a time out so a missing reply does not cause the task to block - indefinitely. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); - - /* Send a number of echo requests. */ - for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) - { - /* Create the string that is sent to the echo server. */ - sprintf( cTxString, "Message number %u\r\n", ( unsigned int ) ulTxCount ); - - /* Send the string to the socket. ulFlags is set to 0, so the zero - copy interface is not used. That means the data from cTxString is - copied into a network buffer inside FreeRTOS_sendto(), and cTxString - can be reused as soon as FreeRTOS_sendto() has returned. 1 is added - to ensure the NULL string terminator is sent as part of the message. */ - FreeRTOS_sendto( xSocket, /* The socket being sent to. */ - ( void * ) cTxString, /* The data being sent. */ - strlen( cTxString ) + 1,/* The length of the data being sent. */ - 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ - &xEchoServerAddress, /* The destination address. */ - sizeof( xEchoServerAddress ) ); - - /* Keep a count of how many echo requests have been transmitted so - it can be compared to the number of echo replies received. It would - be expected to loose at least one to an ARP message the first time - the connection is created. */ - ulTxCount++; - - /* Receive data echoed back to the socket. ulFlags is zero, so the - zero copy option is not being used and the received data will be - copied into the buffer pointed to by cRxString. xAddressLength is - not actually used (at the time of writing this comment, anyway) by - FreeRTOS_recvfrom(), but is set appropriately in case future - versions do use it. */ - memset( ( void * ) cRxString, 0x00, sizeof( cRxString ) ); - FreeRTOS_recvfrom( xSocket, /* The socket being received from. */ - cRxString, /* The buffer into which the received data will be written. */ - sizeof( cRxString ), /* The size of the buffer provided to receive the data. */ - 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ - &xEchoServerAddress, /* The address from where the data was sent (the source address). */ - &xAddressLength ); - - /* Compare the transmitted string to the received string. */ - if( strcmp( cRxString, cTxString ) == 0 ) - { - /* The echo reply was received without error. */ - ulRxCount++; - } - }; - - /* Pause for a short while to ensure the network is not too - congested. */ - vTaskDelay( echoLOOP_DELAY ); - - /* Close this socket before looping back to create another. */ - FreeRTOS_closesocket( xSocket ); - } -} -/*-----------------------------------------------------------*/ - -static void prvZeroCopyEchoClientTask( void *pvParameters ) -{ -xSocket_t xSocket; -struct freertos_sockaddr xEchoServerAddress; -static char cTxString[ 40 ]; -int32_t lLoopCount = 0UL; -volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL; -uint32_t xAddressLength = sizeof( xEchoServerAddress ); -int32_t lReturned; -uint8_t *pucUDPPayloadBuffer; - -const int32_t lMaxLoopCount = 50; -const char * const pcStringToSend = "Zero copy message number"; -/* The buffer is large enough to hold the string, a number, and the string terminator. */ -const size_t xBufferLength = strlen( pcStringToSend ) + 15; - - #if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 - { - /* When the trace recorder code is included user events are generated to - mark the sending and receiving of the echoed data (only in the zero copy - task). */ - xZeroCopySendEvent = xTraceOpenLabel( "ZeroCopyTx" ); - xZeroCopyReceiveEvent = xTraceOpenLabel( "ZeroCopyRx" ); - } - #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS */ - - /* Remove compiler warning about unused parameters. */ - ( void ) pvParameters; - - /* Delay for a little while to ensure the task is out of synch with the - other echo task implemented above. */ - vTaskDelay( echoLOOP_DELAY >> 1 ); - - /* Echo requests are sent to the echo server. The address of the echo - server is configured by the constants configECHO_SERVER_ADDR0 to - configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ - xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); - } - #else - { - xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xEchoServerAddress.sin_family = FREERTOS_AF_INET; - - for( ;; ) - { - /* Create a socket. */ - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); - - /* Set a time out so a missing reply does not cause the task to block - indefinitely. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); - - /* Send a number of echo requests. */ - for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) - { - /* This task is going to send using the zero copy interface. The - data being sent is therefore written directly into a buffer that is - passed by reference into the FreeRTOS_sendto() function. First - obtain a buffer of adequate size from the IP stack. Although a max - delay is used, the actual delay will be capped to - ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence the test to ensure a buffer - was actually obtained. */ - pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xBufferLength, portMAX_DELAY ); - - if( pucUDPPayloadBuffer != NULL ) - { - /* A buffer was successfully obtained. Create the string that is - sent to the echo server. Note the string is written directly - into the buffer obtained from the IP stack. */ - sprintf( ( char * ) pucUDPPayloadBuffer, "%s %u\r\n", "Zero copy message number", ( unsigned int ) ulTxCount ); - - /* Also copy the string into a local buffer so it can be compared - with the string that is later received back from the echo server. */ - strcpy( cTxString, ( char * ) pucUDPPayloadBuffer ); - - /* Pass the buffer into the send function. ulFlags has the - FREERTOS_ZERO_COPY bit set so the IP stack will take control of - the buffer, rather than copy data out of the buffer. */ - echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopySendEvent ); - lReturned = FreeRTOS_sendto( xSocket, /* The socket being sent to. */ - ( void * ) pucUDPPayloadBuffer, /* The buffer being passed into the IP stack. */ - strlen( cTxString ) + 1, /* The length of the data being sent. Plus 1 to ensure the null terminator is part of the data. */ - FREERTOS_ZERO_COPY, /* ulFlags with the zero copy bit is set. */ - &xEchoServerAddress, /* Where the data is being sent. */ - sizeof( xEchoServerAddress ) ); - - if( lReturned == 0 ) - { - /* The send operation failed, so this task is still - responsible for the buffer obtained from the IP stack. To - ensure the buffer is not lost it must either be used again, - or, as in this case, returned to the IP stack using - FreeRTOS_ReleaseUDPPayloadBuffer(). pucUDPPayloadBuffer can - be safely re-used to receive from the socket below once the - buffer has been returned to the stack. */ - FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer ); - } - else - { - /* The send was successful so the IP stack is now managing - the buffer pointed to by pucUDPPayloadBuffer, and the IP - stack will return the buffer once it has been sent. - pucUDPPayloadBuffer can be safely re-used to receive from - the socket below. */ - } - - /* Keep a count of how many echo requests have been transmitted - so it can be compared to the number of echo replies received. - It would be expected to loose at least one to an ARP message the - first time the connection is created. */ - ulTxCount++; - - /* Receive data on the socket. ulFlags has the zero copy bit set - (FREERTOS_ZERO_COPY) indicating to the stack that a reference to - the received data should be passed out to this task using the - second parameter to the FreeRTOS_recvfrom() call. When this is - done the IP stack is no longer responsible for releasing the - buffer, and the task *must* return the buffer to the stack when - it is no longer needed. By default the receive block time is - portMAX_DELAY. */ - echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopyReceiveEvent ); - lReturned = FreeRTOS_recvfrom( xSocket, /* The socket to receive from. */ - ( void * ) &pucUDPPayloadBuffer, /* pucUDPPayloadBuffer will be set to point to the buffer that already contains the received data. */ - 0, /* Ignored because the zero copy interface is being used. */ - FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */ - &xEchoServerAddress, /* The address from which the data was sent. */ - &xAddressLength ); - - if( lReturned > 0 ) - { - /* Compare the string sent to the echo server with the string - received back from the echo server. */ - if( strcmp( ( char * ) pucUDPPayloadBuffer, cTxString ) == 0 ) - { - /* The strings matched. */ - ulRxCount++; - } - - /* The buffer that contains the data passed out of the stack - *must* be returned to the stack. */ - FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer ); - } - } - } - - /* Pause for a short while to ensure the network is not too - congested. */ - vTaskDelay( echoLOOP_DELAY ); - - /* Close this socket before looping back to create another. */ - FreeRTOS_closesocket( xSocket ); - } -} -/*-----------------------------------------------------------*/ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/****************************************************************************** +* +* See the following web page for essential TwoEchoClient.c usage and +* configuration details: +* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Common_Echo_Clients.shtml +* +******************************************************************************/ + + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* FreeRTOS+UDP includes. */ +#include "FreeRTOS_UDP_IP.h" +#include "FreeRTOS_Sockets.h" + +/* Small delay used between attempts to obtain a zero copy buffer. */ +#define echoTINY_DELAY ( ( TickType_t ) 2 ) + +/* The echo tasks create a socket, send out a number of echo requests + * (listening for each echo reply), then close the socket again before + * starting over. This delay is used between each iteration to ensure the + * network does not get too congested. */ +#define echoLOOP_DELAY ( ( TickType_t ) 250 / portTICK_RATE_MS ) + +#if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 + +/* When the trace recorder code is included user events are generated to + * mark the sending and receiving of the echoed data (only in the zero copy + * task. */ + #define echoMARK_SEND_IN_TRACE_BUFFER( x ) vTraceUserEvent( x ) + traceLabel xZeroCopySendEvent, xZeroCopyReceiveEvent; + +#else + +/* When the trace recorder code is not included just #define away the call + * to post the user event. */ + #define echoMARK_SEND_IN_TRACE_BUFFER( x ) + #define xZeroCopySendEvent 0 + #define xZeroCopyReceiveEvent 0 +#endif + +/* The echo server is assumed to be on port 7, which is the standard echo + * protocol port. */ +#define echoECHO_PORT ( 7 ) + +/* + * Uses a socket to send data to, then receive data from, the standard echo + * port number 7. prvEchoClientTask() uses the standard interface. + * prvZeroCopyEchoClientTask() uses the zero copy interface. + */ +static void prvEchoClientTask( void * pvParameters ); +static void prvZeroCopyEchoClientTask( void * pvParameters ); + +/* The receive timeout is set shorter when the windows simulator is used + * because simulated time is slower than real time. */ +#ifdef _WINDOWS_ + const TickType_t xReceiveTimeOut = 50 / portTICK_RATE_MS; +#else + const TickType_t xReceiveTimeOut = 500 / portTICK_RATE_MS; +#endif + +/*-----------------------------------------------------------*/ + +void vStartEchoClientTasks( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ) +{ + /* Create the echo client task that does not use the zero copy interface. */ + xTaskCreate( prvEchoClientTask, /* The function that implements the task. */ + "Echo0", /* Just a text name for the task to aid debugging. */ + usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ + NULL, /* The task parameter, not used in this case. */ + uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ + NULL ); /* The task handle is not used. */ + + /* Create the echo client task that does use the zero copy interface. */ + xTaskCreate( prvZeroCopyEchoClientTask, /* The function that implements the task. */ + "Echo1", /* Just a text name for the task to aid debugging. */ + usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ + NULL, /* The task parameter, not used in this case. */ + uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ + NULL ); /* The task handle is not used. */ +} +/*-----------------------------------------------------------*/ + +static void prvEchoClientTask( void * pvParameters ) +{ + xSocket_t xSocket; + struct freertos_sockaddr xEchoServerAddress; + char cTxString[ 25 ], cRxString[ 25 ]; /* Make sure the stack is large enough to hold these. Turn on stack overflow checking during debug to be sure. */ + int32_t lLoopCount = 0UL; + const int32_t lMaxLoopCount = 50; + volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL; + uint32_t xAddressLength = sizeof( xEchoServerAddress ); + + /* Remove compiler warning about unused parameters. */ + ( void ) pvParameters; + + /* Echo requests are sent to the echo server. The address of the echo + * server is configured by the constants configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ + xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); + } + #else + { + xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xEchoServerAddress.sin_family = FREERTOS_AF_INET; + + for( ; ; ) + { + /* Create a socket. */ + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); + + /* Set a time out so a missing reply does not cause the task to block + * indefinitely. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); + + /* Send a number of echo requests. */ + for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) + { + /* Create the string that is sent to the echo server. */ + sprintf( cTxString, "Message number %u\r\n", ( unsigned int ) ulTxCount ); + + /* Send the string to the socket. ulFlags is set to 0, so the zero + * copy interface is not used. That means the data from cTxString is + * copied into a network buffer inside FreeRTOS_sendto(), and cTxString + * can be reused as soon as FreeRTOS_sendto() has returned. 1 is added + * to ensure the NULL string terminator is sent as part of the message. */ + FreeRTOS_sendto( xSocket, /* The socket being sent to. */ + ( void * ) cTxString, /* The data being sent. */ + strlen( cTxString ) + 1, /* The length of the data being sent. */ + 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ + &xEchoServerAddress, /* The destination address. */ + sizeof( xEchoServerAddress ) ); + + /* Keep a count of how many echo requests have been transmitted so + * it can be compared to the number of echo replies received. It would + * be expected to loose at least one to an ARP message the first time + * the connection is created. */ + ulTxCount++; + + /* Receive data echoed back to the socket. ulFlags is zero, so the + * zero copy option is not being used and the received data will be + * copied into the buffer pointed to by cRxString. xAddressLength is + * not actually used (at the time of writing this comment, anyway) by + * FreeRTOS_recvfrom(), but is set appropriately in case future + * versions do use it. */ + memset( ( void * ) cRxString, 0x00, sizeof( cRxString ) ); + FreeRTOS_recvfrom( xSocket, /* The socket being received from. */ + cRxString, /* The buffer into which the received data will be written. */ + sizeof( cRxString ), /* The size of the buffer provided to receive the data. */ + 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ + &xEchoServerAddress, /* The address from where the data was sent (the source address). */ + &xAddressLength ); + + /* Compare the transmitted string to the received string. */ + if( strcmp( cRxString, cTxString ) == 0 ) + { + /* The echo reply was received without error. */ + ulRxCount++; + } + } + + /* Pause for a short while to ensure the network is not too + * congested. */ + vTaskDelay( echoLOOP_DELAY ); + + /* Close this socket before looping back to create another. */ + FreeRTOS_closesocket( xSocket ); + } +} +/*-----------------------------------------------------------*/ + +static void prvZeroCopyEchoClientTask( void * pvParameters ) +{ + xSocket_t xSocket; + struct freertos_sockaddr xEchoServerAddress; + static char cTxString[ 40 ]; + int32_t lLoopCount = 0UL; + volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL; + uint32_t xAddressLength = sizeof( xEchoServerAddress ); + int32_t lReturned; + uint8_t * pucUDPPayloadBuffer; + + const int32_t lMaxLoopCount = 50; + const char * const pcStringToSend = "Zero copy message number"; +/* The buffer is large enough to hold the string, a number, and the string terminator. */ + const size_t xBufferLength = strlen( pcStringToSend ) + 15; + + #if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 + { + /* When the trace recorder code is included user events are generated to + * mark the sending and receiving of the echoed data (only in the zero copy + * task). */ + xZeroCopySendEvent = xTraceOpenLabel( "ZeroCopyTx" ); + xZeroCopyReceiveEvent = xTraceOpenLabel( "ZeroCopyRx" ); + } + #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS */ + + /* Remove compiler warning about unused parameters. */ + ( void ) pvParameters; + + /* Delay for a little while to ensure the task is out of synch with the + * other echo task implemented above. */ + vTaskDelay( echoLOOP_DELAY >> 1 ); + + /* Echo requests are sent to the echo server. The address of the echo + * server is configured by the constants configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ + xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); + } + #else + { + xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xEchoServerAddress.sin_family = FREERTOS_AF_INET; + + for( ; ; ) + { + /* Create a socket. */ + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); + + /* Set a time out so a missing reply does not cause the task to block + * indefinitely. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); + + /* Send a number of echo requests. */ + for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) + { + /* This task is going to send using the zero copy interface. The + * data being sent is therefore written directly into a buffer that is + * passed by reference into the FreeRTOS_sendto() function. First + * obtain a buffer of adequate size from the IP stack. Although a max + * delay is used, the actual delay will be capped to + * ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence the test to ensure a buffer + * was actually obtained. */ + pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xBufferLength, portMAX_DELAY ); + + if( pucUDPPayloadBuffer != NULL ) + { + /* A buffer was successfully obtained. Create the string that is + * sent to the echo server. Note the string is written directly + * into the buffer obtained from the IP stack. */ + sprintf( ( char * ) pucUDPPayloadBuffer, "%s %u\r\n", "Zero copy message number", ( unsigned int ) ulTxCount ); + + /* Also copy the string into a local buffer so it can be compared + * with the string that is later received back from the echo server. */ + strcpy( cTxString, ( char * ) pucUDPPayloadBuffer ); + + /* Pass the buffer into the send function. ulFlags has the + * FREERTOS_ZERO_COPY bit set so the IP stack will take control of + * the buffer, rather than copy data out of the buffer. */ + echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopySendEvent ); + lReturned = FreeRTOS_sendto( xSocket, /* The socket being sent to. */ + ( void * ) pucUDPPayloadBuffer, /* The buffer being passed into the IP stack. */ + strlen( cTxString ) + 1, /* The length of the data being sent. Plus 1 to ensure the null terminator is part of the data. */ + FREERTOS_ZERO_COPY, /* ulFlags with the zero copy bit is set. */ + &xEchoServerAddress, /* Where the data is being sent. */ + sizeof( xEchoServerAddress ) ); + + if( lReturned == 0 ) + { + /* The send operation failed, so this task is still + * responsible for the buffer obtained from the IP stack. To + * ensure the buffer is not lost it must either be used again, + * or, as in this case, returned to the IP stack using + * FreeRTOS_ReleaseUDPPayloadBuffer(). pucUDPPayloadBuffer can + * be safely re-used to receive from the socket below once the + * buffer has been returned to the stack. */ + FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer ); + } + else + { + /* The send was successful so the IP stack is now managing + * the buffer pointed to by pucUDPPayloadBuffer, and the IP + * stack will return the buffer once it has been sent. + * pucUDPPayloadBuffer can be safely re-used to receive from + * the socket below. */ + } + + /* Keep a count of how many echo requests have been transmitted + * so it can be compared to the number of echo replies received. + * It would be expected to loose at least one to an ARP message the + * first time the connection is created. */ + ulTxCount++; + + /* Receive data on the socket. ulFlags has the zero copy bit set + * (FREERTOS_ZERO_COPY) indicating to the stack that a reference to + * the received data should be passed out to this task using the + * second parameter to the FreeRTOS_recvfrom() call. When this is + * done the IP stack is no longer responsible for releasing the + * buffer, and the task *must* return the buffer to the stack when + * it is no longer needed. By default the receive block time is + * portMAX_DELAY. */ + echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopyReceiveEvent ); + lReturned = FreeRTOS_recvfrom( xSocket, /* The socket to receive from. */ + ( void * ) &pucUDPPayloadBuffer, /* pucUDPPayloadBuffer will be set to point to the buffer that already contains the received data. */ + 0, /* Ignored because the zero copy interface is being used. */ + FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */ + &xEchoServerAddress, /* The address from which the data was sent. */ + &xAddressLength ); + + if( lReturned > 0 ) + { + /* Compare the string sent to the echo server with the string + * received back from the echo server. */ + if( strcmp( ( char * ) pucUDPPayloadBuffer, cTxString ) == 0 ) + { + /* The strings matched. */ + ulRxCount++; + } + + /* The buffer that contains the data passed out of the stack + * must* be returned to the stack. */ + FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer ); + } + } + } + + /* Pause for a short while to ensure the network is not too + * congested. */ + vTaskDelay( echoLOOP_DELAY ); + + /* Close this socket before looping back to create another. */ + FreeRTOS_closesocket( xSocket ); + } +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.h b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.h index 7c0bea985..d656a1c4c 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.h +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.h @@ -1,37 +1,38 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -#ifndef TWO_ECHO_CLIENTS_H -#define TWO_ECHO_CLIENTS_H - -/* - * Create the two UDP echo client tasks. One task uses the standard interface - * to send to and receive from an echo server. The other task uses the zero - * copy interface to send to and receive from an echo server. - */ -void vStartEchoClientTasks( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority ); - -#endif /* TWO_ECHO_CLIENTS_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef TWO_ECHO_CLIENTS_H +#define TWO_ECHO_CLIENTS_H + +/* + * Create the two UDP echo client tasks. One task uses the standard interface + * to send to and receive from an echo server. The other task uses the zero + * copy interface to send to and receive from an echo server. + */ +void vStartEchoClientTasks( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ); + +#endif /* TWO_ECHO_CLIENTS_H */ diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.c index 4bdf2bdb6..f460ca072 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.c +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.c @@ -1,149 +1,150 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -/* - * This file, along with DemoIPTrace.h, provides a basic example use of the - * FreeRTOS+UDP trace macros. The statistics gathered here can be viewed in - * the command line interface. - * See http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/UDP_IP_Trace.shtml - */ - -/* Standard includes. */ -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* FreeRTOS+UDP includes. */ -#include "FreeRTOS_UDP_IP.h" -#include "DemoIPTrace.h" - -/* It is possible to remove the trace macros using the -configINCLUDE_DEMO_DEBUG_STATS setting in FreeRTOSIPConfig.h. */ -#if configINCLUDE_DEMO_DEBUG_STATS == 1 - -/* - * Each row in the xIPTraceValues[] table contains a pointer to a function that - * updates the value for that row. Rows that latch the lowest value point to - * this function (for example, this function can be used to latch the lowest - * number of network buffers that were available during the execution of the - * stack). - */ -static void prvStoreLowest( uint32_t *pulCurrentValue, uint32_t ulCount ); - -/* - * Each row in the xIPTraceValues[] table contains a pointer to a function that - * updates the value for that row. Rows that simply increment an event count - * point to this function. - */ -static void prvIncrementEventCount( uint32_t *pulCurrentValue, uint32_t ulCount ); - - -xExampleDebugStatEntry_t xIPTraceValues[] = -{ - /* Comment out array entries to remove individual trace items. */ - - { iptraceID_NETWORK_INTERFACE_RECEIVE, ( const uint8_t * const ) "Packets received by the network interface", prvIncrementEventCount, 0 }, - { iptraceID_NETWORK_INTERFACE_TRANSMIT, ( const uint8_t * const ) "Count of transmitted packets", prvIncrementEventCount, 0 }, - { iptraceID_PACKET_DROPPED_TO_GENERATE_ARP, ( const uint8_t * const ) "Count of packets dropped to generate ARP", prvIncrementEventCount, 0 }, - { iptraceID_NETWORK_BUFFER_OBTAINED, ( const uint8_t * const ) "Lowest ever available network buffers", prvStoreLowest, 0xffffUL }, - { iptraceID_NETWORK_EVENT_RECEIVED, ( const uint8_t * const ) "Lowest ever free space in network event queue", prvStoreLowest, 0xffffUL }, - { iptraceID_FAILED_TO_OBTAIN_NETWORK_BUFFER, ( const uint8_t * const ) "Count of failed attempts to obtain a network buffer",prvIncrementEventCount, 0 }, - { iptraceID_ARP_TABLE_ENTRY_EXPIRED, ( const uint8_t * const ) "Count of expired ARP entries", prvIncrementEventCount, 0 }, - { iptraceID_FAILED_TO_CREATE_SOCKET, ( const uint8_t * const ) "Count of failures to create a socket", prvIncrementEventCount, 0 }, - { iptraceID_RECVFROM_DISCARDING_BYTES, ( const uint8_t * const ) "Count of times recvfrom() has discarding bytes", prvIncrementEventCount, 0 }, - { iptraceID_ETHERNET_RX_EVENT_LOST, ( const uint8_t * const ) "Count of lost Ethenret Rx events (event queue full?)",prvIncrementEventCount, 0 }, - { iptraceID_STACK_TX_EVENT_LOST, ( const uint8_t * const ) "Count of lost IP stack events (event queue full?)", prvIncrementEventCount, 0 }, - { ipconfigID_BIND_FAILED, ( const uint8_t * const ) "Count of failed calls to bind()", prvIncrementEventCount, 0 }, - { iptraceID_RECVFROM_TIMEOUT, ( const uint8_t * const ) "Count of receive timeouts", prvIncrementEventCount, 0 }, - { iptraceID_SENDTO_DATA_TOO_LONG, ( const uint8_t * const ) "Count of failed sends due to oversized payload", prvIncrementEventCount, 0 }, - { iptraceID_SENDTO_SOCKET_NOT_BOUND, ( const uint8_t * const ) "Count of failed sends due to unbound socket", prvIncrementEventCount, 0 }, - { iptraceID_NO_BUFFER_FOR_SENDTO, ( const uint8_t * const ) "Count of failed transmits due to timeout", prvIncrementEventCount, 0 }, - { iptraceID_WAIT_FOR_TX_DMA_DESCRIPTOR, ( const uint8_t * const ) "Number of times task had to wait to obtain a DMA Tx descriptor", prvIncrementEventCount, 0 }, - { iptraceID_FAILED_TO_NOTIFY_SELECT_GROUP, ( const uint8_t * const ) "Failed to notify select group", prvIncrementEventCount, 0 } -}; - -/*-----------------------------------------------------------*/ - -BaseType_t xExampleDebugStatEntries( void ) -{ - /* Return the number of entries in the xIPTraceValues[] table. */ - return ( BaseType_t ) ( sizeof( xIPTraceValues ) / sizeof( xExampleDebugStatEntry_t ) ); -} -/*-----------------------------------------------------------*/ - -void vExampleDebugStatUpdate( uint8_t ucIdentifier, uint32_t ulValue ) -{ -BaseType_t xIndex; -const BaseType_t xEntries = sizeof( xIPTraceValues ) / sizeof( xExampleDebugStatEntry_t ); - - /* Update an entry in the xIPTraceValues[] table. Each row in the table - includes a pointer to a function that performs the actual update. This - function just executes the update function from that table row. */ - for( xIndex = 0; xIndex < xEntries; xIndex++ ) - { - if( xIPTraceValues[ xIndex ].ucIdentifier == ucIdentifier ) - { - xIPTraceValues[ xIndex ].vPerformAction( &( xIPTraceValues[ xIndex ].ulData ), ulValue ); - break; - } - } - - configASSERT( xIndex != xEntries ); -} -/*-----------------------------------------------------------*/ - -static void prvIncrementEventCount( uint32_t *pulCurrentValue, uint32_t ulCount ) -{ - /* Each row in the xIPTraceValues[] table contains a pointer to a function - that updates the value for that row. Rows that simply increment an event - count point to this function. */ - ( void ) ulCount; - ( *pulCurrentValue )++; -} -/*-----------------------------------------------------------*/ - -static void prvStoreLowest( uint32_t *pulCurrentValue, uint32_t ulCount ) -{ - /* Each row in the xIPTraceValues[] table contains a pointer to a function - that updates the value for that row. Rows that latch the lowest value - point to this function (for example, this function can be used to latch - the lowest number of network buffers that were available during the - execution of the stack). */ - if( ulCount < *pulCurrentValue ) - { - *pulCurrentValue = ulCount; - } -} -/*-----------------------------------------------------------*/ - - -#endif /* configINCLUDE_DEMO_DEBUG_STATS == 1 */ - - - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * This file, along with DemoIPTrace.h, provides a basic example use of the + * FreeRTOS+UDP trace macros. The statistics gathered here can be viewed in + * the command line interface. + * See http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/UDP_IP_Trace.shtml + */ + +/* Standard includes. */ +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* FreeRTOS+UDP includes. */ +#include "FreeRTOS_UDP_IP.h" +#include "DemoIPTrace.h" + +/* It is possible to remove the trace macros using the + * configINCLUDE_DEMO_DEBUG_STATS setting in FreeRTOSIPConfig.h. */ +#if configINCLUDE_DEMO_DEBUG_STATS == 1 + +/* + * Each row in the xIPTraceValues[] table contains a pointer to a function that + * updates the value for that row. Rows that latch the lowest value point to + * this function (for example, this function can be used to latch the lowest + * number of network buffers that were available during the execution of the + * stack). + */ + static void prvStoreLowest( uint32_t * pulCurrentValue, + uint32_t ulCount ); + +/* + * Each row in the xIPTraceValues[] table contains a pointer to a function that + * updates the value for that row. Rows that simply increment an event count + * point to this function. + */ + static void prvIncrementEventCount( uint32_t * pulCurrentValue, + uint32_t ulCount ); + + + xExampleDebugStatEntry_t xIPTraceValues[] = + { + /* Comment out array entries to remove individual trace items. */ + + { iptraceID_NETWORK_INTERFACE_RECEIVE, ( const uint8_t * const ) "Packets received by the network interface", prvIncrementEventCount, 0 }, + { iptraceID_NETWORK_INTERFACE_TRANSMIT, ( const uint8_t * const ) "Count of transmitted packets", prvIncrementEventCount, 0 }, + { iptraceID_PACKET_DROPPED_TO_GENERATE_ARP, ( const uint8_t * const ) "Count of packets dropped to generate ARP", prvIncrementEventCount, 0 }, + { iptraceID_NETWORK_BUFFER_OBTAINED, ( const uint8_t * const ) "Lowest ever available network buffers", prvStoreLowest, 0xffffUL }, + { iptraceID_NETWORK_EVENT_RECEIVED, ( const uint8_t * const ) "Lowest ever free space in network event queue", prvStoreLowest, 0xffffUL }, + { iptraceID_FAILED_TO_OBTAIN_NETWORK_BUFFER, ( const uint8_t * const ) "Count of failed attempts to obtain a network buffer", prvIncrementEventCount, 0 }, + { iptraceID_ARP_TABLE_ENTRY_EXPIRED, ( const uint8_t * const ) "Count of expired ARP entries", prvIncrementEventCount, 0 }, + { iptraceID_FAILED_TO_CREATE_SOCKET, ( const uint8_t * const ) "Count of failures to create a socket", prvIncrementEventCount, 0 }, + { iptraceID_RECVFROM_DISCARDING_BYTES, ( const uint8_t * const ) "Count of times recvfrom() has discarding bytes", prvIncrementEventCount, 0 }, + { iptraceID_ETHERNET_RX_EVENT_LOST, ( const uint8_t * const ) "Count of lost Ethernet Rx events (event queue full?)", prvIncrementEventCount, 0 }, + { iptraceID_STACK_TX_EVENT_LOST, ( const uint8_t * const ) "Count of lost IP stack events (event queue full?)", prvIncrementEventCount, 0 }, + { ipconfigID_BIND_FAILED, ( const uint8_t * const ) "Count of failed calls to bind()", prvIncrementEventCount, 0 }, + { iptraceID_RECVFROM_TIMEOUT, ( const uint8_t * const ) "Count of receive timeouts", prvIncrementEventCount, 0 }, + { iptraceID_SENDTO_DATA_TOO_LONG, ( const uint8_t * const ) "Count of failed sends due to oversized payload", prvIncrementEventCount, 0 }, + { iptraceID_SENDTO_SOCKET_NOT_BOUND, ( const uint8_t * const ) "Count of failed sends due to unbound socket", prvIncrementEventCount, 0 }, + { iptraceID_NO_BUFFER_FOR_SENDTO, ( const uint8_t * const ) "Count of failed transmits due to timeout", prvIncrementEventCount, 0 }, + { iptraceID_WAIT_FOR_TX_DMA_DESCRIPTOR, ( const uint8_t * const ) "Number of times task had to wait to obtain a DMA Tx descriptor", prvIncrementEventCount, 0 }, + { iptraceID_FAILED_TO_NOTIFY_SELECT_GROUP, ( const uint8_t * const ) "Failed to notify select group", prvIncrementEventCount, 0 } + }; + +/*-----------------------------------------------------------*/ + + BaseType_t xExampleDebugStatEntries( void ) + { + /* Return the number of entries in the xIPTraceValues[] table. */ + return ( BaseType_t ) ( sizeof( xIPTraceValues ) / sizeof( xExampleDebugStatEntry_t ) ); + } +/*-----------------------------------------------------------*/ + + void vExampleDebugStatUpdate( uint8_t ucIdentifier, + uint32_t ulValue ) + { + BaseType_t xIndex; + const BaseType_t xEntries = sizeof( xIPTraceValues ) / sizeof( xExampleDebugStatEntry_t ); + + /* Update an entry in the xIPTraceValues[] table. Each row in the table + * includes a pointer to a function that performs the actual update. This + * function just executes the update function from that table row. */ + for( xIndex = 0; xIndex < xEntries; xIndex++ ) + { + if( xIPTraceValues[ xIndex ].ucIdentifier == ucIdentifier ) + { + xIPTraceValues[ xIndex ].vPerformAction( &( xIPTraceValues[ xIndex ].ulData ), ulValue ); + break; + } + } + + configASSERT( xIndex != xEntries ); + } +/*-----------------------------------------------------------*/ + + static void prvIncrementEventCount( uint32_t * pulCurrentValue, + uint32_t ulCount ) + { + /* Each row in the xIPTraceValues[] table contains a pointer to a function + * that updates the value for that row. Rows that simply increment an event + * count point to this function. */ + ( void ) ulCount; + ( *pulCurrentValue )++; + } +/*-----------------------------------------------------------*/ + + static void prvStoreLowest( uint32_t * pulCurrentValue, + uint32_t ulCount ) + { + /* Each row in the xIPTraceValues[] table contains a pointer to a function + * that updates the value for that row. Rows that latch the lowest value + * point to this function (for example, this function can be used to latch + * the lowest number of network buffers that were available during the + * execution of the stack). */ + if( ulCount < *pulCurrentValue ) + { + *pulCurrentValue = ulCount; + } + } +/*-----------------------------------------------------------*/ + + +#endif /* configINCLUDE_DEMO_DEBUG_STATS == 1 */ diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.h b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.h index c355afed6..f8584aefc 100644 --- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.h +++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.h @@ -1,120 +1,123 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -/* - * This file, along with DemoIPTrace.h, provides a basic example use of the - * FreeRTOS+UDP trace macros. The statistics gathered here can be viewed in - * the command line interface. - * See http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/UDP_IP_Trace.shtml - */ - -#ifndef DEMO_IP_TRACE_MACROS_H -#define DEMO_IP_TRACE_MACROS_H - -typedef void ( *vTraceAction_t )( uint32_t *, uint32_t ); - -/* Type that defines each statistic being gathered. */ -typedef struct ExampleDebugStatEntry -{ - uint8_t ucIdentifier; /* Unique identifier for statistic. */ - const uint8_t * const pucDescription; /* Text description for the statistic. */ - vTraceAction_t vPerformAction; /* Action to perform when the statistic is updated (increment counter, store minimum value, store maximum value, etc. */ - uint32_t ulData; /* The meaning of this data is dependent on the trace macro ID. */ -} xExampleDebugStatEntry_t; - -/* Unique identifiers used to locate the entry for each trace macro in the -xIPTraceValues[] table defined in DemoIPTrace.c. */ -#define iptraceID_NETWORK_INTERFACE_RECEIVE 0 -#define iptraceID_NETWORK_INTERFACE_TRANSMIT 1 -#define iptraceID_PACKET_DROPPED_TO_GENERATE_ARP 2 -/* Do not change IDs above this line as the ID is shared with a FreeRTOS+Nabto -demo. */ -#define iptraceID_NETWORK_BUFFER_OBTAINED 3 -#define iptraceID_NETWORK_BUFFER_OBTAINED_FROM_ISR 4 -#define iptraceID_NETWORK_EVENT_RECEIVED 5 -#define iptraceID_FAILED_TO_OBTAIN_NETWORK_BUFFER 6 -#define iptraceID_ARP_TABLE_ENTRY_EXPIRED 7 -#define iptraceID_FAILED_TO_CREATE_SOCKET 8 -#define iptraceID_RECVFROM_DISCARDING_BYTES 9 -#define iptraceID_ETHERNET_RX_EVENT_LOST 10 -#define iptraceID_STACK_TX_EVENT_LOST 11 -#define ipconfigID_BIND_FAILED 12 -#define iptraceID_RECVFROM_TIMEOUT 13 -#define iptraceID_SENDTO_DATA_TOO_LONG 14 -#define iptraceID_SENDTO_SOCKET_NOT_BOUND 15 -#define iptraceID_NO_BUFFER_FOR_SENDTO 16 -#define iptraceID_WAIT_FOR_TX_DMA_DESCRIPTOR 17 -#define iptraceID_FAILED_TO_NOTIFY_SELECT_GROUP 18 - -/* It is possible to remove the trace macros using the -configINCLUDE_DEMO_DEBUG_STATS setting in FreeRTOSIPConfig.h. */ -#if configINCLUDE_DEMO_DEBUG_STATS == 1 - - /* The trace macro definitions themselves. Any trace macros left undefined - will default to be empty macros. */ - #define iptraceNETWORK_BUFFER_OBTAINED( pxBufferAddress ) vExampleDebugStatUpdate( iptraceID_NETWORK_BUFFER_OBTAINED, uxQueueMessagesWaiting( ( xQueueHandle ) xNetworkBufferSemaphore ) ) - #define iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxBufferAddress ) vExampleDebugStatUpdate( iptraceID_NETWORK_BUFFER_OBTAINED, uxQueueMessagesWaiting( ( xQueueHandle ) xNetworkBufferSemaphore ) ) - - #define iptraceNETWORK_EVENT_RECEIVED( eEvent ) { \ - uint16_t usSpace; \ - usSpace = ( uint16_t ) uxQueueMessagesWaiting( xNetworkEventQueue ); \ - /* Minus one as an event was removed before the space was queried. */ \ - usSpace = ( ipconfigEVENT_QUEUE_LENGTH - usSpace ) - 1; \ - vExampleDebugStatUpdate( iptraceID_NETWORK_EVENT_RECEIVED, usSpace ); \ - } - - #define iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER() vExampleDebugStatUpdate( iptraceID_FAILED_TO_OBTAIN_NETWORK_BUFFER, 0 ) - #define iptraceARP_TABLE_ENTRY_EXPIRED( ulIPAddress ) vExampleDebugStatUpdate( iptraceID_ARP_TABLE_ENTRY_EXPIRED, 0 ) - #define iptracePACKET_DROPPED_TO_GENERATE_ARP( ulIPAddress ) vExampleDebugStatUpdate( iptraceID_PACKET_DROPPED_TO_GENERATE_ARP, 0 ) - #define iptraceFAILED_TO_CREATE_SOCKET() vExampleDebugStatUpdate( iptraceID_FAILED_TO_CREATE_SOCKET, 0 ) - #define iptraceRECVFROM_DISCARDING_BYTES( xNumberOfBytesDiscarded ) vExampleDebugStatUpdate( iptraceID_RECVFROM_DISCARDING_BYTES, 0 ) - #define iptraceETHERNET_RX_EVENT_LOST() vExampleDebugStatUpdate( iptraceID_ETHERNET_RX_EVENT_LOST, 0 ) - #define iptraceSTACK_TX_EVENT_LOST( xEvent ) vExampleDebugStatUpdate( iptraceID_STACK_TX_EVENT_LOST, 0 ) - #define iptraceBIND_FAILED( xSocket, usPort ) vExampleDebugStatUpdate( ipconfigID_BIND_FAILED, 0 ) - #define iptraceNETWORK_INTERFACE_TRANSMIT() vExampleDebugStatUpdate( iptraceID_NETWORK_INTERFACE_TRANSMIT, 0 ) - #define iptraceRECVFROM_TIMEOUT() vExampleDebugStatUpdate( iptraceID_RECVFROM_TIMEOUT, 0 ) - #define iptraceSENDTO_DATA_TOO_LONG() vExampleDebugStatUpdate( iptraceID_SENDTO_DATA_TOO_LONG, 0 ) - #define iptraceSENDTO_SOCKET_NOT_BOUND() vExampleDebugStatUpdate( iptraceID_SENDTO_SOCKET_NOT_BOUND, 0 ) - #define iptraceNO_BUFFER_FOR_SENDTO() vExampleDebugStatUpdate( iptraceID_NO_BUFFER_FOR_SENDTO, 0 ) - #define iptraceWAITING_FOR_TX_DMA_DESCRIPTOR() vExampleDebugStatUpdate( iptraceID_WAIT_FOR_TX_DMA_DESCRIPTOR, 0 ) - #define iptraceFAILED_TO_NOTIFY_SELECT_GROUP( xSocket ) vExampleDebugStatUpdate( iptraceID_FAILED_TO_NOTIFY_SELECT_GROUP, 0 ) - #define iptraceNETWORK_INTERFACE_RECEIVE() vExampleDebugStatUpdate( iptraceID_NETWORK_INTERFACE_RECEIVE, 0 ) - - /* - * The function that updates a line in the xIPTraceValues table. - */ - void vExampleDebugStatUpdate( uint8_t ucIdentifier, uint32_t ulValue ); - - /* - * Returns the number of entries in the xIPTraceValues table. - */ - BaseType_t xExampleDebugStatEntries( void ); - -#endif /* configINCLUDE_DEMO_DEBUG_STATS == 1 */ - - -#endif /* DEMO_IP_TRACE_MACROS_H */ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * This file, along with DemoIPTrace.h, provides a basic example use of the + * FreeRTOS+UDP trace macros. The statistics gathered here can be viewed in + * the command line interface. + * See http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/UDP_IP_Trace.shtml + */ + +#ifndef DEMO_IP_TRACE_MACROS_H +#define DEMO_IP_TRACE_MACROS_H + +typedef void ( * vTraceAction_t )( uint32_t *, + uint32_t ); + +/* Type that defines each statistic being gathered. */ +typedef struct ExampleDebugStatEntry +{ + uint8_t ucIdentifier; /* Unique identifier for statistic. */ + const uint8_t * const pucDescription; /* Text description for the statistic. */ + vTraceAction_t vPerformAction; /* Action to perform when the statistic is updated (increment counter, store minimum value, store maximum value, etc. */ + uint32_t ulData; /* The meaning of this data is dependent on the trace macro ID. */ +} xExampleDebugStatEntry_t; + +/* Unique identifiers used to locate the entry for each trace macro in the + * xIPTraceValues[] table defined in DemoIPTrace.c. */ +#define iptraceID_NETWORK_INTERFACE_RECEIVE 0 +#define iptraceID_NETWORK_INTERFACE_TRANSMIT 1 +#define iptraceID_PACKET_DROPPED_TO_GENERATE_ARP 2 + +/* Do not change IDs above this line as the ID is shared with a FreeRTOS+Nabto + * demo. */ +#define iptraceID_NETWORK_BUFFER_OBTAINED 3 +#define iptraceID_NETWORK_BUFFER_OBTAINED_FROM_ISR 4 +#define iptraceID_NETWORK_EVENT_RECEIVED 5 +#define iptraceID_FAILED_TO_OBTAIN_NETWORK_BUFFER 6 +#define iptraceID_ARP_TABLE_ENTRY_EXPIRED 7 +#define iptraceID_FAILED_TO_CREATE_SOCKET 8 +#define iptraceID_RECVFROM_DISCARDING_BYTES 9 +#define iptraceID_ETHERNET_RX_EVENT_LOST 10 +#define iptraceID_STACK_TX_EVENT_LOST 11 +#define ipconfigID_BIND_FAILED 12 +#define iptraceID_RECVFROM_TIMEOUT 13 +#define iptraceID_SENDTO_DATA_TOO_LONG 14 +#define iptraceID_SENDTO_SOCKET_NOT_BOUND 15 +#define iptraceID_NO_BUFFER_FOR_SENDTO 16 +#define iptraceID_WAIT_FOR_TX_DMA_DESCRIPTOR 17 +#define iptraceID_FAILED_TO_NOTIFY_SELECT_GROUP 18 + +/* It is possible to remove the trace macros using the + * configINCLUDE_DEMO_DEBUG_STATS setting in FreeRTOSIPConfig.h. */ +#if configINCLUDE_DEMO_DEBUG_STATS == 1 + +/* The trace macro definitions themselves. Any trace macros left undefined + * will default to be empty macros. */ + #define iptraceNETWORK_BUFFER_OBTAINED( pxBufferAddress ) vExampleDebugStatUpdate( iptraceID_NETWORK_BUFFER_OBTAINED, uxQueueMessagesWaiting( ( xQueueHandle ) xNetworkBufferSemaphore ) ) + #define iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxBufferAddress ) vExampleDebugStatUpdate( iptraceID_NETWORK_BUFFER_OBTAINED, uxQueueMessagesWaiting( ( xQueueHandle ) xNetworkBufferSemaphore ) ) + + #define iptraceNETWORK_EVENT_RECEIVED( eEvent ) \ + { \ + uint16_t usSpace; \ + usSpace = ( uint16_t ) uxQueueMessagesWaiting( xNetworkEventQueue ); \ + /* Minus one as an event was removed before the space was queried. */ \ + usSpace = ( ipconfigEVENT_QUEUE_LENGTH - usSpace ) - 1; \ + vExampleDebugStatUpdate( iptraceID_NETWORK_EVENT_RECEIVED, usSpace ); \ + } + + #define iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER() vExampleDebugStatUpdate( iptraceID_FAILED_TO_OBTAIN_NETWORK_BUFFER, 0 ) + #define iptraceARP_TABLE_ENTRY_EXPIRED( ulIPAddress ) vExampleDebugStatUpdate( iptraceID_ARP_TABLE_ENTRY_EXPIRED, 0 ) + #define iptracePACKET_DROPPED_TO_GENERATE_ARP( ulIPAddress ) vExampleDebugStatUpdate( iptraceID_PACKET_DROPPED_TO_GENERATE_ARP, 0 ) + #define iptraceFAILED_TO_CREATE_SOCKET() vExampleDebugStatUpdate( iptraceID_FAILED_TO_CREATE_SOCKET, 0 ) + #define iptraceRECVFROM_DISCARDING_BYTES( xNumberOfBytesDiscarded ) vExampleDebugStatUpdate( iptraceID_RECVFROM_DISCARDING_BYTES, 0 ) + #define iptraceETHERNET_RX_EVENT_LOST() vExampleDebugStatUpdate( iptraceID_ETHERNET_RX_EVENT_LOST, 0 ) + #define iptraceSTACK_TX_EVENT_LOST( xEvent ) vExampleDebugStatUpdate( iptraceID_STACK_TX_EVENT_LOST, 0 ) + #define iptraceBIND_FAILED( xSocket, usPort ) vExampleDebugStatUpdate( ipconfigID_BIND_FAILED, 0 ) + #define iptraceNETWORK_INTERFACE_TRANSMIT() vExampleDebugStatUpdate( iptraceID_NETWORK_INTERFACE_TRANSMIT, 0 ) + #define iptraceRECVFROM_TIMEOUT() vExampleDebugStatUpdate( iptraceID_RECVFROM_TIMEOUT, 0 ) + #define iptraceSENDTO_DATA_TOO_LONG() vExampleDebugStatUpdate( iptraceID_SENDTO_DATA_TOO_LONG, 0 ) + #define iptraceSENDTO_SOCKET_NOT_BOUND() vExampleDebugStatUpdate( iptraceID_SENDTO_SOCKET_NOT_BOUND, 0 ) + #define iptraceNO_BUFFER_FOR_SENDTO() vExampleDebugStatUpdate( iptraceID_NO_BUFFER_FOR_SENDTO, 0 ) + #define iptraceWAITING_FOR_TX_DMA_DESCRIPTOR() vExampleDebugStatUpdate( iptraceID_WAIT_FOR_TX_DMA_DESCRIPTOR, 0 ) + #define iptraceFAILED_TO_NOTIFY_SELECT_GROUP( xSocket ) vExampleDebugStatUpdate( iptraceID_FAILED_TO_NOTIFY_SELECT_GROUP, 0 ) + #define iptraceNETWORK_INTERFACE_RECEIVE() vExampleDebugStatUpdate( iptraceID_NETWORK_INTERFACE_RECEIVE, 0 ) + +/* + * The function that updates a line in the xIPTraceValues table. + */ + void vExampleDebugStatUpdate( uint8_t ucIdentifier, + uint32_t ulValue ); + +/* + * Returns the number of entries in the xIPTraceValues table. + */ + BaseType_t xExampleDebugStatEntries( void ); + +#endif /* configINCLUDE_DEMO_DEBUG_STATS == 1 */ + + +#endif /* DEMO_IP_TRACE_MACROS_H */ diff --git a/FreeRTOS-Plus/Demo/Common/Logging/windows/Logging_WinSim.c b/FreeRTOS-Plus/Demo/Common/Logging/windows/Logging_WinSim.c index 0b2244381..dd0c9a601 100644 --- a/FreeRTOS-Plus/Demo/Common/Logging/windows/Logging_WinSim.c +++ b/FreeRTOS-Plus/Demo/Common/Logging/windows/Logging_WinSim.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -160,83 +160,82 @@ void vLoggingInit( BaseType_t xLogToStdout, configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED ); #if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) ) + { + HANDLE Win32Thread; + + /* Record which output methods are to be used. */ + xStdoutLoggingUsed = xLogToStdout; + xDiskFileLoggingUsed = xLogToFile; + xUDPLoggingUsed = xLogToUDP; + + /* If a disk file is used then initialize it now. */ + if( xDiskFileLoggingUsed != pdFALSE ) { - HANDLE Win32Thread; - - /* Record which output methods are to be used. */ - xStdoutLoggingUsed = xLogToStdout; - xDiskFileLoggingUsed = xLogToFile; - xUDPLoggingUsed = xLogToUDP; - - /* If a disk file is used then initialize it now. */ - if( xDiskFileLoggingUsed != pdFALSE ) - { - prvFileLoggingInit(); - } - - /* If UDP logging is used then store the address to which the log data - * will be sent - but don't create the socket yet because the network is - * not initialized. */ - if( xUDPLoggingUsed != pdFALSE ) - { - /* Set the address to which the print messages are sent. */ - xPrintUDPAddress.sin_port = FreeRTOS_htons( usRemotePort ); - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xPrintUDPAddress.sin_address.ulIP_IPv4 = ulRemoteIPAddress; - } - #else - { - xPrintUDPAddress.sin_addr = ulRemoteIPAddress; - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xPrintUDPAddress.sin_family = FREERTOS_AF_INET; - - } - - /* If a disk file or stdout are to be used then Win32 system calls will - * have to be made. Such system calls cannot be made from FreeRTOS tasks - * so create a stream buffer to pass the messages to a Win32 thread, then - * create the thread itself, along with a Win32 event that can be used to - * unblock the thread. */ - if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) - { - /* Create the buffer. */ - xLogStreamBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) + dlLOGGING_STREAM_BUFFER_SIZE + 1 ); - configASSERT( xLogStreamBuffer ); - memset( xLogStreamBuffer, '\0', sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) ); - xLogStreamBuffer->LENGTH = dlLOGGING_STREAM_BUFFER_SIZE + 1; - - /* Create the Windows event. */ - pvLoggingThreadEvent = CreateEvent( NULL, FALSE, TRUE, "StdoutLoggingEvent" ); - - /* Create the thread itself. */ - Win32Thread = CreateThread( - NULL, /* Pointer to thread security attributes. */ - 0, /* Initial thread stack size, in bytes. */ - prvWin32LoggingThread, /* Pointer to thread function. */ - NULL, /* Argument for new thread. */ - 0, /* Creation flags. */ - NULL ); - - /* Use the cores that are not used by the FreeRTOS tasks. */ - SetThreadAffinityMask( Win32Thread, ~0x01u ); - SetThreadPriorityBoost( Win32Thread, TRUE ); - SetThreadPriority( Win32Thread, THREAD_PRIORITY_IDLE ); - } + prvFileLoggingInit(); } + + /* If UDP logging is used then store the address to which the log data + * will be sent - but don't create the socket yet because the network is + * not initialized. */ + if( xUDPLoggingUsed != pdFALSE ) + { + /* Set the address to which the print messages are sent. */ + xPrintUDPAddress.sin_port = FreeRTOS_htons( usRemotePort ); + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xPrintUDPAddress.sin_address.ulIP_IPv4 = ulRemoteIPAddress; + } + #else + { + xPrintUDPAddress.sin_addr = ulRemoteIPAddress; + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xPrintUDPAddress.sin_family = FREERTOS_AF_INET; + } + + /* If a disk file or stdout are to be used then Win32 system calls will + * have to be made. Such system calls cannot be made from FreeRTOS tasks + * so create a stream buffer to pass the messages to a Win32 thread, then + * create the thread itself, along with a Win32 event that can be used to + * unblock the thread. */ + if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) + { + /* Create the buffer. */ + xLogStreamBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) + dlLOGGING_STREAM_BUFFER_SIZE + 1 ); + configASSERT( xLogStreamBuffer ); + memset( xLogStreamBuffer, '\0', sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) ); + xLogStreamBuffer->LENGTH = dlLOGGING_STREAM_BUFFER_SIZE + 1; + + /* Create the Windows event. */ + pvLoggingThreadEvent = CreateEvent( NULL, FALSE, TRUE, "StdoutLoggingEvent" ); + + /* Create the thread itself. */ + Win32Thread = CreateThread( + NULL, /* Pointer to thread security attributes. */ + 0, /* Initial thread stack size, in bytes. */ + prvWin32LoggingThread, /* Pointer to thread function. */ + NULL, /* Argument for new thread. */ + 0, /* Creation flags. */ + NULL ); + + /* Use the cores that are not used by the FreeRTOS tasks. */ + SetThreadAffinityMask( Win32Thread, ~0x01u ); + SetThreadPriorityBoost( Win32Thread, TRUE ); + SetThreadPriority( Win32Thread, THREAD_PRIORITY_IDLE ); + } + } #else /* if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) ) */ - { - /* FreeRTOSIPConfig is set such that no print messages will be output. - * Avoid compiler warnings about unused parameters. */ - ( void ) xLogToStdout; - ( void ) xLogToFile; - ( void ) xLogToUDP; - ( void ) usRemotePort; - ( void ) ulRemoteIPAddress; - } + { + /* FreeRTOSIPConfig is set such that no print messages will be output. + * Avoid compiler warnings about unused parameters. */ + ( void ) xLogToStdout; + ( void ) xLogToFile; + ( void ) xLogToUDP; + ( void ) usRemotePort; + ( void ) ulRemoteIPAddress; + } #endif /* ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) */ } /*-----------------------------------------------------------*/ @@ -549,8 +548,8 @@ static void prvLogToFile( const char * pcMessage, } /*-----------------------------------------------------------*/ -void vPlatformInitLogging(void) +void vPlatformInitLogging( void ) { - vLoggingInit(pdTRUE, pdFALSE, pdFALSE, 0U, 0U); + vLoggingInit( pdTRUE, pdFALSE, pdFALSE, 0U, 0U ); } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/freertos_agent_message.c b/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/freertos_agent_message.c index ef0168b5f..3d2ae6b14 100644 --- a/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/freertos_agent_message.c +++ b/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/freertos_agent_message.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/freertos_command_pool.c b/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/freertos_command_pool.c index 3180f7926..153a18c4d 100644 --- a/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/freertos_command_pool.c +++ b/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/freertos_command_pool.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -80,7 +80,7 @@ void Agent_InitializePool( void ) { memset( ( void * ) commandStructurePool, 0x00, sizeof( commandStructurePool ) ); commandStructMessageCtx.queue = xQueueCreate( MQTT_COMMAND_CONTEXTS_POOL_SIZE, - sizeof( MQTTAgentCommand_t * ) ); + sizeof( MQTTAgentCommand_t * ) ); configASSERT( commandStructMessageCtx.queue ); /* Populate the queue. */ diff --git a/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/include/freertos_agent_message.h b/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/include/freertos_agent_message.h index dde922518..44f7ebb1b 100644 --- a/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/include/freertos_agent_message.h +++ b/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/include/freertos_agent_message.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/include/freertos_command_pool.h b/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/include/freertos_command_pool.h index 116cc14e3..46418ae78 100644 --- a/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/include/freertos_command_pool.h +++ b/FreeRTOS-Plus/Demo/Common/coreMQTT_Agent_Interface/include/freertos_command_pool.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/MutualAuthMQTTExample.c b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/MutualAuthMQTTExample.c index a072b753b..9d06bf899 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/MutualAuthMQTTExample.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/MutualAuthMQTTExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -635,41 +635,43 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkCredent uint16_t usNextRetryBackOff = 0U; #ifdef democonfigUSE_AWS_IOT_CORE_BROKER - #if defined( democonfigCLIENT_USERNAME ) - /* - * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect - * to AWS IoT Core with Custom Authentication on port 443. - * - * Custom Authentication uses the contents of the username and password - * fields of the MQTT CONNECT packet to authenticate the client. - * - * For more information, refer to the documentation at: - * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html - */ - static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; - #if democonfigMQTT_BROKER_PORT != 443U - #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." - #endif /* democonfigMQTT_BROKER_PORT != 443U */ - #else /* if !defined( democonfigCLIENT_USERNAME ) */ - /* - * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using - * x509 Certificate Authentication. - */ - static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; - #endif /* !defined( democonfigCLIENT_USERNAME ) */ + #if defined( democonfigCLIENT_USERNAME ) /* - * An ALPN identifier is only required when connecting to AWS IoT core on port 443. - * https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html + * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect + * to AWS IoT Core with Custom Authentication on port 443. + * + * Custom Authentication uses the contents of the username and password + * fields of the MQTT CONNECT packet to authenticate the client. + * + * For more information, refer to the documentation at: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html */ - #if democonfigMQTT_BROKER_PORT == 443U - pxNetworkCredentials->pAlpnProtos = ppcAlpnProtocols; - #elif democonfigMQTT_BROKER_PORT == 8883U - pxNetworkCredentials->pAlpnProtos = NULL; - #else /* democonfigMQTT_BROKER_PORT != 8883U */ - pxNetworkCredentials->pAlpnProtos = NULL; - #error "MQTT connections to AWS IoT Core are only allowed on ports 443 and 8883." + static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; + #if democonfigMQTT_BROKER_PORT != 443U + #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." #endif /* democonfigMQTT_BROKER_PORT != 443U */ + #else /* if !defined( democonfigCLIENT_USERNAME ) */ + + /* + * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using + * x509 Certificate Authentication. + */ + static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; + #endif /* !defined( democonfigCLIENT_USERNAME ) */ + + /* + * An ALPN identifier is only required when connecting to AWS IoT core on port 443. + * https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html + */ + #if democonfigMQTT_BROKER_PORT == 443U + pxNetworkCredentials->pAlpnProtos = ppcAlpnProtocols; + #elif democonfigMQTT_BROKER_PORT == 8883U + pxNetworkCredentials->pAlpnProtos = NULL; + #else /* democonfigMQTT_BROKER_PORT != 8883U */ + pxNetworkCredentials->pAlpnProtos = NULL; + #error "MQTT connections to AWS IoT Core are only allowed on ports 443 and 8883." + #endif /* democonfigMQTT_BROKER_PORT != 443U */ #else /* ifdef democonfigUSE_AWS_IOT_CORE_BROKER */ pxNetworkCredentials->pAlpnProtos = NULL; #endif /* ifdef democonfigUSE_AWS_IOT_CORE_BROKER */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_platform.c b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_platform.c index bb870eafe..d676d4768 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_platform.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_platform.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_platform.h b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_platform.h index fe718fc89..526dd7836 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_platform.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_platform.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -41,7 +41,7 @@ * @brief Cellular library log configuration. * * Cellular library use CellularLogLevel macro for logging. - * The prototye of these logging function is similar with printf with return type ignored. + * The prototype of these logging function is similar with printf with return type ignored. * */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_setup.c b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_setup.c index 536bb3dbd..436b70d64 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_setup.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/cellular_setup.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/comm_if_windows.c b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/comm_if_windows.c index d0b92501f..4412df1d9 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/comm_if_windows.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/comm_if_windows.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/core_mqtt_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/core_mqtt_config.h index ff8d0fae8..5f293106c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/core_mqtt_config.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/core_mqtt_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/main.c index 5275330ee..c15576f49 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/Common/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/cellular_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/cellular_config.h index fe63627c4..0e7bd7285 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/cellular_config.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/cellular_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/demo_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/demo_config.h index 48615df52..c7602d119 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/demo_config.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.sln index b57e3595a..58c08157f 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.sln +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.sln @@ -1,86 +1,86 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mqtt_mutual_auth_demo_with_bg96", "mqtt_mutual_auth_demo_with_bg96.vcxproj", "{D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{68385DE7-AC0F-4213-BEEA-D07E484C093E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.ActiveCfg = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.Build.0 = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.ActiveCfg = Debug|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.Build.0 = Debug|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.ActiveCfg = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.Build.0 = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.ActiveCfg = Release|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.Build.0 = Release|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.ActiveCfg = Release|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.Build.0 = Release|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.ActiveCfg = Release|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {72C209C4-49A4-4942-A201-44706C9D77EC} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {1D441E01-8E23-4433-9EF0-63467713C0F0} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mqtt_mutual_auth_demo_with_bg96", "mqtt_mutual_auth_demo_with_bg96.vcxproj", "{D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{68385DE7-AC0F-4213-BEEA-D07E484C093E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.ActiveCfg = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.Build.0 = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.ActiveCfg = Debug|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.Build.0 = Debug|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.ActiveCfg = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.Build.0 = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.ActiveCfg = Release|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.Build.0 = Release|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.ActiveCfg = Release|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.Build.0 = Release|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.ActiveCfg = Release|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {72C209C4-49A4-4942-A201-44706C9D77EC} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1D441E01-8E23-4433-9EF0-63467713C0F0} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj index 8e358f883..6ff7568f4 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj @@ -1,214 +1,214 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {d5cd24a7-76ba-41ea-afd7-86decf58fbc1} - mqttmutualauthdemowithbg96 - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - Bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - true - true - true - WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - true - true - Bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - true - _DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {d5cd24a7-76ba-41ea-afd7-86decf58fbc1} + mqttmutualauthdemowithbg96 + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + Bcrypt.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + true + WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + true + true + Bcrypt.lib;%(AdditionalDependencies) + + + + + Level3 + true + _DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj.filters index 57563ced5..2ae20055a 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96/mqtt_mutual_auth_demo_with_bg96.vcxproj.filters @@ -1,228 +1,228 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {fd000e4f-72fc-4793-95d2-5e0fa48b3ba8} - - - {8c6a2636-5c23-4bdf-8a05-9f95aa04293b} - - - {4330017d-e8ce-4a33-b4ef-9fe90f2426b4} - - - {147245f8-ee3f-4145-92b9-a9f07163c51c} - - - {11d9ce61-9af6-408a-90fd-6978d46c94fc} - - - {d34ccce7-a7e3-45b3-9ab9-78519144db41} - - - {26846a50-0d36-4873-968c-cccdc24355b6} - - - {977bdebd-1f49-47ec-b2b3-67d5f57ff41b} - - - {f393698c-359c-48d8-a4e5-d53a5500025b} - - - {2a115a7b-70ed-468c-b3ac-2d584c4ef779} - - - {86f3f8ab-e834-48a7-b935-036fe029ae73} - - - {4a4a9a7c-7ba4-4fb0-824b-23c838d77815} - - - {48ac0c9a-e1c2-47da-b315-0f23e97487c9} - - - {09ff68d7-878a-443b-9871-c5500b4cb673} - - - {3824b829-824c-4188-abc7-7304392c558f} - - - {f0330e9f-1e1a-4907-8acb-8dee46a4cc80} - - - {c1cf6a38-0503-40dd-a8de-0a37fb58160f} - - - {74cb620a-700c-4747-ac17-325628423dc0} - - - {3e89de57-dda5-42f7-839b-a70f06891aed} - - - {e6dd4447-6a83-4ce8-8742-8973f5884c20} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\Backoff Algorithm - - - Additional Network Transport Files\TCP Sockets Wrapper\ports\cellular - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - - - Header Files - - - Additional Libraries\FreeRTOS Cellular Interface\include - - - Additional Libraries\FreeRTOS Cellular Interface\include - - - Additional Libraries\FreeRTOS Cellular Interface\include - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\interface - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\interface - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\Backoff Algorithm\include - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Config - - - Config - - - Config - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {fd000e4f-72fc-4793-95d2-5e0fa48b3ba8} + + + {8c6a2636-5c23-4bdf-8a05-9f95aa04293b} + + + {4330017d-e8ce-4a33-b4ef-9fe90f2426b4} + + + {147245f8-ee3f-4145-92b9-a9f07163c51c} + + + {11d9ce61-9af6-408a-90fd-6978d46c94fc} + + + {d34ccce7-a7e3-45b3-9ab9-78519144db41} + + + {26846a50-0d36-4873-968c-cccdc24355b6} + + + {977bdebd-1f49-47ec-b2b3-67d5f57ff41b} + + + {f393698c-359c-48d8-a4e5-d53a5500025b} + + + {2a115a7b-70ed-468c-b3ac-2d584c4ef779} + + + {86f3f8ab-e834-48a7-b935-036fe029ae73} + + + {4a4a9a7c-7ba4-4fb0-824b-23c838d77815} + + + {48ac0c9a-e1c2-47da-b315-0f23e97487c9} + + + {09ff68d7-878a-443b-9871-c5500b4cb673} + + + {3824b829-824c-4188-abc7-7304392c558f} + + + {f0330e9f-1e1a-4907-8acb-8dee46a4cc80} + + + {c1cf6a38-0503-40dd-a8de-0a37fb58160f} + + + {74cb620a-700c-4747-ac17-325628423dc0} + + + {3e89de57-dda5-42f7-839b-a70f06891aed} + + + {e6dd4447-6a83-4ce8-8742-8973f5884c20} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\Backoff Algorithm + + + Additional Network Transport Files\TCP Sockets Wrapper\ports\cellular + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + + + Header Files + + + Additional Libraries\FreeRTOS Cellular Interface\include + + + Additional Libraries\FreeRTOS Cellular Interface\include + + + Additional Libraries\FreeRTOS Cellular Interface\include + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\interface + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\interface + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\Backoff Algorithm\include + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Config + + + Config + + + Config + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/cellular_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/cellular_config.h index 4dcd1d344..81d79aa78 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/cellular_config.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/cellular_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/demo_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/demo_config.h index 1486ee8c3..9a15cc980 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/demo_config.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.sln index f1187f9b8..ead372158 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.sln +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.sln @@ -1,86 +1,86 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mqtt_mutual_auth_demo_with_hl7802", "mqtt_mutual_auth_demo_with_hl7802.vcxproj", "{D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{68385DE7-AC0F-4213-BEEA-D07E484C093E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.ActiveCfg = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.Build.0 = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.ActiveCfg = Debug|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.Build.0 = Debug|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.ActiveCfg = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.Build.0 = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.ActiveCfg = Release|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.Build.0 = Release|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.ActiveCfg = Release|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.Build.0 = Release|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.ActiveCfg = Release|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {72C209C4-49A4-4942-A201-44706C9D77EC} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {1D441E01-8E23-4433-9EF0-63467713C0F0} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mqtt_mutual_auth_demo_with_hl7802", "mqtt_mutual_auth_demo_with_hl7802.vcxproj", "{D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{68385DE7-AC0F-4213-BEEA-D07E484C093E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.ActiveCfg = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.Build.0 = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.ActiveCfg = Debug|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.Build.0 = Debug|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.ActiveCfg = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.Build.0 = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.ActiveCfg = Release|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.Build.0 = Release|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.ActiveCfg = Release|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.Build.0 = Release|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.ActiveCfg = Release|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {72C209C4-49A4-4942-A201-44706C9D77EC} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1D441E01-8E23-4433-9EF0-63467713C0F0} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj index 9869056cd..05788e491 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj @@ -1,215 +1,215 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {d5cd24a7-76ba-41ea-afd7-86decf58fbc1} - mqttmutualauthdemowithbg96 - 10.0 - mqtt_mutual_auth_demo_with_hl7802 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - Bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - true - true - true - WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - true - true - Bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - true - _DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {d5cd24a7-76ba-41ea-afd7-86decf58fbc1} + mqttmutualauthdemowithbg96 + 10.0 + mqtt_mutual_auth_demo_with_hl7802 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + Bcrypt.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + true + WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + true + true + Bcrypt.lib;%(AdditionalDependencies) + + + + + Level3 + true + _DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj.filters index 4a8ab122f..7b17bbbdc 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802/mqtt_mutual_auth_demo_with_hl7802.vcxproj.filters @@ -1,228 +1,228 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {fd000e4f-72fc-4793-95d2-5e0fa48b3ba8} - - - {8c6a2636-5c23-4bdf-8a05-9f95aa04293b} - - - {4330017d-e8ce-4a33-b4ef-9fe90f2426b4} - - - {147245f8-ee3f-4145-92b9-a9f07163c51c} - - - {11d9ce61-9af6-408a-90fd-6978d46c94fc} - - - {d34ccce7-a7e3-45b3-9ab9-78519144db41} - - - {26846a50-0d36-4873-968c-cccdc24355b6} - - - {977bdebd-1f49-47ec-b2b3-67d5f57ff41b} - - - {f393698c-359c-48d8-a4e5-d53a5500025b} - - - {2a115a7b-70ed-468c-b3ac-2d584c4ef779} - - - {86f3f8ab-e834-48a7-b935-036fe029ae73} - - - {4a4a9a7c-7ba4-4fb0-824b-23c838d77815} - - - {a5116c0a-c100-45ea-a882-d6165bd7a055} - - - {85455479-e6b8-4784-a3c5-84b333dafe06} - - - {36e39a09-53d2-4111-9895-c5e96fe3d6c0} - - - {38d73a05-735d-4b33-b4d4-bcdc42685a96} - - - {63387c13-d63e-4ee9-8419-a1a45dbe7d20} - - - {8cece65f-2b2c-498d-855e-b30c9b015818} - - - {4ed0088a-6009-4690-94f1-d8350dcb5608} - - - {3bae7ac0-1bab-4a6f-8267-1240f1867c43} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\Backoff Algorithm - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper\ports\cellular - - - - - Header Files - - - Additional Libraries\FreeRTOS Cellular Interface\include - - - Additional Libraries\FreeRTOS Cellular Interface\include - - - Additional Libraries\FreeRTOS Cellular Interface\include - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\interface - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\interface - - - Additional Libraries\Backoff Algorithm\include - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Config - - - Config - - - Config - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {fd000e4f-72fc-4793-95d2-5e0fa48b3ba8} + + + {8c6a2636-5c23-4bdf-8a05-9f95aa04293b} + + + {4330017d-e8ce-4a33-b4ef-9fe90f2426b4} + + + {147245f8-ee3f-4145-92b9-a9f07163c51c} + + + {11d9ce61-9af6-408a-90fd-6978d46c94fc} + + + {d34ccce7-a7e3-45b3-9ab9-78519144db41} + + + {26846a50-0d36-4873-968c-cccdc24355b6} + + + {977bdebd-1f49-47ec-b2b3-67d5f57ff41b} + + + {f393698c-359c-48d8-a4e5-d53a5500025b} + + + {2a115a7b-70ed-468c-b3ac-2d584c4ef779} + + + {86f3f8ab-e834-48a7-b935-036fe029ae73} + + + {4a4a9a7c-7ba4-4fb0-824b-23c838d77815} + + + {a5116c0a-c100-45ea-a882-d6165bd7a055} + + + {85455479-e6b8-4784-a3c5-84b333dafe06} + + + {36e39a09-53d2-4111-9895-c5e96fe3d6c0} + + + {38d73a05-735d-4b33-b4d4-bcdc42685a96} + + + {63387c13-d63e-4ee9-8419-a1a45dbe7d20} + + + {8cece65f-2b2c-498d-855e-b30c9b015818} + + + {4ed0088a-6009-4690-94f1-d8350dcb5608} + + + {3bae7ac0-1bab-4a6f-8267-1240f1867c43} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\Backoff Algorithm + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper\ports\cellular + + + + + Header Files + + + Additional Libraries\FreeRTOS Cellular Interface\include + + + Additional Libraries\FreeRTOS Cellular Interface\include + + + Additional Libraries\FreeRTOS Cellular Interface\include + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\interface + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\interface + + + Additional Libraries\Backoff Algorithm\include + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Config + + + Config + + + Config + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/cellular_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/cellular_config.h index cdb204ad6..665792541 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/cellular_config.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/cellular_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/demo_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/demo_config.h index db4c5a825..d73ec8328 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/demo_config.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.sln index 2b3e043e1..0e190eb4c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.sln +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.sln @@ -1,86 +1,86 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mqtt_mutual_auth_demo_with_sara_r4", "mqtt_mutual_auth_demo_with_sara_r4.vcxproj", "{D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{68385DE7-AC0F-4213-BEEA-D07E484C093E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.ActiveCfg = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.Build.0 = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.ActiveCfg = Debug|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.Build.0 = Debug|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.ActiveCfg = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.Build.0 = Debug|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.ActiveCfg = Release|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.Build.0 = Release|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.ActiveCfg = Release|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.Build.0 = Release|x64 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.ActiveCfg = Release|Win32 - {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {72C209C4-49A4-4942-A201-44706C9D77EC} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {1D441E01-8E23-4433-9EF0-63467713C0F0} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mqtt_mutual_auth_demo_with_sara_r4", "mqtt_mutual_auth_demo_with_sara_r4.vcxproj", "{D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{68385DE7-AC0F-4213-BEEA-D07E484C093E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.ActiveCfg = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|Win32.Build.0 = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.ActiveCfg = Debug|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x64.Build.0 = Debug|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.ActiveCfg = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Debug|x86.Build.0 = Debug|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.ActiveCfg = Release|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|Win32.Build.0 = Release|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.ActiveCfg = Release|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x64.Build.0 = Release|x64 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.ActiveCfg = Release|Win32 + {D5CD24A7-76BA-41EA-AFD7-86DECF58FBC1}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {72C209C4-49A4-4942-A201-44706C9D77EC} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {68385DE7-AC0F-4213-BEEA-D07E484C093E} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1D441E01-8E23-4433-9EF0-63467713C0F0} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj index 50823aab3..d54a6c9e2 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj @@ -1,214 +1,214 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {d5cd24a7-76ba-41ea-afd7-86decf58fbc1} - mqttmutualauthdemowithbg96 - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - Bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - true - true - true - WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - true - true - Bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - true - _DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {d5cd24a7-76ba-41ea-afd7-86decf58fbc1} + mqttmutualauthdemowithbg96 + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + Bcrypt.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + true + WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + true + true + Bcrypt.lib;%(AdditionalDependencies) + + + + + Level3 + true + _DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\common;..\..\..\Source\FreeRTOS-Cellular-Interface\source\include\private;..\..\..\Source\FreeRTOS-Cellular-Interface\source\interface + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj.filters index b1d85f14b..ce5a11d31 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4/mqtt_mutual_auth_demo_with_sara_r4.vcxproj.filters @@ -1,228 +1,228 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {fd000e4f-72fc-4793-95d2-5e0fa48b3ba8} - - - {8c6a2636-5c23-4bdf-8a05-9f95aa04293b} - - - {4330017d-e8ce-4a33-b4ef-9fe90f2426b4} - - - {147245f8-ee3f-4145-92b9-a9f07163c51c} - - - {cbdf44f0-db7f-42c2-ae96-24d259e6e332} - - - {9cad7110-9e0a-4163-be95-cd4f315981a2} - - - {6e47bf5b-1377-42ae-8d6c-90f991098e3c} - - - {4b61408f-b7b6-4429-99c0-e2838783b9d1} - - - {efefb746-fa37-480c-b69a-3dfd4eba185c} - - - {49b552ec-46e2-4c6f-9319-bab996222351} - - - {29660682-b7ab-4477-976e-624fcab8a457} - - - {0bd56135-b029-4437-92a2-be306153fd72} - - - {11d9ce61-9af6-408a-90fd-6978d46c94fc} - - - {d34ccce7-a7e3-45b3-9ab9-78519144db41} - - - {26846a50-0d36-4873-968c-cccdc24355b6} - - - {977bdebd-1f49-47ec-b2b3-67d5f57ff41b} - - - {f393698c-359c-48d8-a4e5-d53a5500025b} - - - {2a115a7b-70ed-468c-b3ac-2d584c4ef779} - - - {86f3f8ab-e834-48a7-b935-036fe029ae73} - - - {4a4a9a7c-7ba4-4fb0-824b-23c838d77815} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\FreeRTOS Cellular Interface - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\Backoff Algorithm - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Additional Network Transport Files\TCP Sockets Wrapper\ports\cellular - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - - - Header Files - - - Additional Libraries\FreeRTOS Cellular Interface\include - - - Additional Libraries\FreeRTOS Cellular Interface\include - - - Additional Libraries\FreeRTOS Cellular Interface\include - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\common - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\include\private - - - Additional Libraries\FreeRTOS Cellular Interface\interface - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\interface - - - Additional Libraries\Backoff Algorithm\include - - - Additional Libraries\FreeRTOS Cellular Interface\module - - - Config - - - Config - - - Config - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {fd000e4f-72fc-4793-95d2-5e0fa48b3ba8} + + + {8c6a2636-5c23-4bdf-8a05-9f95aa04293b} + + + {4330017d-e8ce-4a33-b4ef-9fe90f2426b4} + + + {147245f8-ee3f-4145-92b9-a9f07163c51c} + + + {cbdf44f0-db7f-42c2-ae96-24d259e6e332} + + + {9cad7110-9e0a-4163-be95-cd4f315981a2} + + + {6e47bf5b-1377-42ae-8d6c-90f991098e3c} + + + {4b61408f-b7b6-4429-99c0-e2838783b9d1} + + + {efefb746-fa37-480c-b69a-3dfd4eba185c} + + + {49b552ec-46e2-4c6f-9319-bab996222351} + + + {29660682-b7ab-4477-976e-624fcab8a457} + + + {0bd56135-b029-4437-92a2-be306153fd72} + + + {11d9ce61-9af6-408a-90fd-6978d46c94fc} + + + {d34ccce7-a7e3-45b3-9ab9-78519144db41} + + + {26846a50-0d36-4873-968c-cccdc24355b6} + + + {977bdebd-1f49-47ec-b2b3-67d5f57ff41b} + + + {f393698c-359c-48d8-a4e5-d53a5500025b} + + + {2a115a7b-70ed-468c-b3ac-2d584c4ef779} + + + {86f3f8ab-e834-48a7-b935-036fe029ae73} + + + {4a4a9a7c-7ba4-4fb0-824b-23c838d77815} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\FreeRTOS Cellular Interface + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\Backoff Algorithm + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Additional Network Transport Files\TCP Sockets Wrapper\ports\cellular + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + + + Header Files + + + Additional Libraries\FreeRTOS Cellular Interface\include + + + Additional Libraries\FreeRTOS Cellular Interface\include + + + Additional Libraries\FreeRTOS Cellular Interface\include + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\common + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\include\private + + + Additional Libraries\FreeRTOS Cellular Interface\interface + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\interface + + + Additional Libraries\Backoff Algorithm\include + + + Additional Libraries\FreeRTOS Cellular Interface\module + + + Config + + + Config + + + Config + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c index 1f0852236..8b34f653c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c @@ -1,386 +1,405 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* Standard Includes */ -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -/* FreeRTOS+Trace includes.*/ -#include "trcDefines.h" -#include "trcRecorder.h" - -/* - * Writes trace data to a disk file when the trace recording is stopped. - * This function will simply overwrite any trace files that already exist. - */ -static void prvSaveTraceFile( void ); - -/* - * Defines a command that returns a table showing the state of each task at the - * time the command is called. - */ -static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Defines a command that returns a table showing how much time each task has - * spent in the Running state. - */ -static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Defines a command that expects exactly three parameters. Each of the three - * parameter are echoed back one at a time. - */ -static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Defines a command that can take a variable number of parameters. Each - * parameter is echoes back one at a time. - */ -static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Defines a command that starts/stops events being recorded for offline viewing - * in FreeRTOS+Trace. - */ -static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* Structure that defines the "run-time-stats" command line command. */ -static const CLI_Command_Definition_t xRunTimeStats = -{ - "run-time-stats", /* The command string to type. */ - "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n", - prvRunTimeStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the "task-stats" command line command. */ -static const CLI_Command_Definition_t xTaskStats = -{ - "task-stats", /* The command string to type. */ - "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n\r\n", - prvTaskStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the "echo_3_parameters" command line command. This -takes exactly three parameters that the command simply echos back one at a -time. */ -static const CLI_Command_Definition_t xThreeParameterEcho = -{ - "echo_3_parameters", - "\r\necho_3_parameters :\r\n Expects three parameters, echos each in turn\r\n\r\n", - prvThreeParameterEchoCommand, /* The function to run. */ - 3 /* Three parameters are expected, which can take any value. */ -}; - -/* Structure that defines the "echo_parameters" command line command. This -takes a variable number of parameters that the command simply echos back one at -a time. */ -static const CLI_Command_Definition_t xParameterEcho = -{ - "echo_parameters", - "\r\necho_parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n\r\n", - prvParameterEchoCommand, /* The function to run. */ - -1 /* The user can enter any number of commands. */ -}; - -/* Structure that defines the "trace" command line command. This takes a single -parameter, which can be either "start" or "stop". */ -static const CLI_Command_Definition_t xStartTrace = -{ - "trace", - "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n\r\n", - prvStartStopTraceCommand, /* The function to run. */ - 1 /* One parameter is expected. Valid values are "start" and "stop". */ -}; - -/*-----------------------------------------------------------*/ - -void vRegisterCLICommands( void ) -{ - /* Register all the command line commands defined immediately above. */ - FreeRTOS_CLIRegisterCommand( &xTaskStats ); - FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); - FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); - FreeRTOS_CLIRegisterCommand( &xParameterEcho ); - FreeRTOS_CLIRegisterCommand( &xStartTrace ); -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *const pcHeader = "Task State Priority Stack #\r\n************************************************\r\n"; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Generate a table of task stats. */ - strcpy( pcWriteBuffer, pcHeader ); - vTaskList( pcWriteBuffer + strlen( pcHeader ) ); - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char * const pcHeader = "Task Abs Time % Time\r\n****************************************\r\n"; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Generate a table of task stats. */ - strcpy( pcWriteBuffer, pcHeader ); - vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) ); - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t lParameterStringLength, xReturn; -static BaseType_t lParameterNumber = 0; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - if( lParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( pcWriteBuffer, "The three parameters were:\r\n" ); - - /* Next time the function is called the first parameter will be echoed - back. */ - lParameterNumber = 1L; - - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - lParameterNumber, /* Return the next parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( pcWriteBuffer, "%d: ", lParameterNumber ); - strncat( pcWriteBuffer, pcParameter, lParameterStringLength ); - strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - if( lParameterNumber == 3L ) - { - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - xReturn = pdFALSE; - lParameterNumber = 0L; - } - else - { - /* There are more parameters to return after this one. */ - xReturn = pdTRUE; - lParameterNumber++; - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t lParameterStringLength, xReturn; -static BaseType_t lParameterNumber = 0; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - if( lParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( pcWriteBuffer, "The parameters were:\r\n" ); - - /* Next time the function is called the first parameter will be echoed - back. */ - lParameterNumber = 1L; - - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - lParameterNumber, /* Return the next parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - if( pcParameter != NULL ) - { - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( pcWriteBuffer, "%d: ", lParameterNumber ); - strncat( pcWriteBuffer, pcParameter, lParameterStringLength ); - strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - - /* There might be more parameters to return after this one. */ - xReturn = pdTRUE; - lParameterNumber++; - } - else - { - /* No more parameters were found. Make sure the write buffer does - not contain a valid string. */ - pcWriteBuffer[ 0 ] = 0x00; - - /* No more data to return. */ - xReturn = pdFALSE; - - /* Start over the next time this command is executed. */ - lParameterNumber = 0; - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t lParameterStringLength; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* There are only two valid parameter values. */ - if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 ) - { - /* Start or restart the trace. */ - vTraceStop(); - vTraceClear(); - - vTraceEnable( TRC_START ); - traceSTART(); - - sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" ); - } - else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 ) - { - /* End the trace, if one is running. */ - vTraceStop(); - sprintf( pcWriteBuffer, "Stopping trace recording and dumping log to disk.\r\n" ); - prvSaveTraceFile(); - } - else - { - sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); - } - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static void prvSaveTraceFile( void ) -{ -FILE* pxOutputFile; - - fopen_s( &pxOutputFile, "Trace.dump", "wb"); - - if( pxOutputFile != NULL ) - { - fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile ); - fclose( pxOutputFile ); - printf( "\r\nTrace output saved to Trace.dump\r\n" ); - } - else - { - printf( "\r\nFailed to create trace dump file\r\n" ); - } -} - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard Includes */ +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* FreeRTOS+Trace includes.*/ +#include "trcDefines.h" +#include "trcRecorder.h" + +/* + * Writes trace data to a disk file when the trace recording is stopped. + * This function will simply overwrite any trace files that already exist. + */ +static void prvSaveTraceFile( void ); + +/* + * Defines a command that returns a table showing the state of each task at the + * time the command is called. + */ +static BaseType_t prvTaskStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Defines a command that returns a table showing how much time each task has + * spent in the Running state. + */ +static BaseType_t prvRunTimeStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Defines a command that expects exactly three parameters. Each of the three + * parameter are echoed back one at a time. + */ +static BaseType_t prvThreeParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Defines a command that can take a variable number of parameters. Each + * parameter is echoes back one at a time. + */ +static BaseType_t prvParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Defines a command that starts/stops events being recorded for offline viewing + * in FreeRTOS+Trace. + */ +static BaseType_t prvStartStopTraceCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* Structure that defines the "run-time-stats" command line command. */ +static const CLI_Command_Definition_t xRunTimeStats = +{ + "run-time-stats", /* The command string to type. */ + "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n", + prvRunTimeStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the "task-stats" command line command. */ +static const CLI_Command_Definition_t xTaskStats = +{ + "task-stats", /* The command string to type. */ + "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n\r\n", + prvTaskStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the "echo_3_parameters" command line command. This + * takes exactly three parameters that the command simply echos back one at a + * time. */ +static const CLI_Command_Definition_t xThreeParameterEcho = +{ + "echo_3_parameters", + "\r\necho_3_parameters :\r\n Expects three parameters, echos each in turn\r\n\r\n", + prvThreeParameterEchoCommand, /* The function to run. */ + 3 /* Three parameters are expected, which can take any value. */ +}; + +/* Structure that defines the "echo_parameters" command line command. This + * takes a variable number of parameters that the command simply echos back one at + * a time. */ +static const CLI_Command_Definition_t xParameterEcho = +{ + "echo_parameters", + "\r\necho_parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n\r\n", + prvParameterEchoCommand, /* The function to run. */ + -1 /* The user can enter any number of commands. */ +}; + +/* Structure that defines the "trace" command line command. This takes a single + * parameter, which can be either "start" or "stop". */ +static const CLI_Command_Definition_t xStartTrace = +{ + "trace", + "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n\r\n", + prvStartStopTraceCommand, /* The function to run. */ + 1 /* One parameter is expected. Valid values are "start" and "stop". */ +}; + +/*-----------------------------------------------------------*/ + +void vRegisterCLICommands( void ) +{ + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xTaskStats ); + FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); + FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); + FreeRTOS_CLIRegisterCommand( &xParameterEcho ); + FreeRTOS_CLIRegisterCommand( &xStartTrace ); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTaskStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * const pcHeader = "Task State Priority Stack #\r\n************************************************\r\n"; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( pcWriteBuffer, pcHeader ); + vTaskList( pcWriteBuffer + strlen( pcHeader ) ); + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvRunTimeStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * const pcHeader = "Task Abs Time % Time\r\n****************************************\r\n"; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( pcWriteBuffer, pcHeader ); + vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) ); + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvThreeParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t lParameterStringLength, xReturn; + static BaseType_t lParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( pcWriteBuffer, "The three parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + * back. */ + lParameterNumber = 1L; + + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( pcWriteBuffer, "%d: ", lParameterNumber ); + strncat( pcWriteBuffer, pcParameter, lParameterStringLength ); + strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + if( lParameterNumber == 3L ) + { + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + xReturn = pdFALSE; + lParameterNumber = 0L; + } + else + { + /* There are more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t lParameterStringLength, xReturn; + static BaseType_t lParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( pcWriteBuffer, "The parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + * back. */ + lParameterNumber = 1L; + + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + if( pcParameter != NULL ) + { + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( pcWriteBuffer, "%d: ", lParameterNumber ); + strncat( pcWriteBuffer, pcParameter, lParameterStringLength ); + strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* There might be more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + else + { + /* No more parameters were found. Make sure the write buffer does + * not contain a valid string. */ + pcWriteBuffer[ 0 ] = 0x00; + + /* No more data to return. */ + xReturn = pdFALSE; + + /* Start over the next time this command is executed. */ + lParameterNumber = 0; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvStartStopTraceCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t lParameterStringLength; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* There are only two valid parameter values. */ + if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 ) + { + /* Start or restart the trace. */ + vTraceStop(); + vTraceClear(); + + vTraceEnable( TRC_START ); + traceSTART(); + + sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" ); + } + else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 ) + { + /* End the trace, if one is running. */ + vTraceStop(); + sprintf( pcWriteBuffer, "Stopping trace recording and dumping log to disk.\r\n" ); + prvSaveTraceFile(); + } + else + { + sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); + } + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static void prvSaveTraceFile( void ) +{ + FILE * pxOutputFile; + + fopen_s( &pxOutputFile, "Trace.dump", "wb" ); + + if( pxOutputFile != NULL ) + { + fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile ); + fclose( pxOutputFile ); + printf( "\r\nTrace output saved to Trace.dump\r\n" ); + } + else + { + printf( "\r\nFailed to create trace dump file\r\n" ); + } +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace.sln index e2b3aaadf..a39dd1293 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace.sln +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace.sln @@ -1,86 +1,86 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator", "FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj", "{F135BC22-C210-45F7-9973-119C839C46D4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{26B7BF31-6E46-462B-8D48-C049C2D6DB7D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|Win32.ActiveCfg = Debug|Win32 - {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|Win32.Build.0 = Debug|Win32 - {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|x64.ActiveCfg = Debug|x64 - {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|x64.Build.0 = Debug|x64 - {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|x86.ActiveCfg = Debug|Win32 - {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|x86.Build.0 = Debug|Win32 - {F135BC22-C210-45F7-9973-119C839C46D4}.Release|Win32.ActiveCfg = Release|Win32 - {F135BC22-C210-45F7-9973-119C839C46D4}.Release|Win32.Build.0 = Release|Win32 - {F135BC22-C210-45F7-9973-119C839C46D4}.Release|x64.ActiveCfg = Release|x64 - {F135BC22-C210-45F7-9973-119C839C46D4}.Release|x64.Build.0 = Release|x64 - {F135BC22-C210-45F7-9973-119C839C46D4}.Release|x86.ActiveCfg = Release|Win32 - {F135BC22-C210-45F7-9973-119C839C46D4}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {26B7BF31-6E46-462B-8D48-C049C2D6DB7D} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {26B7BF31-6E46-462B-8D48-C049C2D6DB7D} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {26B7BF31-6E46-462B-8D48-C049C2D6DB7D} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {278BF1CD-A433-4631-B9A5-B91D7AB559EF} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator", "FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj", "{F135BC22-C210-45F7-9973-119C839C46D4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{26B7BF31-6E46-462B-8D48-C049C2D6DB7D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|Win32.ActiveCfg = Debug|Win32 + {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|Win32.Build.0 = Debug|Win32 + {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|x64.ActiveCfg = Debug|x64 + {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|x64.Build.0 = Debug|x64 + {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|x86.ActiveCfg = Debug|Win32 + {F135BC22-C210-45F7-9973-119C839C46D4}.Debug|x86.Build.0 = Debug|Win32 + {F135BC22-C210-45F7-9973-119C839C46D4}.Release|Win32.ActiveCfg = Release|Win32 + {F135BC22-C210-45F7-9973-119C839C46D4}.Release|Win32.Build.0 = Release|Win32 + {F135BC22-C210-45F7-9973-119C839C46D4}.Release|x64.ActiveCfg = Release|x64 + {F135BC22-C210-45F7-9973-119C839C46D4}.Release|x64.Build.0 = Release|x64 + {F135BC22-C210-45F7-9973-119C839C46D4}.Release|x86.ActiveCfg = Release|Win32 + {F135BC22-C210-45F7-9973-119C839C46D4}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {26B7BF31-6E46-462B-8D48-C049C2D6DB7D} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {26B7BF31-6E46-462B-8D48-C049C2D6DB7D} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {26B7BF31-6E46-462B-8D48-C049C2D6DB7D} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {278BF1CD-A433-4631-B9A5-B91D7AB559EF} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj index 39e19ec84..5a34d701e 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj @@ -1,181 +1,181 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {f135bc22-c210-45f7-9973-119c839c46d4} - FreeRTOSPlusCLIwithTraceVisualStudio_StaticProjects - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {f135bc22-c210-45f7-9973-119c839c46d4} + FreeRTOSPlusCLIwithTraceVisualStudio_StaticProjects + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj.filters index 8c5bd95fc..f6c3feab9 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator.vcxproj.filters @@ -1,84 +1,84 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {b25fcce9-c411-4467-a887-409c4ec86ef6} - - - {c2a6c951-9758-44fc-b428-cc9645243216} - - - {06ab7e65-d618-4f1a-9d40-fca3fa2afa6a} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - FreeRTOS+Trace - - - FreeRTOS+Trace - - - FreeRTOS+Trace - - - FreeRTOS+CLI - - - - - Header Files - - - Header Files - - - FreeRTOS+CLI - - - FreeRTOS+Trace\include - - - FreeRTOS+Trace\include - - - FreeRTOS+Trace\include - - - FreeRTOS+Trace\include - - - FreeRTOS+Trace\include - - - FreeRTOS+Trace\include - - - FreeRTOS+Trace\include - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {b25fcce9-c411-4467-a887-409c4ec86ef6} + + + {c2a6c951-9758-44fc-b428-cc9645243216} + + + {06ab7e65-d618-4f1a-9d40-fca3fa2afa6a} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + FreeRTOS+Trace + + + FreeRTOS+Trace + + + FreeRTOS+Trace + + + FreeRTOS+CLI + + + + + Header Files + + + Header Files + + + FreeRTOS+CLI + + + FreeRTOS+Trace\include + + + FreeRTOS+Trace\include + + + FreeRTOS+Trace\include + + + FreeRTOS+Trace\include + + + FreeRTOS+Trace\include + + + FreeRTOS+Trace\include + + + FreeRTOS+Trace\include + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/READ_ME.url b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/READ_ME.url index 8ee5a95d9..382f92062 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/READ_ME.url +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/READ_ME.url @@ -1,5 +1,5 @@ -[InternetShortcut] -URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_Trace/Free_RTOS_Plus_Trace_CLI_Example.shtml -IDList= -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_Trace/Free_RTOS_Plus_Trace_CLI_Example.shtml +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Run-time-stats-utils.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Run-time-stats-utils.c index c144e1484..f4af004b1 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Run-time-stats-utils.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Run-time-stats-utils.c @@ -1,99 +1,99 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -/* - * Utility functions required to gather run time statistics. See: - * https://www.FreeRTOS.org/rtos-run-time-stats.html - * - * Note that this is a simulated port, where simulated time is a lot slower than - * real time, therefore the run time counter values have no real meaningful - * units. - * - * Also note that it is assumed this demo is going to be used for short periods - * of time only, and therefore timer overflows are not handled. -*/ - -/* FreeRTOS includes. */ -#include - -/* Variables used in the creation of the run time stats time base. Run time -stats record how much time each task spends in the Running state. */ -static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL; - -/*-----------------------------------------------------------*/ - -void vConfigureTimerForRunTimeStats( void ) -{ -LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue; - - /* Initialise the variables used to create the run time stats time base. - Run time stats record how much time each task spends in the Running - state. */ - - if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 ) - { - llTicksPerHundedthMillisecond = 1; - } - else - { - /* How many times does the performance counter increment in 1/100th - millisecond. */ - llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL; - - /* What is the performance counter value now, this will be subtracted - from readings taken at run time. */ - QueryPerformanceCounter( &liInitialRunTimeValue ); - llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart; - } -} -/*-----------------------------------------------------------*/ - -unsigned long ulGetRunTimeCounterValue( void ) -{ -LARGE_INTEGER liCurrentCount; -unsigned long ulReturn; - - /* What is the performance counter value now? */ - QueryPerformanceCounter( &liCurrentCount ); - - /* Subtract the performance counter value reading taken when the - application started to get a count from that reference point, then - scale to (simulated) 1/100ths of a millisecond. */ - if( llTicksPerHundedthMillisecond == 0 ) - { - /* The trace macros can call this function before the kernel has been - started, in which case llTicksPerHundedthMillisecond will not have been - initialised. */ - ulReturn = 0; - } - else - { - ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundedthMillisecond ); - } - - return ulReturn; -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Utility functions required to gather run time statistics. See: + * https://www.FreeRTOS.org/rtos-run-time-stats.html + * + * Note that this is a simulated port, where simulated time is a lot slower than + * real time, therefore the run time counter values have no real meaningful + * units. + * + * Also note that it is assumed this demo is going to be used for short periods + * of time only, and therefore timer overflows are not handled. + */ + +/* FreeRTOS includes. */ +#include + +/* Variables used in the creation of the run time stats time base. Run time + * stats record how much time each task spends in the Running state. */ +static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundredthMillisecond = 0LL; + +/*-----------------------------------------------------------*/ + +void vConfigureTimerForRunTimeStats( void ) +{ + LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue; + + /* Initialise the variables used to create the run time stats time base. + * Run time stats record how much time each task spends in the Running + * state. */ + + if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 ) + { + llTicksPerHundredthMillisecond = 1; + } + else + { + /* How many times does the performance counter increment in 1/100th + * millisecond. */ + llTicksPerHundredthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL; + + /* What is the performance counter value now, this will be subtracted + * from readings taken at run time. */ + QueryPerformanceCounter( &liInitialRunTimeValue ); + llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart; + } +} +/*-----------------------------------------------------------*/ + +unsigned long ulGetRunTimeCounterValue( void ) +{ + LARGE_INTEGER liCurrentCount; + unsigned long ulReturn; + + /* What is the performance counter value now? */ + QueryPerformanceCounter( &liCurrentCount ); + + /* Subtract the performance counter value reading taken when the + * application started to get a count from that reference point, then + * scale to (simulated) 1/100ths of a millisecond. */ + if( llTicksPerHundredthMillisecond == 0 ) + { + /* The trace macros can call this function before the kernel has been + * started, in which case llTicksPerHundredthMillisecond will not have been + * initialised. */ + ulReturn = 0; + } + else + { + ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundredthMillisecond ); + } + + return ulReturn; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcConfig.h index 701e3685d..4cb913001 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcConfig.h @@ -1,413 +1,413 @@ -/******************************************************************************* - * Trace Recorder Library for Tracealyzer v4.1.4 - * Percepio AB, www.percepio.com - * - * trcConfig.h - * - * Main configuration parameters for the trace recorder library. - * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h. - * - * Read more at http://percepio.com/2016/10/05/rtos-tracing/ - * - * Terms of Use - * This file is part of the trace recorder library (RECORDER), which is the - * intellectual property of Percepio AB (PERCEPIO) and provided under a - * license as follows. - * The RECORDER may be used free of charge for the purpose of recording data - * intended for analysis in PERCEPIO products. It may not be used or modified - * for other purposes without explicit permission from PERCEPIO. - * You may distribute the RECORDER in its original source code form, assuming - * this text (terms of use, disclaimer, copyright notice) is unchanged. You are - * allowed to distribute the RECORDER with minor modifications intended for - * configuration or porting of the RECORDER, e.g., to allow using it on a - * specific processor, processor family or with a specific communication - * interface. Any such modifications should be documented directly below - * this comment block. - * - * Disclaimer - * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty - * as to its use or performance. PERCEPIO does not and cannot warrant the - * performance or results you may obtain by using the RECORDER or documentation. - * PERCEPIO make no warranties, express or implied, as to noninfringement of - * third party rights, merchantability, or fitness for any particular purpose. - * In no event will PERCEPIO, its technology partners, or distributors be liable - * to you for any consequential, incidental or special damages, including any - * lost profits or lost savings, even if a representative of PERCEPIO has been - * advised of the possibility of such damages, or for any claim by any third - * party. Some jurisdictions do not allow the exclusion or limitation of - * incidental, consequential or special damages, or the exclusion of implied - * warranties or limitations on how long an implied warranty may last, so the - * above limitations may not apply to you. - * - * Tabs are used for indent in this file (1 tab = 4 spaces) - * - * Copyright Percepio AB, 2018. - * www.percepio.com - ******************************************************************************/ - -#ifndef TRC_CONFIG_H -#define TRC_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "trcDefines.h" - -/****************************************************************************** - * Include of processor header file - * - * Here you may need to include the header file for your processor. This is - * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API. - * Try that in case of build problems. Otherwise, remove the #error line below. - *****************************************************************************/ -//#error "Trace Recorder: Please include your processor's header file here and remove this line." - -/******************************************************************************* - * Configuration Macro: TRC_CFG_HARDWARE_PORT - * - * Specify what hardware port to use (i.e., the "timestamping driver"). - * - * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M". - * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is - * available on most such devices. In case your device don't have DWT support, - * you will get an error message opening the trace. In that case, you may - * force the recorder to use SysTick timestamping instead, using this define: - * - * #define TRC_CFG_ARM_CM_USE_SYSTICK - * - * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically. - * - * See trcHardwarePort.h for available ports and information on how to - * define your own port, if not already present. - ******************************************************************************/ -#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_Win32 - -/******************************************************************************* - * Configuration Macro: TRC_CFG_RECORDER_MODE - * - * Specify what recording mode to use. Snapshot means that the data is saved in - * an internal RAM buffer, for later upload. Streaming means that the data is - * transferred continuously to the host PC. - * - * For more information, see http://percepio.com/2016/10/05/rtos-tracing/ - * and the Tracealyzer User Manual. - * - * Values: - * TRC_RECORDER_MODE_SNAPSHOT - * TRC_RECORDER_MODE_STREAMING - ******************************************************************************/ -#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT - -/****************************************************************************** - * TRC_CFG_FREERTOS_VERSION - * - * Specify what version of FreeRTOS that is used (don't change unless using the - * trace recorder library with an older version of FreeRTOS). - * - * TRC_FREERTOS_VERSION_7_3_X If using FreeRTOS v7.3.X - * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X - * TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X - * TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X - * TRC_FREERTOS_VERSION_8_X_X If using FreeRTOS v8.X.X - * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0 - * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1 - * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2 - * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 - * TRC_FREERTOS_VERSION_10_0_1 If using FreeRTOS v10.0.1 - * TRC_FREERTOS_VERSION_10_1_0 If using FreeRTOS v10.1.0 - * TRC_FREERTOS_VERSION_10_1_1 If using FreeRTOS v10.1.1 - * TRC_FREERTOS_VERSION_10_2_0 If using FreeRTOS v10.2.0 - * TRC_FREERTOS_VERSION_10_2_1 If using FreeRTOS v10.2.1 - * TRC_FREERTOS_VERSION_10_3_0 If using FreeRTOS v10.3.0 - * TRC_FREERTOS_VERSION_10_3_1 If using FreeRTOS v10.3.1 - * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 or later - *****************************************************************************/ -#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_0 - -/******************************************************************************* - * TRC_CFG_SCHEDULING_ONLY - * - * Macro which should be defined as an integer value. - * - * If this setting is enabled (= 1), only scheduling events are recorded. - * If disabled (= 0), all events are recorded (unless filtered in other ways). - * - * Default value is 0 (= include additional events). - ******************************************************************************/ -#define TRC_CFG_SCHEDULING_ONLY 0 - - /****************************************************************************** - * TRC_CFG_INCLUDE_MEMMANG_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). - * - * This controls if malloc and free calls should be traced. Set this to zero (0) - * to exclude malloc/free calls, or one (1) to include such events in the trace. - * - * Default value is 1. - *****************************************************************************/ -#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1 - - /****************************************************************************** - * TRC_CFG_INCLUDE_USER_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), all code related to User Events is excluded in order - * to reduce code size. Any attempts of storing User Events are then silently - * ignored. - * - * User Events are application-generated events, like "printf" but for the - * trace log, generated using vTracePrint and vTracePrintF. - * The formatting is done on host-side, by Tracealyzer. User Events are - * therefore much faster than a console printf and can often be used - * in timing critical code without problems. - * - * Note: In streaming mode, User Events are used to provide error messages - * and warnings from the recorder (in case of incorrect configuration) for - * display in Tracealyzer. Disabling user events will also disable these - * warnings. You can however still catch them by calling xTraceGetLastError - * or by putting breakpoints in prvTraceError and prvTraceWarning. - * - * Default value is 1. - *****************************************************************************/ -#define TRC_CFG_INCLUDE_USER_EVENTS 1 - - /***************************************************************************** - * TRC_CFG_INCLUDE_ISR_TRACING - * - * Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the code for recording Interrupt Service Routines is - * excluded, in order to reduce code size. This means that any calls to - * vTraceStoreISRBegin/vTraceStoreISREnd will be ignored. - * This does not completely disable ISR tracing, in cases where an ISR is - * calling a traced kernel service. These events will still be recorded and - * show up in anonymous ISR instances in Tracealyzer, with names such as - * "ISR sending to ". - * To disable such tracing, please refer to vTraceSetFilterGroup and - * vTraceSetFilterMask. - * - * Default value is 1. - * - * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin - * and vTraceStoreISREnd in your interrupt handlers. - *****************************************************************************/ -#define TRC_CFG_INCLUDE_ISR_TRACING 1 - - /***************************************************************************** - * TRC_CFG_INCLUDE_READY_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). - * - * If one (1), events are recorded when tasks enter scheduling state "ready". - * This allows Tracealyzer to show the initial pending time before tasks enter - * the execution state, and present accurate response times. - * If zero (0), "ready events" are not created, which allows for recording - * longer traces in the same amount of RAM. - * - * Default value is 1. - *****************************************************************************/ -#define TRC_CFG_INCLUDE_READY_EVENTS 1 - - /***************************************************************************** - * TRC_CFG_INCLUDE_OSTICK_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). - * - * If this is one (1), events will be generated whenever the OS clock is - * increased. If zero (0), OS tick events are not generated, which allows for - * recording longer traces in the same amount of RAM. - * - * Default value is 1. - *****************************************************************************/ -#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1 - - /***************************************************************************** - * TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the trace will exclude any "event group" events. - * - * Default value is 0 (excluded) since dependent on event_groups.c - *****************************************************************************/ -#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 0 - - /***************************************************************************** - * TRC_CFG_INCLUDE_TIMER_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the trace will exclude any Timer events. - * - * Default value is 0 since dependent on timers.c - *****************************************************************************/ -#define TRC_CFG_INCLUDE_TIMER_EVENTS 1 - - /***************************************************************************** - * TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the trace will exclude any "pending function call" - * events, such as xTimerPendFunctionCall(). - * - * Default value is 0 since dependent on timers.c - *****************************************************************************/ -#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 - -/******************************************************************************* - * Configuration Macro: TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the trace will exclude any stream buffer or message - * buffer events. - * - * Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10) - ******************************************************************************/ -#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 0 - - /****************************************************************************** - * TRC_CFG_ENABLE_STACK_MONITOR - * - * If enabled (1), the recorder periodically reports the unused stack space of - * all active tasks. - * The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task - * is always created by the recorder when in streaming mode. - * In snapshot mode, the TzCtrl task is only used for stack monitoring and is - * not created unless this is enabled. - *****************************************************************************/ -#define TRC_CFG_ENABLE_STACK_MONITOR 0 - - /****************************************************************************** - * TRC_CFG_STACK_MONITOR_MAX_TASKS - * - * Macro which should be defined as a non-zero integer value. - * - * This controls how many tasks that can be monitored by the stack monitor. - * If this is too small, some tasks will be excluded and a warning is shown. - * - * Default value is 10. - *****************************************************************************/ -#define TRC_CFG_STACK_MONITOR_MAX_TASKS 10 - - /****************************************************************************** - * TRC_CFG_STACK_MONITOR_MAX_REPORTS - * - * Macro which should be defined as a non-zero integer value. - * - * This defines how many tasks that will be subject to stack usage analysis for - * each execution of the Tracealyzer Control task (TzCtrl). Note that the stack - * monitoring cycles between the tasks, so this does not affect WHICH tasks that - * are monitored, but HOW OFTEN each task stack is analyzed. - * - * This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the - * frequency of the stack monitoring. This is motivated since the stack analysis - * can take some time to execute. - * However, note that the stack analysis runs in a separate task (TzCtrl) that - * can be executed on low priority. This way, you can avoid that the stack - * analysis disturbs any time-sensitive tasks. - * - * Default value is 1. - *****************************************************************************/ -#define TRC_CFG_STACK_MONITOR_MAX_REPORTS 1 - - /******************************************************************************* - * Configuration Macro: TRC_CFG_CTRL_TASK_PRIORITY - * - * The scheduling priority of the Tracealyzer Control (TzCtrl) task. - * - * In streaming mode, TzCtrl is used to receive start/stop commands from - * Tracealyzer and in some cases also to transmit the trace data (for stream - * ports that uses the internal buffer, like TCP/IP). For such stream ports, - * make sure the TzCtrl priority is high enough to ensure reliable periodic - * execution and transfer of the data, but low enough to avoid disturbing any - * time-sensitive functions. - * - * In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is - * not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should - * be low, to avoid disturbing any time-sensitive tasks. - ******************************************************************************/ -#define TRC_CFG_CTRL_TASK_PRIORITY 1 - - /******************************************************************************* - * Configuration Macro: TRC_CFG_CTRL_TASK_DELAY - * - * The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY), - * which affects the frequency of the stack monitoring. - * - * In streaming mode, this also affects the trace data transfer if you are using - * a stream port leveraging the internal buffer (like TCP/IP). A shorter delay - * increases the CPU load of TzCtrl somewhat, but may improve the performance of - * of the trace streaming, especially if the trace buffer is small. - ******************************************************************************/ -#define TRC_CFG_CTRL_TASK_DELAY 10 - - /******************************************************************************* - * Configuration Macro: TRC_CFG_CTRL_TASK_STACK_SIZE - * - * The stack size of the Tracealyzer Control (TzCtrl) task. - * See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl. - ******************************************************************************/ -#define TRC_CFG_CTRL_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 2) - -/******************************************************************************* - * Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION - * - * Specifies how the recorder buffer is allocated (also in case of streaming, in - * port using the recorder's internal temporary buffer) - * - * Values: - * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal) - * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable - * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer - * - * Static and dynamic mode does the allocation for you, either in compile time - * (static) or in runtime (malloc). - * The custom mode allows you to control how and where the allocation is made, - * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer(). - ******************************************************************************/ -#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC - -/****************************************************************************** - * TRC_CFG_MAX_ISR_NESTING - * - * Defines how many levels of interrupt nesting the recorder can handle, in - * case multiple ISRs are traced and ISR nesting is possible. If this - * is exceeded, the particular ISR will not be traced and the recorder then - * logs an error message. This setting is used to allocate an internal stack - * for keeping track of the previous execution context (4 byte per entry). - * - * This value must be a non-zero positive constant, at least 1. - * - * Default value: 8 - *****************************************************************************/ -#define TRC_CFG_MAX_ISR_NESTING 8 - -/****************************************************************************** - * TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND - * - * When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace - * point in prvNotifyQueueSetContainer() in queue.c is renamed from - * traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from - * other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED. - *****************************************************************************/ -#define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND TRC_ACKNOWLEDGED /* 0 or TRC_ACKNOWLEDGED */ - -#define TRC_CFG_RECORDER_DATA_ATTRIBUTE - -/* Specific configuration, depending on Streaming/Snapshot mode */ -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) -#include "trcSnapshotConfig.h" -#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) -#include "trcStreamingConfig.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _TRC_CONFIG_H */ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v4.1.4 + * Percepio AB, www.percepio.com + * + * trcConfig.h + * + * Main configuration parameters for the trace recorder library. + * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h. + * + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2018. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_CONFIG_H + #define TRC_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + + #include "trcDefines.h" + +/****************************************************************************** + * Include of processor header file + * + * Here you may need to include the header file for your processor. This is + * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API. + * Try that in case of build problems. Otherwise, remove the #error line below. + *****************************************************************************/ +/*#error "Trace Recorder: Please include your processor's header file here and remove this line." */ + +/******************************************************************************* + * Configuration Macro: TRC_CFG_HARDWARE_PORT + * + * Specify what hardware port to use (i.e., the "timestamping driver"). + * + * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M". + * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is + * available on most such devices. In case your device don't have DWT support, + * you will get an error message opening the trace. In that case, you may + * force the recorder to use SysTick timestamping instead, using this define: + * + * #define TRC_CFG_ARM_CM_USE_SYSTICK + * + * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically. + * + * See trcHardwarePort.h for available ports and information on how to + * define your own port, if not already present. + ******************************************************************************/ + #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_Win32 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RECORDER_MODE + * + * Specify what recording mode to use. Snapshot means that the data is saved in + * an internal RAM buffer, for later upload. Streaming means that the data is + * transferred continuously to the host PC. + * + * For more information, see http://percepio.com/2016/10/05/rtos-tracing/ + * and the Tracealyzer User Manual. + * + * Values: + * TRC_RECORDER_MODE_SNAPSHOT + * TRC_RECORDER_MODE_STREAMING + ******************************************************************************/ + #define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT + +/****************************************************************************** + * TRC_CFG_FREERTOS_VERSION + * + * Specify what version of FreeRTOS that is used (don't change unless using the + * trace recorder library with an older version of FreeRTOS). + * + * TRC_FREERTOS_VERSION_7_3_X If using FreeRTOS v7.3.X + * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X + * TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X + * TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X + * TRC_FREERTOS_VERSION_8_X_X If using FreeRTOS v8.X.X + * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0 + * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1 + * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2 + * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 + * TRC_FREERTOS_VERSION_10_0_1 If using FreeRTOS v10.0.1 + * TRC_FREERTOS_VERSION_10_1_0 If using FreeRTOS v10.1.0 + * TRC_FREERTOS_VERSION_10_1_1 If using FreeRTOS v10.1.1 + * TRC_FREERTOS_VERSION_10_2_0 If using FreeRTOS v10.2.0 + * TRC_FREERTOS_VERSION_10_2_1 If using FreeRTOS v10.2.1 + * TRC_FREERTOS_VERSION_10_3_0 If using FreeRTOS v10.3.0 + * TRC_FREERTOS_VERSION_10_3_1 If using FreeRTOS v10.3.1 + * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 or later + *****************************************************************************/ + #define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_0 + +/******************************************************************************* + * TRC_CFG_SCHEDULING_ONLY + * + * Macro which should be defined as an integer value. + * + * If this setting is enabled (= 1), only scheduling events are recorded. + * If disabled (= 0), all events are recorded (unless filtered in other ways). + * + * Default value is 0 (= include additional events). + ******************************************************************************/ + #define TRC_CFG_SCHEDULING_ONLY 0 + +/****************************************************************************** + * TRC_CFG_INCLUDE_MEMMANG_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * This controls if malloc and free calls should be traced. Set this to zero (0) + * to exclude malloc/free calls, or one (1) to include such events in the trace. + * + * Default value is 1. + *****************************************************************************/ + #define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1 + +/****************************************************************************** + * TRC_CFG_INCLUDE_USER_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), all code related to User Events is excluded in order + * to reduce code size. Any attempts of storing User Events are then silently + * ignored. + * + * User Events are application-generated events, like "printf" but for the + * trace log, generated using vTracePrint and vTracePrintF. + * The formatting is done on host-side, by Tracealyzer. User Events are + * therefore much faster than a console printf and can often be used + * in timing critical code without problems. + * + * Note: In streaming mode, User Events are used to provide error messages + * and warnings from the recorder (in case of incorrect configuration) for + * display in Tracealyzer. Disabling user events will also disable these + * warnings. You can however still catch them by calling xTraceGetLastError + * or by putting breakpoints in prvTraceError and prvTraceWarning. + * + * Default value is 1. + *****************************************************************************/ + #define TRC_CFG_INCLUDE_USER_EVENTS 1 + +/***************************************************************************** +* TRC_CFG_INCLUDE_ISR_TRACING +* +* Macro which should be defined as either zero (0) or one (1). +* +* If this is zero (0), the code for recording Interrupt Service Routines is +* excluded, in order to reduce code size. This means that any calls to +* vTraceStoreISRBegin/vTraceStoreISREnd will be ignored. +* This does not completely disable ISR tracing, in cases where an ISR is +* calling a traced kernel service. These events will still be recorded and +* show up in anonymous ISR instances in Tracealyzer, with names such as +* "ISR sending to ". +* To disable such tracing, please refer to vTraceSetFilterGroup and +* vTraceSetFilterMask. +* +* Default value is 1. +* +* Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin +* and vTraceStoreISREnd in your interrupt handlers. +*****************************************************************************/ + #define TRC_CFG_INCLUDE_ISR_TRACING 1 + +/***************************************************************************** +* TRC_CFG_INCLUDE_READY_EVENTS +* +* Macro which should be defined as either zero (0) or one (1). +* +* If one (1), events are recorded when tasks enter scheduling state "ready". +* This allows Tracealyzer to show the initial pending time before tasks enter +* the execution state, and present accurate response times. +* If zero (0), "ready events" are not created, which allows for recording +* longer traces in the same amount of RAM. +* +* Default value is 1. +*****************************************************************************/ + #define TRC_CFG_INCLUDE_READY_EVENTS 1 + +/***************************************************************************** +* TRC_CFG_INCLUDE_OSTICK_EVENTS +* +* Macro which should be defined as either zero (0) or one (1). +* +* If this is one (1), events will be generated whenever the OS clock is +* increased. If zero (0), OS tick events are not generated, which allows for +* recording longer traces in the same amount of RAM. +* +* Default value is 1. +*****************************************************************************/ + #define TRC_CFG_INCLUDE_OSTICK_EVENTS 1 + +/***************************************************************************** +* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS +* +* Macro which should be defined as either zero (0) or one (1). +* +* If this is zero (0), the trace will exclude any "event group" events. +* +* Default value is 0 (excluded) since dependent on event_groups.c +*****************************************************************************/ + #define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 0 + +/***************************************************************************** +* TRC_CFG_INCLUDE_TIMER_EVENTS +* +* Macro which should be defined as either zero (0) or one (1). +* +* If this is zero (0), the trace will exclude any Timer events. +* +* Default value is 0 since dependent on timers.c +*****************************************************************************/ + #define TRC_CFG_INCLUDE_TIMER_EVENTS 1 + +/***************************************************************************** +* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS +* +* Macro which should be defined as either zero (0) or one (1). +* +* If this is zero (0), the trace will exclude any "pending function call" +* events, such as xTimerPendFunctionCall(). +* +* Default value is 0 since dependent on timers.c +*****************************************************************************/ + #define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any stream buffer or message + * buffer events. + * + * Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10) + ******************************************************************************/ + #define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 0 + +/****************************************************************************** + * TRC_CFG_ENABLE_STACK_MONITOR + * + * If enabled (1), the recorder periodically reports the unused stack space of + * all active tasks. + * The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task + * is always created by the recorder when in streaming mode. + * In snapshot mode, the TzCtrl task is only used for stack monitoring and is + * not created unless this is enabled. + *****************************************************************************/ + #define TRC_CFG_ENABLE_STACK_MONITOR 0 + +/****************************************************************************** + * TRC_CFG_STACK_MONITOR_MAX_TASKS + * + * Macro which should be defined as a non-zero integer value. + * + * This controls how many tasks that can be monitored by the stack monitor. + * If this is too small, some tasks will be excluded and a warning is shown. + * + * Default value is 10. + *****************************************************************************/ + #define TRC_CFG_STACK_MONITOR_MAX_TASKS 10 + +/****************************************************************************** + * TRC_CFG_STACK_MONITOR_MAX_REPORTS + * + * Macro which should be defined as a non-zero integer value. + * + * This defines how many tasks that will be subject to stack usage analysis for + * each execution of the Tracealyzer Control task (TzCtrl). Note that the stack + * monitoring cycles between the tasks, so this does not affect WHICH tasks that + * are monitored, but HOW OFTEN each task stack is analyzed. + * + * This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the + * frequency of the stack monitoring. This is motivated since the stack analysis + * can take some time to execute. + * However, note that the stack analysis runs in a separate task (TzCtrl) that + * can be executed on low priority. This way, you can avoid that the stack + * analysis disturbs any time-sensitive tasks. + * + * Default value is 1. + *****************************************************************************/ + #define TRC_CFG_STACK_MONITOR_MAX_REPORTS 1 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_CTRL_TASK_PRIORITY + * + * The scheduling priority of the Tracealyzer Control (TzCtrl) task. + * + * In streaming mode, TzCtrl is used to receive start/stop commands from + * Tracealyzer and in some cases also to transmit the trace data (for stream + * ports that uses the internal buffer, like TCP/IP). For such stream ports, + * make sure the TzCtrl priority is high enough to ensure reliable periodic + * execution and transfer of the data, but low enough to avoid disturbing any + * time-sensitive functions. + * + * In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is + * not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should + * be low, to avoid disturbing any time-sensitive tasks. + ******************************************************************************/ + #define TRC_CFG_CTRL_TASK_PRIORITY 1 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_CTRL_TASK_DELAY + * + * The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY), + * which affects the frequency of the stack monitoring. + * + * In streaming mode, this also affects the trace data transfer if you are using + * a stream port leveraging the internal buffer (like TCP/IP). A shorter delay + * increases the CPU load of TzCtrl somewhat, but may improve the performance of + * of the trace streaming, especially if the trace buffer is small. + ******************************************************************************/ + #define TRC_CFG_CTRL_TASK_DELAY 10 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_CTRL_TASK_STACK_SIZE + * + * The stack size of the Tracealyzer Control (TzCtrl) task. + * See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl. + ******************************************************************************/ + #define TRC_CFG_CTRL_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION + * + * Specifies how the recorder buffer is allocated (also in case of streaming, in + * port using the recorder's internal temporary buffer) + * + * Values: + * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal) + * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable + * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer + * + * Static and dynamic mode does the allocation for you, either in compile time + * (static) or in runtime (malloc). + * The custom mode allows you to control how and where the allocation is made, + * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer(). + ******************************************************************************/ + #define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC + +/****************************************************************************** + * TRC_CFG_MAX_ISR_NESTING + * + * Defines how many levels of interrupt nesting the recorder can handle, in + * case multiple ISRs are traced and ISR nesting is possible. If this + * is exceeded, the particular ISR will not be traced and the recorder then + * logs an error message. This setting is used to allocate an internal stack + * for keeping track of the previous execution context (4 byte per entry). + * + * This value must be a non-zero positive constant, at least 1. + * + * Default value: 8 + *****************************************************************************/ + #define TRC_CFG_MAX_ISR_NESTING 8 + +/****************************************************************************** + * TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND + * + * When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace + * point in prvNotifyQueueSetContainer() in queue.c is renamed from + * traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from + * other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED. + *****************************************************************************/ + #define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND TRC_ACKNOWLEDGED /* 0 or TRC_ACKNOWLEDGED */ + + #define TRC_CFG_RECORDER_DATA_ATTRIBUTE + +/* Specific configuration, depending on Streaming/Snapshot mode */ + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) + #include "trcSnapshotConfig.h" + #elif ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + #include "trcStreamingConfig.h" + #endif + + #ifdef __cplusplus +} + #endif + +#endif /* _TRC_CONFIG_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcKernelPortConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcKernelPortConfig.h index 84879b35a..e1fa2b2a9 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcKernelPortConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcKernelPortConfig.h @@ -11,11 +11,11 @@ */ #ifndef TRC_KERNEL_PORT_CONFIG_H -#define TRC_KERNEL_PORT_CONFIG_H + #define TRC_KERNEL_PORT_CONFIG_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /** * @def TRC_CFG_RECORDER_MODE @@ -30,7 +30,7 @@ extern "C" { * TRC_RECORDER_MODE_SNAPSHOT * TRC_RECORDER_MODE_STREAMING */ -#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT + #define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT /** * @def TRC_CFG_FREERTOS_VERSION @@ -38,7 +38,7 @@ extern "C" { * trace recorder library with an older version of FreeRTOS). * * TRC_FREERTOS_VERSION_7_3_X If using FreeRTOS v7.3.X - * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X + * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X * TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X * TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X * TRC_FREERTOS_VERSION_8_X_X If using FreeRTOS v8.X.X @@ -56,7 +56,7 @@ extern "C" { * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 * TRC_FREERTOS_VERSION_10_4_1 If using FreeRTOS v10.4.1 or later */ -#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_1 + #define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_1 /** * @def TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS @@ -66,7 +66,7 @@ extern "C" { * * Default value is 0 (excluded) since dependent on event_groups.c */ -#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 0 + #define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 0 /** * @def TRC_CFG_INCLUDE_TIMER_EVENTS @@ -76,18 +76,18 @@ extern "C" { * * Default value is 0 since dependent on timers.c */ -#define TRC_CFG_INCLUDE_TIMER_EVENTS 1 + #define TRC_CFG_INCLUDE_TIMER_EVENTS 1 /** * @def TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS * @brief Macro which should be defined as either zero (0) or one (1). * - * If this is zero (0), the trace will exclude any "pending function call" + * If this is zero (0), the trace will exclude any "pending function call" * events, such as xTimerPendFunctionCall(). * * Default value is 0 since dependent on timers.c */ -#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 + #define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 /** * @def TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS @@ -98,7 +98,7 @@ extern "C" { * * Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10) */ -#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 0 + #define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 0 /** * @def TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND @@ -107,10 +107,10 @@ extern "C" { * traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from * other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED. */ -#define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND 0 /* TRC_ACKNOWLEDGED */ + #define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND 0 /* TRC_ACKNOWLEDGED */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* TRC_KERNEL_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h index d4910f2b0..f5cb0571e 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h @@ -9,11 +9,11 @@ */ #ifndef TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H -#define TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H + #define TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /** * @def TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE... @@ -36,15 +36,15 @@ extern "C" { * check the actual usage by selecting View menu -> Trace Details -> * Resource Usage -> Object Table. */ -#define TRC_CFG_NTASK 150 -#define TRC_CFG_NISR 90 -#define TRC_CFG_NQUEUE 90 -#define TRC_CFG_NSEMAPHORE 90 -#define TRC_CFG_NMUTEX 90 -#define TRC_CFG_NTIMER 250 -#define TRC_CFG_NEVENTGROUP 90 -#define TRC_CFG_NSTREAMBUFFER 50 -#define TRC_CFG_NMESSAGEBUFFER 50 + #define TRC_CFG_NTASK 150 + #define TRC_CFG_NISR 90 + #define TRC_CFG_NQUEUE 90 + #define TRC_CFG_NSEMAPHORE 90 + #define TRC_CFG_NMUTEX 90 + #define TRC_CFG_NTIMER 250 + #define TRC_CFG_NEVENTGROUP 90 + #define TRC_CFG_NSTREAMBUFFER 50 + #define TRC_CFG_NMESSAGEBUFFER 50 /** * @def TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ... @@ -52,18 +52,18 @@ extern "C" { * kernel objects, such as tasks and queues. If longer names are used, they will * be truncated when stored in the recorder. */ -#define TRC_CFG_NAME_LEN_TASK 15 -#define TRC_CFG_NAME_LEN_ISR 15 -#define TRC_CFG_NAME_LEN_QUEUE 15 -#define TRC_CFG_NAME_LEN_SEMAPHORE 15 -#define TRC_CFG_NAME_LEN_MUTEX 15 -#define TRC_CFG_NAME_LEN_TIMER 15 -#define TRC_CFG_NAME_LEN_EVENTGROUP 15 -#define TRC_CFG_NAME_LEN_STREAMBUFFER 15 -#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 + #define TRC_CFG_NAME_LEN_TASK 15 + #define TRC_CFG_NAME_LEN_ISR 15 + #define TRC_CFG_NAME_LEN_QUEUE 15 + #define TRC_CFG_NAME_LEN_SEMAPHORE 15 + #define TRC_CFG_NAME_LEN_MUTEX 15 + #define TRC_CFG_NAME_LEN_TIMER 15 + #define TRC_CFG_NAME_LEN_EVENTGROUP 15 + #define TRC_CFG_NAME_LEN_STREAMBUFFER 15 + #define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcSnapshotConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcSnapshotConfig.h index aa2229346..4466f8b0c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcSnapshotConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/trcSnapshotConfig.h @@ -1,378 +1,378 @@ -/******************************************************************************* - * Trace Recorder Library for Tracealyzer v4.1.4 - * Percepio AB, www.percepio.com - * - * trcSnapshotConfig.h - * - * Configuration parameters for trace recorder library in snapshot mode. - * Read more at http://percepio.com/2016/10/05/rtos-tracing/ - * - * Terms of Use - * This file is part of the trace recorder library (RECORDER), which is the - * intellectual property of Percepio AB (PERCEPIO) and provided under a - * license as follows. - * The RECORDER may be used free of charge for the purpose of recording data - * intended for analysis in PERCEPIO products. It may not be used or modified - * for other purposes without explicit permission from PERCEPIO. - * You may distribute the RECORDER in its original source code form, assuming - * this text (terms of use, disclaimer, copyright notice) is unchanged. You are - * allowed to distribute the RECORDER with minor modifications intended for - * configuration or porting of the RECORDER, e.g., to allow using it on a - * specific processor, processor family or with a specific communication - * interface. Any such modifications should be documented directly below - * this comment block. - * - * Disclaimer - * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty - * as to its use or performance. PERCEPIO does not and cannot warrant the - * performance or results you may obtain by using the RECORDER or documentation. - * PERCEPIO make no warranties, express or implied, as to noninfringement of - * third party rights, merchantability, or fitness for any particular purpose. - * In no event will PERCEPIO, its technology partners, or distributors be liable - * to you for any consequential, incidental or special damages, including any - * lost profits or lost savings, even if a representative of PERCEPIO has been - * advised of the possibility of such damages, or for any claim by any third - * party. Some jurisdictions do not allow the exclusion or limitation of - * incidental, consequential or special damages, or the exclusion of implied - * warranties or limitations on how long an implied warranty may last, so the - * above limitations may not apply to you. - * - * Tabs are used for indent in this file (1 tab = 4 spaces) - * - * Copyright Percepio AB, 2018. - * www.percepio.com - ******************************************************************************/ - -#ifndef TRC_SNAPSHOT_CONFIG_H -#define TRC_SNAPSHOT_CONFIG_H - -#define TRC_SNAPSHOT_MODE_RING_BUFFER (0x01) -#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL (0x02) - -/****************************************************************************** - * TRC_CFG_SNAPSHOT_MODE - * - * Macro which should be defined as one of: - * - TRC_SNAPSHOT_MODE_RING_BUFFER - * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL - * Default is TRC_SNAPSHOT_MODE_RING_BUFFER. - * - * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the - * events are stored in a ring buffer, i.e., where the oldest events are - * overwritten when the buffer becomes full. This allows you to get the last - * events leading up to an interesting state, e.g., an error, without having - * to store the whole run since startup. - * - * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the - * recording is stopped when the buffer becomes full. This is useful for - * recording events following a specific state, e.g., the startup sequence. - *****************************************************************************/ -#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER - -/******************************************************************************* - * TRC_CFG_EVENT_BUFFER_SIZE - * - * Macro which should be defined as an integer value. - * - * This defines the capacity of the event buffer, i.e., the number of records - * it may store. Most events use one record (4 byte), although some events - * require multiple 4-byte records. You should adjust this to the amount of RAM - * available in the target system. - * - * Default value is 1000, which means that 4000 bytes is allocated for the - * event buffer. - ******************************************************************************/ -#define TRC_CFG_EVENT_BUFFER_SIZE 15000 - -/******************************************************************************* - * TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE... - * - * A group of macros which should be defined as integer values, zero or larger. - * - * These define the capacity of the Object Property Table, i.e., the maximum - * number of objects active at any given point, within each object class (e.g., - * task, queue, semaphore, ...). - * - * If tasks or other objects are deleted in your system, this - * setting does not limit the total amount of objects created, only the number - * of objects that have been successfully created but not yet deleted. - * - * Using too small values will cause vTraceError to be called, which stores an - * error message in the trace that is shown when opening the trace file. The - * error message can also be retrieved using xTraceGetLastError. - * - * It can be wise to start with large values for these constants, - * unless you are very confident on these numbers. Then do a recording and - * check the actual usage by selecting View menu -> Trace Details -> - * Resource Usage -> Object Table. - ******************************************************************************/ -#define TRC_CFG_NTASK 150 -#define TRC_CFG_NISR 90 -#define TRC_CFG_NQUEUE 90 -#define TRC_CFG_NSEMAPHORE 90 -#define TRC_CFG_NMUTEX 90 -#define TRC_CFG_NTIMER 250 -#define TRC_CFG_NEVENTGROUP 90 -#define TRC_CFG_NSTREAMBUFFER 50 -#define TRC_CFG_NMESSAGEBUFFER 50 - - -/****************************************************************************** - * TRC_CFG_INCLUDE_FLOAT_SUPPORT - * - * Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the support for logging floating point values in - * vTracePrintF is stripped out, in case floating point values are not used or - * supported by the platform used. - * - * Floating point values are only used in vTracePrintF and its subroutines, to - * allow for storing float (%f) or double (%lf) arguments. - * - * vTracePrintF can be used with integer and string arguments in either case. - * - * Default value is 0. - *****************************************************************************/ -#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 - -/******************************************************************************* - * TRC_CFG_SYMBOL_TABLE_SIZE - * - * Macro which should be defined as an integer value. - * - * This defines the capacity of the symbol table, in bytes. This symbol table - * stores User Events labels and names of deleted tasks, queues, or other kernel - * objects. If you don't use User Events or delete any kernel - * objects you set this to a very low value. The minimum recommended value is 4. - * A size of zero (0) is not allowed since a zero-sized array may result in a - * 32-bit pointer, i.e., using 4 bytes rather than 0. - * - * Default value is 800. - ******************************************************************************/ -#define TRC_CFG_SYMBOL_TABLE_SIZE 5000 - -#if (TRC_CFG_SYMBOL_TABLE_SIZE == 0) -#error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!" -#endif - -/****************************************************************************** - * TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ... - * - * Macros that specify the maximum lengths (number of characters) for names of - * kernel objects, such as tasks and queues. If longer names are used, they will - * be truncated when stored in the recorder. - *****************************************************************************/ -#define TRC_CFG_NAME_LEN_TASK 15 -#define TRC_CFG_NAME_LEN_ISR 15 -#define TRC_CFG_NAME_LEN_QUEUE 15 -#define TRC_CFG_NAME_LEN_SEMAPHORE 15 -#define TRC_CFG_NAME_LEN_MUTEX 15 -#define TRC_CFG_NAME_LEN_TIMER 15 -#define TRC_CFG_NAME_LEN_EVENTGROUP 15 -#define TRC_CFG_NAME_LEN_STREAMBUFFER 15 -#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 - -/****************************************************************************** - *** ADVANCED SETTINGS ******************************************************** - ****************************************************************************** - * The remaining settings are not necessary to modify but allows for optimizing - * the recorder setup for your specific needs, e.g., to exclude events that you - * are not interested in, in order to get longer traces. - *****************************************************************************/ - -/****************************************************************************** -* TRC_CFG_HEAP_SIZE_BELOW_16M -* -* An integer constant that can be used to reduce the buffer usage of memory -* allocation events (malloc/free). This value should be 1 if the heap size is -* below 16 MB (2^24 byte), and you can live with reported addresses showing the -* lower 24 bits only. If 0, you get the full 32-bit addresses. -* -* Default value is 0. -******************************************************************************/ -#define TRC_CFG_HEAP_SIZE_BELOW_16M 0 - -/****************************************************************************** - * TRC_CFG_USE_IMPLICIT_IFE_RULES - * - * Macro which should be defined as either zero (0) or one (1). - * Default is 1. - * - * Tracealyzer groups the events into "instances" based on Instance Finish - * Events (IFEs), produced either by default rules or calls to the recorder - * functions vTraceInstanceFinishedNow and vTraceInstanceFinishedNext. - * - * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is - * used, resulting in a "typical" grouping of events into instances. - * If these rules don't give appropriate instances in your case, you can - * override the default rules using vTraceInstanceFinishedNow/Next for one - * or several tasks. The default IFE rules are then disabled for those tasks. - * - * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are - * disabled globally. You must then call vTraceInstanceFinishedNow or - * vTraceInstanceFinishedNext to manually group the events into instances, - * otherwise the tasks will appear a single long instance. - * - * The default IFE rules count the following events as "instance finished": - * - Task delay, delay until - * - Task suspend - * - Blocking on "input" operations, i.e., when the task is waiting for the - * next a message/signal/event. But only if this event is blocking. - * - * For details, see trcSnapshotKernelPort.h and look for references to the - * macro trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED. - *****************************************************************************/ -#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1 - -/****************************************************************************** - * TRC_CFG_USE_16BIT_OBJECT_HANDLES - * - * Macro which should be defined as either zero (0) or one (1). - * - * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel - * objects such as tasks and queues. This limits the supported number of - * concurrently active objects to 255 of each type (tasks, queues, mutexes, - * etc.) Note: 255, not 256, since handle 0 is reserved. - * - * If set to 1 (one), the recorder uses 16-bit handles to identify kernel - * objects such as tasks and queues. This limits the supported number of - * concurrent objects to 65535 of each type (object class). However, since the - * object property table is limited to 64 KB, the practical limit is about - * 3000 objects in total. - * - * Default is 0 (8-bit handles) - * - * NOTE: An object with handle above 255 will use an extra 4-byte record in - * the event buffer whenever the object is referenced. Moreover, some internal - * tables in the recorder gets slightly larger when using 16-bit handles. - *****************************************************************************/ -#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0 - -/****************************************************************************** - * TRC_CFG_USE_TRACE_ASSERT - * - * Macro which should be defined as either zero (0) or one (1). - * Default is 1. - * - * If this is one (1), the TRACE_ASSERT macro (used at various locations in the - * trace recorder) will verify that a relevant condition is true. - * If the condition is false, prvTraceError() will be called, which stops the - * recording and stores an error message that is displayed when opening the - * trace in Tracealyzer. - * - * This is used on several places in the recorder code for sanity checks on - * parameters. Can be switched off to reduce the footprint of the tracing, but - * we recommend to have it enabled initially. - *****************************************************************************/ -#define TRC_CFG_USE_TRACE_ASSERT 1 - -/******************************************************************************* - * TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER - * - * Macro which should be defined as an integer value. - * - * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the - * separate user event buffer (UB). - * In this mode, user events are stored separately from other events, - * e.g., RTOS events. Thereby you can get a much longer history of - * user events as they don't need to share the buffer space with more - * frequent events. - * - * The UB is typically used with the snapshot ring-buffer mode, so the - * recording can continue when the main buffer gets full. And since the - * main buffer then overwrites the earliest events, Tracealyzer displays - * "Unknown Actor" instead of task scheduling for periods with UB data only. - * - * In UB mode, user events are structured as UB channels, which contains - * a channel name and a default format string. Register a UB channel using - * xTraceRegisterUBChannel. - * - * Events and data arguments are written using vTraceUBEvent and - * vTraceUBData. They are designed to provide efficient logging of - * repeating events, using the same format string within each channel. - * - * Examples: - * - * traceString chn1 = xTraceRegisterString("Channel 1"); - * traceString fmt1 = xTraceRegisterString("Event!"); - * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); - * - * traceString chn2 = xTraceRegisterString("Channel 2"); - * traceString fmt2 = xTraceRegisterString("X: %d, Y: %d"); - * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); - * - * // Result in "[Channel 1] Event!" - * vTraceUBEvent(UBCh1); - * - * // Result in "[Channel 2] X: 23, Y: 19" - * vTraceUBData(UBCh2, 23, 19); - * - * You can also use the other user event functions, like vTracePrintF. - * as they are then rerouted to the UB instead of the main event buffer. - * vTracePrintF then looks up the correct UB channel based on the - * provided channel name and format string, or creates a new UB channel - * if no match is found. The format string should therefore not contain - * "random" messages but mainly format specifiers. Random strings should - * be stored using %s and with the string as an argument. - * - * // Creates a new UB channel ("Channel 2", "%Z: %d") - * vTracePrintF(chn2, "%Z: %d", value1); - * - * // Finds the existing UB channel - * vTracePrintF(chn2, "%Z: %d", value2); - - ******************************************************************************/ -#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0 - -/******************************************************************************* - * TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE - * - * Macro which should be defined as an integer value. - * - * This defines the capacity of the user event buffer (UB), in number of slots. - * A single user event can use multiple slots, depending on the arguments. - * - * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. - ******************************************************************************/ -#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200 - -/******************************************************************************* - * TRC_CFG_UB_CHANNELS - * - * Macro which should be defined as an integer value. - * - * This defines the number of User Event Buffer Channels (UB channels). - * These are used to structure the events when using the separate user - * event buffer, and contains both a User Event Channel (the name) and - * a default format string for the channel. - * - * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. - ******************************************************************************/ -#define TRC_CFG_UB_CHANNELS 32 - -/******************************************************************************* - * TRC_CFG_ISR_TAILCHAINING_THRESHOLD - * - * Macro which should be defined as an integer value. - * - * If tracing multiple ISRs, this setting allows for accurate display of the - * context-switching also in cases when the ISRs execute in direct sequence. - * - * vTraceStoreISREnd normally assumes that the ISR returns to the previous - * context, i.e., a task or a preempted ISR. But if another traced ISR - * executes in direct sequence, Tracealyzer may incorrectly display a minimal - * fragment of the previous context in between the ISRs. - * - * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is - * however a threshold value that must be measured for your specific setup. - * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ - * - * The default setting is 0, meaning "disabled" and that you may get an - * extra fragments of the previous context in between tail-chained ISRs. - * - * Note: This setting has separate definitions in trcSnapshotConfig.h and - * trcStreamingConfig.h, since it is affected by the recorder mode. - ******************************************************************************/ -#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 - -#endif /*TRC_SNAPSHOT_CONFIG_H*/ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v4.1.4 + * Percepio AB, www.percepio.com + * + * trcSnapshotConfig.h + * + * Configuration parameters for trace recorder library in snapshot mode. + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2018. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_SNAPSHOT_CONFIG_H +#define TRC_SNAPSHOT_CONFIG_H + +#define TRC_SNAPSHOT_MODE_RING_BUFFER ( 0x01 ) +#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL ( 0x02 ) + +/****************************************************************************** + * TRC_CFG_SNAPSHOT_MODE + * + * Macro which should be defined as one of: + * - TRC_SNAPSHOT_MODE_RING_BUFFER + * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL + * Default is TRC_SNAPSHOT_MODE_RING_BUFFER. + * + * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the + * events are stored in a ring buffer, i.e., where the oldest events are + * overwritten when the buffer becomes full. This allows you to get the last + * events leading up to an interesting state, e.g., an error, without having + * to store the whole run since startup. + * + * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the + * recording is stopped when the buffer becomes full. This is useful for + * recording events following a specific state, e.g., the startup sequence. + *****************************************************************************/ +#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER + +/******************************************************************************* + * TRC_CFG_EVENT_BUFFER_SIZE + * + * Macro which should be defined as an integer value. + * + * This defines the capacity of the event buffer, i.e., the number of records + * it may store. Most events use one record (4 byte), although some events + * require multiple 4-byte records. You should adjust this to the amount of RAM + * available in the target system. + * + * Default value is 1000, which means that 4000 bytes is allocated for the + * event buffer. + ******************************************************************************/ +#define TRC_CFG_EVENT_BUFFER_SIZE 15000 + +/******************************************************************************* + * TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE... + * + * A group of macros which should be defined as integer values, zero or larger. + * + * These define the capacity of the Object Property Table, i.e., the maximum + * number of objects active at any given point, within each object class (e.g., + * task, queue, semaphore, ...). + * + * If tasks or other objects are deleted in your system, this + * setting does not limit the total amount of objects created, only the number + * of objects that have been successfully created but not yet deleted. + * + * Using too small values will cause vTraceError to be called, which stores an + * error message in the trace that is shown when opening the trace file. The + * error message can also be retrieved using xTraceGetLastError. + * + * It can be wise to start with large values for these constants, + * unless you are very confident on these numbers. Then do a recording and + * check the actual usage by selecting View menu -> Trace Details -> + * Resource Usage -> Object Table. + ******************************************************************************/ +#define TRC_CFG_NTASK 150 +#define TRC_CFG_NISR 90 +#define TRC_CFG_NQUEUE 90 +#define TRC_CFG_NSEMAPHORE 90 +#define TRC_CFG_NMUTEX 90 +#define TRC_CFG_NTIMER 250 +#define TRC_CFG_NEVENTGROUP 90 +#define TRC_CFG_NSTREAMBUFFER 50 +#define TRC_CFG_NMESSAGEBUFFER 50 + + +/****************************************************************************** + * TRC_CFG_INCLUDE_FLOAT_SUPPORT + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the support for logging floating point values in + * vTracePrintF is stripped out, in case floating point values are not used or + * supported by the platform used. + * + * Floating point values are only used in vTracePrintF and its subroutines, to + * allow for storing float (%f) or double (%lf) arguments. + * + * vTracePrintF can be used with integer and string arguments in either case. + * + * Default value is 0. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 + +/******************************************************************************* + * TRC_CFG_SYMBOL_TABLE_SIZE + * + * Macro which should be defined as an integer value. + * + * This defines the capacity of the symbol table, in bytes. This symbol table + * stores User Events labels and names of deleted tasks, queues, or other kernel + * objects. If you don't use User Events or delete any kernel + * objects you set this to a very low value. The minimum recommended value is 4. + * A size of zero (0) is not allowed since a zero-sized array may result in a + * 32-bit pointer, i.e., using 4 bytes rather than 0. + * + * Default value is 800. + ******************************************************************************/ +#define TRC_CFG_SYMBOL_TABLE_SIZE 5000 + +#if ( TRC_CFG_SYMBOL_TABLE_SIZE == 0 ) + #error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!" +#endif + +/****************************************************************************** + * TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ... + * + * Macros that specify the maximum lengths (number of characters) for names of + * kernel objects, such as tasks and queues. If longer names are used, they will + * be truncated when stored in the recorder. + *****************************************************************************/ +#define TRC_CFG_NAME_LEN_TASK 15 +#define TRC_CFG_NAME_LEN_ISR 15 +#define TRC_CFG_NAME_LEN_QUEUE 15 +#define TRC_CFG_NAME_LEN_SEMAPHORE 15 +#define TRC_CFG_NAME_LEN_MUTEX 15 +#define TRC_CFG_NAME_LEN_TIMER 15 +#define TRC_CFG_NAME_LEN_EVENTGROUP 15 +#define TRC_CFG_NAME_LEN_STREAMBUFFER 15 +#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 + +/****************************************************************************** + *** ADVANCED SETTINGS ******************************************************** + ****************************************************************************** + * The remaining settings are not necessary to modify but allows for optimizing + * the recorder setup for your specific needs, e.g., to exclude events that you + * are not interested in, in order to get longer traces. + *****************************************************************************/ + +/****************************************************************************** +* TRC_CFG_HEAP_SIZE_BELOW_16M +* +* An integer constant that can be used to reduce the buffer usage of memory +* allocation events (malloc/free). This value should be 1 if the heap size is +* below 16 MB (2^24 byte), and you can live with reported addresses showing the +* lower 24 bits only. If 0, you get the full 32-bit addresses. +* +* Default value is 0. +******************************************************************************/ +#define TRC_CFG_HEAP_SIZE_BELOW_16M 0 + +/****************************************************************************** + * TRC_CFG_USE_IMPLICIT_IFE_RULES + * + * Macro which should be defined as either zero (0) or one (1). + * Default is 1. + * + * Tracealyzer groups the events into "instances" based on Instance Finish + * Events (IFEs), produced either by default rules or calls to the recorder + * functions vTraceInstanceFinishedNow and vTraceInstanceFinishedNext. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is + * used, resulting in a "typical" grouping of events into instances. + * If these rules don't give appropriate instances in your case, you can + * override the default rules using vTraceInstanceFinishedNow/Next for one + * or several tasks. The default IFE rules are then disabled for those tasks. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are + * disabled globally. You must then call vTraceInstanceFinishedNow or + * vTraceInstanceFinishedNext to manually group the events into instances, + * otherwise the tasks will appear a single long instance. + * + * The default IFE rules count the following events as "instance finished": + * - Task delay, delay until + * - Task suspend + * - Blocking on "input" operations, i.e., when the task is waiting for the + * next a message/signal/event. But only if this event is blocking. + * + * For details, see trcSnapshotKernelPort.h and look for references to the + * macro trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED. + *****************************************************************************/ +#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1 + +/****************************************************************************** + * TRC_CFG_USE_16BIT_OBJECT_HANDLES + * + * Macro which should be defined as either zero (0) or one (1). + * + * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrently active objects to 255 of each type (tasks, queues, mutexes, + * etc.) Note: 255, not 256, since handle 0 is reserved. + * + * If set to 1 (one), the recorder uses 16-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrent objects to 65535 of each type (object class). However, since the + * object property table is limited to 64 KB, the practical limit is about + * 3000 objects in total. + * + * Default is 0 (8-bit handles) + * + * NOTE: An object with handle above 255 will use an extra 4-byte record in + * the event buffer whenever the object is referenced. Moreover, some internal + * tables in the recorder gets slightly larger when using 16-bit handles. + *****************************************************************************/ +#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0 + +/****************************************************************************** + * TRC_CFG_USE_TRACE_ASSERT + * + * Macro which should be defined as either zero (0) or one (1). + * Default is 1. + * + * If this is one (1), the TRACE_ASSERT macro (used at various locations in the + * trace recorder) will verify that a relevant condition is true. + * If the condition is false, prvTraceError() will be called, which stops the + * recording and stores an error message that is displayed when opening the + * trace in Tracealyzer. + * + * This is used on several places in the recorder code for sanity checks on + * parameters. Can be switched off to reduce the footprint of the tracing, but + * we recommend to have it enabled initially. + *****************************************************************************/ +#define TRC_CFG_USE_TRACE_ASSERT 1 + +/******************************************************************************* + * TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER + * + * Macro which should be defined as an integer value. + * + * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the + * separate user event buffer (UB). + * In this mode, user events are stored separately from other events, + * e.g., RTOS events. Thereby you can get a much longer history of + * user events as they don't need to share the buffer space with more + * frequent events. + * + * The UB is typically used with the snapshot ring-buffer mode, so the + * recording can continue when the main buffer gets full. And since the + * main buffer then overwrites the earliest events, Tracealyzer displays + * "Unknown Actor" instead of task scheduling for periods with UB data only. + * + * In UB mode, user events are structured as UB channels, which contains + * a channel name and a default format string. Register a UB channel using + * xTraceRegisterUBChannel. + * + * Events and data arguments are written using vTraceUBEvent and + * vTraceUBData. They are designed to provide efficient logging of + * repeating events, using the same format string within each channel. + * + * Examples: + * + * traceString chn1 = xTraceRegisterString("Channel 1"); + * traceString fmt1 = xTraceRegisterString("Event!"); + * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); + * + * traceString chn2 = xTraceRegisterString("Channel 2"); + * traceString fmt2 = xTraceRegisterString("X: %d, Y: %d"); + * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); + * + * // Result in "[Channel 1] Event!" + * vTraceUBEvent(UBCh1); + * + * // Result in "[Channel 2] X: 23, Y: 19" + * vTraceUBData(UBCh2, 23, 19); + * + * You can also use the other user event functions, like vTracePrintF. + * as they are then rerouted to the UB instead of the main event buffer. + * vTracePrintF then looks up the correct UB channel based on the + * provided channel name and format string, or creates a new UB channel + * if no match is found. The format string should therefore not contain + * "random" messages but mainly format specifiers. Random strings should + * be stored using %s and with the string as an argument. + * + * // Creates a new UB channel ("Channel 2", "%Z: %d") + * vTracePrintF(chn2, "%Z: %d", value1); + * + * // Finds the existing UB channel + * vTracePrintF(chn2, "%Z: %d", value2); + * + ******************************************************************************/ +#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0 + +/******************************************************************************* + * TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE + * + * Macro which should be defined as an integer value. + * + * This defines the capacity of the user event buffer (UB), in number of slots. + * A single user event can use multiple slots, depending on the arguments. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + ******************************************************************************/ +#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200 + +/******************************************************************************* + * TRC_CFG_UB_CHANNELS + * + * Macro which should be defined as an integer value. + * + * This defines the number of User Event Buffer Channels (UB channels). + * These are used to structure the events when using the separate user + * event buffer, and contains both a User Event Channel (the name) and + * a default format string for the channel. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + ******************************************************************************/ +#define TRC_CFG_UB_CHANNELS 32 + +/******************************************************************************* + * TRC_CFG_ISR_TAILCHAINING_THRESHOLD + * + * Macro which should be defined as an integer value. + * + * If tracing multiple ISRs, this setting allows for accurate display of the + * context-switching also in cases when the ISRs execute in direct sequence. + * + * vTraceStoreISREnd normally assumes that the ISR returns to the previous + * context, i.e., a task or a preempted ISR. But if another traced ISR + * executes in direct sequence, Tracealyzer may incorrectly display a minimal + * fragment of the previous context in between the ISRs. + * + * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is + * however a threshold value that must be measured for your specific setup. + * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ + * + * The default setting is 0, meaning "disabled" and that you may get an + * extra fragments of the previous context in between tail-chained ISRs. + * + * Note: This setting has separate definitions in trcSnapshotConfig.h and + * trcStreamingConfig.h, since it is affected by the recorder mode. + ******************************************************************************/ +#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 + +#endif /*TRC_SNAPSHOT_CONFIG_H*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c index f44eba5ac..261192fbc 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c @@ -1,220 +1,219 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -#pragma comment( lib, "ws2_32.lib" ) - -/* Win32 includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -/* Dimensions the buffer into which input characters are placed. */ -#define cmdMAX_INPUT_SIZE 60 - -/* Dimensions the buffer into which string outputs can be placed. */ -#define cmdMAX_OUTPUT_SIZE 1024 - -/* Dimensions the buffer passed to the recvfrom() call. */ -#define cmdSOCKET_INPUT_BUFFER_SIZE 60 - -/* - * Open and configure the UDP socket. - */ -static SOCKET prvOpenUDPSocket( void ); - -/*-----------------------------------------------------------*/ - -/* - * Task that provides the input and output for the FreeRTOS+CLI command - * interpreter. In this case a UDP port is used. See the URL in the comments - * within main.c for the location of the online documentation. - */ -void vUDPCommandInterpreterTask( void *pvParameters ) -{ -long lBytes, lByte; -signed char cInChar, cInputIndex = 0; -static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ]; -BaseType_t xMoreDataToFollow; -volatile int iErrorCode = 0; -struct sockaddr_in xClient; -int xClientAddressLength = sizeof( struct sockaddr_in ); -SOCKET xSocket; - - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; - - /* Attempt to open the socket. */ - xSocket = prvOpenUDPSocket(); - - if( xSocket != INVALID_SOCKET ) - { - for( ;; ) - { - /* Wait for incoming data on the opened socket. */ - lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength ); - - if( lBytes == SOCKET_ERROR ) - { - /* Something went wrong, but it is not handled by this simple - example. */ - iErrorCode = WSAGetLastError(); - } - else - { - /* Process each received byte in turn. */ - lByte = 0; - while( lByte < lBytes ) - { - /* The next character in the input buffer. */ - cInChar = cLocalBuffer[ lByte ]; - lByte++; - - /* Newline characters are taken as the end of the command - string. */ - if( cInChar == '\n' ) - { - /* Process the input string received prior to the - newline. */ - do - { - /* Pass the string to FreeRTOS+CLI. */ - xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE ); - - /* Send the output generated by the command's - implementation. */ - sendto( xSocket, cOutputString, strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); - - } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */ - - /* All the strings generated by the command processing - have been sent. Clear the input string ready to receive - the next command. */ - cInputIndex = 0; - memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); - - /* Transmit a spacer, just to make the command console - easier to read. */ - sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); - } - else - { - if( cInChar == '\r' ) - { - /* Ignore the character. Newlines are used to - detect the end of the input string. */ - } - else if( cInChar == '\b' ) - { - /* Backspace was pressed. Erase the last character - in the string - if any. */ - if( cInputIndex > 0 ) - { - cInputIndex--; - cInputString[ cInputIndex ] = '\0'; - } - } - else - { - /* A character was entered. Add it to the string - entered so far. When a \n is entered the complete - string will be passed to the command interpreter. */ - if( cInputIndex < cmdMAX_INPUT_SIZE ) - { - cInputString[ cInputIndex ] = cInChar; - cInputIndex++; - } - } - } - } - } - } - } - else - { - /* The socket could not be opened. */ - vTaskDelete( NULL ); - } -} -/*-----------------------------------------------------------*/ - -static SOCKET prvOpenUDPSocket( void ) -{ -WSADATA xWSAData; -WORD wVersionRequested; -struct sockaddr_in xServer; -SOCKET xSocket = INVALID_SOCKET; - - wVersionRequested = MAKEWORD( 2, 2 ); - - /* Prepare to use WinSock. */ - if( WSAStartup( wVersionRequested, &xWSAData ) != 0 ) - { - fprintf( stderr, "Could not open Windows connection.\n" ); - } - else - { - xSocket = socket( AF_INET, SOCK_DGRAM, 0 ); - if( xSocket == INVALID_SOCKET) - { - fprintf( stderr, "Could not create socket.\n" ); - WSACleanup(); - } - else - { - /* Zero out the server structure. */ - memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) ); - - /* Set family and port. */ - xServer.sin_family = AF_INET; - xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER ); - - /* Assign the loopback address */ - xServer.sin_addr.S_un.S_un_b.s_b1 = 127; - xServer.sin_addr.S_un.S_un_b.s_b2 = 0; - xServer.sin_addr.S_un.S_un_b.s_b3 = 0; - xServer.sin_addr.S_un.S_un_b.s_b4 = 1; - - /* Bind the address to the socket. */ - if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 ) - { - fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER ); - closesocket( xSocket ); - xSocket = INVALID_SOCKET; - WSACleanup(); - } - } - } - - return xSocket; -} - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#pragma comment( lib, "ws2_32.lib" ) + +/* Win32 includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* Dimensions the buffer into which input characters are placed. */ +#define cmdMAX_INPUT_SIZE 60 + +/* Dimensions the buffer into which string outputs can be placed. */ +#define cmdMAX_OUTPUT_SIZE 1024 + +/* Dimensions the buffer passed to the recvfrom() call. */ +#define cmdSOCKET_INPUT_BUFFER_SIZE 60 + +/* + * Open and configure the UDP socket. + */ +static SOCKET prvOpenUDPSocket( void ); + +/*-----------------------------------------------------------*/ + +/* + * Task that provides the input and output for the FreeRTOS+CLI command + * interpreter. In this case a UDP port is used. See the URL in the comments + * within main.c for the location of the online documentation. + */ +void vUDPCommandInterpreterTask( void * pvParameters ) +{ + long lBytes, lByte; + signed char cInChar, cInputIndex = 0; + static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ]; + BaseType_t xMoreDataToFollow; + volatile int iErrorCode = 0; + struct sockaddr_in xClient; + int xClientAddressLength = sizeof( struct sockaddr_in ); + SOCKET xSocket; + + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; + + /* Attempt to open the socket. */ + xSocket = prvOpenUDPSocket(); + + if( xSocket != INVALID_SOCKET ) + { + for( ; ; ) + { + /* Wait for incoming data on the opened socket. */ + lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength ); + + if( lBytes == SOCKET_ERROR ) + { + /* Something went wrong, but it is not handled by this simple + * example. */ + iErrorCode = WSAGetLastError(); + } + else + { + /* Process each received byte in turn. */ + lByte = 0; + + while( lByte < lBytes ) + { + /* The next character in the input buffer. */ + cInChar = cLocalBuffer[ lByte ]; + lByte++; + + /* Newline characters are taken as the end of the command + * string. */ + if( cInChar == '\n' ) + { + /* Process the input string received prior to the + * newline. */ + do + { + /* Pass the string to FreeRTOS+CLI. */ + xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE ); + + /* Send the output generated by the command's + * implementation. */ + sendto( xSocket, cOutputString, strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); + } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */ + + /* All the strings generated by the command processing + * have been sent. Clear the input string ready to receive + * the next command. */ + cInputIndex = 0; + memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); + + /* Transmit a spacer, just to make the command console + * easier to read. */ + sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); + } + else + { + if( cInChar == '\r' ) + { + /* Ignore the character. Newlines are used to + * detect the end of the input string. */ + } + else if( cInChar == '\b' ) + { + /* Backspace was pressed. Erase the last character + * in the string - if any. */ + if( cInputIndex > 0 ) + { + cInputIndex--; + cInputString[ cInputIndex ] = '\0'; + } + } + else + { + /* A character was entered. Add it to the string + * entered so far. When a \n is entered the complete + * string will be passed to the command interpreter. */ + if( cInputIndex < cmdMAX_INPUT_SIZE ) + { + cInputString[ cInputIndex ] = cInChar; + cInputIndex++; + } + } + } + } + } + } + } + else + { + /* The socket could not be opened. */ + vTaskDelete( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static SOCKET prvOpenUDPSocket( void ) +{ + WSADATA xWSAData; + WORD wVersionRequested; + struct sockaddr_in xServer; + SOCKET xSocket = INVALID_SOCKET; + + wVersionRequested = MAKEWORD( 2, 2 ); + + /* Prepare to use WinSock. */ + if( WSAStartup( wVersionRequested, &xWSAData ) != 0 ) + { + fprintf( stderr, "Could not open Windows connection.\n" ); + } + else + { + xSocket = socket( AF_INET, SOCK_DGRAM, 0 ); + + if( xSocket == INVALID_SOCKET ) + { + fprintf( stderr, "Could not create socket.\n" ); + WSACleanup(); + } + else + { + /* Zero out the server structure. */ + memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) ); + + /* Set family and port. */ + xServer.sin_family = AF_INET; + xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER ); + + /* Assign the loopback address */ + xServer.sin_addr.S_un.S_un_b.s_b1 = 127; + xServer.sin_addr.S_un.S_un_b.s_b2 = 0; + xServer.sin_addr.S_un.S_un_b.s_b3 = 0; + xServer.sin_addr.S_un.S_un_b.s_b4 = 1; + + /* Bind the address to the socket. */ + if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 ) + { + fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER ); + closesocket( xSocket ); + xSocket = INVALID_SOCKET; + WSACleanup(); + } + } + } + + return xSocket; +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/WIN32.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/WIN32.vcxproj index 7f5d44435..9fd48a71d 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/WIN32.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/WIN32.vcxproj @@ -1,162 +1,162 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {C686325E-3261-42F7-AEB1-DDE5280E1CEB} - RTOSDemo - - - - Application - false - MultiByte - v142 - - - Application - false - MultiByte - v142 - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - .\Debug\ - .\Debug\ - true - .\Release\ - .\Release\ - false - - - - .\Debug/WIN32.tlb - - - - - Disabled - ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;.;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/WIN32.pch - .\Debug/ - .\Debug/ - .\Debug/ - Level4 - true - false - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c09 - - - .\Debug/RTOSDemo.exe - true - true - .\Debug/WIN32.pdb - Console - MachineX86 - %(AdditionalDependencies) - - - - - true - .\Debug/WIN32.bsc - - - - - .\Release/WIN32.tlb - - - - - MaxSpeed - OnlyExplicitInline - _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/WIN32.pch - .\Release/ - .\Release/ - .\Release/ - Level3 - true - ..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;.\lwIP_Apps;.;%(AdditionalIncludeDirectories) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c09 - - - .\Release/RTOSDemo.exe - true - .\Release/WIN32.pdb - Console - MachineX86 - ..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap - wpcap.lib;%(AdditionalDependencies) - - - true - .\Release/WIN32.bsc - - - - - - - - - - - - - - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {C686325E-3261-42F7-AEB1-DDE5280E1CEB} + RTOSDemo + + + + Application + false + MultiByte + v142 + + + Application + false + MultiByte + v142 + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\Debug\ + .\Debug\ + true + .\Release\ + .\Release\ + false + + + + .\Debug/WIN32.tlb + + + + + Disabled + ..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\FreeRTOS-Plus-CLI;.\Trace_Recorder_Configuration;.;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + .\Debug/WIN32.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level4 + true + false + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + .\Debug/RTOSDemo.exe + true + true + .\Debug/WIN32.pdb + Console + MachineX86 + %(AdditionalDependencies) + + + + + true + .\Debug/WIN32.bsc + + + + + .\Release/WIN32.tlb + + + + + MaxSpeed + OnlyExplicitInline + _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Release/WIN32.pch + .\Release/ + .\Release/ + .\Release/ + Level3 + true + ..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;.\lwIP_Apps;.;%(AdditionalIncludeDirectories) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + .\Release/RTOSDemo.exe + true + .\Release/WIN32.pdb + Console + MachineX86 + ..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap + wpcap.lib;%(AdditionalDependencies) + + + true + .\Release/WIN32.bsc + + + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/WIN32.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/WIN32.vcxproj.filters index fb4c5b7f5..a238741cc 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/WIN32.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/WIN32.vcxproj.filters @@ -1,101 +1,101 @@ - - - - - {38712199-cebf-4124-bf15-398f7c3419ea} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - {34567deb-d5ab-4a56-8640-0aaec609521a} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {af3445a1-4908-4170-89ed-39345d90d30c} - - - {f32be356-4763-4cae-9020-974a2638cb08} - *.c - - - {88f409e6-d396-4ac5-94bd-7a99c914be46} - - - {e5ad4ec7-23dc-4295-8add-2acaee488f5a} - - - {629e761f-e8a8-430e-b44e-f38d83292b54} - - - {19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4} - - - - - {fd43c0ed-fdbc-437f-a5a3-c50399690bd7} - - - {91dffc7b-279b-44f6-a2b2-f5d2e132a85d} - - - - - Demo App Source - - - FreeRTOS\Source\Portable - - - FreeRTOS\Source\Portable - - - FreeRTOS\Source - - - FreeRTOS\Source - - - FreeRTOS\Source - - - FreeRTOS\Source - - - Demo App Source - - - Demo App Source - - - Demo App Source - - - FreeRTOS+\FreeRTOS+CLI - - - FreeRTOS+\FreeRTOS+Trace - - - FreeRTOS+\FreeRTOS+Trace - - - FreeRTOS+\FreeRTOS+Trace - - - FreeRTOS\Source - - - FreeRTOS\Source - - - - - FreeRTOS\Configuration Files - - - Demo App Source\Trace Recorder Configuration - - - Demo App Source\Trace Recorder Configuration - - + + + + + {38712199-cebf-4124-bf15-398f7c3419ea} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {34567deb-d5ab-4a56-8640-0aaec609521a} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {af3445a1-4908-4170-89ed-39345d90d30c} + + + {f32be356-4763-4cae-9020-974a2638cb08} + *.c + + + {88f409e6-d396-4ac5-94bd-7a99c914be46} + + + {e5ad4ec7-23dc-4295-8add-2acaee488f5a} + + + {629e761f-e8a8-430e-b44e-f38d83292b54} + + + {19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4} + + + + + {fd43c0ed-fdbc-437f-a5a3-c50399690bd7} + + + {91dffc7b-279b-44f6-a2b2-f5d2e132a85d} + + + + + Demo App Source + + + FreeRTOS\Source\Portable + + + FreeRTOS\Source\Portable + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source + + + Demo App Source + + + Demo App Source + + + Demo App Source + + + FreeRTOS+\FreeRTOS+CLI + + + FreeRTOS+\FreeRTOS+Trace + + + FreeRTOS+\FreeRTOS+Trace + + + FreeRTOS+\FreeRTOS+Trace + + + FreeRTOS\Source + + + FreeRTOS\Source + + + + + FreeRTOS\Configuration Files + + + Demo App Source\Trace Recorder Configuration + + + Demo App Source\Trace Recorder Configuration + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/main.c index 9be1c776e..cb73bac98 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/main.c @@ -1,252 +1,252 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - ****************************************************************************** - * -NOTE- The Win32 port is a simulation (or is that emulation?) only! Do not - * expect to get real time behaviour from the Win32 port or this demo - * application. It is provided as a convenient development and demonstration - * test bed only. This was tested using Windows XP on a dual core laptop. - * - * Windows will not be running the FreeRTOS simulator threads continuously, so - * the timing information in the FreeRTOS+Trace logs have no meaningful units. - * See the documentation page for the Windows simulator for an explanation of - * the slow timing: - * https://www.FreeRTOS.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html - * - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT - - * - * Documentation for this demo can be found on: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_Trace/Free_RTOS_Plus_Trace_CLI_Example.shtml - ****************************************************************************** - * - * This is a simple FreeRTOS Windows simulator project that makes it easy to - * evaluate FreeRTOS+CLI and FreeRTOS+Trace on a standard desktop PC, without - * any external hardware or interfaces being required. - * - * To keep everything as simple as possible, the command line interface is - * accessed through a UDP socket on the default Windows loopback IP address of - * 127.0.0.1. Full instructions are provided on the documentation page - * referenced above. - * - * Commands are provided to both start and stop a FreeRTOS+Trace recording. - * Stopping a recording will result in the recorded data being saved to the - * hard disk, ready for viewing in the FreeRTOS+Trace graphical user interface. - * Again, full instructions are provided on the documentation page referenced - * above. - * - * A queue send task and a queue receive task are defined in this file. The - * queue receive task spends most of its time blocked on the queue waiting for - * messages to arrive. The queue send task periodically sends a message to the - * queue, causing the queue receive task to exit the Blocked state. The - * priority of the queue receive task is above that of the queue send task, so - * it pre-empts the queue send task as soon as it leaves the Blocked state. It - * then consumes the message from the queue and prints "message received" to - * the screen before returning to block on the queue once again. This - * sequencing is clearly visible in the recorded FreeRTOS+Trace data. - * - */ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include -#include "task.h" -#include "queue.h" - -/* FreeRTOS+Trace includes. */ -#include "trcDefines.h" -#include "trcRecorder.h" - -/* Priorities at which the tasks are created. */ -#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) -#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) -#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY ) - -/* The rate at which data is sent to the queue. The (simulated) 250ms value is -converted to ticks using the portTICK_RATE_MS constant. */ -#define mainQUEUE_SEND_FREQUENCY_MS ( 250 / portTICK_RATE_MS ) - -/* The number of items the queue can hold. This is 1 as the receive task -will remove items as they are added, meaning the send task should always find -the queue empty. */ -#define mainQUEUE_LENGTH ( 1 ) - -/*-----------------------------------------------------------*/ - -/* - * The queue send and receive tasks as described in the comments at the top of - * this file. - */ -static void prvQueueReceiveTask( void *pvParameters ); -static void prvQueueSendTask( void *pvParameters ); - -/* - * The task that implements the UDP command interpreter using FreeRTOS+CLI. - */ -extern void vUDPCommandInterpreterTask( void *pvParameters ); - -/* - * Register commands that can be used with FreeRTOS+CLI through the UDP socket. - * The commands are defined in CLI-commands.c. - */ -extern void vRegisterCLICommands( void ); - -/* The queue used by both tasks. */ -static xQueueHandle xQueue = NULL; - -/*-----------------------------------------------------------*/ - -int main( void ) -{ -const uint32_t ulLongTime_ms = 250UL; - - /* Initialise the trace recorder and create the label used to post user - events to the trace recording on each tick interrupt. */ - vTraceEnable( TRC_START ); - - /* Create the queue used to pass messages from the queue send task to the - queue receive task. */ - xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); - - /* Give the queue a name for the FreeRTOS+Trace log. */ - vTraceSetQueueName( xQueue, "DemoQ" ); - - /* Start the two tasks as described in the comments at the top of this - file. */ - xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ - "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ - configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. Not actually used as a stack in the Win32 simulator port. */ - NULL, /* The parameter passed to the task - not used in this example. */ - mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ - NULL ); /* The task handle is not required, so NULL is passed. */ - - xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); - - /* Create the task that handles the CLI on a UDP port. The port number - is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */ - xTaskCreate( vUDPCommandInterpreterTask, "CLI", configMINIMAL_STACK_SIZE, NULL, mainUDP_CLI_TASK_PRIORITY, NULL ); - - /* Register commands with the FreeRTOS+CLI command interpreter. */ - vRegisterCLICommands(); - - /* Start the tasks and timer running. */ - vTaskStartScheduler(); - - /* If all is well, the scheduler will now be running, and the following - line will never be reached. If the following line does execute, then - there was insufficient FreeRTOS heap memory available for the idle and/or - timer tasks to be created. See the memory management section on the - FreeRTOS web site for more details (this is standard text that is not - really applicable to the Win32 simulator port). */ - for( ;; ) - { - Sleep( ulLongTime_ms ); - } -} -/*-----------------------------------------------------------*/ - -static void prvQueueSendTask( void *pvParameters ) -{ -TickType_t xNextWakeTime; -const unsigned long ulValueToSend = 100UL; - - /* Remove warning about unused parameters. */ - ( void ) pvParameters; - - /* Initialise xNextWakeTime - this only needs to be done once. */ - xNextWakeTime = xTaskGetTickCount(); - - for( ;; ) - { - /* Place this task in the blocked state until it is time to run again. - While in the Blocked state this task will not consume any CPU time. */ - vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); - - /* Send to the queue - causing the queue receive task to unblock and - write a message to the display. 0 is used as the block time so the - sending operation will not block - it shouldn't need to block as the - queue should always be empty at this point in the code, and it is an - error if it is not. */ - xQueueSend( xQueue, &ulValueToSend, 0U ); - } -} -/*-----------------------------------------------------------*/ - -static void prvQueueReceiveTask( void *pvParameters ) -{ -unsigned long ulReceivedValue; - - /* Remove warning about unused parameters. */ - ( void ) pvParameters; - - for( ;; ) - { - /* Wait until something arrives in the queue - this task will block - indefinitely provided INCLUDE_vTaskSuspend is set to 1 in - FreeRTOSConfig.h. */ - xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); - - /* To get here something must have been received from the queue, but - is it the expected value? If it is, write the message to the - display before looping back to block on the queue again. */ - if( ulReceivedValue == 100UL ) - { - printf( "Message received!\r\n" ); - ulReceivedValue = 0U; - } - } -} -/*-----------------------------------------------------------*/ - -void vApplicationIdleHook( void ) -{ -const unsigned long ulMSToSleep = 5; - - /* This function is called on each cycle of the idle task if - configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU - load. */ - Sleep( ulMSToSleep ); -} -/*-----------------------------------------------------------*/ - -static uint32_t ulEntryTime = 0; - -void vTraceTimerReset( void ) -{ - ulEntryTime = xTaskGetTickCount(); -} - -uint32_t uiTraceTimerGetFrequency( void ) -{ - return configTICK_RATE_HZ; -} - -uint32_t uiTraceTimerGetValue( void ) -{ - return ( xTaskGetTickCount() - ulEntryTime ); -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + ****************************************************************************** + * -NOTE- The Win32 port is a simulation (or is that emulation?) only! Do not + * expect to get real time behaviour from the Win32 port or this demo + * application. It is provided as a convenient development and demonstration + * test bed only. This was tested using Windows XP on a dual core laptop. + * + * Windows will not be running the FreeRTOS simulator threads continuously, so + * the timing information in the FreeRTOS+Trace logs have no meaningful units. + * See the documentation page for the Windows simulator for an explanation of + * the slow timing: + * https://www.FreeRTOS.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html + * - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT - + * + * Documentation for this demo can be found on: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_Trace/Free_RTOS_Plus_Trace_CLI_Example.shtml + ****************************************************************************** + * + * This is a simple FreeRTOS Windows simulator project that makes it easy to + * evaluate FreeRTOS+CLI and FreeRTOS+Trace on a standard desktop PC, without + * any external hardware or interfaces being required. + * + * To keep everything as simple as possible, the command line interface is + * accessed through a UDP socket on the default Windows loopback IP address of + * 127.0.0.1. Full instructions are provided on the documentation page + * referenced above. + * + * Commands are provided to both start and stop a FreeRTOS+Trace recording. + * Stopping a recording will result in the recorded data being saved to the + * hard disk, ready for viewing in the FreeRTOS+Trace graphical user interface. + * Again, full instructions are provided on the documentation page referenced + * above. + * + * A queue send task and a queue receive task are defined in this file. The + * queue receive task spends most of its time blocked on the queue waiting for + * messages to arrive. The queue send task periodically sends a message to the + * queue, causing the queue receive task to exit the Blocked state. The + * priority of the queue receive task is above that of the queue send task, so + * it pre-empts the queue send task as soon as it leaves the Blocked state. It + * then consumes the message from the queue and prints "message received" to + * the screen before returning to block on the queue once again. This + * sequencing is clearly visible in the recorded FreeRTOS+Trace data. + * + */ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include +#include "task.h" +#include "queue.h" + +/* FreeRTOS+Trace includes. */ +#include "trcDefines.h" +#include "trcRecorder.h" + +/* Priorities at which the tasks are created. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY ) + +/* The rate at which data is sent to the queue. The (simulated) 250ms value is + * converted to ticks using the portTICK_RATE_MS constant. */ +#define mainQUEUE_SEND_FREQUENCY_MS ( 250 / portTICK_RATE_MS ) + +/* The number of items the queue can hold. This is 1 as the receive task + * will remove items as they are added, meaning the send task should always find + * the queue empty. */ +#define mainQUEUE_LENGTH ( 1 ) + +/*-----------------------------------------------------------*/ + +/* + * The queue send and receive tasks as described in the comments at the top of + * this file. + */ +static void prvQueueReceiveTask( void * pvParameters ); +static void prvQueueSendTask( void * pvParameters ); + +/* + * The task that implements the UDP command interpreter using FreeRTOS+CLI. + */ +extern void vUDPCommandInterpreterTask( void * pvParameters ); + +/* + * Register commands that can be used with FreeRTOS+CLI through the UDP socket. + * The commands are defined in CLI-commands.c. + */ +extern void vRegisterCLICommands( void ); + +/* The queue used by both tasks. */ +static xQueueHandle xQueue = NULL; + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + const uint32_t ulLongTime_ms = 250UL; + + /* Initialise the trace recorder and create the label used to post user + * events to the trace recording on each tick interrupt. */ + vTraceEnable( TRC_START ); + + /* Create the queue used to pass messages from the queue send task to the + * queue receive task. */ + xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); + + /* Give the queue a name for the FreeRTOS+Trace log. */ + vTraceSetQueueName( xQueue, "DemoQ" ); + + /* Start the two tasks as described in the comments at the top of this + * file. */ + xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ + "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ + configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. Not actually used as a stack in the Win32 simulator port. */ + NULL, /* The parameter passed to the task - not used in this example. */ + mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ + NULL ); /* The task handle is not required, so NULL is passed. */ + + xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + /* Create the task that handles the CLI on a UDP port. The port number + * is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */ + xTaskCreate( vUDPCommandInterpreterTask, "CLI", configMINIMAL_STACK_SIZE, NULL, mainUDP_CLI_TASK_PRIORITY, NULL ); + + /* Register commands with the FreeRTOS+CLI command interpreter. */ + vRegisterCLICommands(); + + /* Start the tasks and timer running. */ + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + * line will never be reached. If the following line does execute, then + * there was insufficient FreeRTOS heap memory available for the idle and/or + * timer tasks to be created. See the memory management section on the + * FreeRTOS web site for more details (this is standard text that is not + * really applicable to the Win32 simulator port). */ + for( ; ; ) + { + Sleep( ulLongTime_ms ); + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueSendTask( void * pvParameters ) +{ + TickType_t xNextWakeTime; + const unsigned long ulValueToSend = 100UL; + + /* Remove warning about unused parameters. */ + ( void ) pvParameters; + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount(); + + for( ; ; ) + { + /* Place this task in the blocked state until it is time to run again. + * While in the Blocked state this task will not consume any CPU time. */ + vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); + + /* Send to the queue - causing the queue receive task to unblock and + * write a message to the display. 0 is used as the block time so the + * sending operation will not block - it shouldn't need to block as the + * queue should always be empty at this point in the code, and it is an + * error if it is not. */ + xQueueSend( xQueue, &ulValueToSend, 0U ); + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueReceiveTask( void * pvParameters ) +{ + unsigned long ulReceivedValue; + + /* Remove warning about unused parameters. */ + ( void ) pvParameters; + + for( ; ; ) + { + /* Wait until something arrives in the queue - this task will block + * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + * FreeRTOSConfig.h. */ + xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); + + /* To get here something must have been received from the queue, but + * is it the expected value? If it is, write the message to the + * display before looping back to block on the queue again. */ + if( ulReceivedValue == 100UL ) + { + printf( "Message received!\r\n" ); + ulReceivedValue = 0U; + } + } +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + const unsigned long ulMSToSleep = 5; + + /* This function is called on each cycle of the idle task if + * configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU + * load. */ + Sleep( ulMSToSleep ); +} +/*-----------------------------------------------------------*/ + +static uint32_t ulEntryTime = 0; + +void vTraceTimerReset( void ) +{ + ulEntryTime = xTaskGetTickCount(); +} + +uint32_t uiTraceTimerGetFrequency( void ) +{ + return configTICK_RATE_HZ; +} + +uint32_t uiTraceTimerGetValue( void ) +{ + return( xTaskGetTickCount() - ulEntryTime ); +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/readme.txt b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/readme.txt index 1a0cbcfe0..896b84133 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/readme.txt +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/readme.txt @@ -1,7 +1,7 @@ -Directories: - -+ FreeRTOS-Plus/Demo_Projects_Using_FreeRTOS_Simulator/FreeRTOS_Plus_CLI_with_Trace - contains a FreeRTOS windows simulator demo project for both FreeRTOS+CLI and - FreeRTOS+Trace. See http://www.FreeRTOS.org/trace for information on using - the project. - +Directories: + ++ FreeRTOS-Plus/Demo_Projects_Using_FreeRTOS_Simulator/FreeRTOS_Plus_CLI_with_Trace + contains a FreeRTOS windows simulator demo project for both FreeRTOS+CLI and + FreeRTOS+Trace. See http://www.FreeRTOS.org/trace for information on using + the project. + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ReadMe.txt b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ReadMe.txt index 756100103..3771918a4 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ReadMe.txt +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ReadMe.txt @@ -1,7 +1,7 @@ -This demo was removed in FreeRTOS V10.0.0 as FreeRTOS+FAT SL was not distributed -in that release. The full FreeRTOS+FAT product (as opposed to the 'SL' Super -Lean product) is still available. Previous versions of FreeRTOS can be -downloaded from http://sourceforge.net/projects/freertos/files/FreeRTOS/ - - - +This demo was removed in FreeRTOS V10.0.0 as FreeRTOS+FAT SL was not distributed +in that release. The full FreeRTOS+FAT product (as opposed to the 'SL' Super +Lean product) is still available. Previous versions of FreeRTOS can be +downloaded from http://sourceforge.net/projects/freertos/files/FreeRTOS/ + + + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redconf.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redconf.c index 129697fb8..cfa983975 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redconf.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redconf.c @@ -1,17 +1,18 @@ -/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION - UTILITY. DO NOT MODIFY. - - Generated by configuration utility version 2.0 -*/ -/** @file -*/ -#include -#include -#include -#include - - -const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT] = -{ - { 512U, 65536U, false, 256U, 0U, "" } -}; +/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION + * UTILITY. DO NOT MODIFY. + * + * Generated by configuration utility version 2.0 + */ + +/** @file + */ +#include +#include +#include +#include + + +const VOLCONF gaRedVolConf[ REDCONF_VOLUME_COUNT ] = +{ + { 512U, 65536U, false, 256U, 0U, "" } +}; diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redconf.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redconf.h index c0d2f2a6b..0cfecc806 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redconf.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redconf.h @@ -1,112 +1,113 @@ -/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION - UTILITY. DO NOT MODIFY. - - Generated by configuration utility version 2.0 -*/ -/** @file -*/ -#ifndef REDCONF_H -#define REDCONF_H - - -#include - -#define REDCONF_READ_ONLY 0 - -#define REDCONF_API_POSIX 1 - -#define REDCONF_API_FSE 0 - -#define REDCONF_API_POSIX_FORMAT 1 - -#define REDCONF_API_POSIX_LINK 1 - -#define REDCONF_API_POSIX_UNLINK 1 - -#define REDCONF_API_POSIX_MKDIR 1 - -#define REDCONF_API_POSIX_RMDIR 1 - -#define REDCONF_API_POSIX_RENAME 1 - -#define REDCONF_RENAME_ATOMIC 1 - -#define REDCONF_API_POSIX_FTRUNCATE 1 - -#define REDCONF_API_POSIX_READDIR 1 - -#define REDCONF_NAME_MAX 28U - -#define REDCONF_PATH_SEPARATOR '/' - -#define REDCONF_TASK_COUNT 10U - -#define REDCONF_HANDLE_COUNT 10U - -#define REDCONF_API_FSE_FORMAT 0 - -#define REDCONF_API_FSE_TRUNCATE 0 - -#define REDCONF_API_FSE_TRANSMASKGET 0 - -#define REDCONF_API_FSE_TRANSMASKSET 0 - -#define REDCONF_OUTPUT 1 - -#define REDCONF_ASSERTS 1 - -#define REDCONF_BLOCK_SIZE 512U - -#define REDCONF_VOLUME_COUNT 1U - -#define REDCONF_ENDIAN_BIG 0 - -#define REDCONF_ALIGNMENT_SIZE 4U - -#define REDCONF_CRC_ALGORITHM CRC_SLICEBY8 - -#define REDCONF_INODE_BLOCKS 1 - -#define REDCONF_INODE_TIMESTAMPS 1 - -#define REDCONF_ATIME 0 - -#define REDCONF_DIRECT_POINTERS 4U - -#define REDCONF_INDIRECT_POINTERS 32U - -#define REDCONF_BUFFER_COUNT 12U - -#define RedMemCpyUnchecked memcpy - -#define RedMemMoveUnchecked memmove - -#define RedMemSetUnchecked memset - -#define RedMemCmpUnchecked memcmp - -#define RedStrLenUnchecked strlen - -#define RedStrCmpUnchecked strcmp - -#define RedStrNCmpUnchecked strncmp - -#define RedStrNCpyUnchecked strncpy - -#define REDCONF_TRANSACT_DEFAULT (( RED_TRANSACT_CREAT | RED_TRANSACT_MKDIR | RED_TRANSACT_RENAME | RED_TRANSACT_LINK | RED_TRANSACT_UNLINK | RED_TRANSACT_FSYNC | RED_TRANSACT_CLOSE | RED_TRANSACT_VOLFULL | RED_TRANSACT_UMOUNT ) & RED_TRANSACT_MASK) - -#define REDCONF_IMAP_INLINE 0 - -#define REDCONF_IMAP_EXTERNAL 1 - -#define REDCONF_DISCARDS 0 - -#define REDCONF_IMAGE_BUILDER 0 - -#define REDCONF_CHECKER 0 - -#define RED_CONFIG_UTILITY_VERSION 0x2000000U - -#define RED_CONFIG_MINCOMPAT_VER 0x1000200U - -#endif +/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION + * UTILITY. DO NOT MODIFY. + * + * Generated by configuration utility version 2.0 + */ + +/** @file + */ +#ifndef REDCONF_H +#define REDCONF_H + + +#include + +#define REDCONF_READ_ONLY 0 + +#define REDCONF_API_POSIX 1 + +#define REDCONF_API_FSE 0 + +#define REDCONF_API_POSIX_FORMAT 1 + +#define REDCONF_API_POSIX_LINK 1 + +#define REDCONF_API_POSIX_UNLINK 1 + +#define REDCONF_API_POSIX_MKDIR 1 + +#define REDCONF_API_POSIX_RMDIR 1 + +#define REDCONF_API_POSIX_RENAME 1 + +#define REDCONF_RENAME_ATOMIC 1 + +#define REDCONF_API_POSIX_FTRUNCATE 1 + +#define REDCONF_API_POSIX_READDIR 1 + +#define REDCONF_NAME_MAX 28U + +#define REDCONF_PATH_SEPARATOR '/' + +#define REDCONF_TASK_COUNT 10U + +#define REDCONF_HANDLE_COUNT 10U + +#define REDCONF_API_FSE_FORMAT 0 + +#define REDCONF_API_FSE_TRUNCATE 0 + +#define REDCONF_API_FSE_TRANSMASKGET 0 + +#define REDCONF_API_FSE_TRANSMASKSET 0 + +#define REDCONF_OUTPUT 1 + +#define REDCONF_ASSERTS 1 + +#define REDCONF_BLOCK_SIZE 512U + +#define REDCONF_VOLUME_COUNT 1U + +#define REDCONF_ENDIAN_BIG 0 + +#define REDCONF_ALIGNMENT_SIZE 4U + +#define REDCONF_CRC_ALGORITHM CRC_SLICEBY8 + +#define REDCONF_INODE_BLOCKS 1 + +#define REDCONF_INODE_TIMESTAMPS 1 + +#define REDCONF_ATIME 0 + +#define REDCONF_DIRECT_POINTERS 4U + +#define REDCONF_INDIRECT_POINTERS 32U + +#define REDCONF_BUFFER_COUNT 12U + +#define RedMemCpyUnchecked memcpy + +#define RedMemMoveUnchecked memmove + +#define RedMemSetUnchecked memset + +#define RedMemCmpUnchecked memcmp + +#define RedStrLenUnchecked strlen + +#define RedStrCmpUnchecked strcmp + +#define RedStrNCmpUnchecked strncmp + +#define RedStrNCpyUnchecked strncpy + +#define REDCONF_TRANSACT_DEFAULT ( ( RED_TRANSACT_CREAT | RED_TRANSACT_MKDIR | RED_TRANSACT_RENAME | RED_TRANSACT_LINK | RED_TRANSACT_UNLINK | RED_TRANSACT_FSYNC | RED_TRANSACT_CLOSE | RED_TRANSACT_VOLFULL | RED_TRANSACT_UMOUNT ) & RED_TRANSACT_MASK ) + +#define REDCONF_IMAP_INLINE 0 + +#define REDCONF_IMAP_EXTERNAL 1 + +#define REDCONF_DISCARDS 0 + +#define REDCONF_IMAGE_BUILDER 0 + +#define REDCONF_CHECKER 0 + +#define RED_CONFIG_UTILITY_VERSION 0x2000000U + +#define RED_CONFIG_MINCOMPAT_VER 0x1000200U + +#endif /* ifndef REDCONF_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redtypes.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redtypes.h index 8c896db37..c20e3186c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redtypes.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/redtypes.h @@ -1,110 +1,111 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Defines basic types used by Reliance Edge. - - The following types *must* be defined by this header, either directly (using - typedef) or indirectly (by including other headers, such as the C99 headers - stdint.h and stdbool.h): - - - bool: Boolean type, capable of storing true (1) or false (0) - - uint8_t: Unsigned 8-bit integer - - int8_t: Signed 8-bit integer - - uint16_t: Unsigned 16-bit integer - - int16_t: Signed 16-bit integer - - uint32_t: Unsigned 32-bit integer - - int32_t: Signed 32-bit integer - - uint64_t: Unsigned 64-bit integer - - int64_t: Signed 64-bit integer - - uintptr_t: Unsigned integer capable of storing a pointer, preferably the - same size as pointers themselves. - - These types deliberately use the same names as the standard C99 types, so - that if the C99 headers stdint.h and stdbool.h are available, they may be - included here. - - If the user application defines similar types, those may be reused. For - example, suppose there is an application header apptypes.h which defines - types with a similar purpose but different names. That header could be - reused to define the types Reliance Edge needs: - - ~~~{.c} - #include - - typedef BOOL bool; - typedef BYTE uint8_t; - typedef INT8 int8_t; - // And so on... - ~~~ - - If there are neither C99 headers nor suitable types in application headers, - this header should be populated with typedefs that define the required types - in terms of the standard C types. This requires knowledge of the size of - the C types on the target hardware (e.g., how big is an "int" or a pointer). - Below is an example which assumes the target has 8-bit chars, 16-bit shorts, - 32-bit ints, 32-bit pointers, and 64-bit long longs: - - ~~~{.c} - typedef int bool; - typedef unsigned char uint8_t; - typedef signed char int8_t; - typedef unsigned short uint16_t; - typedef short int16_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned long long uint64_t; - typedef long long int64_t; - typedef uint32_t uintptr_t; - ~~~ -*/ -#ifndef REDTYPES_H -#define REDTYPES_H - - -typedef int bool; /**< @brief Boolean type; either true or false. */ - -typedef unsigned __int8 uint8_t; /**< @brief Unsigned 8-bit integer. */ -typedef __int8 int8_t; /**< @brief Signed 8-bit integer. */ - -typedef unsigned __int16 uint16_t; /**< @brief Unsigned 16-bit integer. */ -typedef __int16 int16_t; /**< @brief Signed 16-bit integer. */ - -typedef unsigned __int32 uint32_t; /**< @brief Unsigned 32-bit integer. */ -typedef __int32 int32_t; /**< @brief Signed 32-bit integer. */ - -typedef unsigned __int64 uint64_t; /**< @brief Unsigned 64-bit integer. */ -typedef __int64 int64_t; /**< @brief Signed 64-bit integer. */ - -/** @brief Unsigned integer capable of storing a pointer. -*/ -#ifdef _WIN64 -typedef uint64_t uintptr_t; -#else -typedef uint32_t uintptr_t; -#endif - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Defines basic types used by Reliance Edge. + * + * The following types *must* be defined by this header, either directly (using + * typedef) or indirectly (by including other headers, such as the C99 headers + * stdint.h and stdbool.h): + * + * - bool: Boolean type, capable of storing true (1) or false (0) + * - uint8_t: Unsigned 8-bit integer + * - int8_t: Signed 8-bit integer + * - uint16_t: Unsigned 16-bit integer + * - int16_t: Signed 16-bit integer + * - uint32_t: Unsigned 32-bit integer + * - int32_t: Signed 32-bit integer + * - uint64_t: Unsigned 64-bit integer + * - int64_t: Signed 64-bit integer + * - uintptr_t: Unsigned integer capable of storing a pointer, preferably the + * same size as pointers themselves. + * + * These types deliberately use the same names as the standard C99 types, so + * that if the C99 headers stdint.h and stdbool.h are available, they may be + * included here. + * + * If the user application defines similar types, those may be reused. For + * example, suppose there is an application header apptypes.h which defines + * types with a similar purpose but different names. That header could be + * reused to define the types Reliance Edge needs: + * + * ~~~{.c} + #include + * + * typedef BOOL bool; + * typedef BYTE uint8_t; + * typedef INT8 int8_t; + * // And so on... + * ~~~ + * + * If there are neither C99 headers nor suitable types in application headers, + * this header should be populated with typedefs that define the required types + * in terms of the standard C types. This requires knowledge of the size of + * the C types on the target hardware (e.g., how big is an "int" or a pointer). + * Below is an example which assumes the target has 8-bit chars, 16-bit shorts, + * 32-bit ints, 32-bit pointers, and 64-bit long longs: + * + * ~~~{.c} + * typedef int bool; + * typedef unsigned char uint8_t; + * typedef signed char int8_t; + * typedef unsigned short uint16_t; + * typedef short int16_t; + * typedef unsigned int uint32_t; + * typedef int int32_t; + * typedef unsigned long long uint64_t; + * typedef long long int64_t; + * typedef uint32_t uintptr_t; + * ~~~ + */ +#ifndef REDTYPES_H +#define REDTYPES_H + + +typedef int bool; /**< @brief Boolean type; either true or false. */ + +typedef unsigned __int8 uint8_t; /**< @brief Unsigned 8-bit integer. */ +typedef __int8 int8_t; /**< @brief Signed 8-bit integer. */ + +typedef unsigned __int16 uint16_t; /**< @brief Unsigned 16-bit integer. */ +typedef __int16 int16_t; /**< @brief Signed 16-bit integer. */ + +typedef unsigned __int32 uint32_t; /**< @brief Unsigned 32-bit integer. */ +typedef __int32 int32_t; /**< @brief Signed 32-bit integer. */ + +typedef unsigned __int64 uint64_t; /**< @brief Unsigned 64-bit integer. */ +typedef __int64 int64_t; /**< @brief Signed 64-bit integer. */ + +/** @brief Unsigned integer capable of storing a pointer. + */ +#ifdef _WIN64 + typedef uint64_t uintptr_t; +#else + typedef uint32_t uintptr_t; +#endif + + +#endif /* ifndef REDTYPES_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-Related-CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-Related-CLI-commands.c index 7ca6582b2..24a3e7bf4 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-Related-CLI-commands.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-Related-CLI-commands.c @@ -1,1524 +1,1605 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* Standard includes. */ -#include -#include -#include - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -/* File system includes. */ -#include -#include - -#ifdef _WINDOWS_ - #define snprintf _snprintf -#endif - -#define cliNEW_LINE "\r\n" - -/******************************************************************************* - * See the URL in the comments within main.c for the location of the online - * documentation. - ******************************************************************************/ - -/* - * Print out information on a single file. - */ -static void prvCreateFileInfoString( char *pcBuffer, REDDIRENT *pxDirent ); - -/* - * Copies an existing file into a newly created file. - */ -static BaseType_t prvPerformCopy( int32_t lSourceFildes, - int32_t lDestinationFiledes, - char *pxWriteBuffer, - size_t xWriteBufferLen ); - -/* - * Implements the DIR command. - */ -static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the DEL command. - */ -static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the TYPE command. - */ -static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the APPEND command. - */ -static BaseType_t prvAPPENDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the COPY command. - */ -static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the CREATE command. - */ -static BaseType_t prvCREATECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the MKDIR command. - */ -static BaseType_t prvMKDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the RENAME command. - */ -static BaseType_t prvRENAMECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the LINK command. - */ -static BaseType_t prvLINKCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the STAT command. - */ -static BaseType_t prvSTATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the STATFS command. - */ -static BaseType_t prvSTATFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the FORMAT command. - */ -static BaseType_t prvFORMATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the TRANSACT command. - */ -static BaseType_t prvTRANSACTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the TRANSMASKGET command. - */ -static BaseType_t prvTRANSMASKGETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the TRANSMASKSET command. - */ -static BaseType_t prvTRANSMASKSETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the ABORT command. - */ -static BaseType_t prvABORTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the TEST command. - */ -static BaseType_t prvTESTFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - - -/* Structure that defines the DIR command line command, which lists all the -files in the current directory. */ -static const CLI_Command_Definition_t xDIR = -{ - "dir", /* The command string to type. */ - "\r\ndir :\r\n Lists the files in the named directory\r\n", - prvDIRCommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the TYPE command line command, which prints the -contents of a file to the console. */ -static const CLI_Command_Definition_t xTYPE = -{ - "type", /* The command string to type. */ - "\r\ntype :\r\n Prints file contents to the terminal\r\n", - prvTYPECommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the APPEND command line command, which appends data -to a file. */ -static const CLI_Command_Definition_t xAPPEND = -{ - "append", /* The command string to type. */ - "\r\nappend :\r\n Appends data to a file (created if it does not exist)\r\n", - prvAPPENDCommand, /* The function to run. */ - 3 /* Three parameters are expected. */ -}; - -/* Structure that defines the DEL command line command, which deletes a file. */ -static const CLI_Command_Definition_t xDEL = -{ - "del", /* The command string to type. */ - "\r\ndel :\r\n deletes a file or directory\r\n", - prvDELCommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the COPY command line command, which copies a file. */ -static const CLI_Command_Definition_t xCOPY = -{ - "copy", /* The command string to type. */ - "\r\ncopy :\r\n Copies to \r\n", - prvCOPYCommand, /* The function to run. */ - 2 /* Two parameters are expected. */ -}; - -/* Structure that defines the CREATE command line command, which creates an -empty file. */ -static const CLI_Command_Definition_t xCREATE = -{ - "create", /* The command string to type. */ - "\r\ncreate :\r\n Creates an empty file\r\n", - prvCREATECommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the MKDIR command line command, which creates an -empty directory. */ -static const CLI_Command_Definition_t xMKDIR = -{ - "mkdir", /* The command string to type. */ - "\r\nmkdir :\r\n Creates an empty directory\r\n", - prvMKDIRCommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the RENAME command line command, which renames a file. */ -static const CLI_Command_Definition_t xRENAME = -{ - "rename", /* The command string to type. */ - "\r\nrename :\r\n Rename to \r\n", - prvRENAMECommand, /* The function to run. */ - 2 /* Two parameters are expected. */ -}; - -/* Structure that defines the LINK command line command, which creates a hard -link. */ -static const CLI_Command_Definition_t xLINK = -{ - "link", /* The command string to type. */ - "\r\nlink :\r\n Create hard link pointing at \r\n", - prvLINKCommand, /* The function to run. */ - 2 /* Two parameters are expected. */ -}; - -/* Structure that defines the STAT command line command, which shows various -information about a file. */ -static const CLI_Command_Definition_t xSTAT = -{ - "stat", /* The command string to type. */ - "\r\nstat :\r\n Show file information\r\n", - prvSTATCommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the STATFS command line command, which shows various -file system information. */ -static const CLI_Command_Definition_t xSTATFS = -{ - "statfs", /* The command string to type. */ - "\r\nstatfs:\r\n Show file system information.\r\n", - prvSTATFSCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the FORMAT command line command, which re-formats the -file system. */ -static const CLI_Command_Definition_t xFORMAT = -{ - "format", /* The command string to type. */ - "\r\nformat:\r\n Re-formats the file system volume. ALL FILES WILL BE DELETED!\r\n", - prvFORMATCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the TRANSACT command line command, which commits a -transaction point. */ -static const CLI_Command_Definition_t xTRANSACT = -{ - "transact", /* The command string to type. */ - "\r\ntransact:\r\n Commit a Reliance Edge transaction point\r\n", - prvTRANSACTCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the TRANSMASKGET command line command, which retrieves -the current automatic transaction event mask. */ -static const CLI_Command_Definition_t xTRANSMASKGET = -{ - "transmaskget", /* The command string to type. */ - "\r\ntransmaskget:\r\n Retrieve the Reliance Edge automatic transaction mask\r\n", - prvTRANSMASKGETCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the TRANSMASKSET command line command, which sets the -automatic transaction event mask. */ -static const CLI_Command_Definition_t xTRANSMASKSET = -{ - "transmaskset", /* The command string to type. */ - "\r\ntransmaskset :\r\n Set the Reliance Edge automatic transaction mask\r\n", - prvTRANSMASKSETCommand, /* The function to run. */ - 1 /* One parameter is expected. */ -}; - -/* Structure that defines the ABORT command line command, which rolls back -changes which have not been transacted. */ -static const CLI_Command_Definition_t xABORT = -{ - "abort", /* The command string to type. */ - "\r\nabort:\r\n Roll back all changes not part of the last transaction point\r\n", - prvABORTCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the TEST-FS command line command, which executes some -file system driver tests. */ -static const CLI_Command_Definition_t xTEST_FS = -{ - "test-fs", /* The command string to type. */ - "\r\ntest-fs:\r\n Executes file system tests. ALL FILES WILL BE DELETED!\r\n", - prvTESTFSCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/*-----------------------------------------------------------*/ - -void vRegisterFileSystemCLICommands( void ) -{ - /* Register all the command line commands defined immediately above. */ - FreeRTOS_CLIRegisterCommand( &xDIR ); - FreeRTOS_CLIRegisterCommand( &xTYPE ); - FreeRTOS_CLIRegisterCommand( &xAPPEND ); - FreeRTOS_CLIRegisterCommand( &xDEL ); - FreeRTOS_CLIRegisterCommand( &xCOPY ); - FreeRTOS_CLIRegisterCommand( &xCREATE ); - FreeRTOS_CLIRegisterCommand( &xMKDIR ); - FreeRTOS_CLIRegisterCommand( &xRENAME ); - FreeRTOS_CLIRegisterCommand( &xLINK ); - FreeRTOS_CLIRegisterCommand( &xSTAT ); - FreeRTOS_CLIRegisterCommand( &xSTATFS ); - FreeRTOS_CLIRegisterCommand( &xFORMAT ); - FreeRTOS_CLIRegisterCommand( &xTRANSACT ); - FreeRTOS_CLIRegisterCommand( &xTRANSMASKGET ); - FreeRTOS_CLIRegisterCommand( &xTRANSMASKSET ); - FreeRTOS_CLIRegisterCommand( &xABORT ); - FreeRTOS_CLIRegisterCommand( &xTEST_FS ); -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -static REDDIR *pxDir = NULL; -REDDIRENT *pxDirent; -const char *pcParameter; -BaseType_t xParameterStringLength, xReturn = pdFALSE; - - /* This assumes pcWriteBuffer is long enough. */ - ( void ) pcCommandString; - - /* Ensure the buffer leaves space for the \r\n. */ - configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); - xWriteBufferLen -= strlen( cliNEW_LINE ); - - if( pxDir == NULL ) - { - /* Retrieve the directory to DIR. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* This is the first time this function has been executed since the Dir - command was run. Open the directory. */ - pxDir = red_opendir( pcParameter ); - } - - if( pxDir ) - { - /* red_readdir() returns NULL either on error or upon reaching the - end of the directory. Clear errno so these conditions can be - distinguished. */ - red_errno = 0; - pxDirent = red_readdir( pxDir ); - - if( pxDirent ) - { - prvCreateFileInfoString( pcWriteBuffer, pxDirent ); - xReturn = pdPASS; - } - else if( red_errno == 0 ) - { - /* There are no more files. Close the directory. */ - red_closedir( pxDir ); - pxDir = NULL; - - /* No string to return. */ - pcWriteBuffer[ 0 ] = 0x00; - } - else - { - snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d reading directory.", ( int ) red_errno ); - } - } - else - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOENT : - snprintf( pcWriteBuffer, xWriteBufferLen, "Directory not found." ); - break; - - case RED_ENOTDIR : - snprintf( pcWriteBuffer, xWriteBufferLen, "Directory not found or not a directory." ); - break; - - default : - snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening directory.", ( int ) red_errno ); - break; - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength, xReturn = pdTRUE; -static int32_t lFildes = -1; -REDSTAT finfo; -int32_t lStatus, lBytesRead; -size_t xColumns = 50U; - - /* Ensure there is always a null terminator after each character written. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - - /* Ensure the buffer leaves space for the \r\n. */ - configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); - xWriteBufferLen -= strlen( cliNEW_LINE ); - - if( xWriteBufferLen < xColumns ) - { - /* Ensure the loop that uses xColumns as an end condition does not - write off the end of the buffer. */ - xColumns = xWriteBufferLen; - } - - if( lFildes == -1 ) - { - /* The file has not been opened yet. Find the file name. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to open the requested file. */ - lFildes = red_open( pcParameter, RED_O_RDONLY ); - if( lFildes == -1 ) - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOENT : - case RED_ENOTDIR : - snprintf( pcWriteBuffer, xWriteBufferLen, "File not found." ); - break; - - default : - snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening file.", ( int ) red_errno ); - break; - } - } - else - { - /* Make sure this is a file, not a directory. */ - lStatus = red_fstat( lFildes, &finfo ); - if( lStatus == 0 ) - { - if( RED_S_ISDIR( finfo.st_mode ) ) - { - snprintf( pcWriteBuffer, xWriteBufferLen, "Cannot TYPE a directory." ); - red_close( lFildes ); - lFildes = -1; - } - } - else - { - snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file.", ( int ) red_errno ); - red_close( lFildes ); - lFildes = -1; - } - } - } - - if( lFildes != -1 ) - { - /* Read the next chunk of data from the file. */ - lBytesRead = red_read( lFildes, pcWriteBuffer, xColumns ); - - if( lBytesRead < ( int32_t ) xColumns ) - { - /* Error or no more characters to return. */ - red_close( lFildes ); - lFildes = -1; - } - } - - if( lFildes == -1 ) - { - /* Either the file was not opened, or all the data from the file has - been returned and the file is now closed. */ - xReturn = pdFALSE; - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvAPPENDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -char *pcFileName = NULL; -const char *pcCharacter = NULL, *pcLength; -BaseType_t xParameterStringLength, xGoodParameters = pdTRUE; -int32_t lFildes, lAppendLength = -1, lThisWrite, lTotalWritten, lBytesWritten; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* Find the length to write. */ - pcLength = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 3, /* Return the third parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - configASSERT( pcLength ); - - /* Convert the string into a number. */ - lAppendLength = RedAtoI( pcLength ); - if( lAppendLength < 0 ) - { - strcpy( pcWriteBuffer, "Third parameter cannot be a negative number." ); - xGoodParameters = pdFALSE; - } - - if( xGoodParameters ) - { - /* Find the character to write. */ - pcCharacter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 2, /* Return the second parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - configASSERT( pcCharacter ); - - if( xParameterStringLength != 1 ) - { - strcpy( pcWriteBuffer, "Second parameter must be a single character." ); - xGoodParameters = pdFALSE; - } - } - - if( xGoodParameters ) - { - /* Find the file name. */ - pcFileName = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - configASSERT( pcFileName ); - - /* Terminate the string. */ - pcFileName[ xParameterStringLength ] = 0x00; - } - - if( xGoodParameters ) - { - /* Attempt to open the requested file. */ - lFildes = red_open( pcFileName, RED_O_WRONLY|RED_O_APPEND|RED_O_CREAT ); - - if( lFildes == -1 ) - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOENT : - case RED_ENOTDIR : - strcpy( pcWriteBuffer, "Bad file path." ); - break; - - case RED_EISDIR : - strcpy( pcWriteBuffer, "Cannot append to a directory." ); - break; - - default : - sprintf( pcWriteBuffer, "Error %d opening file.", ( int ) red_errno ); - break; - } - } - else - { - /* Put the requested character into the buffer. */ - memset( pcWriteBuffer, pcCharacter[0], xWriteBufferLen ); - - /* Append the data. */ - for( lTotalWritten = 0; lTotalWritten < lAppendLength; lTotalWritten += lThisWrite ) - { - lThisWrite = lAppendLength - lTotalWritten; - if( lThisWrite > ( int32_t ) xWriteBufferLen ) - { - lThisWrite = ( int32_t ) xWriteBufferLen; - } - - lBytesWritten = red_write( lFildes, pcWriteBuffer, lThisWrite ); - if( lBytesWritten == -1 ) - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOSPC : - strcpy( pcWriteBuffer, "Out of disk space." ); - break; - - default : - sprintf( pcWriteBuffer, "Error %d writing to file.", ( int ) red_errno ); - break; - } - - break; - } - else if( lBytesWritten != lThisWrite ) - { - /* Some data was written, but not all of it. This only - happens when the disk is full or the file reached its - maximum size. That latter is unlikely in this demo. */ - strcpy( pcWriteBuffer, "Out of disk space." ); - break; - } - } - - if( lTotalWritten == lAppendLength ) - { - strcpy( pcWriteBuffer, "Append successful." ); - } - - red_close( lFildes ); - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength; -int32_t lStatus; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to delete the file or directory. */ - lStatus = red_unlink( pcParameter ); - - if( lStatus == 0 ) - { - sprintf( pcWriteBuffer, "%s was deleted", pcParameter ); - } - else - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOTDIR : - case RED_ENOENT : - sprintf( pcWriteBuffer, "File not found." ); - break; - - case RED_ENOTEMPTY : - sprintf( pcWriteBuffer, "Cannot remove directory: not empty." ); - break; - - default : - sprintf( pcWriteBuffer, "Error %d deleting file.", ( int ) red_errno ); - break; - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -char *pcSourceFile; -const char *pcDestinationFile; -BaseType_t xParameterStringLength; -int32_t lSourceFildes, lDestinationFildes; - - /* Obtain the name of the destination file. */ - pcDestinationFile = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 2, /* Return the second parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcDestinationFile ); - - /* Obtain the name of the source file. */ - pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcSourceFile ); - - /* Terminate the string. */ - pcSourceFile[ xParameterStringLength ] = 0x00; - - /* See if the source file exists, openm it if it does. */ - lSourceFildes = red_open( pcSourceFile, RED_O_RDONLY ); - - if( lSourceFildes == -1 ) - { - sprintf( pcWriteBuffer, "Source file does not exist" ); - } - else - { - /* Create the destination file, error if it already exists. */ - lDestinationFildes = red_open( pcDestinationFile, RED_O_CREAT|RED_O_EXCL|RED_O_WRONLY ); - - if( lDestinationFildes == -1 ) - { - sprintf( pcWriteBuffer, "Error: Destination file already exists" ); - } - else - { - if( prvPerformCopy( lSourceFildes, lDestinationFildes, pcWriteBuffer, xWriteBufferLen ) == pdPASS ) - { - sprintf( pcWriteBuffer, "Copy made" ); - } - else - { - sprintf( pcWriteBuffer, "Error during copy" ); - } - - red_close( lDestinationFildes ); - } - - red_close( lSourceFildes ); - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvCREATECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength; -int32_t lFildes; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to create the file. */ - lFildes = red_open( pcParameter, RED_O_CREAT|RED_O_EXCL|RED_O_RDWR ); - - if( lFildes != -1 ) - { - sprintf( pcWriteBuffer, "%s was created", pcParameter ); - red_close( lFildes ); - } - else - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOTDIR : - case RED_ENOENT : - sprintf( pcWriteBuffer, "Bad file path." ); - break; - - case RED_EEXIST : - sprintf( pcWriteBuffer, "File already exists." ); - break; - - default : - sprintf( pcWriteBuffer, "Error %d creating file.", ( int ) red_errno ); - break; - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvMKDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength; -int32_t lStatus; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to create the file. */ - lStatus = red_mkdir( pcParameter ); - - if( lStatus == 0 ) - { - sprintf( pcWriteBuffer, "%s was created", pcParameter ); - } - else - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOTDIR : - case RED_ENOENT : - sprintf( pcWriteBuffer, "Bad file path." ); - break; - - case RED_EEXIST : - sprintf( pcWriteBuffer, "Directory already exists." ); - break; - - default : - sprintf( pcWriteBuffer, "Error %d creating directory.", ( int ) red_errno ); - break; - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvRENAMECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcDestinationFile; -char *pcSourceFile; -BaseType_t xParameterStringLength; -int32_t lStatus; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* Obtain the name of the destination file. */ - pcDestinationFile = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 2, /* Return the second parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcDestinationFile ); - - /* Obtain the name of the source file. */ - pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcSourceFile ); - - /* Terminate the string. */ - pcSourceFile[ xParameterStringLength ] = 0x00; - - /* Attempt to rename the file. */ - lStatus = red_rename( pcSourceFile, pcDestinationFile ); - - if( lStatus == 0 ) - { - sprintf( pcWriteBuffer, "%s was renamed to %s", pcSourceFile, pcDestinationFile ); - } - else - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOTDIR : - case RED_ENOENT : - case RED_EISDIR : - sprintf( pcWriteBuffer, "Bad file path." ); - break; - - /* This will only be seen if POSIX rename is disabled. */ - case RED_EEXIST : - sprintf( pcWriteBuffer, "Destination already exists." ); - break; - - default : - sprintf( pcWriteBuffer, "Error %d renaming file.", ( int ) red_errno ); - break; - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvLINKCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcDestinationFile; -char *pcSourceFile; -BaseType_t xParameterStringLength; -int32_t lStatus; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* Obtain the name of the destination file. */ - pcDestinationFile = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 2, /* Return the second parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcDestinationFile ); - - /* Obtain the name of the source file. */ - pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcSourceFile ); - - /* Terminate the string. */ - pcSourceFile[ xParameterStringLength ] = 0x00; - - /* Attempt to create the hard link. */ - lStatus = red_link( pcSourceFile, pcDestinationFile ); - - if( lStatus == 0 ) - { - sprintf( pcWriteBuffer, "%s was linked to %s", pcDestinationFile, pcSourceFile ); - } - else - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOTDIR : - case RED_ENOENT : - sprintf( pcWriteBuffer, "Bad file path." ); - break; - - case RED_EPERM : - sprintf( pcWriteBuffer, "Cannot link a directory." ); - break; - - case RED_EMLINK : - sprintf( pcWriteBuffer, "Too many hard links." ); - break; - - default : - sprintf( pcWriteBuffer, "Error %d linking file.", ( int ) red_errno ); - break; - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvSTATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter, *pcModeString; -BaseType_t xParameterStringLength; -REDSTAT finfo; -int32_t lFildes, lStatus; - - /* Ensure the buffer leaves space for the \r\n. */ - configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); - xWriteBufferLen -= strlen( cliNEW_LINE ); - - /* Find the file name. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Attempt to open the requested file. */ - lFildes = red_open( pcParameter, RED_O_RDONLY ); - if( lFildes == -1 ) - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_ENOENT : - case RED_ENOTDIR : - snprintf( pcWriteBuffer, xWriteBufferLen, "File not found." ); - break; - - default : - snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening file.", ( int ) red_errno ); - break; - } - } - else - { - lStatus = red_fstat( lFildes, &finfo ); - if( lStatus == 0 ) - { - if( RED_S_ISDIR( finfo.st_mode ) ) - { - pcModeString = "dir"; - } - else - { - pcModeString = "file"; - } - - snprintf( pcWriteBuffer, xWriteBufferLen, "ino=%lu mode=0x%04x(%s) nlink=%x size=%lu blocks=%lu", - ( unsigned long ) finfo.st_ino, ( unsigned ) finfo.st_mode, pcModeString, - ( unsigned ) finfo.st_nlink, (unsigned long) finfo.st_size, (unsigned long) finfo.st_blocks ); - } - else - { - snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file.", ( int ) red_errno ); - } - - red_close( lFildes ); - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvSTATFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -REDSTATFS fsinfo; -int32_t lStatus; - - /* Avoid compiler warnings. */ - ( void ) pcCommandString; - - /* Ensure the buffer leaves space for the \r\n. */ - configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); - xWriteBufferLen -= strlen( cliNEW_LINE ); - - lStatus = red_statvfs( "", &fsinfo ); - - if( lStatus == -1 ) - { - snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file system.", ( int ) red_errno ); - } - else - { - snprintf( pcWriteBuffer, xWriteBufferLen, - "Block size: %lu\r\n" - "Block count: %lu\r\n" - "Free blocks: %lu\r\n" - "Inode count: %lu\r\n" - "Free inodes: %lu\r\n", - ( unsigned long ) fsinfo.f_bsize, ( unsigned long ) fsinfo.f_blocks, - ( unsigned long ) fsinfo.f_bfree, ( unsigned long ) fsinfo.f_files, - ( unsigned long ) fsinfo.f_ffree ); - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvFORMATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -int32_t lStatus; - - /* Avoid compiler warnings. */ - ( void ) pcCommandString; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* File system volumes cannot be formatted while mounted. */ - lStatus = red_umount( "" ); - if( lStatus == -1 ) - { - sprintf( pcWriteBuffer, "Error %d during unmount.", ( int ) red_errno ); - } - else - { - /* Re-format the file system volume. */ - lStatus = red_format( "" ); - - if( lStatus == -1 ) - { - sprintf( pcWriteBuffer, "Error %d during format.", ( int ) red_errno ); - } - else - { - /* Mount again so that other commands will work properly. */ - lStatus = red_mount( "" ); - - if( lStatus == -1 ) - { - sprintf( pcWriteBuffer, "Error %d during mount.", ( int ) red_errno ); - } - else - { - strcpy( pcWriteBuffer, "Format successful." ); - } - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTRANSACTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -int32_t lStatus; - - /* Avoid compiler warnings. */ - ( void ) pcCommandString; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* Save the original transaction mask settings. */ - lStatus = red_transact( "" ); - - if( lStatus == -1 ) - { - sprintf( pcWriteBuffer, "Error %d during transaction point.", ( int ) red_errno ); - } - else - { - strcpy( pcWriteBuffer, "Transaction point successful." ); - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTRANSMASKGETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -uint32_t ulEventMask; -int32_t lStatus; - - /* Avoid compiler warnings. */ - ( void ) pcCommandString; - - /* Ensure the buffer leaves space for the \r\n. */ - configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); - xWriteBufferLen -= strlen( cliNEW_LINE ); - - lStatus = red_gettransmask( "", &ulEventMask ); - if( lStatus == -1 ) - { - snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d retrieving automatic transaction event mask.", ( int ) red_errno ); - } - else - { - snprintf( pcWriteBuffer, xWriteBufferLen, - "Current automatic transaction event mask: 0x%04lx\r\n" - "RED_TRANSACT_UMOUNT (0x0001): %s\r\n" - "RED_TRANSACT_CREAT (0x0002): %s\r\n" - "RED_TRANSACT_UNLINK (0x0004): %s\r\n" - "RED_TRANSACT_MKDIR (0x0008): %s\r\n" - "RED_TRANSACT_RENAME (0x0010): %s\r\n" - "RED_TRANSACT_LINK (0x0020): %s\r\n" - "RED_TRANSACT_CLOSE (0x0040): %s\r\n" - "RED_TRANSACT_WRITE (0x0080): %s\r\n" - "RED_TRANSACT_FSYNC (0x0100): %s\r\n" - "RED_TRANSACT_TRUNCATE (0x0200): %s\r\n" - "RED_TRANSACT_VOLFULL (0x0400): %s\r\n", - ( unsigned long ) ulEventMask, - ( ulEventMask & RED_TRANSACT_UMOUNT ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_CREAT ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_UNLINK ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_MKDIR ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_RENAME ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_LINK ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_CLOSE ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_WRITE ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_FSYNC ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_TRUNCATE ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_VOLFULL ) ? "Enabled" : "Disabled" ); - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTRANSMASKSETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength; -uint32_t ulEventMask; -int32_t lStatus; - - /* Ensure the buffer leaves space for the \r\n. */ - configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); - xWriteBufferLen -= strlen( cliNEW_LINE ); - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - if( ( pcParameter[0] == '0' ) && ( ( pcParameter[1] == 'x' ) || ( pcParameter[1] == 'X' ) ) ) - { - pcParameter += 2; - } - - /* Convert the argument into a value. */ - RedHtoUL( pcParameter, &ulEventMask ); - - /* Set the new transaction mask. */ - lStatus = red_settransmask( "", ulEventMask ); - if( lStatus == -1 ) - { - /* User-friendly messages for common errors. */ - switch( red_errno ) - { - case RED_EINVAL: - snprintf( pcWriteBuffer, xWriteBufferLen, "Invalid bits in transaction mask." ); - break; - - default : - snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d setting transaction mask.", ( int ) red_errno ); - break; - } - } - else - { - snprintf( pcWriteBuffer, xWriteBufferLen, - "Successfully set automatic transaction mask. Enabled events:\r\n" - "RED_TRANSACT_UMOUNT (0x0001): %s\r\n" - "RED_TRANSACT_CREAT (0x0002): %s\r\n" - "RED_TRANSACT_UNLINK (0x0004): %s\r\n" - "RED_TRANSACT_MKDIR (0x0008): %s\r\n" - "RED_TRANSACT_RENAME (0x0010): %s\r\n" - "RED_TRANSACT_LINK (0x0020): %s\r\n" - "RED_TRANSACT_CLOSE (0x0040): %s\r\n" - "RED_TRANSACT_WRITE (0x0080): %s\r\n" - "RED_TRANSACT_FSYNC (0x0100): %s\r\n" - "RED_TRANSACT_TRUNCATE (0x0200): %s\r\n" - "RED_TRANSACT_VOLFULL (0x0400): %s\r\n", - ( ulEventMask & RED_TRANSACT_UMOUNT ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_CREAT ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_UNLINK ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_MKDIR ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_RENAME ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_LINK ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_CLOSE ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_WRITE ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_FSYNC ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_TRUNCATE ) ? "Enabled" : "Disabled", - ( ulEventMask & RED_TRANSACT_VOLFULL ) ? "Enabled" : "Disabled" ); - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvABORTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -uint32_t ulEventMask; -int32_t lStatus; - - /* Avoid compiler warnings. */ - ( void ) pcCommandString; - - /* This function assumes xWriteBufferLen is large enough! */ - ( void ) xWriteBufferLen; - - /* Save the original transaction mask settings. */ - lStatus = red_gettransmask( "", &ulEventMask ); - - if( lStatus == -1 ) - { - sprintf( pcWriteBuffer, "Error %d querying transaction mask.", ( int ) red_errno ); - } - else - { - /* Make it so that red_umount() will not automatically commit a new - transaction point. */ - lStatus = red_settransmask( "", ulEventMask & ~( ( uint32_t ) RED_TRANSACT_UMOUNT ) ); - - if( lStatus == -1 ) - { - sprintf( pcWriteBuffer, "Error %d setting transaction mask.", ( int ) red_errno ); - } - else - { - /* Unmount. Since red_umount() will not transact, all changes which - were not already transacted are rolled back. */ - lStatus = red_umount( "" ); - - if( lStatus == -1 ) - { - sprintf( pcWriteBuffer, "Error %d during unmount.", ( int ) red_errno ); - } - else - { - /* Mount. Mount always starts from the last transaction point. */ - lStatus = red_mount( "" ); - - if( lStatus == -1 ) - { - sprintf( pcWriteBuffer, "Error %d during mount.", ( int ) red_errno ); - } - else - { - strcpy( pcWriteBuffer, "Working state changes successfully aborted." ); - } - } - - /* Restore the original transaction mask settings. */ - red_settransmask( "", ulEventMask ); - } - } - - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTESTFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -UBaseType_t uxOriginalPriority; -FSSTRESSPARAM param; - - /* Avoid compiler warnings. */ - ( void ) xWriteBufferLen; - ( void ) pcCommandString; - - /* Limitations in the interaction with the Windows TCP/IP stack require - the command console to run at the idle priority. Raise the priority for - the duration of the tests to ensure there are not multiple switches to the - idle task as in the simulated environment the idle task hook function may - include a (relatively) long delay. */ - uxOriginalPriority = uxTaskPriorityGet( NULL ); - vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); - - /* Delete all files to avoid interfering with the test. */ - red_umount( "" ); - red_format( "" ); - red_mount( "" ); - - FsstressDefaultParams(¶m); - param.fVerbose = pdTRUE; - param.ulNops = 10000; - param.ulSeed = 1; - FsstressStart(¶m); - - /* Clean up after the test. */ - red_umount( "" ); - red_format( "" ); - red_mount( "" ); - - /* Reset back to the original priority. */ - vTaskPrioritySet( NULL, uxOriginalPriority ); - - sprintf( pcWriteBuffer, "%s", "Test results were sent to Windows console" ); - strcat( pcWriteBuffer, cliNEW_LINE ); - - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvPerformCopy( int32_t lSourceFildes, - int32_t lDestinationFiledes, - char *pxWriteBuffer, - size_t xWriteBufferLen ) -{ -int32_t lBytesRead; -BaseType_t xReturn = pdPASS; - - /* Assuming both files are at offset zero. */ - - for( ;; ) - { - /* Read the next block of data. */ - lBytesRead = red_read( lSourceFildes, pxWriteBuffer, xWriteBufferLen ); - if( lBytesRead <= 0 ) - { - if( lBytesRead == -1) - { - /* Error reading from file. */ - xReturn = pdFAIL; - } - else - { - /* No error: reached end of file, time to stop. */ - } - - break; - } - - /* Write the block of data to the end of the file. */ - if( red_write( lDestinationFiledes, pxWriteBuffer, lBytesRead ) != lBytesRead ) - { - xReturn = pdFAIL; - break; - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static void prvCreateFileInfoString( char *pcBuffer, REDDIRENT *pxDirent ) -{ -const char *pcFile = "file", *pcDirectory = "directory"; -const char *pcAttrib; - - /* Point pcAttrib to a string that describes the file. */ - if( RED_S_ISDIR(pxDirent->d_stat.st_mode) ) - { - pcAttrib = pcDirectory; - } - else - { - pcAttrib = pcFile; - } - - /* Create a string that includes the file name, the file size and the - attributes string. */ - sprintf( pcBuffer, "%s [%s] [size=%lld]", pxDirent->d_name, pcAttrib, pxDirent->d_stat.st_size ); -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* File system includes. */ +#include +#include + +#ifdef _WINDOWS_ + #define snprintf _snprintf +#endif + +#define cliNEW_LINE "\r\n" + +/******************************************************************************* + * See the URL in the comments within main.c for the location of the online + * documentation. + ******************************************************************************/ + +/* + * Print out information on a single file. + */ +static void prvCreateFileInfoString( char * pcBuffer, + REDDIRENT * pxDirent ); + +/* + * Copies an existing file into a newly created file. + */ +static BaseType_t prvPerformCopy( int32_t lSourceFildes, + int32_t lDestinationFiledes, + char * pxWriteBuffer, + size_t xWriteBufferLen ); + +/* + * Implements the DIR command. + */ +static BaseType_t prvDIRCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the DEL command. + */ +static BaseType_t prvDELCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the TYPE command. + */ +static BaseType_t prvTYPECommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the APPEND command. + */ +static BaseType_t prvAPPENDCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the COPY command. + */ +static BaseType_t prvCOPYCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the CREATE command. + */ +static BaseType_t prvCREATECommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the MKDIR command. + */ +static BaseType_t prvMKDIRCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the RENAME command. + */ +static BaseType_t prvRENAMECommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the LINK command. + */ +static BaseType_t prvLINKCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the STAT command. + */ +static BaseType_t prvSTATCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the STATFS command. + */ +static BaseType_t prvSTATFSCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the FORMAT command. + */ +static BaseType_t prvFORMATCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the TRANSACT command. + */ +static BaseType_t prvTRANSACTCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the TRANSMASKGET command. + */ +static BaseType_t prvTRANSMASKGETCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the TRANSMASKSET command. + */ +static BaseType_t prvTRANSMASKSETCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the ABORT command. + */ +static BaseType_t prvABORTCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the TEST command. + */ +static BaseType_t prvTESTFSCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + + +/* Structure that defines the DIR command line command, which lists all the + * files in the current directory. */ +static const CLI_Command_Definition_t xDIR = +{ + "dir", /* The command string to type. */ + "\r\ndir :\r\n Lists the files in the named directory\r\n", + prvDIRCommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the TYPE command line command, which prints the + * contents of a file to the console. */ +static const CLI_Command_Definition_t xTYPE = +{ + "type", /* The command string to type. */ + "\r\ntype :\r\n Prints file contents to the terminal\r\n", + prvTYPECommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the APPEND command line command, which appends data + * to a file. */ +static const CLI_Command_Definition_t xAPPEND = +{ + "append", /* The command string to type. */ + "\r\nappend :\r\n Appends data to a file (created if it does not exist)\r\n", + prvAPPENDCommand, /* The function to run. */ + 3 /* Three parameters are expected. */ +}; + +/* Structure that defines the DEL command line command, which deletes a file. */ +static const CLI_Command_Definition_t xDEL = +{ + "del", /* The command string to type. */ + "\r\ndel :\r\n deletes a file or directory\r\n", + prvDELCommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the COPY command line command, which copies a file. */ +static const CLI_Command_Definition_t xCOPY = +{ + "copy", /* The command string to type. */ + "\r\ncopy :\r\n Copies to \r\n", + prvCOPYCommand, /* The function to run. */ + 2 /* Two parameters are expected. */ +}; + +/* Structure that defines the CREATE command line command, which creates an + * empty file. */ +static const CLI_Command_Definition_t xCREATE = +{ + "create", /* The command string to type. */ + "\r\ncreate :\r\n Creates an empty file\r\n", + prvCREATECommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the MKDIR command line command, which creates an + * empty directory. */ +static const CLI_Command_Definition_t xMKDIR = +{ + "mkdir", /* The command string to type. */ + "\r\nmkdir :\r\n Creates an empty directory\r\n", + prvMKDIRCommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the RENAME command line command, which renames a file. */ +static const CLI_Command_Definition_t xRENAME = +{ + "rename", /* The command string to type. */ + "\r\nrename :\r\n Rename to \r\n", + prvRENAMECommand, /* The function to run. */ + 2 /* Two parameters are expected. */ +}; + +/* Structure that defines the LINK command line command, which creates a hard + * link. */ +static const CLI_Command_Definition_t xLINK = +{ + "link", /* The command string to type. */ + "\r\nlink :\r\n Create hard link pointing at \r\n", + prvLINKCommand, /* The function to run. */ + 2 /* Two parameters are expected. */ +}; + +/* Structure that defines the STAT command line command, which shows various + * information about a file. */ +static const CLI_Command_Definition_t xSTAT = +{ + "stat", /* The command string to type. */ + "\r\nstat :\r\n Show file information\r\n", + prvSTATCommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the STATFS command line command, which shows various + * file system information. */ +static const CLI_Command_Definition_t xSTATFS = +{ + "statfs", /* The command string to type. */ + "\r\nstatfs:\r\n Show file system information.\r\n", + prvSTATFSCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the FORMAT command line command, which re-formats the + * file system. */ +static const CLI_Command_Definition_t xFORMAT = +{ + "format", /* The command string to type. */ + "\r\nformat:\r\n Re-formats the file system volume. ALL FILES WILL BE DELETED!\r\n", + prvFORMATCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the TRANSACT command line command, which commits a + * transaction point. */ +static const CLI_Command_Definition_t xTRANSACT = +{ + "transact", /* The command string to type. */ + "\r\ntransact:\r\n Commit a Reliance Edge transaction point\r\n", + prvTRANSACTCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the TRANSMASKGET command line command, which retrieves + * the current automatic transaction event mask. */ +static const CLI_Command_Definition_t xTRANSMASKGET = +{ + "transmaskget", /* The command string to type. */ + "\r\ntransmaskget:\r\n Retrieve the Reliance Edge automatic transaction mask\r\n", + prvTRANSMASKGETCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the TRANSMASKSET command line command, which sets the + * automatic transaction event mask. */ +static const CLI_Command_Definition_t xTRANSMASKSET = +{ + "transmaskset", /* The command string to type. */ + "\r\ntransmaskset :\r\n Set the Reliance Edge automatic transaction mask\r\n", + prvTRANSMASKSETCommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the ABORT command line command, which rolls back + * changes which have not been transacted. */ +static const CLI_Command_Definition_t xABORT = +{ + "abort", /* The command string to type. */ + "\r\nabort:\r\n Roll back all changes not part of the last transaction point\r\n", + prvABORTCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the TEST-FS command line command, which executes some + * file system driver tests. */ +static const CLI_Command_Definition_t xTEST_FS = +{ + "test-fs", /* The command string to type. */ + "\r\ntest-fs:\r\n Executes file system tests. ALL FILES WILL BE DELETED!\r\n", + prvTESTFSCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/*-----------------------------------------------------------*/ + +void vRegisterFileSystemCLICommands( void ) +{ + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xDIR ); + FreeRTOS_CLIRegisterCommand( &xTYPE ); + FreeRTOS_CLIRegisterCommand( &xAPPEND ); + FreeRTOS_CLIRegisterCommand( &xDEL ); + FreeRTOS_CLIRegisterCommand( &xCOPY ); + FreeRTOS_CLIRegisterCommand( &xCREATE ); + FreeRTOS_CLIRegisterCommand( &xMKDIR ); + FreeRTOS_CLIRegisterCommand( &xRENAME ); + FreeRTOS_CLIRegisterCommand( &xLINK ); + FreeRTOS_CLIRegisterCommand( &xSTAT ); + FreeRTOS_CLIRegisterCommand( &xSTATFS ); + FreeRTOS_CLIRegisterCommand( &xFORMAT ); + FreeRTOS_CLIRegisterCommand( &xTRANSACT ); + FreeRTOS_CLIRegisterCommand( &xTRANSMASKGET ); + FreeRTOS_CLIRegisterCommand( &xTRANSMASKSET ); + FreeRTOS_CLIRegisterCommand( &xABORT ); + FreeRTOS_CLIRegisterCommand( &xTEST_FS ); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvDIRCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + static REDDIR * pxDir = NULL; + REDDIRENT * pxDirent; + const char * pcParameter; + BaseType_t xParameterStringLength, xReturn = pdFALSE; + + /* This assumes pcWriteBuffer is long enough. */ + ( void ) pcCommandString; + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + if( pxDir == NULL ) + { + /* Retrieve the directory to DIR. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* This is the first time this function has been executed since the Dir + * command was run. Open the directory. */ + pxDir = red_opendir( pcParameter ); + } + + if( pxDir ) + { + /* red_readdir() returns NULL either on error or upon reaching the + * end of the directory. Clear errno so these conditions can be + * distinguished. */ + red_errno = 0; + pxDirent = red_readdir( pxDir ); + + if( pxDirent ) + { + prvCreateFileInfoString( pcWriteBuffer, pxDirent ); + xReturn = pdPASS; + } + else if( red_errno == 0 ) + { + /* There are no more files. Close the directory. */ + red_closedir( pxDir ); + pxDir = NULL; + + /* No string to return. */ + pcWriteBuffer[ 0 ] = 0x00; + } + else + { + snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d reading directory.", ( int ) red_errno ); + } + } + else + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOENT: + snprintf( pcWriteBuffer, xWriteBufferLen, "Directory not found." ); + break; + + case RED_ENOTDIR: + snprintf( pcWriteBuffer, xWriteBufferLen, "Directory not found or not a directory." ); + break; + + default: + snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening directory.", ( int ) red_errno ); + break; + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTYPECommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength, xReturn = pdTRUE; + static int32_t lFildes = -1; + REDSTAT finfo; + int32_t lStatus, lBytesRead; + size_t xColumns = 50U; + + /* Ensure there is always a null terminator after each character written. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + if( xWriteBufferLen < xColumns ) + { + /* Ensure the loop that uses xColumns as an end condition does not + * write off the end of the buffer. */ + xColumns = xWriteBufferLen; + } + + if( lFildes == -1 ) + { + /* The file has not been opened yet. Find the file name. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to open the requested file. */ + lFildes = red_open( pcParameter, RED_O_RDONLY ); + + if( lFildes == -1 ) + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOENT: + case RED_ENOTDIR: + snprintf( pcWriteBuffer, xWriteBufferLen, "File not found." ); + break; + + default: + snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening file.", ( int ) red_errno ); + break; + } + } + else + { + /* Make sure this is a file, not a directory. */ + lStatus = red_fstat( lFildes, &finfo ); + + if( lStatus == 0 ) + { + if( RED_S_ISDIR( finfo.st_mode ) ) + { + snprintf( pcWriteBuffer, xWriteBufferLen, "Cannot TYPE a directory." ); + red_close( lFildes ); + lFildes = -1; + } + } + else + { + snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file.", ( int ) red_errno ); + red_close( lFildes ); + lFildes = -1; + } + } + } + + if( lFildes != -1 ) + { + /* Read the next chunk of data from the file. */ + lBytesRead = red_read( lFildes, pcWriteBuffer, xColumns ); + + if( lBytesRead < ( int32_t ) xColumns ) + { + /* Error or no more characters to return. */ + red_close( lFildes ); + lFildes = -1; + } + } + + if( lFildes == -1 ) + { + /* Either the file was not opened, or all the data from the file has + * been returned and the file is now closed. */ + xReturn = pdFALSE; + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvAPPENDCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + char * pcFileName = NULL; + const char * pcCharacter = NULL, * pcLength; + BaseType_t xParameterStringLength, xGoodParameters = pdTRUE; + int32_t lFildes, lAppendLength = -1, lThisWrite, lTotalWritten, lBytesWritten; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Find the length to write. */ + pcLength = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 3, /* Return the third parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + configASSERT( pcLength ); + + /* Convert the string into a number. */ + lAppendLength = RedAtoI( pcLength ); + + if( lAppendLength < 0 ) + { + strcpy( pcWriteBuffer, "Third parameter cannot be a negative number." ); + xGoodParameters = pdFALSE; + } + + if( xGoodParameters ) + { + /* Find the character to write. */ + pcCharacter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 2, /* Return the second parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + configASSERT( pcCharacter ); + + if( xParameterStringLength != 1 ) + { + strcpy( pcWriteBuffer, "Second parameter must be a single character." ); + xGoodParameters = pdFALSE; + } + } + + if( xGoodParameters ) + { + /* Find the file name. */ + pcFileName = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + configASSERT( pcFileName ); + + /* Terminate the string. */ + pcFileName[ xParameterStringLength ] = 0x00; + } + + if( xGoodParameters ) + { + /* Attempt to open the requested file. */ + lFildes = red_open( pcFileName, RED_O_WRONLY | RED_O_APPEND | RED_O_CREAT ); + + if( lFildes == -1 ) + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOENT: + case RED_ENOTDIR: + strcpy( pcWriteBuffer, "Bad file path." ); + break; + + case RED_EISDIR: + strcpy( pcWriteBuffer, "Cannot append to a directory." ); + break; + + default: + sprintf( pcWriteBuffer, "Error %d opening file.", ( int ) red_errno ); + break; + } + } + else + { + /* Put the requested character into the buffer. */ + memset( pcWriteBuffer, pcCharacter[ 0 ], xWriteBufferLen ); + + /* Append the data. */ + for( lTotalWritten = 0; lTotalWritten < lAppendLength; lTotalWritten += lThisWrite ) + { + lThisWrite = lAppendLength - lTotalWritten; + + if( lThisWrite > ( int32_t ) xWriteBufferLen ) + { + lThisWrite = ( int32_t ) xWriteBufferLen; + } + + lBytesWritten = red_write( lFildes, pcWriteBuffer, lThisWrite ); + + if( lBytesWritten == -1 ) + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOSPC: + strcpy( pcWriteBuffer, "Out of disk space." ); + break; + + default: + sprintf( pcWriteBuffer, "Error %d writing to file.", ( int ) red_errno ); + break; + } + + break; + } + else if( lBytesWritten != lThisWrite ) + { + /* Some data was written, but not all of it. This only + * happens when the disk is full or the file reached its + * maximum size. That latter is unlikely in this demo. */ + strcpy( pcWriteBuffer, "Out of disk space." ); + break; + } + } + + if( lTotalWritten == lAppendLength ) + { + strcpy( pcWriteBuffer, "Append successful." ); + } + + red_close( lFildes ); + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvDELCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength; + int32_t lStatus; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to delete the file or directory. */ + lStatus = red_unlink( pcParameter ); + + if( lStatus == 0 ) + { + sprintf( pcWriteBuffer, "%s was deleted", pcParameter ); + } + else + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOTDIR: + case RED_ENOENT: + sprintf( pcWriteBuffer, "File not found." ); + break; + + case RED_ENOTEMPTY: + sprintf( pcWriteBuffer, "Cannot remove directory: not empty." ); + break; + + default: + sprintf( pcWriteBuffer, "Error %d deleting file.", ( int ) red_errno ); + break; + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvCOPYCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + char * pcSourceFile; + const char * pcDestinationFile; + BaseType_t xParameterStringLength; + int32_t lSourceFildes, lDestinationFildes; + + /* Obtain the name of the destination file. */ + pcDestinationFile = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 2, /* Return the second parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcDestinationFile ); + + /* Obtain the name of the source file. */ + pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcSourceFile ); + + /* Terminate the string. */ + pcSourceFile[ xParameterStringLength ] = 0x00; + + /* See if the source file exists, open it if it does. */ + lSourceFildes = red_open( pcSourceFile, RED_O_RDONLY ); + + if( lSourceFildes == -1 ) + { + sprintf( pcWriteBuffer, "Source file does not exist" ); + } + else + { + /* Create the destination file, error if it already exists. */ + lDestinationFildes = red_open( pcDestinationFile, RED_O_CREAT | RED_O_EXCL | RED_O_WRONLY ); + + if( lDestinationFildes == -1 ) + { + sprintf( pcWriteBuffer, "Error: Destination file already exists" ); + } + else + { + if( prvPerformCopy( lSourceFildes, lDestinationFildes, pcWriteBuffer, xWriteBufferLen ) == pdPASS ) + { + sprintf( pcWriteBuffer, "Copy made" ); + } + else + { + sprintf( pcWriteBuffer, "Error during copy" ); + } + + red_close( lDestinationFildes ); + } + + red_close( lSourceFildes ); + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvCREATECommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength; + int32_t lFildes; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to create the file. */ + lFildes = red_open( pcParameter, RED_O_CREAT | RED_O_EXCL | RED_O_RDWR ); + + if( lFildes != -1 ) + { + sprintf( pcWriteBuffer, "%s was created", pcParameter ); + red_close( lFildes ); + } + else + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOTDIR: + case RED_ENOENT: + sprintf( pcWriteBuffer, "Bad file path." ); + break; + + case RED_EEXIST: + sprintf( pcWriteBuffer, "File already exists." ); + break; + + default: + sprintf( pcWriteBuffer, "Error %d creating file.", ( int ) red_errno ); + break; + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvMKDIRCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength; + int32_t lStatus; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to create the file. */ + lStatus = red_mkdir( pcParameter ); + + if( lStatus == 0 ) + { + sprintf( pcWriteBuffer, "%s was created", pcParameter ); + } + else + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOTDIR: + case RED_ENOENT: + sprintf( pcWriteBuffer, "Bad file path." ); + break; + + case RED_EEXIST: + sprintf( pcWriteBuffer, "Directory already exists." ); + break; + + default: + sprintf( pcWriteBuffer, "Error %d creating directory.", ( int ) red_errno ); + break; + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvRENAMECommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcDestinationFile; + char * pcSourceFile; + BaseType_t xParameterStringLength; + int32_t lStatus; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Obtain the name of the destination file. */ + pcDestinationFile = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 2, /* Return the second parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcDestinationFile ); + + /* Obtain the name of the source file. */ + pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcSourceFile ); + + /* Terminate the string. */ + pcSourceFile[ xParameterStringLength ] = 0x00; + + /* Attempt to rename the file. */ + lStatus = red_rename( pcSourceFile, pcDestinationFile ); + + if( lStatus == 0 ) + { + sprintf( pcWriteBuffer, "%s was renamed to %s", pcSourceFile, pcDestinationFile ); + } + else + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOTDIR: + case RED_ENOENT: + case RED_EISDIR: + sprintf( pcWriteBuffer, "Bad file path." ); + break; + + /* This will only be seen if POSIX rename is disabled. */ + case RED_EEXIST: + sprintf( pcWriteBuffer, "Destination already exists." ); + break; + + default: + sprintf( pcWriteBuffer, "Error %d renaming file.", ( int ) red_errno ); + break; + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvLINKCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcDestinationFile; + char * pcSourceFile; + BaseType_t xParameterStringLength; + int32_t lStatus; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Obtain the name of the destination file. */ + pcDestinationFile = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 2, /* Return the second parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcDestinationFile ); + + /* Obtain the name of the source file. */ + pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcSourceFile ); + + /* Terminate the string. */ + pcSourceFile[ xParameterStringLength ] = 0x00; + + /* Attempt to create the hard link. */ + lStatus = red_link( pcSourceFile, pcDestinationFile ); + + if( lStatus == 0 ) + { + sprintf( pcWriteBuffer, "%s was linked to %s", pcDestinationFile, pcSourceFile ); + } + else + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOTDIR: + case RED_ENOENT: + sprintf( pcWriteBuffer, "Bad file path." ); + break; + + case RED_EPERM: + sprintf( pcWriteBuffer, "Cannot link a directory." ); + break; + + case RED_EMLINK: + sprintf( pcWriteBuffer, "Too many hard links." ); + break; + + default: + sprintf( pcWriteBuffer, "Error %d linking file.", ( int ) red_errno ); + break; + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvSTATCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter, * pcModeString; + BaseType_t xParameterStringLength; + REDSTAT finfo; + int32_t lFildes, lStatus; + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + /* Find the file name. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to open the requested file. */ + lFildes = red_open( pcParameter, RED_O_RDONLY ); + + if( lFildes == -1 ) + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_ENOENT: + case RED_ENOTDIR: + snprintf( pcWriteBuffer, xWriteBufferLen, "File not found." ); + break; + + default: + snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening file.", ( int ) red_errno ); + break; + } + } + else + { + lStatus = red_fstat( lFildes, &finfo ); + + if( lStatus == 0 ) + { + if( RED_S_ISDIR( finfo.st_mode ) ) + { + pcModeString = "dir"; + } + else + { + pcModeString = "file"; + } + + snprintf( pcWriteBuffer, xWriteBufferLen, "ino=%lu mode=0x%04x(%s) nlink=%x size=%lu blocks=%lu", + ( unsigned long ) finfo.st_ino, ( unsigned ) finfo.st_mode, pcModeString, + ( unsigned ) finfo.st_nlink, ( unsigned long ) finfo.st_size, ( unsigned long ) finfo.st_blocks ); + } + else + { + snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file.", ( int ) red_errno ); + } + + red_close( lFildes ); + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvSTATFSCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + REDSTATFS fsinfo; + int32_t lStatus; + + /* Avoid compiler warnings. */ + ( void ) pcCommandString; + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + lStatus = red_statvfs( "", &fsinfo ); + + if( lStatus == -1 ) + { + snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file system.", ( int ) red_errno ); + } + else + { + snprintf( pcWriteBuffer, xWriteBufferLen, + "Block size: %lu\r\n" + "Block count: %lu\r\n" + "Free blocks: %lu\r\n" + "Inode count: %lu\r\n" + "Free inodes: %lu\r\n", + ( unsigned long ) fsinfo.f_bsize, ( unsigned long ) fsinfo.f_blocks, + ( unsigned long ) fsinfo.f_bfree, ( unsigned long ) fsinfo.f_files, + ( unsigned long ) fsinfo.f_ffree ); + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvFORMATCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + int32_t lStatus; + + /* Avoid compiler warnings. */ + ( void ) pcCommandString; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* File system volumes cannot be formatted while mounted. */ + lStatus = red_umount( "" ); + + if( lStatus == -1 ) + { + sprintf( pcWriteBuffer, "Error %d during unmount.", ( int ) red_errno ); + } + else + { + /* Re-format the file system volume. */ + lStatus = red_format( "" ); + + if( lStatus == -1 ) + { + sprintf( pcWriteBuffer, "Error %d during format.", ( int ) red_errno ); + } + else + { + /* Mount again so that other commands will work properly. */ + lStatus = red_mount( "" ); + + if( lStatus == -1 ) + { + sprintf( pcWriteBuffer, "Error %d during mount.", ( int ) red_errno ); + } + else + { + strcpy( pcWriteBuffer, "Format successful." ); + } + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTRANSACTCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + int32_t lStatus; + + /* Avoid compiler warnings. */ + ( void ) pcCommandString; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Save the original transaction mask settings. */ + lStatus = red_transact( "" ); + + if( lStatus == -1 ) + { + sprintf( pcWriteBuffer, "Error %d during transaction point.", ( int ) red_errno ); + } + else + { + strcpy( pcWriteBuffer, "Transaction point successful." ); + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTRANSMASKGETCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + uint32_t ulEventMask; + int32_t lStatus; + + /* Avoid compiler warnings. */ + ( void ) pcCommandString; + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + lStatus = red_gettransmask( "", &ulEventMask ); + + if( lStatus == -1 ) + { + snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d retrieving automatic transaction event mask.", ( int ) red_errno ); + } + else + { + snprintf( pcWriteBuffer, xWriteBufferLen, + "Current automatic transaction event mask: 0x%04lx\r\n" + "RED_TRANSACT_UMOUNT (0x0001): %s\r\n" + "RED_TRANSACT_CREAT (0x0002): %s\r\n" + "RED_TRANSACT_UNLINK (0x0004): %s\r\n" + "RED_TRANSACT_MKDIR (0x0008): %s\r\n" + "RED_TRANSACT_RENAME (0x0010): %s\r\n" + "RED_TRANSACT_LINK (0x0020): %s\r\n" + "RED_TRANSACT_CLOSE (0x0040): %s\r\n" + "RED_TRANSACT_WRITE (0x0080): %s\r\n" + "RED_TRANSACT_FSYNC (0x0100): %s\r\n" + "RED_TRANSACT_TRUNCATE (0x0200): %s\r\n" + "RED_TRANSACT_VOLFULL (0x0400): %s\r\n", + ( unsigned long ) ulEventMask, + ( ulEventMask & RED_TRANSACT_UMOUNT ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_CREAT ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_UNLINK ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_MKDIR ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_RENAME ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_LINK ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_CLOSE ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_WRITE ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_FSYNC ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_TRUNCATE ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_VOLFULL ) ? "Enabled" : "Disabled" ); + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTRANSMASKSETCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength; + uint32_t ulEventMask; + int32_t lStatus; + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + if( ( pcParameter[ 0 ] == '0' ) && ( ( pcParameter[ 1 ] == 'x' ) || ( pcParameter[ 1 ] == 'X' ) ) ) + { + pcParameter += 2; + } + + /* Convert the argument into a value. */ + RedHtoUL( pcParameter, &ulEventMask ); + + /* Set the new transaction mask. */ + lStatus = red_settransmask( "", ulEventMask ); + + if( lStatus == -1 ) + { + /* User-friendly messages for common errors. */ + switch( red_errno ) + { + case RED_EINVAL: + snprintf( pcWriteBuffer, xWriteBufferLen, "Invalid bits in transaction mask." ); + break; + + default: + snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d setting transaction mask.", ( int ) red_errno ); + break; + } + } + else + { + snprintf( pcWriteBuffer, xWriteBufferLen, + "Successfully set automatic transaction mask. Enabled events:\r\n" + "RED_TRANSACT_UMOUNT (0x0001): %s\r\n" + "RED_TRANSACT_CREAT (0x0002): %s\r\n" + "RED_TRANSACT_UNLINK (0x0004): %s\r\n" + "RED_TRANSACT_MKDIR (0x0008): %s\r\n" + "RED_TRANSACT_RENAME (0x0010): %s\r\n" + "RED_TRANSACT_LINK (0x0020): %s\r\n" + "RED_TRANSACT_CLOSE (0x0040): %s\r\n" + "RED_TRANSACT_WRITE (0x0080): %s\r\n" + "RED_TRANSACT_FSYNC (0x0100): %s\r\n" + "RED_TRANSACT_TRUNCATE (0x0200): %s\r\n" + "RED_TRANSACT_VOLFULL (0x0400): %s\r\n", + ( ulEventMask & RED_TRANSACT_UMOUNT ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_CREAT ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_UNLINK ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_MKDIR ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_RENAME ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_LINK ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_CLOSE ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_WRITE ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_FSYNC ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_TRUNCATE ) ? "Enabled" : "Disabled", + ( ulEventMask & RED_TRANSACT_VOLFULL ) ? "Enabled" : "Disabled" ); + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvABORTCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + uint32_t ulEventMask; + int32_t lStatus; + + /* Avoid compiler warnings. */ + ( void ) pcCommandString; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Save the original transaction mask settings. */ + lStatus = red_gettransmask( "", &ulEventMask ); + + if( lStatus == -1 ) + { + sprintf( pcWriteBuffer, "Error %d querying transaction mask.", ( int ) red_errno ); + } + else + { + /* Make it so that red_umount() will not automatically commit a new + * transaction point. */ + lStatus = red_settransmask( "", ulEventMask & ~( ( uint32_t ) RED_TRANSACT_UMOUNT ) ); + + if( lStatus == -1 ) + { + sprintf( pcWriteBuffer, "Error %d setting transaction mask.", ( int ) red_errno ); + } + else + { + /* Unmount. Since red_umount() will not transact, all changes which + * were not already transacted are rolled back. */ + lStatus = red_umount( "" ); + + if( lStatus == -1 ) + { + sprintf( pcWriteBuffer, "Error %d during unmount.", ( int ) red_errno ); + } + else + { + /* Mount. Mount always starts from the last transaction point. */ + lStatus = red_mount( "" ); + + if( lStatus == -1 ) + { + sprintf( pcWriteBuffer, "Error %d during mount.", ( int ) red_errno ); + } + else + { + strcpy( pcWriteBuffer, "Working state changes successfully aborted." ); + } + } + + /* Restore the original transaction mask settings. */ + red_settransmask( "", ulEventMask ); + } + } + + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTESTFSCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + UBaseType_t uxOriginalPriority; + FSSTRESSPARAM param; + + /* Avoid compiler warnings. */ + ( void ) xWriteBufferLen; + ( void ) pcCommandString; + + /* Limitations in the interaction with the Windows TCP/IP stack require + * the command console to run at the idle priority. Raise the priority for + * the duration of the tests to ensure there are not multiple switches to the + * idle task as in the simulated environment the idle task hook function may + * include a (relatively) long delay. */ + uxOriginalPriority = uxTaskPriorityGet( NULL ); + vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); + + /* Delete all files to avoid interfering with the test. */ + red_umount( "" ); + red_format( "" ); + red_mount( "" ); + + FsstressDefaultParams( ¶m ); + param.fVerbose = pdTRUE; + param.ulNops = 10000; + param.ulSeed = 1; + FsstressStart( ¶m ); + + /* Clean up after the test. */ + red_umount( "" ); + red_format( "" ); + red_mount( "" ); + + /* Reset back to the original priority. */ + vTaskPrioritySet( NULL, uxOriginalPriority ); + + sprintf( pcWriteBuffer, "%s", "Test results were sent to Windows console" ); + strcat( pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvPerformCopy( int32_t lSourceFildes, + int32_t lDestinationFiledes, + char * pxWriteBuffer, + size_t xWriteBufferLen ) +{ + int32_t lBytesRead; + BaseType_t xReturn = pdPASS; + + /* Assuming both files are at offset zero. */ + + for( ; ; ) + { + /* Read the next block of data. */ + lBytesRead = red_read( lSourceFildes, pxWriteBuffer, xWriteBufferLen ); + + if( lBytesRead <= 0 ) + { + if( lBytesRead == -1 ) + { + /* Error reading from file. */ + xReturn = pdFAIL; + } + else + { + /* No error: reached end of file, time to stop. */ + } + + break; + } + + /* Write the block of data to the end of the file. */ + if( red_write( lDestinationFiledes, pxWriteBuffer, lBytesRead ) != lBytesRead ) + { + xReturn = pdFAIL; + break; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvCreateFileInfoString( char * pcBuffer, + REDDIRENT * pxDirent ) +{ + const char * pcFile = "file", * pcDirectory = "directory"; + const char * pcAttrib; + + /* Point pcAttrib to a string that describes the file. */ + if( RED_S_ISDIR( pxDirent->d_stat.st_mode ) ) + { + pcAttrib = pcDirectory; + } + else + { + pcAttrib = pcFile; + } + + /* Create a string that includes the file name, the file size and the + * attributes string. */ + sprintf( pcBuffer, "%s [%s] [size=%lld]", pxDirent->d_name, pcAttrib, pxDirent->d_stat.st_size ); +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-system-demo.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-system-demo.c index d1c25818a..14252915a 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-system-demo.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-system-demo.c @@ -1,288 +1,284 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -/******************************************************************************* - * See the URL in the comments within main.c for the location of the online - * documentation. - ******************************************************************************/ - -/* Standard includes. */ -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" - -/* File system includes. */ -#include - -/* The number of bytes read/written to the example files at a time. */ -#define fsRAM_BUFFER_SIZE 200 - -/* The volume prefix is an empty string, for convenience since there is only one -volume in this demo. -*/ -#define fsVOLUME_NAME "" - -/*-----------------------------------------------------------*/ - -/* - * Creates and verifies different files on the volume, demonstrating the use of - * various different API functions. - */ -void vCreateAndVerifySampleFiles( void ); - -/* - * Create a set of example files in the root directory of the volume using - * f_write(). - */ -static void prvCreateDemoFiles( void ); - -/* - * Use f_read() to read back and verify the files that were created by - * prvCreateDemoFiles(). - */ -static void prvVerifyDemoFiles( void ); - -/*-----------------------------------------------------------*/ - -/* A buffer used to both create content to write to disk, and read content back -from a disk. Note there is no mutual exclusion on this buffer. */ -static char cRAMBuffer[ fsRAM_BUFFER_SIZE ]; - -/* Names of directories that are created. */ -static const char *pcDirectory1 = "/SUB1", *pcDirectory2 = "/SUB1/SUB2"; - -/*-----------------------------------------------------------*/ - -void vCreateAndVerifySampleFiles( void ) -{ -int32_t lStatus; - - /* First initialize the Reliance Edge driver. */ - lStatus = red_init(); - - /* Format the volume. */ - if( lStatus == 0 ) - { - lStatus = red_format( fsVOLUME_NAME ); - } - - /* Mount the volume. */ - if( lStatus == 0 ) - { - lStatus = red_mount( fsVOLUME_NAME ); - } - - if( lStatus == 0 ) - { - /* Create a set of files using red_write(). */ - prvCreateDemoFiles(); - - /* Read back and verify the files that were created using red_write(). */ - prvVerifyDemoFiles(); - } -} -/*-----------------------------------------------------------*/ - -static void prvCreateDemoFiles( void ) -{ -BaseType_t xFileNumber, xWriteNumber; -char cFilePath[ 64 ]; -const BaseType_t xMaxFiles = 5; -uint32_t ulEventMask; -int32_t lBytesWritten, lFildes, lStatus; -int iByte; - - /* Save the current transaction point settings. */ - lStatus = red_gettransmask( fsVOLUME_NAME, &ulEventMask ); - configASSERT( lStatus == 0 ); - - /* Disable automatic transaction points so that all of the files can be - created in one atomic operation. */ - lStatus = red_settransmask( fsVOLUME_NAME, RED_TRANSACT_MANUAL ); - configASSERT( lStatus == 0 ); - - /* Create xMaxFiles files. Each created file will be - ( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled - with a different repeating character. */ - for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) - { - /* Generate a file name. */ - sprintf( cFilePath, "/root%03d.txt", xFileNumber ); - - /* Print out the file name and the directory into which the file is - being written. */ - printf( "Creating file %s\r\n", cFilePath ); - - /* Open the file, creating the file if it does not already exist. */ - lFildes = red_open( cFilePath, RED_O_CREAT|RED_O_TRUNC|RED_O_WRONLY ); - configASSERT( lFildes != -1 ); - - /* Fill the RAM buffer with data that will be written to the file. This - is just a repeating ascii character that indicates the file number. */ - memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE ); - - /* Write the RAM buffer to the opened file a number of times. The - number of times the RAM buffer is written to the file depends on the - file number, so the length of each created file will be different. */ - for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ ) - { - lBytesWritten = red_write( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE ); - configASSERT( lBytesWritten == fsRAM_BUFFER_SIZE ); - } - - /* Close the file so another file can be created. */ - lStatus = red_close( lFildes ); - configASSERT( lStatus == 0 ); - } - - /* Commit a transaction point, atomically adding the set of files to the - transacted state. */ - lStatus = red_transact( fsVOLUME_NAME ); - configASSERT( lStatus == 0 ); - - /* Create a sub directory. */ - printf( "Creating directory %s\r\n", pcDirectory1 ); - - lStatus = red_mkdir( pcDirectory1 ); - configASSERT( lStatus == 0 ); - - /* Create a subdirectory in the new directory. */ - printf( "Creating directory %s\r\n", pcDirectory2 ); - - lStatus = red_mkdir( pcDirectory2 ); - configASSERT( lStatus == 0 ); - - /* Generate the file name. */ - sprintf( cFilePath, "%s/file.txt", pcDirectory2 ); - - /* Print out the file name and the directory into which the file is being - written. */ - printf( "Writing file %s\r\n", cFilePath ); - - lFildes = red_open( cFilePath, RED_O_CREAT|RED_O_TRUNC|RED_O_WRONLY ); - - /* Write the file. It is filled with incrementing ascii characters starting - from '0'. */ - for( iByte = 0; iByte < fsRAM_BUFFER_SIZE; iByte++ ) - { - cRAMBuffer[ iByte ] = ( char ) ( ( int ) '0' + iByte ); - } - - lBytesWritten = red_write( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE ); - configASSERT( lBytesWritten == fsRAM_BUFFER_SIZE ); - - /* Finished so close the file. */ - lStatus = red_close( lFildes ); - configASSERT( lStatus == 0 ); - - /* Commit a transaction point, atomically adding the set of files and - directories to the transacted state. */ - lStatus = red_transact( fsVOLUME_NAME ); - configASSERT( lStatus == 0 ); - - /* Restore previous transaction point settings. */ - lStatus = red_settransmask( fsVOLUME_NAME, ulEventMask ); - configASSERT( lStatus == 0 ); -} -/*-----------------------------------------------------------*/ - -static void prvVerifyDemoFiles( void ) -{ -BaseType_t xFileNumber, xReadNumber; -char cFilePath[ 64 ]; -const BaseType_t xMaxFiles = 5; -long lChar; -int32_t lBytesRead, lFildes, lStatus; -int iByte; - - /* Read back the files that were created by prvCreateDemoFiles(). */ - for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) - { - /* Generate the file name. */ - sprintf( cFilePath, "/root%03d.txt", xFileNumber ); - - /* Print out the file name and the directory from which the file is - being read. */ - printf( "Reading file %s\r\n", cFilePath ); - - /* Open the file for reading. */ - lFildes = red_open( cFilePath, RED_O_RDONLY ); - configASSERT( lFildes != -1 ); - - /* Read the file into the RAM buffer, checking the file contents are as - expected. The size of the file depends on the file number. */ - for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ ) - { - /* Start with the RAM buffer clear. */ - memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE ); - - lBytesRead = red_read( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE ); - configASSERT( lBytesRead == fsRAM_BUFFER_SIZE ); - - /* Check the RAM buffer is filled with the expected data. Each - file contains a different repeating ascii character that indicates - the number of the file. */ - for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ ) - { - configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) ); - } - } - - /* Close the file. */ - lStatus = red_close( lFildes ); - configASSERT( lStatus == 0 ); - } - - /* Generate the file name. */ - sprintf( cFilePath, "%s/file.txt", pcDirectory2 ); - - /* Print out the file name and the directory from which the file is being - read. */ - printf( "Reading file %s\r\n", cFilePath ); - - /* This time the file is opened for reading. */ - lFildes = red_open( cFilePath, RED_O_RDONLY ); - configASSERT( lFildes != -1 ); - - /* Read the file. */ - lBytesRead = red_read( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE ); - configASSERT( lBytesRead == fsRAM_BUFFER_SIZE ); - - /* Verify the file 1 byte at a time. */ - for( iByte = 0; iByte < fsRAM_BUFFER_SIZE; iByte++ ) - { - configASSERT( cRAMBuffer[ iByte ] == ( char ) ( ( int ) '0' + iByte ) ); - } - - /* Finished so close the file. */ - lStatus = red_close( lFildes ); - configASSERT( lStatus == 0 ); -} - - - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/******************************************************************************* + * See the URL in the comments within main.c for the location of the online + * documentation. + ******************************************************************************/ + +/* Standard includes. */ +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" + +/* File system includes. */ +#include + +/* The number of bytes read/written to the example files at a time. */ +#define fsRAM_BUFFER_SIZE 200 + +/* The volume prefix is an empty string, for convenience since there is only one + * volume in this demo. + */ +#define fsVOLUME_NAME "" + +/*-----------------------------------------------------------*/ + +/* + * Creates and verifies different files on the volume, demonstrating the use of + * various different API functions. + */ +void vCreateAndVerifySampleFiles( void ); + +/* + * Create a set of example files in the root directory of the volume using + * f_write(). + */ +static void prvCreateDemoFiles( void ); + +/* + * Use f_read() to read back and verify the files that were created by + * prvCreateDemoFiles(). + */ +static void prvVerifyDemoFiles( void ); + +/*-----------------------------------------------------------*/ + +/* A buffer used to both create content to write to disk, and read content back + * from a disk. Note there is no mutual exclusion on this buffer. */ +static char cRAMBuffer[ fsRAM_BUFFER_SIZE ]; + +/* Names of directories that are created. */ +static const char * pcDirectory1 = "/SUB1", * pcDirectory2 = "/SUB1/SUB2"; + +/*-----------------------------------------------------------*/ + +void vCreateAndVerifySampleFiles( void ) +{ + int32_t lStatus; + + /* First initialize the Reliance Edge driver. */ + lStatus = red_init(); + + /* Format the volume. */ + if( lStatus == 0 ) + { + lStatus = red_format( fsVOLUME_NAME ); + } + + /* Mount the volume. */ + if( lStatus == 0 ) + { + lStatus = red_mount( fsVOLUME_NAME ); + } + + if( lStatus == 0 ) + { + /* Create a set of files using red_write(). */ + prvCreateDemoFiles(); + + /* Read back and verify the files that were created using red_write(). */ + prvVerifyDemoFiles(); + } +} +/*-----------------------------------------------------------*/ + +static void prvCreateDemoFiles( void ) +{ + BaseType_t xFileNumber, xWriteNumber; + char cFilePath[ 64 ]; + const BaseType_t xMaxFiles = 5; + uint32_t ulEventMask; + int32_t lBytesWritten, lFildes, lStatus; + int iByte; + + /* Save the current transaction point settings. */ + lStatus = red_gettransmask( fsVOLUME_NAME, &ulEventMask ); + configASSERT( lStatus == 0 ); + + /* Disable automatic transaction points so that all of the files can be + * created in one atomic operation. */ + lStatus = red_settransmask( fsVOLUME_NAME, RED_TRANSACT_MANUAL ); + configASSERT( lStatus == 0 ); + + /* Create xMaxFiles files. Each created file will be + * ( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled + * with a different repeating character. */ + for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) + { + /* Generate a file name. */ + sprintf( cFilePath, "/root%03d.txt", xFileNumber ); + + /* Print out the file name and the directory into which the file is + * being written. */ + printf( "Creating file %s\r\n", cFilePath ); + + /* Open the file, creating the file if it does not already exist. */ + lFildes = red_open( cFilePath, RED_O_CREAT | RED_O_TRUNC | RED_O_WRONLY ); + configASSERT( lFildes != -1 ); + + /* Fill the RAM buffer with data that will be written to the file. This + * is just a repeating ascii character that indicates the file number. */ + memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE ); + + /* Write the RAM buffer to the opened file a number of times. The + * number of times the RAM buffer is written to the file depends on the + * file number, so the length of each created file will be different. */ + for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ ) + { + lBytesWritten = red_write( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE ); + configASSERT( lBytesWritten == fsRAM_BUFFER_SIZE ); + } + + /* Close the file so another file can be created. */ + lStatus = red_close( lFildes ); + configASSERT( lStatus == 0 ); + } + + /* Commit a transaction point, atomically adding the set of files to the + * transacted state. */ + lStatus = red_transact( fsVOLUME_NAME ); + configASSERT( lStatus == 0 ); + + /* Create a sub directory. */ + printf( "Creating directory %s\r\n", pcDirectory1 ); + + lStatus = red_mkdir( pcDirectory1 ); + configASSERT( lStatus == 0 ); + + /* Create a subdirectory in the new directory. */ + printf( "Creating directory %s\r\n", pcDirectory2 ); + + lStatus = red_mkdir( pcDirectory2 ); + configASSERT( lStatus == 0 ); + + /* Generate the file name. */ + sprintf( cFilePath, "%s/file.txt", pcDirectory2 ); + + /* Print out the file name and the directory into which the file is being + * written. */ + printf( "Writing file %s\r\n", cFilePath ); + + lFildes = red_open( cFilePath, RED_O_CREAT | RED_O_TRUNC | RED_O_WRONLY ); + + /* Write the file. It is filled with incrementing ascii characters starting + * from '0'. */ + for( iByte = 0; iByte < fsRAM_BUFFER_SIZE; iByte++ ) + { + cRAMBuffer[ iByte ] = ( char ) ( ( int ) '0' + iByte ); + } + + lBytesWritten = red_write( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE ); + configASSERT( lBytesWritten == fsRAM_BUFFER_SIZE ); + + /* Finished so close the file. */ + lStatus = red_close( lFildes ); + configASSERT( lStatus == 0 ); + + /* Commit a transaction point, atomically adding the set of files and + * directories to the transacted state. */ + lStatus = red_transact( fsVOLUME_NAME ); + configASSERT( lStatus == 0 ); + + /* Restore previous transaction point settings. */ + lStatus = red_settransmask( fsVOLUME_NAME, ulEventMask ); + configASSERT( lStatus == 0 ); +} +/*-----------------------------------------------------------*/ + +static void prvVerifyDemoFiles( void ) +{ + BaseType_t xFileNumber, xReadNumber; + char cFilePath[ 64 ]; + const BaseType_t xMaxFiles = 5; + long lChar; + int32_t lBytesRead, lFildes, lStatus; + int iByte; + + /* Read back the files that were created by prvCreateDemoFiles(). */ + for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) + { + /* Generate the file name. */ + sprintf( cFilePath, "/root%03d.txt", xFileNumber ); + + /* Print out the file name and the directory from which the file is + * being read. */ + printf( "Reading file %s\r\n", cFilePath ); + + /* Open the file for reading. */ + lFildes = red_open( cFilePath, RED_O_RDONLY ); + configASSERT( lFildes != -1 ); + + /* Read the file into the RAM buffer, checking the file contents are as + * expected. The size of the file depends on the file number. */ + for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ ) + { + /* Start with the RAM buffer clear. */ + memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE ); + + lBytesRead = red_read( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE ); + configASSERT( lBytesRead == fsRAM_BUFFER_SIZE ); + + /* Check the RAM buffer is filled with the expected data. Each + * file contains a different repeating ascii character that indicates + * the number of the file. */ + for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ ) + { + configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) ); + } + } + + /* Close the file. */ + lStatus = red_close( lFildes ); + configASSERT( lStatus == 0 ); + } + + /* Generate the file name. */ + sprintf( cFilePath, "%s/file.txt", pcDirectory2 ); + + /* Print out the file name and the directory from which the file is being + * read. */ + printf( "Reading file %s\r\n", cFilePath ); + + /* This time the file is opened for reading. */ + lFildes = red_open( cFilePath, RED_O_RDONLY ); + configASSERT( lFildes != -1 ); + + /* Read the file. */ + lBytesRead = red_read( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE ); + configASSERT( lBytesRead == fsRAM_BUFFER_SIZE ); + + /* Verify the file 1 byte at a time. */ + for( iByte = 0; iByte < fsRAM_BUFFER_SIZE; iByte++ ) + { + configASSERT( cRAMBuffer[ iByte ] == ( char ) ( ( int ) '0' + iByte ) ); + } + + /* Finished so close the file. */ + lStatus = red_close( lFildes ); + configASSERT( lStatus == 0 ); +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.sln index c51954c57..c5143a31c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.sln +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.sln @@ -1,86 +1,86 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_Reliance_Edge_with_CLI", "FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj", "{292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{BB78C687-07C7-4DFA-A8B0-80547662AC5D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|Win32.ActiveCfg = Debug|Win32 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|Win32.Build.0 = Debug|Win32 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|x64.ActiveCfg = Debug|x64 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|x64.Build.0 = Debug|x64 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|x86.ActiveCfg = Debug|Win32 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|x86.Build.0 = Debug|Win32 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|Win32.ActiveCfg = Release|Win32 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|Win32.Build.0 = Release|Win32 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|x64.ActiveCfg = Release|x64 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|x64.Build.0 = Release|x64 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|x86.ActiveCfg = Release|Win32 - {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {BB78C687-07C7-4DFA-A8B0-80547662AC5D} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {BB78C687-07C7-4DFA-A8B0-80547662AC5D} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {BB78C687-07C7-4DFA-A8B0-80547662AC5D} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {88FCBE63-FE27-42E6-8F61-FD500B17B15F} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_Reliance_Edge_with_CLI", "FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj", "{292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{BB78C687-07C7-4DFA-A8B0-80547662AC5D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|Win32.ActiveCfg = Debug|Win32 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|Win32.Build.0 = Debug|Win32 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|x64.ActiveCfg = Debug|x64 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|x64.Build.0 = Debug|x64 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|x86.ActiveCfg = Debug|Win32 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Debug|x86.Build.0 = Debug|Win32 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|Win32.ActiveCfg = Release|Win32 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|Win32.Build.0 = Release|Win32 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|x64.ActiveCfg = Release|x64 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|x64.Build.0 = Release|x64 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|x86.ActiveCfg = Release|Win32 + {292E0A6B-B7FA-4AF5-BD35-D3EE63CED2FF}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {BB78C687-07C7-4DFA-A8B0-80547662AC5D} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {BB78C687-07C7-4DFA-A8B0-80547662AC5D} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {BB78C687-07C7-4DFA-A8B0-80547662AC5D} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {88FCBE63-FE27-42E6-8F61-FD500B17B15F} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj index fd8885db6..071d5de2d 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj @@ -1,206 +1,206 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {292e0a6b-b7fa-4af5-bd35-d3ee63ced2ff} - FreeRTOSPlusRelianceEdgewithCLI - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\Source\Reliance-Edge\os\freertos\include;..\..\Source\Reliance-Edge\projects\freertos\win32-demo;..\..\Source\Reliance-Edge\core\include;..\..\Source\Reliance-Edge\include;..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\FreeRTOS-Plus-CLI;.;.\ConfigurationFiles;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {292e0a6b-b7fa-4af5-bd35-d3ee63ced2ff} + FreeRTOSPlusRelianceEdgewithCLI + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + ..\..\Source\Reliance-Edge\os\freertos\include;..\..\Source\Reliance-Edge\projects\freertos\win32-demo;..\..\Source\Reliance-Edge\core\include;..\..\Source\Reliance-Edge\include;..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\FreeRTOS-Plus-CLI;.;.\ConfigurationFiles;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj.filters index 5783d4d6c..53d3d6069 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/FreeRTOS_Plus_Reliance_Edge_with_CLI.vcxproj.filters @@ -1,177 +1,177 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {65b8e9c3-41b9-4e36-a792-ae820cb5720d} - - - {a66ccd52-20db-4311-8edf-6e2927dfcd84} - - - {688b3585-58c1-48f8-925d-7b79c9997765} - - - {a3485680-f5cc-4464-b049-8dd26ebbf34a} - - - {c68304b0-febc-41aa-b063-c98236ca911a} - - - {e6ca7a10-ab7a-4f37-a360-9fe1fc7d2012} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - FreeRTOS+CLI - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\util - - - FreeRTOS+Reliance Edge\util - - - FreeRTOS+Reliance Edge\util - - - FreeRTOS+Reliance Edge\util - - - FreeRTOS+Reliance Edge\util - - - FreeRTOS+Reliance Edge\util - - - FreeRTOS+Reliance Edge\util - - - FreeRTOS+Reliance Edge\test - - - FreeRTOS+Reliance Edge\test - - - FreeRTOS+Reliance Edge\test - - - FreeRTOS+Reliance Edge\test - - - FreeRTOS+Reliance Edge\test - - - FreeRTOS+Reliance Edge\test - - - FreeRTOS+Reliance Edge\test - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\driver - - - FreeRTOS+Reliance Edge\port - - - FreeRTOS+Reliance Edge\port - - - FreeRTOS+Reliance Edge\port - - - FreeRTOS+Reliance Edge\port - - - FreeRTOS+Reliance Edge\port - - - FreeRTOS+Reliance Edge\port - - - FreeRTOS+Reliance Edge\port - - - - - Header Files - - - Header Files - - - FreeRTOS+CLI - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {65b8e9c3-41b9-4e36-a792-ae820cb5720d} + + + {a66ccd52-20db-4311-8edf-6e2927dfcd84} + + + {688b3585-58c1-48f8-925d-7b79c9997765} + + + {a3485680-f5cc-4464-b049-8dd26ebbf34a} + + + {c68304b0-febc-41aa-b063-c98236ca911a} + + + {e6ca7a10-ab7a-4f37-a360-9fe1fc7d2012} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + FreeRTOS+CLI + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\util + + + FreeRTOS+Reliance Edge\util + + + FreeRTOS+Reliance Edge\util + + + FreeRTOS+Reliance Edge\util + + + FreeRTOS+Reliance Edge\util + + + FreeRTOS+Reliance Edge\util + + + FreeRTOS+Reliance Edge\util + + + FreeRTOS+Reliance Edge\test + + + FreeRTOS+Reliance Edge\test + + + FreeRTOS+Reliance Edge\test + + + FreeRTOS+Reliance Edge\test + + + FreeRTOS+Reliance Edge\test + + + FreeRTOS+Reliance Edge\test + + + FreeRTOS+Reliance Edge\test + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\driver + + + FreeRTOS+Reliance Edge\port + + + FreeRTOS+Reliance Edge\port + + + FreeRTOS+Reliance Edge\port + + + FreeRTOS+Reliance Edge\port + + + FreeRTOS+Reliance Edge\port + + + FreeRTOS+Reliance Edge\port + + + FreeRTOS+Reliance Edge\port + + + + + Header Files + + + Header Files + + + FreeRTOS+CLI + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Instructions_ReadMe.url b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Instructions_ReadMe.url index 9aca2c69e..79e185555 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Instructions_ReadMe.url +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Instructions_ReadMe.url @@ -1,6 +1,6 @@ -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 -[InternetShortcut] -URL=http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml -IDList= -HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml +IDList= +HotKey=0 diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Run-time-stats-utils.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Run-time-stats-utils.c index 0e387ca3e..79fef9b05 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Run-time-stats-utils.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Run-time-stats-utils.c @@ -1,89 +1,89 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -/* - * Utility functions required to gather run time statistics. See: - * https://www.FreeRTOS.org/rtos-run-time-stats.html - * - * Note that this is a simulated port, where simulated time is a lot slower than - * real time, therefore the run time counter values have no real meaningful - * units. - * - * Also note that it is assumed this demo is going to be used for short periods - * of time only, and therefore timer overflows are not handled. -*/ - -/* FreeRTOS includes. */ -#include - -/* Variables used in the creation of the run time stats time base. Run time -stats record how much time each task spends in the Running state. */ -static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL; - -/*-----------------------------------------------------------*/ - -void vConfigureTimerForRunTimeStats( void ) -{ -LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue; - - /* Initialise the variables used to create the run time stats time base. - Run time stats record how much time each task spends in the Running - state. */ - - if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 ) - { - llTicksPerHundedthMillisecond = 1; - } - else - { - /* How many times does the performance counter increment in 1/100th - millisecond. */ - llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL; - - /* What is the performance counter value now, this will be subtracted - from readings taken at run time. */ - QueryPerformanceCounter( &liInitialRunTimeValue ); - llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart; - } -} -/*-----------------------------------------------------------*/ - -unsigned long ulGetRunTimeCounterValue( void ) -{ -LARGE_INTEGER liCurrentCount; -unsigned long ulReturn; - - /* What is the performance counter value now? */ - QueryPerformanceCounter( &liCurrentCount ); - - /* Subtract the performance counter value reading taken when the - application started to get a count from that reference point, then - scale to (simulated) 1/100ths of a millisecond. */ - ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundedthMillisecond ); - - return ulReturn; -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Utility functions required to gather run time statistics. See: + * https://www.FreeRTOS.org/rtos-run-time-stats.html + * + * Note that this is a simulated port, where simulated time is a lot slower than + * real time, therefore the run time counter values have no real meaningful + * units. + * + * Also note that it is assumed this demo is going to be used for short periods + * of time only, and therefore timer overflows are not handled. + */ + +/* FreeRTOS includes. */ +#include + +/* Variables used in the creation of the run time stats time base. Run time + * stats record how much time each task spends in the Running state. */ +static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundredthMillisecond = 0LL; + +/*-----------------------------------------------------------*/ + +void vConfigureTimerForRunTimeStats( void ) +{ + LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue; + + /* Initialise the variables used to create the run time stats time base. + * Run time stats record how much time each task spends in the Running + * state. */ + + if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 ) + { + llTicksPerHundredthMillisecond = 1; + } + else + { + /* How many times does the performance counter increment in 1/100th + * millisecond. */ + llTicksPerHundredthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL; + + /* What is the performance counter value now, this will be subtracted + * from readings taken at run time. */ + QueryPerformanceCounter( &liInitialRunTimeValue ); + llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart; + } +} +/*-----------------------------------------------------------*/ + +unsigned long ulGetRunTimeCounterValue( void ) +{ + LARGE_INTEGER liCurrentCount; + unsigned long ulReturn; + + /* What is the performance counter value now? */ + QueryPerformanceCounter( &liCurrentCount ); + + /* Subtract the performance counter value reading taken when the + * application started to get a count from that reference point, then + * scale to (simulated) 1/100ths of a millisecond. */ + ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundredthMillisecond ); + + return ulReturn; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Sample-CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Sample-CLI-commands.c index 76a742acf..1006350b4 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Sample-CLI-commands.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Sample-CLI-commands.c @@ -1,378 +1,399 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - - /****************************************************************************** - * - * See the following URL for information on the commands defined in this file: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml - * - ******************************************************************************/ - - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* Standard includes. */ -#include -#include -#include - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS - #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0 -#endif - - -/* - * Implements the run-time-stats command. - */ -static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the task-stats command. - */ -static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the echo-three-parameters command. - */ -static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the echo-parameters command. - */ -static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Implements the "trace start" and "trace stop" commands; - */ -#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); -#endif - -/* Structure that defines the "run-time-stats" command line command. This -generates a table that shows how much run time each task has */ -static const CLI_Command_Definition_t xRunTimeStats = -{ - "run-time-stats", /* The command string to type. */ - "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n", - prvRunTimeStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the "task-stats" command line command. This generates -a table that gives information on each task in the system. */ -static const CLI_Command_Definition_t xTaskStats = -{ - "task-stats", /* The command string to type. */ - "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n", - prvTaskStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ -}; - -/* Structure that defines the "echo_3_parameters" command line command. This -takes exactly three parameters that the command simply echos back one at a -time. */ -static const CLI_Command_Definition_t xThreeParameterEcho = -{ - "echo-3-parameters", - "\r\necho-3-parameters :\r\n Expects three parameters, echos each in turn\r\n", - prvThreeParameterEchoCommand, /* The function to run. */ - 3 /* Three parameters are expected, which can take any value. */ -}; - -/* Structure that defines the "echo_parameters" command line command. This -takes a variable number of parameters that the command simply echos back one at -a time. */ -static const CLI_Command_Definition_t xParameterEcho = -{ - "echo-parameters", - "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n", - prvParameterEchoCommand, /* The function to run. */ - -1 /* The user can enter any number of commands. */ -}; - -#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - /* Structure that defines the "trace" command line command. This takes a single - parameter, which can be either "start" or "stop". */ - static const CLI_Command_Definition_t xStartStopTrace = - { - "trace", - "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n", - prvStartStopTraceCommand, /* The function to run. */ - 1 /* One parameter is expected. Valid values are "start" and "stop". */ - }; -#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ - -/*-----------------------------------------------------------*/ - -void vRegisterSampleCLICommands( void ) -{ - /* Register all the command line commands defined immediately above. */ - FreeRTOS_CLIRegisterCommand( &xTaskStats ); - FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); - FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); - FreeRTOS_CLIRegisterCommand( &xParameterEcho ); - - #if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 ) - { - FreeRTOS_CLIRegisterCommand( & xStartStopTrace ); - } - #endif -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *const pcHeader = "Task State Priority Stack #\r\n************************************************\r\n"; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Generate a table of task stats. */ - strcpy( pcWriteBuffer, pcHeader ); - vTaskList( pcWriteBuffer + strlen( pcHeader ) ); - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char * const pcHeader = "Task Abs Time % Time\r\n****************************************\r\n"; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Generate a table of task stats. */ - strcpy( pcWriteBuffer, pcHeader ); - vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) ); - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength, xReturn; -static BaseType_t lParameterNumber = 0; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - if( lParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( pcWriteBuffer, "The three parameters were:\r\n" ); - - /* Next time the function is called the first parameter will be echoed - back. */ - lParameterNumber = 1L; - - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - lParameterNumber, /* Return the next parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); - strncat( pcWriteBuffer, pcParameter, xParameterStringLength ); - strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - if( lParameterNumber == 3L ) - { - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - xReturn = pdFALSE; - lParameterNumber = 0L; - } - else - { - /* There are more parameters to return after this one. */ - xReturn = pdTRUE; - lParameterNumber++; - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -const char *pcParameter; -BaseType_t xParameterStringLength, xReturn; -static BaseType_t lParameterNumber = 0; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - if( lParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( pcWriteBuffer, "The parameters were:\r\n" ); - - /* Next time the function is called the first parameter will be echoed - back. */ - lParameterNumber = 1L; - - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - lParameterNumber, /* Return the next parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); - - if( pcParameter != NULL ) - { - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); - strncat( pcWriteBuffer, pcParameter, xParameterStringLength ); - strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - - /* There might be more parameters to return after this one. */ - xReturn = pdTRUE; - lParameterNumber++; - } - else - { - /* No more parameters were found. Make sure the write buffer does - not contain a valid string. */ - pcWriteBuffer[ 0 ] = 0x00; - - /* No more data to return. */ - xReturn = pdFALSE; - - /* Start over the next time this command is executed. */ - lParameterNumber = 0; - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - - static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) - { - const char *pcParameter; - BaseType_t lParameterStringLength; - - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); - - /* Obtain the parameter string. */ - pcParameter = FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); - - /* Sanity check something was returned. */ - configASSERT( pcParameter ); - - /* There are only two valid parameter values. */ - if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 ) - { - /* Start or restart the trace. */ - vTraceStop(); - vTraceClear(); - vTraceStart(); - - sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" ); - } - else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 ) - { - /* End the trace, if one is running. */ - vTraceStop(); - sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" ); - } - else - { - sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); - } - - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; - } - -#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/****************************************************************************** +* +* See the following URL for information on the commands defined in this file: +* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml +* +******************************************************************************/ + + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS + #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0 +#endif + + +/* + * Implements the run-time-stats command. + */ +static BaseType_t prvTaskStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the task-stats command. + */ +static BaseType_t prvRunTimeStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the echo-three-parameters command. + */ +static BaseType_t prvThreeParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the echo-parameters command. + */ +static BaseType_t prvParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Implements the "trace start" and "trace stop" commands; + */ +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + static BaseType_t prvStartStopTraceCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); +#endif + +/* Structure that defines the "run-time-stats" command line command. This + * generates a table that shows how much run time each task has */ +static const CLI_Command_Definition_t xRunTimeStats = +{ + "run-time-stats", /* The command string to type. */ + "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n", + prvRunTimeStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the "task-stats" command line command. This generates + * a table that gives information on each task in the system. */ +static const CLI_Command_Definition_t xTaskStats = +{ + "task-stats", /* The command string to type. */ + "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n", + prvTaskStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the "echo_3_parameters" command line command. This + * takes exactly three parameters that the command simply echos back one at a + * time. */ +static const CLI_Command_Definition_t xThreeParameterEcho = +{ + "echo-3-parameters", + "\r\necho-3-parameters :\r\n Expects three parameters, echos each in turn\r\n", + prvThreeParameterEchoCommand, /* The function to run. */ + 3 /* Three parameters are expected, which can take any value. */ +}; + +/* Structure that defines the "echo_parameters" command line command. This + * takes a variable number of parameters that the command simply echos back one at + * a time. */ +static const CLI_Command_Definition_t xParameterEcho = +{ + "echo-parameters", + "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n", + prvParameterEchoCommand, /* The function to run. */ + -1 /* The user can enter any number of commands. */ +}; + +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + +/* Structure that defines the "trace" command line command. This takes a single + * parameter, which can be either "start" or "stop". */ + static const CLI_Command_Definition_t xStartStopTrace = + { + "trace", + "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n", + prvStartStopTraceCommand, /* The function to run. */ + 1 /* One parameter is expected. Valid values are "start" and "stop". */ + }; +#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ + +/*-----------------------------------------------------------*/ + +void vRegisterSampleCLICommands( void ) +{ + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xTaskStats ); + FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); + FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); + FreeRTOS_CLIRegisterCommand( &xParameterEcho ); + + #if ( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 ) + { + FreeRTOS_CLIRegisterCommand( &xStartStopTrace ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTaskStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * const pcHeader = "Task State Priority Stack #\r\n************************************************\r\n"; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( pcWriteBuffer, pcHeader ); + vTaskList( pcWriteBuffer + strlen( pcHeader ) ); + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvRunTimeStatsCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * const pcHeader = "Task Abs Time % Time\r\n****************************************\r\n"; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( pcWriteBuffer, pcHeader ); + vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) ); + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvThreeParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength, xReturn; + static BaseType_t lParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( pcWriteBuffer, "The three parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + * back. */ + lParameterNumber = 1L; + + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); + strncat( pcWriteBuffer, pcParameter, xParameterStringLength ); + strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + if( lParameterNumber == 3L ) + { + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + xReturn = pdFALSE; + lParameterNumber = 0L; + } + else + { + /* There are more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvParameterEchoCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + const char * pcParameter; + BaseType_t xParameterStringLength, xReturn; + static BaseType_t lParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( pcWriteBuffer, "The parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + * back. */ + lParameterNumber = 1L; + + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + if( pcParameter != NULL ) + { + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); + strncat( pcWriteBuffer, pcParameter, xParameterStringLength ); + strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* There might be more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + else + { + /* No more parameters were found. Make sure the write buffer does + * not contain a valid string. */ + pcWriteBuffer[ 0 ] = 0x00; + + /* No more data to return. */ + xReturn = pdFALSE; + + /* Start over the next time this command is executed. */ + lParameterNumber = 0; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + + static BaseType_t prvStartStopTraceCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) + { + const char * pcParameter; + BaseType_t lParameterStringLength; + + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Obtain the parameter string. */ + pcParameter = FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* There are only two valid parameter values. */ + if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 ) + { + /* Start or restart the trace. */ + vTraceStop(); + vTraceClear(); + vTraceStart(); + + sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" ); + } + else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 ) + { + /* End the trace, if one is running. */ + vTraceStop(); + sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" ); + } + else + { + sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); + } + + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; + } + +#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/UDPCommandServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/UDPCommandServer.c index f7a858845..54c852545 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/UDPCommandServer.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/UDPCommandServer.c @@ -1,228 +1,227 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - - -#pragma comment( lib, "ws2_32.lib" ) - -/* Win32 includes. */ -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* Standard includes. */ -#include -#include - -/* FreeRTOS+CLI includes. */ -#include "FreeRTOS_CLI.h" - -/* Dimensions the buffer into which input characters are placed. */ -#define cmdMAX_INPUT_SIZE 60 - -/* Dimensions the buffer into which string outputs can be placed. */ -#define cmdMAX_OUTPUT_SIZE 1024 - -/* Dimensions the buffer passed to the recvfrom() call. */ -#define cmdSOCKET_INPUT_BUFFER_SIZE 60 - -/* DEL acts as a backspace. */ -#define cmdASCII_DEL ( 0x7F ) - -/* - * Open and configure the UDP socket. - */ -static SOCKET prvOpenUDPSocket( void ); - -/*-----------------------------------------------------------*/ - -/* - * Task that provides the input and output for the FreeRTOS+CLI command - * interpreter. In this case a WinSock UDP port is used for convenience as this - * demo runs in a simulated environment on a Windows PC. See the URL in the - * comments within main.c for the location of the online documentation. - */ -void vUDPCommandInterpreterTask( void *pvParameters ) -{ -long lBytes, lByte; -signed char cInChar, cInputIndex = 0; -static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ]; -BaseType_t xMoreDataToFollow; -volatile int iErrorCode = 0; -struct sockaddr_in xClient; -int xClientAddressLength = sizeof( struct sockaddr_in ); -SOCKET xSocket; - - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; - - /* Attempt to open the socket. */ - xSocket = prvOpenUDPSocket(); - - if( xSocket != INVALID_SOCKET ) - { - for( ;; ) - { - /* Wait for incoming data on the opened socket. */ - lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength ); - - if( lBytes == SOCKET_ERROR ) - { - /* Something went wrong, but it is not handled by this simple - example. */ - iErrorCode = WSAGetLastError(); - } - else - { - /* Process each received byte in turn. */ - lByte = 0; - while( lByte < lBytes ) - { - /* The next character in the input buffer. */ - cInChar = cLocalBuffer[ lByte ]; - lByte++; - - /* Newline characters are taken as the end of the command - string. */ - if( cInChar == '\n' ) - { - /* Process the input string received prior to the - newline. */ - do - { - /* Pass the string to FreeRTOS+CLI. */ - xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE ); - - /* Send the output generated by the command's - implementation. */ - sendto( xSocket, cOutputString, strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); - - } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */ - - /* All the strings generated by the command processing - have been sent. Clear the input string ready to receive - the next command. */ - cInputIndex = 0; - memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); - - /* Transmit a spacer, just to make the command console - easier to read. */ - sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); - } - else - { - if( cInChar == '\r' ) - { - /* Ignore the character. Newlines are used to - detect the end of the input string. */ - } - else if( ( cInChar == '\b' ) || ( cInChar == cmdASCII_DEL ) ) - { - /* Backspace was pressed. Erase the last character - in the string - if any. */ - if( cInputIndex > 0 ) - { - cInputIndex--; - cInputString[ cInputIndex ] = '\0'; - } - } - else - { - /* A character was entered. Add it to the string - entered so far. When a \n is entered the complete - string will be passed to the command interpreter. */ - if( cInputIndex < cmdMAX_INPUT_SIZE ) - { - cInputString[ cInputIndex ] = cInChar; - cInputIndex++; - } - } - } - } - } - } - } - else - { - /* The socket could not be opened. */ - vTaskDelete( NULL ); - } -} -/*-----------------------------------------------------------*/ - -static SOCKET prvOpenUDPSocket( void ) -{ -WSADATA xWSAData; -WORD wVersionRequested; -struct sockaddr_in xServer; -SOCKET xSocket = INVALID_SOCKET; - - wVersionRequested = MAKEWORD( 2, 2 ); - - /* Prepare to use WinSock. */ - if( WSAStartup( wVersionRequested, &xWSAData ) != 0 ) - { - fprintf( stderr, "Could not open Windows connection.\n" ); - } - else - { - xSocket = socket( AF_INET, SOCK_DGRAM, 0 ); - if( xSocket == INVALID_SOCKET) - { - fprintf( stderr, "Could not create socket.\n" ); - WSACleanup(); - } - else - { - /* Zero out the server structure. */ - memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) ); - - /* Set family and port. */ - xServer.sin_family = AF_INET; - xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER ); - - /* Assign the loopback address */ - xServer.sin_addr.S_un.S_un_b.s_b1 = 127; - xServer.sin_addr.S_un.S_un_b.s_b2 = 0; - xServer.sin_addr.S_un.S_un_b.s_b3 = 0; - xServer.sin_addr.S_un.S_un_b.s_b4 = 1; - - /* Bind the address to the socket. */ - if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 ) - { - fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER ); - closesocket( xSocket ); - xSocket = INVALID_SOCKET; - WSACleanup(); - } - } - } - - return xSocket; -} - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +#pragma comment( lib, "ws2_32.lib" ) + +/* Win32 includes. */ +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* Dimensions the buffer into which input characters are placed. */ +#define cmdMAX_INPUT_SIZE 60 + +/* Dimensions the buffer into which string outputs can be placed. */ +#define cmdMAX_OUTPUT_SIZE 1024 + +/* Dimensions the buffer passed to the recvfrom() call. */ +#define cmdSOCKET_INPUT_BUFFER_SIZE 60 + +/* DEL acts as a backspace. */ +#define cmdASCII_DEL ( 0x7F ) + +/* + * Open and configure the UDP socket. + */ +static SOCKET prvOpenUDPSocket( void ); + +/*-----------------------------------------------------------*/ + +/* + * Task that provides the input and output for the FreeRTOS+CLI command + * interpreter. In this case a WinSock UDP port is used for convenience as this + * demo runs in a simulated environment on a Windows PC. See the URL in the + * comments within main.c for the location of the online documentation. + */ +void vUDPCommandInterpreterTask( void * pvParameters ) +{ + long lBytes, lByte; + signed char cInChar, cInputIndex = 0; + static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ]; + BaseType_t xMoreDataToFollow; + volatile int iErrorCode = 0; + struct sockaddr_in xClient; + int xClientAddressLength = sizeof( struct sockaddr_in ); + SOCKET xSocket; + + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; + + /* Attempt to open the socket. */ + xSocket = prvOpenUDPSocket(); + + if( xSocket != INVALID_SOCKET ) + { + for( ; ; ) + { + /* Wait for incoming data on the opened socket. */ + lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength ); + + if( lBytes == SOCKET_ERROR ) + { + /* Something went wrong, but it is not handled by this simple + * example. */ + iErrorCode = WSAGetLastError(); + } + else + { + /* Process each received byte in turn. */ + lByte = 0; + + while( lByte < lBytes ) + { + /* The next character in the input buffer. */ + cInChar = cLocalBuffer[ lByte ]; + lByte++; + + /* Newline characters are taken as the end of the command + * string. */ + if( cInChar == '\n' ) + { + /* Process the input string received prior to the + * newline. */ + do + { + /* Pass the string to FreeRTOS+CLI. */ + xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE ); + + /* Send the output generated by the command's + * implementation. */ + sendto( xSocket, cOutputString, strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); + } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */ + + /* All the strings generated by the command processing + * have been sent. Clear the input string ready to receive + * the next command. */ + cInputIndex = 0; + memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); + + /* Transmit a spacer, just to make the command console + * easier to read. */ + sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); + } + else + { + if( cInChar == '\r' ) + { + /* Ignore the character. Newlines are used to + * detect the end of the input string. */ + } + else if( ( cInChar == '\b' ) || ( cInChar == cmdASCII_DEL ) ) + { + /* Backspace was pressed. Erase the last character + * in the string - if any. */ + if( cInputIndex > 0 ) + { + cInputIndex--; + cInputString[ cInputIndex ] = '\0'; + } + } + else + { + /* A character was entered. Add it to the string + * entered so far. When a \n is entered the complete + * string will be passed to the command interpreter. */ + if( cInputIndex < cmdMAX_INPUT_SIZE ) + { + cInputString[ cInputIndex ] = cInChar; + cInputIndex++; + } + } + } + } + } + } + } + else + { + /* The socket could not be opened. */ + vTaskDelete( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static SOCKET prvOpenUDPSocket( void ) +{ + WSADATA xWSAData; + WORD wVersionRequested; + struct sockaddr_in xServer; + SOCKET xSocket = INVALID_SOCKET; + + wVersionRequested = MAKEWORD( 2, 2 ); + + /* Prepare to use WinSock. */ + if( WSAStartup( wVersionRequested, &xWSAData ) != 0 ) + { + fprintf( stderr, "Could not open Windows connection.\n" ); + } + else + { + xSocket = socket( AF_INET, SOCK_DGRAM, 0 ); + + if( xSocket == INVALID_SOCKET ) + { + fprintf( stderr, "Could not create socket.\n" ); + WSACleanup(); + } + else + { + /* Zero out the server structure. */ + memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) ); + + /* Set family and port. */ + xServer.sin_family = AF_INET; + xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER ); + + /* Assign the loopback address */ + xServer.sin_addr.S_un.S_un_b.s_b1 = 127; + xServer.sin_addr.S_un.S_un_b.s_b2 = 0; + xServer.sin_addr.S_un.S_un_b.s_b3 = 0; + xServer.sin_addr.S_un.S_un_b.s_b4 = 1; + + /* Bind the address to the socket. */ + if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 ) + { + fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER ); + closesocket( xSocket ); + xSocket = INVALID_SOCKET; + WSACleanup(); + } + } + } + + return xSocket; +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/main.c index fd8f1ec5d..551b3d69a 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/main.c @@ -1,146 +1,146 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/****************************************************************************** - * - * This demo is described on the following web page: - * TODO: This link describes the FAT version of this demo. - * https://www.FreeRTOS.org/FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml - * - ******************************************************************************/ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include -#include "task.h" -#include "queue.h" -#include "semphr.h" - -/* Priorities at which the tasks are created. */ -#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY ) - -/*-----------------------------------------------------------*/ - -/* - * Register the generic commands that can be used with FreeRTOS+CLI. - */ -extern void vRegisterSampleCLICommands( void ); - -/* - * Register the file system commands that can be used with FreeRTOS+CLI. - */ -extern void vRegisterFileSystemCLICommands( void ); - -/* - * The task that implements the UDP command interpreter using FreeRTOS+CLI. - */ -extern void vUDPCommandInterpreterTask( void *pvParameters ); - -/* - * Creates and verifies different files on the volume, demonstrating the use of - * various different API functions. - */ -extern void vCreateAndVerifySampleFiles( void ); - -/*-----------------------------------------------------------*/ - -/* See http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml -for instructions. */ - -int main( void ) -{ -const uint32_t ulLongTime_ms = 250UL; - - /* Initialise the drive and file system, then create a few example - files. The output from this function just goes to the stdout window, - allowing the output to be viewed when the UDP command console is not - connected. */ - vCreateAndVerifySampleFiles(); - - /* Register generic commands with the FreeRTOS+CLI command interpreter. */ - vRegisterSampleCLICommands(); - - /* Register file system related commands with the FreeRTOS+CLI command - interpreter. */ - vRegisterFileSystemCLICommands(); - - /* Create the task that handles the CLI on a UDP port. The port number - is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */ - xTaskCreate( vUDPCommandInterpreterTask, /* The function that implements the command interpreter IO handling. */ - "CLI", /* The name of the task - just to assist debugging. */ - configMINIMAL_STACK_SIZE, NULL, /* The size of the stack allocated to the task. */ - mainUDP_CLI_TASK_PRIORITY, /* The priority at which the task will run. */ - NULL ); /* A handle to the task is not required, so NULL is passed. */ - - /* Start the RTOS scheduler. */ - vTaskStartScheduler(); - - /* If all is well, the scheduler will now be running, and the following - line will never be reached. If the following line does execute, then - there was insufficient FreeRTOS heap memory available for the idle and/or - timer tasks to be created. See the memory management section on the - FreeRTOS web site for more details (this is standard text that is not - really applicable to the Win32 simulator port). */ - for( ;; ) - { - Sleep( ulLongTime_ms ); - } -} -/*-----------------------------------------------------------*/ - -void vApplicationIdleHook( void ) -{ -const unsigned long ulMSToSleep = 5; - - /* This function is called on each cycle of the idle task if - configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU - load. */ - Sleep( ulMSToSleep ); -} -/*-----------------------------------------------------------*/ - -void vApplicationMallocFailedHook( void ) -{ - /* vApplicationMallocFailedHook() will only be called if - configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook - function that will get called if a call to pvPortMalloc() fails. - pvPortMalloc() is called internally by the kernel whenever a task, queue, - timer or semaphore is created. It is also called by various parts of the - demo application. If heap_1.c, heap_2.c or heap_4.c are used, then the - size of the heap available to pvPortMalloc() is defined by - configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize() - API function can be used to query the size of free heap space that remains - (although it does not provide information on how the remaining heap might - be fragmented). */ - taskDISABLE_INTERRUPTS(); - for( ;; ); -} - - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/****************************************************************************** +* +* This demo is described on the following web page: +* TODO: This link describes the FAT version of this demo. +* https://www.FreeRTOS.org/FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml +* +******************************************************************************/ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Priorities at which the tasks are created. */ +#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY ) + +/*-----------------------------------------------------------*/ + +/* + * Register the generic commands that can be used with FreeRTOS+CLI. + */ +extern void vRegisterSampleCLICommands( void ); + +/* + * Register the file system commands that can be used with FreeRTOS+CLI. + */ +extern void vRegisterFileSystemCLICommands( void ); + +/* + * The task that implements the UDP command interpreter using FreeRTOS+CLI. + */ +extern void vUDPCommandInterpreterTask( void * pvParameters ); + +/* + * Creates and verifies different files on the volume, demonstrating the use of + * various different API functions. + */ +extern void vCreateAndVerifySampleFiles( void ); + +/*-----------------------------------------------------------*/ + +/* See http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml + * for instructions. */ + +int main( void ) +{ + const uint32_t ulLongTime_ms = 250UL; + + /* Initialise the drive and file system, then create a few example + * files. The output from this function just goes to the stdout window, + * allowing the output to be viewed when the UDP command console is not + * connected. */ + vCreateAndVerifySampleFiles(); + + /* Register generic commands with the FreeRTOS+CLI command interpreter. */ + vRegisterSampleCLICommands(); + + /* Register file system related commands with the FreeRTOS+CLI command + * interpreter. */ + vRegisterFileSystemCLICommands(); + + /* Create the task that handles the CLI on a UDP port. The port number + * is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */ + xTaskCreate( vUDPCommandInterpreterTask, /* The function that implements the command interpreter IO handling. */ + "CLI", /* The name of the task - just to assist debugging. */ + configMINIMAL_STACK_SIZE, NULL, /* The size of the stack allocated to the task. */ + mainUDP_CLI_TASK_PRIORITY, /* The priority at which the task will run. */ + NULL ); /* A handle to the task is not required, so NULL is passed. */ + + /* Start the RTOS scheduler. */ + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + * line will never be reached. If the following line does execute, then + * there was insufficient FreeRTOS heap memory available for the idle and/or + * timer tasks to be created. See the memory management section on the + * FreeRTOS web site for more details (this is standard text that is not + * really applicable to the Win32 simulator port). */ + for( ; ; ) + { + Sleep( ulLongTime_ms ); + } +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + const unsigned long ulMSToSleep = 5; + + /* This function is called on each cycle of the idle task if + * configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU + * load. */ + Sleep( ulMSToSleep ); +} +/*-----------------------------------------------------------*/ + +void vApplicationMallocFailedHook( void ) +{ + /* vApplicationMallocFailedHook() will only be called if + * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook + * function that will get called if a call to pvPortMalloc() fails. + * pvPortMalloc() is called internally by the kernel whenever a task, queue, + * timer or semaphore is created. It is also called by various parts of the + * demo application. If heap_1.c, heap_2.c or heap_4.c are used, then the + * size of the heap available to pvPortMalloc() is defined by + * configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize() + * API function can be used to query the size of free heap space that remains + * (although it does not provide information on how the remaining heap might + * be fragmented). */ + taskDISABLE_INTERRUPTS(); + + for( ; ; ) + { + } +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOS-simulator-for-Linux.url b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOS-simulator-for-Linux.url index 60f7ee8c3..84cc36d60 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOS-simulator-for-Linux.url +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOS-simulator-for-Linux.url @@ -1,5 +1,5 @@ -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,11 -[InternetShortcut] -IDList= -URL=https://www.freertos.org/FreeRTOS-simulator-for-Linux.html +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 +[InternetShortcut] +IDList= +URL=https://www.freertos.org/FreeRTOS-simulator-for-Linux.html diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOSConfig.h index f79849dde..7ec703eb8 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOSConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -130,30 +130,30 @@ extern void vAssertCalled( const char * const pcFileName, #if ( projCOVERAGE_TEST == 1 ) - /* Insert NOPs in empty decision paths to ensure both true and false paths - * are being tested. */ +/* Insert NOPs in empty decision paths to ensure both true and false paths + * are being tested. */ #define mtCOVERAGE_TEST_MARKER() __asm volatile ( "NOP" ) - /* Ensure the tick count overflows during the coverage test. */ +/* Ensure the tick count overflows during the coverage test. */ #define configINITIAL_TICK_COUNT 0xffffd800UL - /* Allows tests of trying to allocate more than the heap has free. */ +/* Allows tests of trying to allocate more than the heap has free. */ #define configUSE_MALLOC_FAILED_HOOK 0 - /* To test builds that remove the static qualifier for debug builds. */ +/* To test builds that remove the static qualifier for debug builds. */ #define portREMOVE_STATIC_QUALIFIER #else /* if ( projCOVERAGE_TEST == 1 ) */ - /* It is a good idea to define configASSERT() while developing. configASSERT() - * uses the same semantics as the standard C assert() macro. Don't define - * configASSERT() when performing code coverage tests though, as it is not - * intended to asserts() to fail, some some code is intended not to run if no - * errors are present. */ +/* It is a good idea to define configASSERT() while developing. configASSERT() + * uses the same semantics as the standard C assert() macro. Don't define + * configASSERT() when performing code coverage tests though, as it is not + * intended to asserts() to fail, some some code is intended not to run if no + * errors are present. */ #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ) #define configUSE_MALLOC_FAILED_HOOK 0 - /* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */ +/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */ #include "trcRecorder.h" #endif /* if ( projCOVERAGE_TEST == 1 ) */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOSIPConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOSIPConfig.h index 378ac2369..070ee6cc1 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOSIPConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/FreeRTOSIPConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Makefile b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Makefile index 5f1614738..4622f31ef 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Makefile +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Makefile @@ -57,7 +57,7 @@ SOURCE_FILES += ${FREERTOS_PLUS_TCP_DIR}/portable/BufferManagement/BufferAllocat SOURCE_FILES += ${FREERTOS_PLUS_TCP_DIR}/portable/NetworkInterface/libslirp/MBuffNetifBackendLibslirp.c SOURCE_FILES += ${FREERTOS_PLUS_TCP_DIR}/portable/NetworkInterface/libslirp/MBuffNetworkInterface.c -CFLAGS := -ggdb3 +CFLAGS := -ggdb3 LDFLAGS := -ggdb3 -pthread # Get libslirp package configuration (header and library paths) diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/SimpleTCPEchoServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/SimpleTCPEchoServer.c index 40842ab4a..8eb563100 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/SimpleTCPEchoServer.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/SimpleTCPEchoServer.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -183,9 +183,9 @@ /* Set the window and buffer sizes. */ #if ( ipconfigUSE_TCP_WIN == 1 ) - { - FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); - } + { + FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); + } #endif /* ipconfigUSE_TCP_WIN */ /* Bind the socket to the port that the client task will send to, then @@ -196,7 +196,7 @@ FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); FreeRTOS_listen( xListeningSocket, xBacklog ); - for( ;; ) + for( ; ; ) { /* Wait for a client to connect. */ xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize ); @@ -235,7 +235,7 @@ FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xReceiveTimeOut ) ); - for( ;; ) + for( ; ; ) { /* Zero out the receive array so there is NULL at the end of the string * when it is printed out. */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/TCPEchoClient_SingleTasks.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/TCPEchoClient_SingleTasks.c index c52ad4a4d..6c11240f7 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/TCPEchoClient_SingleTasks.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/TCPEchoClient_SingleTasks.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -159,9 +159,9 @@ #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) { xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); } #else { @@ -416,5 +416,5 @@ return eDHCPContinue; } -#endif +#endif /* if ( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_DHCP_HOOK != 0 ) ) */ /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/TCPEchoClient_SingleTasks.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/TCPEchoClient_SingleTasks.h index a3a22021f..ca12b0a7b 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/TCPEchoClient_SingleTasks.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/TCPEchoClient_SingleTasks.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -31,9 +31,8 @@ * Create the TCP echo client tasks. This is the version where an echo request * is made from the same task that listens for the echo reply. */ -void vStartTCPEchoClientTasks_SingleTasks( size_t uxTaskStackSize, UBaseType_t uxTaskPriority ); +void vStartTCPEchoClientTasks_SingleTasks( size_t uxTaskStackSize, + UBaseType_t uxTaskPriority ); BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ); #endif /* SINGLE_TASK_TCP_ECHO_CLIENTS_H */ - - diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcConfig.h index e2a24acef..a3c730211 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcConfig.h @@ -1,320 +1,320 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Main configuration parameters for the trace recorder library. - * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h. - */ - -#ifndef TRC_CONFIG_H -#define TRC_CONFIG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/****************************************************************************** - * Include of processor header file - * - * Here you may need to include the header file for your processor. This is - * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API. - * Try that in case of build problems. Otherwise, remove the #error line below. - *****************************************************************************/ -/*#error "Trace Recorder: Please include your processor's header file here and remove this line." */ - -/** - * @def TRC_CFG_HARDWARE_PORT - * @brief Specify what hardware port to use (i.e., the "timestamping driver"). - * - * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M". - * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is - * available on most such devices. In case your device don't have DWT support, - * you will get an error message opening the trace. In that case, you may - * force the recorder to use SysTick timestamping instead, using this define: - * - * #define TRC_CFG_ARM_CM_USE_SYSTICK - * - * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically. - * - * See trcHardwarePort.h for available ports and information on how to - * define your own port, if not already present. - */ -#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_Win64 - -/** - * @def TRC_CFG_SCHEDULING_ONLY - * @brief Macro which should be defined as an integer value. - * - * If this setting is enabled (= 1), only scheduling events are recorded. - * If disabled (= 0), all events are recorded (unless filtered in other ways). - * - * Default value is 0 (= include additional events). - */ -#define TRC_CFG_SCHEDULING_ONLY 0 - -/** - * @def TRC_CFG_INCLUDE_MEMMANG_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * This controls if malloc and free calls should be traced. Set this to zero (0) - * to exclude malloc/free calls, or one (1) to include such events in the trace. - * - * Default value is 1. - */ -#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1 - -/** - * @def TRC_CFG_INCLUDE_USER_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), all code related to User Events is excluded in order - * to reduce code size. Any attempts of storing User Events are then silently - * ignored. - * - * User Events are application-generated events, like "printf" but for the - * trace log, generated using vTracePrint and vTracePrintF. - * The formatting is done on host-side, by Tracealyzer. User Events are - * therefore much faster than a console printf and can often be used - * in timing critical code without problems. - * - * Note: In streaming mode, User Events are used to provide error messages - * and warnings from the recorder (in case of incorrect configuration) for - * display in Tracealyzer. Disabling user events will also disable these - * warnings. You can however still catch them by calling xTraceErrorGetLast - * or by putting breakpoints in xTraceError and xTraceWarning. - * - * Default value is 1. - */ -#define TRC_CFG_INCLUDE_USER_EVENTS 1 - -/** - * @def TRC_CFG_INCLUDE_ISR_TRACING - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the code for recording Interrupt Service Routines is - * excluded, in order to reduce code size. This means that any calls to - * vTraceStoreISRBegin/vTraceStoreISREnd will be ignored. - * This does not completely disable ISR tracing, in cases where an ISR is - * calling a traced kernel service. These events will still be recorded and - * show up in anonymous ISR instances in Tracealyzer, with names such as - * "ISR sending to ". - * To disable such tracing, please refer to vTraceSetFilterGroup and - * vTraceSetFilterMask. - * - * Default value is 1. - * - * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin - * and vTraceStoreISREnd in your interrupt handlers. - */ -#define TRC_CFG_INCLUDE_ISR_TRACING 1 - -/** - * @def TRC_CFG_INCLUDE_READY_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If one (1), events are recorded when tasks enter scheduling state "ready". - * This allows Tracealyzer to show the initial pending time before tasks enter - * the execution state, and present accurate response times. - * If zero (0), "ready events" are not created, which allows for recording - * longer traces in the same amount of RAM. - * - * Default value is 1. - */ -#define TRC_CFG_INCLUDE_READY_EVENTS 1 - -/** - * @def TRC_CFG_INCLUDE_OSTICK_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is one (1), events will be generated whenever the OS clock is - * increased. If zero (0), OS tick events are not generated, which allows for - * recording longer traces in the same amount of RAM. - * - * Default value is 1. - */ -#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1 - -/** - * @def TRC_CFG_ENABLE_STACK_MONITOR - * @brief If enabled (1), the recorder periodically reports the unused stack space of - * all active tasks. - * The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task - * is always created by the recorder when in streaming mode. - * In snapshot mode, the TzCtrl task is only used for stack monitoring and is - * not created unless this is enabled. - */ -#define TRC_CFG_ENABLE_STACK_MONITOR 1 - -/** - * @def TRC_CFG_STACK_MONITOR_MAX_TASKS - * @brief Macro which should be defined as a non-zero integer value. - * - * This controls how many tasks that can be monitored by the stack monitor. - * If this is too small, some tasks will be excluded and a warning is shown. - * - * Default value is 10. - */ -#define TRC_CFG_STACK_MONITOR_MAX_TASKS 10 - -/** - * @def TRC_CFG_STACK_MONITOR_MAX_REPORTS - * @brief Macro which should be defined as a non-zero integer value. - * - * This defines how many tasks that will be subject to stack usage analysis for - * each execution of the Tracealyzer Control task (TzCtrl). Note that the stack - * monitoring cycles between the tasks, so this does not affect WHICH tasks that - * are monitored, but HOW OFTEN each task stack is analyzed. - * - * This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the - * frequency of the stack monitoring. This is motivated since the stack analysis - * can take some time to execute. - * However, note that the stack analysis runs in a separate task (TzCtrl) that - * can be executed on low priority. This way, you can avoid that the stack - * analysis disturbs any time-sensitive tasks. - * - * Default value is 1. - */ -#define TRC_CFG_STACK_MONITOR_MAX_REPORTS 1 - -/** - * @def TRC_CFG_CTRL_TASK_PRIORITY - * @brief The scheduling priority of the Tracealyzer Control (TzCtrl) task. - * - * In streaming mode, TzCtrl is used to receive start/stop commands from - * Tracealyzer and in some cases also to transmit the trace data (for stream - * ports that uses the internal buffer, like TCP/IP). For such stream ports, - * make sure the TzCtrl priority is high enough to ensure reliable periodic - * execution and transfer of the data, but low enough to avoid disturbing any - * time-sensitive functions. - * - * In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is - * not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should - * be low, to avoid disturbing any time-sensitive tasks. - */ -#define TRC_CFG_CTRL_TASK_PRIORITY 1 - -/** - * @def TRC_CFG_CTRL_TASK_DELAY - * @brief The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY), - * which affects the frequency of the stack monitoring. - * - * In streaming mode, this also affects the trace data transfer if you are using - * a stream port leveraging the internal buffer (like TCP/IP). A shorter delay - * increases the CPU load of TzCtrl somewhat, but may improve the performance of - * of the trace streaming, especially if the trace buffer is small. - */ -#define TRC_CFG_CTRL_TASK_DELAY 2 - -/** - * @def TRC_CFG_CTRL_TASK_STACK_SIZE - * @brief The stack size of the Tracealyzer Control (TzCtrl) task. - * See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl. - */ -#define TRC_CFG_CTRL_TASK_STACK_SIZE 4096 - -/** - * @def TRC_CFG_RECORDER_BUFFER_ALLOCATION - * @brief Specifies how the recorder buffer is allocated (also in case of streaming, in - * port using the recorder's internal temporary buffer) - * - * Values: - * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal) - * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable - * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer - * - * Static and dynamic mode does the allocation for you, either in compile time - * (static) or in runtime (malloc). - * The custom mode allows you to control how and where the allocation is made, - * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer(). - */ -#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC - -/** - * @def TRC_CFG_MAX_ISR_NESTING - * @brief Defines how many levels of interrupt nesting the recorder can handle, in - * case multiple ISRs are traced and ISR nesting is possible. If this - * is exceeded, the particular ISR will not be traced and the recorder then - * logs an error message. This setting is used to allocate an internal stack - * for keeping track of the previous execution context (4 byte per entry). - * - * This value must be a non-zero positive constant, at least 1. - * - * Default value: 8 - */ -#define TRC_CFG_MAX_ISR_NESTING 8 - -/** - * @def TRC_CFG_ISR_TAILCHAINING_THRESHOLD - * @brief Macro which should be defined as an integer value. - * - * If tracing multiple ISRs, this setting allows for accurate display of the - * context-switching also in cases when the ISRs execute in direct sequence. - * - * vTraceStoreISREnd normally assumes that the ISR returns to the previous - * context, i.e., a task or a preempted ISR. But if another traced ISR - * executes in direct sequence, Tracealyzer may incorrectly display a minimal - * fragment of the previous context in between the ISRs. - * - * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is - * however a threshold value that must be measured for your specific setup. - * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ - * - * The default setting is 0, meaning "disabled" and that you may get an - * extra fragments of the previous context in between tail-chained ISRs. - * - * Note: This setting has separate definitions in trcSnapshotConfig.h and - * trcStreamingConfig.h, since it is affected by the recorder mode. - */ -#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 - -/** - * @def TRC_CFG_RECORDER_DATA_INIT - * @brief Macro which states wether the recorder data should have an initial value. - * - * In very specific cases where traced objects are created before main(), - * the recorder will need to be started even before that. In these cases, - * the recorder data would be initialized by vTraceEnable(TRC_INIT) but could - * then later be overwritten by the initialization value. - * If this is an issue for you, set TRC_CFG_RECORDER_DATA_INIT to 0. - * The following code can then be used before any traced objects are created: - * - * extern uint32_t RecorderEnabled; - * RecorderEnabled = 0; - * xTraceInitialize(); - * - * After the clocks are properly initialized, use vTraceEnable(...) to start - * the tracing. - * - * Default value is 1. - */ -#define TRC_CFG_RECORDER_DATA_INIT 1 - -/** - * @def TRC_CFG_RECORDER_DATA_ATTRIBUTE - * @brief When setting TRC_CFG_RECORDER_DATA_INIT to 0, you might also need to make - * sure certain recorder data is placed in a specific RAM section to avoid being - * zeroed out after initialization. Define TRC_CFG_RECORDER_DATA_ATTRIBUTE as - * that attribute. - * - * Example: - * #define TRC_CFG_RECORDER_DATA_ATTRIBUTE __attribute__((section(".bss.trace_recorder_data"))) - * - * Default value is empty. - */ -#define TRC_CFG_RECORDER_DATA_ATTRIBUTE - -/** - * @def TRC_CFG_USE_TRACE_ASSERT - * @brief Enable or disable debug asserts. Information regarding any assert that is - * triggered will be in trcAssert.c. - */ -#define TRC_CFG_USE_TRACE_ASSERT 1 - -#ifdef __cplusplus -} -#endif - -#endif /* _TRC_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Main configuration parameters for the trace recorder library. + * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h. + */ + +#ifndef TRC_CONFIG_H + #define TRC_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/****************************************************************************** + * Include of processor header file + * + * Here you may need to include the header file for your processor. This is + * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API. + * Try that in case of build problems. Otherwise, remove the #error line below. + *****************************************************************************/ +/*#error "Trace Recorder: Please include your processor's header file here and remove this line." */ + +/** + * @def TRC_CFG_HARDWARE_PORT + * @brief Specify what hardware port to use (i.e., the "timestamping driver"). + * + * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M". + * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is + * available on most such devices. In case your device don't have DWT support, + * you will get an error message opening the trace. In that case, you may + * force the recorder to use SysTick timestamping instead, using this define: + * + * #define TRC_CFG_ARM_CM_USE_SYSTICK + * + * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically. + * + * See trcHardwarePort.h for available ports and information on how to + * define your own port, if not already present. + */ + #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_Win64 + +/** + * @def TRC_CFG_SCHEDULING_ONLY + * @brief Macro which should be defined as an integer value. + * + * If this setting is enabled (= 1), only scheduling events are recorded. + * If disabled (= 0), all events are recorded (unless filtered in other ways). + * + * Default value is 0 (= include additional events). + */ + #define TRC_CFG_SCHEDULING_ONLY 0 + +/** + * @def TRC_CFG_INCLUDE_MEMMANG_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * This controls if malloc and free calls should be traced. Set this to zero (0) + * to exclude malloc/free calls, or one (1) to include such events in the trace. + * + * Default value is 1. + */ + #define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1 + +/** + * @def TRC_CFG_INCLUDE_USER_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), all code related to User Events is excluded in order + * to reduce code size. Any attempts of storing User Events are then silently + * ignored. + * + * User Events are application-generated events, like "printf" but for the + * trace log, generated using vTracePrint and vTracePrintF. + * The formatting is done on host-side, by Tracealyzer. User Events are + * therefore much faster than a console printf and can often be used + * in timing critical code without problems. + * + * Note: In streaming mode, User Events are used to provide error messages + * and warnings from the recorder (in case of incorrect configuration) for + * display in Tracealyzer. Disabling user events will also disable these + * warnings. You can however still catch them by calling xTraceErrorGetLast + * or by putting breakpoints in xTraceError and xTraceWarning. + * + * Default value is 1. + */ + #define TRC_CFG_INCLUDE_USER_EVENTS 1 + +/** + * @def TRC_CFG_INCLUDE_ISR_TRACING + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the code for recording Interrupt Service Routines is + * excluded, in order to reduce code size. This means that any calls to + * vTraceStoreISRBegin/vTraceStoreISREnd will be ignored. + * This does not completely disable ISR tracing, in cases where an ISR is + * calling a traced kernel service. These events will still be recorded and + * show up in anonymous ISR instances in Tracealyzer, with names such as + * "ISR sending to ". + * To disable such tracing, please refer to vTraceSetFilterGroup and + * vTraceSetFilterMask. + * + * Default value is 1. + * + * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin + * and vTraceStoreISREnd in your interrupt handlers. + */ + #define TRC_CFG_INCLUDE_ISR_TRACING 1 + +/** + * @def TRC_CFG_INCLUDE_READY_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If one (1), events are recorded when tasks enter scheduling state "ready". + * This allows Tracealyzer to show the initial pending time before tasks enter + * the execution state, and present accurate response times. + * If zero (0), "ready events" are not created, which allows for recording + * longer traces in the same amount of RAM. + * + * Default value is 1. + */ + #define TRC_CFG_INCLUDE_READY_EVENTS 1 + +/** + * @def TRC_CFG_INCLUDE_OSTICK_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is one (1), events will be generated whenever the OS clock is + * increased. If zero (0), OS tick events are not generated, which allows for + * recording longer traces in the same amount of RAM. + * + * Default value is 1. + */ + #define TRC_CFG_INCLUDE_OSTICK_EVENTS 1 + +/** + * @def TRC_CFG_ENABLE_STACK_MONITOR + * @brief If enabled (1), the recorder periodically reports the unused stack space of + * all active tasks. + * The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task + * is always created by the recorder when in streaming mode. + * In snapshot mode, the TzCtrl task is only used for stack monitoring and is + * not created unless this is enabled. + */ + #define TRC_CFG_ENABLE_STACK_MONITOR 1 + +/** + * @def TRC_CFG_STACK_MONITOR_MAX_TASKS + * @brief Macro which should be defined as a non-zero integer value. + * + * This controls how many tasks that can be monitored by the stack monitor. + * If this is too small, some tasks will be excluded and a warning is shown. + * + * Default value is 10. + */ + #define TRC_CFG_STACK_MONITOR_MAX_TASKS 10 + +/** + * @def TRC_CFG_STACK_MONITOR_MAX_REPORTS + * @brief Macro which should be defined as a non-zero integer value. + * + * This defines how many tasks that will be subject to stack usage analysis for + * each execution of the Tracealyzer Control task (TzCtrl). Note that the stack + * monitoring cycles between the tasks, so this does not affect WHICH tasks that + * are monitored, but HOW OFTEN each task stack is analyzed. + * + * This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the + * frequency of the stack monitoring. This is motivated since the stack analysis + * can take some time to execute. + * However, note that the stack analysis runs in a separate task (TzCtrl) that + * can be executed on low priority. This way, you can avoid that the stack + * analysis disturbs any time-sensitive tasks. + * + * Default value is 1. + */ + #define TRC_CFG_STACK_MONITOR_MAX_REPORTS 1 + +/** + * @def TRC_CFG_CTRL_TASK_PRIORITY + * @brief The scheduling priority of the Tracealyzer Control (TzCtrl) task. + * + * In streaming mode, TzCtrl is used to receive start/stop commands from + * Tracealyzer and in some cases also to transmit the trace data (for stream + * ports that uses the internal buffer, like TCP/IP). For such stream ports, + * make sure the TzCtrl priority is high enough to ensure reliable periodic + * execution and transfer of the data, but low enough to avoid disturbing any + * time-sensitive functions. + * + * In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is + * not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should + * be low, to avoid disturbing any time-sensitive tasks. + */ + #define TRC_CFG_CTRL_TASK_PRIORITY 1 + +/** + * @def TRC_CFG_CTRL_TASK_DELAY + * @brief The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY), + * which affects the frequency of the stack monitoring. + * + * In streaming mode, this also affects the trace data transfer if you are using + * a stream port leveraging the internal buffer (like TCP/IP). A shorter delay + * increases the CPU load of TzCtrl somewhat, but may improve the performance of + * of the trace streaming, especially if the trace buffer is small. + */ + #define TRC_CFG_CTRL_TASK_DELAY 2 + +/** + * @def TRC_CFG_CTRL_TASK_STACK_SIZE + * @brief The stack size of the Tracealyzer Control (TzCtrl) task. + * See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl. + */ + #define TRC_CFG_CTRL_TASK_STACK_SIZE 4096 + +/** + * @def TRC_CFG_RECORDER_BUFFER_ALLOCATION + * @brief Specifies how the recorder buffer is allocated (also in case of streaming, in + * port using the recorder's internal temporary buffer) + * + * Values: + * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal) + * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable + * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer + * + * Static and dynamic mode does the allocation for you, either in compile time + * (static) or in runtime (malloc). + * The custom mode allows you to control how and where the allocation is made, + * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer(). + */ + #define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC + +/** + * @def TRC_CFG_MAX_ISR_NESTING + * @brief Defines how many levels of interrupt nesting the recorder can handle, in + * case multiple ISRs are traced and ISR nesting is possible. If this + * is exceeded, the particular ISR will not be traced and the recorder then + * logs an error message. This setting is used to allocate an internal stack + * for keeping track of the previous execution context (4 byte per entry). + * + * This value must be a non-zero positive constant, at least 1. + * + * Default value: 8 + */ + #define TRC_CFG_MAX_ISR_NESTING 8 + +/** + * @def TRC_CFG_ISR_TAILCHAINING_THRESHOLD + * @brief Macro which should be defined as an integer value. + * + * If tracing multiple ISRs, this setting allows for accurate display of the + * context-switching also in cases when the ISRs execute in direct sequence. + * + * vTraceStoreISREnd normally assumes that the ISR returns to the previous + * context, i.e., a task or a preempted ISR. But if another traced ISR + * executes in direct sequence, Tracealyzer may incorrectly display a minimal + * fragment of the previous context in between the ISRs. + * + * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is + * however a threshold value that must be measured for your specific setup. + * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ + * + * The default setting is 0, meaning "disabled" and that you may get an + * extra fragments of the previous context in between tail-chained ISRs. + * + * Note: This setting has separate definitions in trcSnapshotConfig.h and + * trcStreamingConfig.h, since it is affected by the recorder mode. + */ + #define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 + +/** + * @def TRC_CFG_RECORDER_DATA_INIT + * @brief Macro which states wether the recorder data should have an initial value. + * + * In very specific cases where traced objects are created before main(), + * the recorder will need to be started even before that. In these cases, + * the recorder data would be initialized by vTraceEnable(TRC_INIT) but could + * then later be overwritten by the initialization value. + * If this is an issue for you, set TRC_CFG_RECORDER_DATA_INIT to 0. + * The following code can then be used before any traced objects are created: + * + * extern uint32_t RecorderEnabled; + * RecorderEnabled = 0; + * xTraceInitialize(); + * + * After the clocks are properly initialized, use vTraceEnable(...) to start + * the tracing. + * + * Default value is 1. + */ + #define TRC_CFG_RECORDER_DATA_INIT 1 + +/** + * @def TRC_CFG_RECORDER_DATA_ATTRIBUTE + * @brief When setting TRC_CFG_RECORDER_DATA_INIT to 0, you might also need to make + * sure certain recorder data is placed in a specific RAM section to avoid being + * zeroed out after initialization. Define TRC_CFG_RECORDER_DATA_ATTRIBUTE as + * that attribute. + * + * Example: + * #define TRC_CFG_RECORDER_DATA_ATTRIBUTE __attribute__((section(".bss.trace_recorder_data"))) + * + * Default value is empty. + */ + #define TRC_CFG_RECORDER_DATA_ATTRIBUTE + +/** + * @def TRC_CFG_USE_TRACE_ASSERT + * @brief Enable or disable debug asserts. Information regarding any assert that is + * triggered will be in trcAssert.c. + */ + #define TRC_CFG_USE_TRACE_ASSERT 1 + + #ifdef __cplusplus +} + #endif + +#endif /* _TRC_CONFIG_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcKernelPortConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcKernelPortConfig.h index 387df1ab6..df440bdce 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcKernelPortConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcKernelPortConfig.h @@ -11,11 +11,11 @@ */ #ifndef TRC_KERNEL_PORT_CONFIG_H -#define TRC_KERNEL_PORT_CONFIG_H + #define TRC_KERNEL_PORT_CONFIG_H -#ifdef __cplusplus + #ifdef __cplusplus extern "C" { -#endif + #endif /** * @def TRC_CFG_RECORDER_MODE @@ -30,7 +30,7 @@ * TRC_RECORDER_MODE_SNAPSHOT * TRC_RECORDER_MODE_STREAMING */ -#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT + #define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT /** * @def TRC_CFG_FREERTOS_VERSION @@ -56,7 +56,7 @@ * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 * TRC_FREERTOS_VERSION_10_4_1 If using FreeRTOS v10.4.1 or later */ -#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_1 + #define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_1 /** * @def TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS @@ -66,7 +66,7 @@ * * Default value is 0 (excluded) since dependent on event_groups.c */ -#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 1 + #define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 1 /** * @def TRC_CFG_INCLUDE_TIMER_EVENTS @@ -76,7 +76,7 @@ * * Default value is 0 since dependent on timers.c */ -#define TRC_CFG_INCLUDE_TIMER_EVENTS 1 + #define TRC_CFG_INCLUDE_TIMER_EVENTS 1 /** * @def TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS @@ -87,7 +87,7 @@ * * Default value is 0 since dependent on timers.c */ -#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 + #define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 /** * @def TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS @@ -98,7 +98,7 @@ * * Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10) */ -#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 1 + #define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 1 /** * @def TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND @@ -107,10 +107,10 @@ * traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from * other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED. */ -#define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND 0 /* TRC_ACKNOWLEDGED */ + #define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND 0 /* TRC_ACKNOWLEDGED */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* TRC_KERNEL_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h index 023a80316..f5cb0571e 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h @@ -9,11 +9,11 @@ */ #ifndef TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H -#define TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H + #define TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H -#ifdef __cplusplus + #ifdef __cplusplus extern "C" { -#endif + #endif /** * @def TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE... @@ -36,15 +36,15 @@ * check the actual usage by selecting View menu -> Trace Details -> * Resource Usage -> Object Table. */ -#define TRC_CFG_NTASK 150 -#define TRC_CFG_NISR 90 -#define TRC_CFG_NQUEUE 90 -#define TRC_CFG_NSEMAPHORE 90 -#define TRC_CFG_NMUTEX 90 -#define TRC_CFG_NTIMER 250 -#define TRC_CFG_NEVENTGROUP 90 -#define TRC_CFG_NSTREAMBUFFER 50 -#define TRC_CFG_NMESSAGEBUFFER 50 + #define TRC_CFG_NTASK 150 + #define TRC_CFG_NISR 90 + #define TRC_CFG_NQUEUE 90 + #define TRC_CFG_NSEMAPHORE 90 + #define TRC_CFG_NMUTEX 90 + #define TRC_CFG_NTIMER 250 + #define TRC_CFG_NEVENTGROUP 90 + #define TRC_CFG_NSTREAMBUFFER 50 + #define TRC_CFG_NMESSAGEBUFFER 50 /** * @def TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ... @@ -52,18 +52,18 @@ * kernel objects, such as tasks and queues. If longer names are used, they will * be truncated when stored in the recorder. */ -#define TRC_CFG_NAME_LEN_TASK 15 -#define TRC_CFG_NAME_LEN_ISR 15 -#define TRC_CFG_NAME_LEN_QUEUE 15 -#define TRC_CFG_NAME_LEN_SEMAPHORE 15 -#define TRC_CFG_NAME_LEN_MUTEX 15 -#define TRC_CFG_NAME_LEN_TIMER 15 -#define TRC_CFG_NAME_LEN_EVENTGROUP 15 -#define TRC_CFG_NAME_LEN_STREAMBUFFER 15 -#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 + #define TRC_CFG_NAME_LEN_TASK 15 + #define TRC_CFG_NAME_LEN_ISR 15 + #define TRC_CFG_NAME_LEN_QUEUE 15 + #define TRC_CFG_NAME_LEN_SEMAPHORE 15 + #define TRC_CFG_NAME_LEN_MUTEX 15 + #define TRC_CFG_NAME_LEN_TIMER 15 + #define TRC_CFG_NAME_LEN_EVENTGROUP 15 + #define TRC_CFG_NAME_LEN_STREAMBUFFER 15 + #define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcSnapshotConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcSnapshotConfig.h index 98bc7a6de..fc339aea1 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcSnapshotConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/trcSnapshotConfig.h @@ -1,245 +1,245 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Configuration parameters for trace recorder library in snapshot mode. - * Read more at http://percepio.com/2016/10/05/rtos-tracing/ - */ - -#ifndef TRC_SNAPSHOT_CONFIG_H -#define TRC_SNAPSHOT_CONFIG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/** - * @def TRC_CFG_SNAPSHOT_MODE - * @brief Macro which should be defined as one of: - * - TRC_SNAPSHOT_MODE_RING_BUFFER - * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL - * Default is TRC_SNAPSHOT_MODE_RING_BUFFER. - * - * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the - * events are stored in a ring buffer, i.e., where the oldest events are - * overwritten when the buffer becomes full. This allows you to get the last - * events leading up to an interesting state, e.g., an error, without having - * to store the whole run since startup. - * - * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the - * recording is stopped when the buffer becomes full. This is useful for - * recording events following a specific state, e.g., the startup sequence. - */ -#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER - -/** - * @def TRC_CFG_EVENT_BUFFER_SIZE - * @brief Macro which should be defined as an integer value. - * - * This defines the capacity of the event buffer, i.e., the number of records - * it may store. Most events use one record (4 byte), although some events - * require multiple 4-byte records. You should adjust this to the amount of RAM - * available in the target system. - * - * Default value is 1000, which means that 4000 bytes is allocated for the - * event buffer. - */ -#define TRC_CFG_EVENT_BUFFER_SIZE 50000 - -/** - * @def TRC_CFG_INCLUDE_FLOAT_SUPPORT - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the support for logging floating point values in - * vTracePrintF is stripped out, in case floating point values are not used or - * supported by the platform used. - * - * Floating point values are only used in vTracePrintF and its subroutines, to - * allow for storing float (%f) or double (%lf) arguments. - * - * vTracePrintF can be used with integer and string arguments in either case. - * - * Default value is 0. - */ -#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 - -/** - * @def TRC_CFG_SYMBOL_TABLE_SIZE - * @brief Macro which should be defined as an integer value. - * - * This defines the capacity of the symbol table, in bytes. This symbol table - * stores User Events labels and names of deleted tasks, queues, or other kernel - * objects. If you don't use User Events or delete any kernel - * objects you set this to a very low value. The minimum recommended value is 4. - * A size of zero (0) is not allowed since a zero-sized array may result in a - * 32-bit pointer, i.e., using 4 bytes rather than 0. - * - * Default value is 800. - */ -#define TRC_CFG_SYMBOL_TABLE_SIZE 8000 - -#if ( TRC_CFG_SYMBOL_TABLE_SIZE == 0 ) - #error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!" -#endif - -/****************************************************************************** - *** ADVANCED SETTINGS ******************************************************** - ****************************************************************************** - * The remaining settings are not necessary to modify but allows for optimizing - * the recorder setup for your specific needs, e.g., to exclude events that you - * are not interested in, in order to get longer traces. - *****************************************************************************/ - -/** - * @def TRC_CFG_HEAP_SIZE_BELOW_16M - * @brief An integer constant that can be used to reduce the buffer usage of memory - * allocation events (malloc/free). This value should be 1 if the heap size is - * below 16 MB (2^24 byte), and you can live with reported addresses showing the - * lower 24 bits only. If 0, you get the full 32-bit addresses. - * - * Default value is 0. - */ -#define TRC_CFG_HEAP_SIZE_BELOW_16M 0 - -/** - * @def TRC_CFG_USE_IMPLICIT_IFE_RULES - * @brief Macro which should be defined as either zero (0) or one (1). - * Default is 1. - * - * Tracealyzer groups the events into "instances" based on Instance Finish - * Events (IFEs), produced either by default rules or calls to the recorder - * functions xTraceTaskInstanceFinishedNow and xTraceTaskInstanceFinishedNext. - * - * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is - * used, resulting in a "typical" grouping of events into instances. - * If these rules don't give appropriate instances in your case, you can - * override the default rules using xTraceTaskInstanceFinishedNow/Next for one - * or several tasks. The default IFE rules are then disabled for those tasks. - * - * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are - * disabled globally. You must then call xTraceTaskInstanceFinishedNow or - * xTraceTaskInstanceFinishedNext to manually group the events into instances, - * otherwise the tasks will appear a single long instance. - * - * The default IFE rules count the following events as "instance finished": - * - Task delay, delay until - * - Task suspend - * - Blocking on "input" operations, i.e., when the task is waiting for the - * next a message/signal/event. But only if this event is blocking. - */ -#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1 - -/** - * @def TRC_CFG_USE_16BIT_OBJECT_HANDLES - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel - * objects such as tasks and queues. This limits the supported number of - * concurrently active objects to 255 of each type (tasks, queues, mutexes, - * etc.) Note: 255, not 256, since handle 0 is reserved. - * - * If set to 1 (one), the recorder uses 16-bit handles to identify kernel - * objects such as tasks and queues. This limits the supported number of - * concurrent objects to 65535 of each type (object class). However, since the - * object property table is limited to 64 KB, the practical limit is about - * 3000 objects in total. - * - * Default is 0 (8-bit handles) - * - * NOTE: An object with handle above 255 will use an extra 4-byte record in - * the event buffer whenever the object is referenced. Moreover, some internal - * tables in the recorder gets slightly larger when using 16-bit handles. - */ -#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 1 - -/** - * @def TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER - * @brief Macro which should be defined as an integer value. - * - * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the - * separate user event buffer (UB). - * In this mode, user events are stored separately from other events, - * e.g., RTOS events. Thereby you can get a much longer history of - * user events as they don't need to share the buffer space with more - * frequent events. - * - * The UB is typically used with the snapshot ring-buffer mode, so the - * recording can continue when the main buffer gets full. And since the - * main buffer then overwrites the earliest events, Tracealyzer displays - * "Unknown Actor" instead of task scheduling for periods with UB data only. - * - * In UB mode, user events are structured as UB channels, which contains - * a channel name and a default format string. Register a UB channel using - * xTraceRegisterUBChannel. - * - * Events and data arguments are written using vTraceUBEvent and - * vTraceUBData. They are designed to provide efficient logging of - * repeating events, using the same format string within each channel. - * - * Examples: - * TraceStringHandle_t chn1; - * TraceStringHandle_t fmt1; - * xTraceStringRegister("Channel 1", &chn1); - * xTraceStringRegister("Event!", &fmt1); - * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); - * - * TraceStringHandle_t chn2; - * TraceStringHandle_t fmt2; - * xTraceStringRegister("Channel 2", &chn2); - * xTraceStringRegister("X: %d, Y: %d", &fmt2); - * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); - * - * // Result in "[Channel 1] Event!" - * vTraceUBEvent(UBCh1); - * - * // Result in "[Channel 2] X: 23, Y: 19" - * vTraceUBData(UBCh2, 23, 19); - * - * You can also use the other user event functions, like xTracePrintF. - * as they are then rerouted to the UB instead of the main event buffer. - * vTracePrintF then looks up the correct UB channel based on the - * provided channel name and format string, or creates a new UB channel - * if no match is found. The format string should therefore not contain - * "random" messages but mainly format specifiers. Random strings should - * be stored using %s and with the string as an argument. - * - * // Creates a new UB channel ("Channel 2", "%Z: %d") - * xTracePrintF(chn2, "%Z: %d", value1); - * - * // Finds the existing UB channel - * xTracePrintF(chn2, "%Z: %d", value2); - */ -#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 1 - -/** - * @def TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE - * @brief Macro which should be defined as an integer value. - * - * This defines the capacity of the user event buffer (UB), in number of slots. - * A single user event can use multiple slots, depending on the arguments. - * - * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. - */ -#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200 - -/** - * @def TRC_CFG_UB_CHANNELS - * @brief Macro which should be defined as an integer value. - * - * This defines the number of User Event Buffer Channels (UB channels). - * These are used to structure the events when using the separate user - * event buffer, and contains both a User Event Channel (the name) and - * a default format string for the channel. - * - * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. - */ -#define TRC_CFG_UB_CHANNELS 32 - -#ifdef __cplusplus -} -#endif - -#endif /*TRC_SNAPSHOT_CONFIG_H*/ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Configuration parameters for trace recorder library in snapshot mode. + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + */ + +#ifndef TRC_SNAPSHOT_CONFIG_H + #define TRC_SNAPSHOT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @def TRC_CFG_SNAPSHOT_MODE + * @brief Macro which should be defined as one of: + * - TRC_SNAPSHOT_MODE_RING_BUFFER + * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL + * Default is TRC_SNAPSHOT_MODE_RING_BUFFER. + * + * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the + * events are stored in a ring buffer, i.e., where the oldest events are + * overwritten when the buffer becomes full. This allows you to get the last + * events leading up to an interesting state, e.g., an error, without having + * to store the whole run since startup. + * + * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the + * recording is stopped when the buffer becomes full. This is useful for + * recording events following a specific state, e.g., the startup sequence. + */ + #define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER + +/** + * @def TRC_CFG_EVENT_BUFFER_SIZE + * @brief Macro which should be defined as an integer value. + * + * This defines the capacity of the event buffer, i.e., the number of records + * it may store. Most events use one record (4 byte), although some events + * require multiple 4-byte records. You should adjust this to the amount of RAM + * available in the target system. + * + * Default value is 1000, which means that 4000 bytes is allocated for the + * event buffer. + */ + #define TRC_CFG_EVENT_BUFFER_SIZE 50000 + +/** + * @def TRC_CFG_INCLUDE_FLOAT_SUPPORT + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the support for logging floating point values in + * vTracePrintF is stripped out, in case floating point values are not used or + * supported by the platform used. + * + * Floating point values are only used in vTracePrintF and its subroutines, to + * allow for storing float (%f) or double (%lf) arguments. + * + * vTracePrintF can be used with integer and string arguments in either case. + * + * Default value is 0. + */ + #define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 + +/** + * @def TRC_CFG_SYMBOL_TABLE_SIZE + * @brief Macro which should be defined as an integer value. + * + * This defines the capacity of the symbol table, in bytes. This symbol table + * stores User Events labels and names of deleted tasks, queues, or other kernel + * objects. If you don't use User Events or delete any kernel + * objects you set this to a very low value. The minimum recommended value is 4. + * A size of zero (0) is not allowed since a zero-sized array may result in a + * 32-bit pointer, i.e., using 4 bytes rather than 0. + * + * Default value is 800. + */ + #define TRC_CFG_SYMBOL_TABLE_SIZE 8000 + + #if ( TRC_CFG_SYMBOL_TABLE_SIZE == 0 ) + #error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!" + #endif + +/****************************************************************************** + *** ADVANCED SETTINGS ******************************************************** + ****************************************************************************** + * The remaining settings are not necessary to modify but allows for optimizing + * the recorder setup for your specific needs, e.g., to exclude events that you + * are not interested in, in order to get longer traces. + *****************************************************************************/ + +/** + * @def TRC_CFG_HEAP_SIZE_BELOW_16M + * @brief An integer constant that can be used to reduce the buffer usage of memory + * allocation events (malloc/free). This value should be 1 if the heap size is + * below 16 MB (2^24 byte), and you can live with reported addresses showing the + * lower 24 bits only. If 0, you get the full 32-bit addresses. + * + * Default value is 0. + */ + #define TRC_CFG_HEAP_SIZE_BELOW_16M 0 + +/** + * @def TRC_CFG_USE_IMPLICIT_IFE_RULES + * @brief Macro which should be defined as either zero (0) or one (1). + * Default is 1. + * + * Tracealyzer groups the events into "instances" based on Instance Finish + * Events (IFEs), produced either by default rules or calls to the recorder + * functions xTraceTaskInstanceFinishedNow and xTraceTaskInstanceFinishedNext. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is + * used, resulting in a "typical" grouping of events into instances. + * If these rules don't give appropriate instances in your case, you can + * override the default rules using xTraceTaskInstanceFinishedNow/Next for one + * or several tasks. The default IFE rules are then disabled for those tasks. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are + * disabled globally. You must then call xTraceTaskInstanceFinishedNow or + * xTraceTaskInstanceFinishedNext to manually group the events into instances, + * otherwise the tasks will appear a single long instance. + * + * The default IFE rules count the following events as "instance finished": + * - Task delay, delay until + * - Task suspend + * - Blocking on "input" operations, i.e., when the task is waiting for the + * next a message/signal/event. But only if this event is blocking. + */ + #define TRC_CFG_USE_IMPLICIT_IFE_RULES 1 + +/** + * @def TRC_CFG_USE_16BIT_OBJECT_HANDLES + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrently active objects to 255 of each type (tasks, queues, mutexes, + * etc.) Note: 255, not 256, since handle 0 is reserved. + * + * If set to 1 (one), the recorder uses 16-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrent objects to 65535 of each type (object class). However, since the + * object property table is limited to 64 KB, the practical limit is about + * 3000 objects in total. + * + * Default is 0 (8-bit handles) + * + * NOTE: An object with handle above 255 will use an extra 4-byte record in + * the event buffer whenever the object is referenced. Moreover, some internal + * tables in the recorder gets slightly larger when using 16-bit handles. + */ + #define TRC_CFG_USE_16BIT_OBJECT_HANDLES 1 + +/** + * @def TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER + * @brief Macro which should be defined as an integer value. + * + * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the + * separate user event buffer (UB). + * In this mode, user events are stored separately from other events, + * e.g., RTOS events. Thereby you can get a much longer history of + * user events as they don't need to share the buffer space with more + * frequent events. + * + * The UB is typically used with the snapshot ring-buffer mode, so the + * recording can continue when the main buffer gets full. And since the + * main buffer then overwrites the earliest events, Tracealyzer displays + * "Unknown Actor" instead of task scheduling for periods with UB data only. + * + * In UB mode, user events are structured as UB channels, which contains + * a channel name and a default format string. Register a UB channel using + * xTraceRegisterUBChannel. + * + * Events and data arguments are written using vTraceUBEvent and + * vTraceUBData. They are designed to provide efficient logging of + * repeating events, using the same format string within each channel. + * + * Examples: + * TraceStringHandle_t chn1; + * TraceStringHandle_t fmt1; + * xTraceStringRegister("Channel 1", &chn1); + * xTraceStringRegister("Event!", &fmt1); + * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); + * + * TraceStringHandle_t chn2; + * TraceStringHandle_t fmt2; + * xTraceStringRegister("Channel 2", &chn2); + * xTraceStringRegister("X: %d, Y: %d", &fmt2); + * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); + * + * // Result in "[Channel 1] Event!" + * vTraceUBEvent(UBCh1); + * + * // Result in "[Channel 2] X: 23, Y: 19" + * vTraceUBData(UBCh2, 23, 19); + * + * You can also use the other user event functions, like xTracePrintF. + * as they are then rerouted to the UB instead of the main event buffer. + * vTracePrintF then looks up the correct UB channel based on the + * provided channel name and format string, or creates a new UB channel + * if no match is found. The format string should therefore not contain + * "random" messages but mainly format specifiers. Random strings should + * be stored using %s and with the string as an argument. + * + * // Creates a new UB channel ("Channel 2", "%Z: %d") + * xTracePrintF(chn2, "%Z: %d", value1); + * + * // Finds the existing UB channel + * xTracePrintF(chn2, "%Z: %d", value2); + */ + #define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 1 + +/** + * @def TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE + * @brief Macro which should be defined as an integer value. + * + * This defines the capacity of the user event buffer (UB), in number of slots. + * A single user event can use multiple slots, depending on the arguments. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + */ + #define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200 + +/** + * @def TRC_CFG_UB_CHANNELS + * @brief Macro which should be defined as an integer value. + * + * This defines the number of User Event Buffer Channels (UB channels). + * These are used to structure the events when using the separate user + * event buffer, and contains both a User Event Channel (the name) and + * a default format string for the channel. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + */ + #define TRC_CFG_UB_CHANNELS 32 + + #ifdef __cplusplus +} + #endif + +#endif /*TRC_SNAPSHOT_CONFIG_H*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/code_coverage_additions.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/code_coverage_additions.c index 03b6cb042..ae8d7fd69 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/code_coverage_additions.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/code_coverage_additions.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -377,7 +377,7 @@ static BaseType_t prvTaskQueryFunctions( void ) BaseType_t xReturn = pdPASS; UBaseType_t uxNumberOfTasks, uxReturned, ux; uint32_t ulTotalRunTime1, ulTotalRunTime2; - const uint32_t ulRunTimeTollerance = ( uint32_t ) 0xfff; + const uint32_t ulRunTimeTolerance = ( uint32_t ) 0xfff; /* Obtain task status with the stack high water mark and without the * state. */ @@ -464,12 +464,12 @@ static BaseType_t prvTaskQueryFunctions( void ) memset( ( void * ) pxStatusArray, 0xaa, uxNumberOfTasks * sizeof( TaskStatus_t ) ); uxReturned = uxTaskGetSystemState( pxStatusArray, uxNumberOfTasks, &ulTotalRunTime2 ); - if( ( ulTotalRunTime2 - ulTotalRunTime1 ) > ulRunTimeTollerance ) + if( ( ulTotalRunTime2 - ulTotalRunTime1 ) > ulRunTimeTolerance ) { xReturn = pdFAIL; } - /* Basic santity check of array contents. */ + /* Basic sanity check of array contents. */ for( ux = 0; ux < uxReturned; ux++ ) { if( pxStatusArray[ ux ].eCurrentState >= ( UBaseType_t ) eInvalid ) @@ -595,7 +595,7 @@ static BaseType_t prvTimerQuery( void ) xTimerPeriod, pdFALSE, ( void * ) xTimerPeriod, - NULL ); /* Not actually going to start timer so NULL callback is ok. */ + NULL ); /* Not actually going to start timer so NULL callback is ok. */ if( xTimer != NULL ) { diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/console.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/console.c index 92da2ca8c..ec6a047ba 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/console.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/console.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/console.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/console.h index 20106257b..f0ea97b32 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/console.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/console.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -24,21 +24,22 @@ * */ #ifndef CONSOLE_H -#define CONSOLE_H + #define CONSOLE_H -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /*----------------------------------------------------------- - * Example console I/O wrappers. - *----------------------------------------------------------*/ +* Example console I/O wrappers. +*----------------------------------------------------------*/ -void console_init(void); -void console_print(const char *fmt, ...); + void console_init( void ); + void console_print( const char * fmt, + ... ); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* CONSOLE_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main.c index 03ebcc8c4..2f9e825ef 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -118,29 +118,29 @@ int main( void ) { /* Do not include trace code when performing a code coverage analysis. */ #if ( projCOVERAGE_TEST != 1 ) - { - /* Initialise the trace recorder. Use of the trace recorder is optional. - * See http://www.FreeRTOS.org/trace for more information. */ - xTraceEnable( TRC_START ); + { + /* Initialise the trace recorder. Use of the trace recorder is optional. + * See http://www.FreeRTOS.org/trace for more information. */ + xTraceEnable( TRC_START ); - /* Start the trace recording - the recording is written to a file if - * configASSERT() is called. */ - printf( "\r\nTrace started.\r\nThe trace will be dumped to disk if a call to configASSERT() fails.\r\n" ); - printf( "\r\nThe trace will be dumped to disk if Enter is hit.\r\n" ); - traceSTART(); - } + /* Start the trace recording - the recording is written to a file if + * configASSERT() is called. */ + printf( "\r\nTrace started.\r\nThe trace will be dumped to disk if a call to configASSERT() fails.\r\n" ); + printf( "\r\nThe trace will be dumped to disk if Enter is hit.\r\n" ); + traceSTART(); + } #endif console_init(); #if ( mainSELECTED_APPLICATION == ECHO_CLIENT_DEMO ) - { - console_print( "Starting echo client demo\n" ); - main_tcp_echo_client_tasks(); - } + { + console_print( "Starting echo client demo\n" ); + main_tcp_echo_client_tasks(); + } #else - { - #error "The selected demo is not valid" - } + { + #error "The selected demo is not valid" + } #endif /* if ( mainSELECTED_APPLICATION ) */ return 0; @@ -298,25 +298,25 @@ static void prvSaveTraceFile( void ) { /* Tracing is not used when code coverage analysis is being performed. */ #if ( projCOVERAGE_TEST != 1 ) - { - FILE * pxOutputFile; - pxOutputFile = fopen( "Trace.dump", "wb" ); + { + FILE * pxOutputFile; + pxOutputFile = fopen( "Trace.dump", "wb" ); - if( pxOutputFile != NULL ) + if( pxOutputFile != NULL ) + { { - { - xTraceDisable(); - fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile ); - fclose( pxOutputFile ); - printf( "\r\nTrace output saved to Trace.dump\r\n" ); - xTraceEnable( TRC_START ); - } - } - else - { - printf( "\r\nFailed to create trace dump file\r\n" ); + xTraceDisable(); + fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile ); + fclose( pxOutputFile ); + printf( "\r\nTrace output saved to Trace.dump\r\n" ); + xTraceEnable( TRC_START ); } } + else + { + printf( "\r\nFailed to create trace dump file\r\n" ); + } + } #endif /* if ( projCOVERAGE_TEST != 1 ) */ } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main_networking.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main_networking.c index e89b36f63..085f29509 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main_networking.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/main_networking.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -120,12 +120,12 @@ static UBaseType_t ulNextRand; #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - /* In case multiple interfaces are used, define them statically. */ +/* In case multiple interfaces are used, define them statically. */ - /* There is only 1 physical interface. */ +/* There is only 1 physical interface. */ static NetworkInterface_t xInterfaces[ 1 ]; - /* It will have several end-points. */ +/* It will have several end-points. */ static NetworkEndPoint_t xEndPoints[ 4 ]; #endif /* if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ @@ -159,26 +159,25 @@ void main_tcp_echo_client_tasks( void ) memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof( ucMACAddress ) ); -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + extern NetworkInterface_t * pxLibslirp_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ); + pxLibslirp_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); - extern NetworkInterface_t * pxLibslirp_FillInterfaceDescriptor( BaseType_t xEMACIndex, - NetworkInterface_t * pxInterface ); - pxLibslirp_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); - - /* === End-point 0 === */ - FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints [ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + /* === End-point 0 === */ + FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); #if ( ipconfigUSE_DHCP != 0 ) - { - /* End-point 0 wants to use DHCPv4. */ - xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; - } - #endif /* ( ipconfigUSE_DHCP != 0 ) */ + { + /* End-point 0 wants to use DHCPv4. */ + xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; + } + #endif /* ( ipconfigUSE_DHCP != 0 ) */ - FreeRTOS_IPInit_Multi(); -#else - /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ - FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); -#endif /* if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + FreeRTOS_IPInit_Multi(); + #else /* if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ + FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + #endif /* if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ /* Start the RTOS scheduler. */ FreeRTOS_debug_printf( ( "vTaskStartScheduler\n" ) ); @@ -223,9 +222,9 @@ void main_tcp_echo_client_tasks( void ) * demo tasks. */ #if ( mainCREATE_TCP_ECHO_TASKS_SINGLE == 1 ) - { - vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY ); - } + { + vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY ); + } #endif /* mainCREATE_TCP_ECHO_TASKS_SINGLE */ xTasksAlreadyCreated = pdTRUE; diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/runtime_stats_hooks.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/runtime_stats_hooks.c index c5271d0b9..ce5500708 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/runtime_stats_hooks.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/runtime_stats_hooks.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/CMSDK_CM3.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/CMSDK_CM3.h old mode 100755 new mode 100644 index da3cbe16c..5d01a8fe5 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/CMSDK_CM3.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/CMSDK_CM3.h @@ -1,99 +1,99 @@ /* MPS2 CMSIS Library -* -* Copyright (c) 2006-2016 ARM Limited -* SPDX-License-Identifier: BSD-3-Clause -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* @file CMSDK_CM3.h -* @brief CMSIS Core Peripheral Access Layer Header File for -* CMSDK_CM3 Device -* -*******************************************************************************/ + * + * Copyright (c) 2006-2016 ARM Limited + * SPDX-License-Identifier: BSD-3-Clause + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + * @file CMSDK_CM3.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * CMSDK_CM3 Device + * + *******************************************************************************/ #ifndef CMSDK_CM3_H -#define CMSDK_CM3_H + #define CMSDK_CM3_H -#ifdef __cplusplus - extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* ------------------------- Interrupt Number Definition ------------------------ */ -typedef enum IRQn -{ + typedef enum IRQn + { /* ------------------- Cortex-M3 Processor Exceptions Numbers ------------------- */ - NonMaskableInt_IRQn = -14, /* 2 Non Maskable Interrupt */ - HardFault_IRQn = -13, /* 3 HardFault Interrupt */ - MemoryManagement_IRQn = -12, /* 4 Memory Management Interrupt */ - BusFault_IRQn = -11, /* 5 Bus Fault Interrupt */ - UsageFault_IRQn = -10, /* 6 Usage Fault Interrupt */ - SVCall_IRQn = -5, /* 11 SV Call Interrupt */ - DebugMonitor_IRQn = -4, /* 12 Debug Monitor Interrupt */ - PendSV_IRQn = -2, /* 14 Pend SV Interrupt */ - SysTick_IRQn = -1, /* 15 System Tick Interrupt */ + NonMaskableInt_IRQn = -14, /* 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /* 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /* 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /* 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /* 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /* 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /* 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /* 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /* 15 System Tick Interrupt */ /****** CMSDK Specific Interrupt Numbers *********************************************************/ - UARTRX0_IRQn = 0, /*!< UART 0 RX Interrupt */ - UARTTX0_IRQn = 1, /*!< UART 0 TX Interrupt */ - UARTRX1_IRQn = 2, /*!< UART 1 RX Interrupt */ - UARTTX1_IRQn = 3, /*!< UART 1 TX Interrupt */ - UARTRX2_IRQn = 4, /*!< UART 2 RX Interrupt */ - UARTTX2_IRQn = 5, /*!< UART 2 TX Interrupt */ - PORT0_ALL_IRQn = 6, /*!< Port 0 combined Interrupt */ - PORT1_ALL_IRQn = 7, /*!< Port 1 combined Interrupt */ - TIMER0_IRQn = 8, /*!< TIMER 0 Interrupt */ - TIMER1_IRQn = 9, /*!< TIMER 1 Interrupt */ - DUALTIMER_IRQn = 10, /*!< Dual Timer Interrupt */ - SPI_IRQn = 11, /*!< SPI Interrupt */ - UARTOVF_IRQn = 12, /*!< UART 0,1,2 Overflow Interrupt */ - ETHERNET_IRQn = 13, /*!< Ethernet Interrupt */ - I2S_IRQn = 14, /*!< I2S Interrupt */ - TSC_IRQn = 15, /*!< Touch Screen Interrupt */ - PORT2_ALL_IRQn = 16, /*!< Port 2 combined Interrupt */ - PORT3_ALL_IRQn = 17, /*!< Port 3 combined Interrupt */ - UARTRX3_IRQn = 18, /*!< UART 3 RX Interrupt */ - UARTTX3_IRQn = 19, /*!< UART 3 TX Interrupt */ - UARTRX4_IRQn = 20, /*!< UART 4 RX Interrupt */ - UARTTX4_IRQn = 21, /*!< UART 4 TX Interrupt */ - ADCSPI_IRQn = 22, /*!< SHIELD ADC SPI Interrupt */ - SHIELDSPI_IRQn = 23, /*!< SHIELD SPI Combined Interrupt */ - PORT0_0_IRQn = 24, /*!< GPIO Port 0 pin 0 Interrupt */ - PORT0_1_IRQn = 25, /*!< GPIO Port 0 pin 1 Interrupt */ - PORT0_2_IRQn = 26, /*!< GPIO Port 0 pin 2 Interrupt */ - PORT0_3_IRQn = 27, /*!< GPIO Port 0 pin 3 Interrupt */ - PORT0_4_IRQn = 28, /*!< GPIO Port 0 pin 4 Interrupt */ - PORT0_5_IRQn = 29, /*!< GPIO Port 0 pin 5 Interrupt */ - PORT0_6_IRQn = 30, /*!< GPIO Port 0 pin 6 Interrupt */ - PORT0_7_IRQn = 31, /*!< GPIO Port 0 pin 7 Interrupt */ -} IRQn_Type; + UARTRX0_IRQn = 0, /*!< UART 0 RX Interrupt */ + UARTTX0_IRQn = 1, /*!< UART 0 TX Interrupt */ + UARTRX1_IRQn = 2, /*!< UART 1 RX Interrupt */ + UARTTX1_IRQn = 3, /*!< UART 1 TX Interrupt */ + UARTRX2_IRQn = 4, /*!< UART 2 RX Interrupt */ + UARTTX2_IRQn = 5, /*!< UART 2 TX Interrupt */ + PORT0_ALL_IRQn = 6, /*!< Port 0 combined Interrupt */ + PORT1_ALL_IRQn = 7, /*!< Port 1 combined Interrupt */ + TIMER0_IRQn = 8, /*!< TIMER 0 Interrupt */ + TIMER1_IRQn = 9, /*!< TIMER 1 Interrupt */ + DUALTIMER_IRQn = 10, /*!< Dual Timer Interrupt */ + SPI_IRQn = 11, /*!< SPI Interrupt */ + UARTOVF_IRQn = 12, /*!< UART 0,1,2 Overflow Interrupt */ + ETHERNET_IRQn = 13, /*!< Ethernet Interrupt */ + I2S_IRQn = 14, /*!< I2S Interrupt */ + TSC_IRQn = 15, /*!< Touch Screen Interrupt */ + PORT2_ALL_IRQn = 16, /*!< Port 2 combined Interrupt */ + PORT3_ALL_IRQn = 17, /*!< Port 3 combined Interrupt */ + UARTRX3_IRQn = 18, /*!< UART 3 RX Interrupt */ + UARTTX3_IRQn = 19, /*!< UART 3 TX Interrupt */ + UARTRX4_IRQn = 20, /*!< UART 4 RX Interrupt */ + UARTTX4_IRQn = 21, /*!< UART 4 TX Interrupt */ + ADCSPI_IRQn = 22, /*!< SHIELD ADC SPI Interrupt */ + SHIELDSPI_IRQn = 23, /*!< SHIELD SPI Combined Interrupt */ + PORT0_0_IRQn = 24, /*!< GPIO Port 0 pin 0 Interrupt */ + PORT0_1_IRQn = 25, /*!< GPIO Port 0 pin 1 Interrupt */ + PORT0_2_IRQn = 26, /*!< GPIO Port 0 pin 2 Interrupt */ + PORT0_3_IRQn = 27, /*!< GPIO Port 0 pin 3 Interrupt */ + PORT0_4_IRQn = 28, /*!< GPIO Port 0 pin 4 Interrupt */ + PORT0_5_IRQn = 29, /*!< GPIO Port 0 pin 5 Interrupt */ + PORT0_6_IRQn = 30, /*!< GPIO Port 0 pin 6 Interrupt */ + PORT0_7_IRQn = 31, /*!< GPIO Port 0 pin 7 Interrupt */ + } IRQn_Type; /* ================================================================================ */ @@ -101,560 +101,558 @@ typedef enum IRQn /* ================================================================================ */ /* -------- Configuration of the Cortex-M3 Processor and Core Peripherals ------- */ -#define __CM3_REV 0x0201 /* Core revision r2p1 */ -#define __MPU_PRESENT 1 /* MPU present or not */ -#define __NVIC_PRIO_BITS 8 /* Number of Bits used for Priority Levels */ -#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ + #define __CM3_REV 0x0201 /* Core revision r2p1 */ + #define __MPU_PRESENT 1 /* MPU present or not */ + #define __NVIC_PRIO_BITS 8 /* Number of Bits used for Priority Levels */ + #define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ -#include /* Processor and core peripherals */ + #include /* Processor and core peripherals */ /* ================================================================================ */ /* ================ Device Specific Peripheral Section ================ */ /* ================================================================================ */ /* ------------------- Start of section using anonymous unions ------------------ */ -#if defined ( __CC_ARM ) - #pragma push -#pragma anon_unions -#elif defined(__ICCARM__) - #pragma language=extended -#elif defined(__GNUC__) - /* anonymous unions are enabled by default */ -#elif defined(__TMS470__) + #if defined( __CC_ARM ) + #pragma push + #pragma anon_unions + #elif defined( __ICCARM__ ) + #pragma language=extended + #elif defined( __GNUC__ ) + /* anonymous unions are enabled by default */ + #elif defined( __TMS470__ ) /* anonymous unions are enabled by default */ -#elif defined(__TASKING__) - #pragma warning 586 -#else - #warning Not supported compiler type -#endif + #elif defined( __TASKING__ ) + #pragma warning 586 + #else /* if defined( __CC_ARM ) */ + #warning Not supported compiler type + #endif /* if defined( __CC_ARM ) */ /*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/ -typedef struct -{ - __IO uint32_t DATA; /* Offset: 0x000 (R/W) Data Register */ - __IO uint32_t STATE; /* Offset: 0x004 (R/W) Status Register */ - __IO uint32_t CTRL; /* Offset: 0x008 (R/W) Control Register */ - union { - __I uint32_t INTSTATUS; /* Offset: 0x00C (R/ ) Interrupt Status Register */ - __O uint32_t INTCLEAR; /* Offset: 0x00C ( /W) Interrupt Clear Register */ - }; - __IO uint32_t BAUDDIV; /* Offset: 0x010 (R/W) Baudrate Divider Register */ - -} CMSDK_UART_TypeDef; + typedef struct + { + __IO uint32_t DATA; /* Offset: 0x000 (R/W) Data Register */ + __IO uint32_t STATE; /* Offset: 0x004 (R/W) Status Register */ + __IO uint32_t CTRL; /* Offset: 0x008 (R/W) Control Register */ + union + { + __I uint32_t INTSTATUS; /* Offset: 0x00C (R/ ) Interrupt Status Register */ + __O uint32_t INTCLEAR; /* Offset: 0x00C ( /W) Interrupt Clear Register */ + }; + __IO uint32_t BAUDDIV; /* Offset: 0x010 (R/W) Baudrate Divider Register */ + } CMSDK_UART_TypeDef; /* CMSDK_UART DATA Register Definitions */ -#define CMSDK_UART_DATA_Pos 0 /* CMSDK_UART_DATA_Pos: DATA Position */ -#define CMSDK_UART_DATA_Msk (0xFFul << CMSDK_UART_DATA_Pos) /* CMSDK_UART DATA: DATA Mask */ + #define CMSDK_UART_DATA_Pos 0 /* CMSDK_UART_DATA_Pos: DATA Position */ + #define CMSDK_UART_DATA_Msk ( 0xFFul << CMSDK_UART_DATA_Pos ) /* CMSDK_UART DATA: DATA Mask */ -#define CMSDK_UART_STATE_RXOR_Pos 3 /* CMSDK_UART STATE: RXOR Position */ -#define CMSDK_UART_STATE_RXOR_Msk (0x1ul << CMSDK_UART_STATE_RXOR_Pos) /* CMSDK_UART STATE: RXOR Mask */ + #define CMSDK_UART_STATE_RXOR_Pos 3 /* CMSDK_UART STATE: RXOR Position */ + #define CMSDK_UART_STATE_RXOR_Msk ( 0x1ul << CMSDK_UART_STATE_RXOR_Pos ) /* CMSDK_UART STATE: RXOR Mask */ -#define CMSDK_UART_STATE_TXOR_Pos 2 /* CMSDK_UART STATE: TXOR Position */ -#define CMSDK_UART_STATE_TXOR_Msk (0x1ul << CMSDK_UART_STATE_TXOR_Pos) /* CMSDK_UART STATE: TXOR Mask */ + #define CMSDK_UART_STATE_TXOR_Pos 2 /* CMSDK_UART STATE: TXOR Position */ + #define CMSDK_UART_STATE_TXOR_Msk ( 0x1ul << CMSDK_UART_STATE_TXOR_Pos ) /* CMSDK_UART STATE: TXOR Mask */ -#define CMSDK_UART_STATE_RXBF_Pos 1 /* CMSDK_UART STATE: RXBF Position */ -#define CMSDK_UART_STATE_RXBF_Msk (0x1ul << CMSDK_UART_STATE_RXBF_Pos) /* CMSDK_UART STATE: RXBF Mask */ + #define CMSDK_UART_STATE_RXBF_Pos 1 /* CMSDK_UART STATE: RXBF Position */ + #define CMSDK_UART_STATE_RXBF_Msk ( 0x1ul << CMSDK_UART_STATE_RXBF_Pos ) /* CMSDK_UART STATE: RXBF Mask */ -#define CMSDK_UART_STATE_TXBF_Pos 0 /* CMSDK_UART STATE: TXBF Position */ -#define CMSDK_UART_STATE_TXBF_Msk (0x1ul << CMSDK_UART_STATE_TXBF_Pos ) /* CMSDK_UART STATE: TXBF Mask */ + #define CMSDK_UART_STATE_TXBF_Pos 0 /* CMSDK_UART STATE: TXBF Position */ + #define CMSDK_UART_STATE_TXBF_Msk ( 0x1ul << CMSDK_UART_STATE_TXBF_Pos ) /* CMSDK_UART STATE: TXBF Mask */ -#define CMSDK_UART_CTRL_HSTM_Pos 6 /* CMSDK_UART CTRL: HSTM Position */ -#define CMSDK_UART_CTRL_HSTM_Msk (0x01ul << CMSDK_UART_CTRL_HSTM_Pos) /* CMSDK_UART CTRL: HSTM Mask */ + #define CMSDK_UART_CTRL_HSTM_Pos 6 /* CMSDK_UART CTRL: HSTM Position */ + #define CMSDK_UART_CTRL_HSTM_Msk ( 0x01ul << CMSDK_UART_CTRL_HSTM_Pos ) /* CMSDK_UART CTRL: HSTM Mask */ -#define CMSDK_UART_CTRL_RXORIRQEN_Pos 5 /* CMSDK_UART CTRL: RXORIRQEN Position */ -#define CMSDK_UART_CTRL_RXORIRQEN_Msk (0x01ul << CMSDK_UART_CTRL_RXORIRQEN_Pos) /* CMSDK_UART CTRL: RXORIRQEN Mask */ + #define CMSDK_UART_CTRL_RXORIRQEN_Pos 5 /* CMSDK_UART CTRL: RXORIRQEN Position */ + #define CMSDK_UART_CTRL_RXORIRQEN_Msk ( 0x01ul << CMSDK_UART_CTRL_RXORIRQEN_Pos ) /* CMSDK_UART CTRL: RXORIRQEN Mask */ -#define CMSDK_UART_CTRL_TXORIRQEN_Pos 4 /* CMSDK_UART CTRL: TXORIRQEN Position */ -#define CMSDK_UART_CTRL_TXORIRQEN_Msk (0x01ul << CMSDK_UART_CTRL_TXORIRQEN_Pos) /* CMSDK_UART CTRL: TXORIRQEN Mask */ + #define CMSDK_UART_CTRL_TXORIRQEN_Pos 4 /* CMSDK_UART CTRL: TXORIRQEN Position */ + #define CMSDK_UART_CTRL_TXORIRQEN_Msk ( 0x01ul << CMSDK_UART_CTRL_TXORIRQEN_Pos ) /* CMSDK_UART CTRL: TXORIRQEN Mask */ -#define CMSDK_UART_CTRL_RXIRQEN_Pos 3 /* CMSDK_UART CTRL: RXIRQEN Position */ -#define CMSDK_UART_CTRL_RXIRQEN_Msk (0x01ul << CMSDK_UART_CTRL_RXIRQEN_Pos) /* CMSDK_UART CTRL: RXIRQEN Mask */ + #define CMSDK_UART_CTRL_RXIRQEN_Pos 3 /* CMSDK_UART CTRL: RXIRQEN Position */ + #define CMSDK_UART_CTRL_RXIRQEN_Msk ( 0x01ul << CMSDK_UART_CTRL_RXIRQEN_Pos ) /* CMSDK_UART CTRL: RXIRQEN Mask */ -#define CMSDK_UART_CTRL_TXIRQEN_Pos 2 /* CMSDK_UART CTRL: TXIRQEN Position */ -#define CMSDK_UART_CTRL_TXIRQEN_Msk (0x01ul << CMSDK_UART_CTRL_TXIRQEN_Pos) /* CMSDK_UART CTRL: TXIRQEN Mask */ + #define CMSDK_UART_CTRL_TXIRQEN_Pos 2 /* CMSDK_UART CTRL: TXIRQEN Position */ + #define CMSDK_UART_CTRL_TXIRQEN_Msk ( 0x01ul << CMSDK_UART_CTRL_TXIRQEN_Pos ) /* CMSDK_UART CTRL: TXIRQEN Mask */ -#define CMSDK_UART_CTRL_RXEN_Pos 1 /* CMSDK_UART CTRL: RXEN Position */ -#define CMSDK_UART_CTRL_RXEN_Msk (0x01ul << CMSDK_UART_CTRL_RXEN_Pos) /* CMSDK_UART CTRL: RXEN Mask */ + #define CMSDK_UART_CTRL_RXEN_Pos 1 /* CMSDK_UART CTRL: RXEN Position */ + #define CMSDK_UART_CTRL_RXEN_Msk ( 0x01ul << CMSDK_UART_CTRL_RXEN_Pos ) /* CMSDK_UART CTRL: RXEN Mask */ -#define CMSDK_UART_CTRL_TXEN_Pos 0 /* CMSDK_UART CTRL: TXEN Position */ -#define CMSDK_UART_CTRL_TXEN_Msk (0x01ul << CMSDK_UART_CTRL_TXEN_Pos) /* CMSDK_UART CTRL: TXEN Mask */ + #define CMSDK_UART_CTRL_TXEN_Pos 0 /* CMSDK_UART CTRL: TXEN Position */ + #define CMSDK_UART_CTRL_TXEN_Msk ( 0x01ul << CMSDK_UART_CTRL_TXEN_Pos ) /* CMSDK_UART CTRL: TXEN Mask */ -#define CMSDK_UART_INTSTATUS_RXORIRQ_Pos 3 /* CMSDK_UART CTRL: RXORIRQ Position */ -#define CMSDK_UART_CTRL_RXORIRQ_Msk (0x01ul << CMSDK_UART_INTSTATUS_RXORIRQ_Pos) /* CMSDK_UART CTRL: RXORIRQ Mask */ + #define CMSDK_UART_INTSTATUS_RXORIRQ_Pos 3 /* CMSDK_UART CTRL: RXORIRQ Position */ + #define CMSDK_UART_CTRL_RXORIRQ_Msk ( 0x01ul << CMSDK_UART_INTSTATUS_RXORIRQ_Pos ) /* CMSDK_UART CTRL: RXORIRQ Mask */ -#define CMSDK_UART_CTRL_TXORIRQ_Pos 2 /* CMSDK_UART CTRL: TXORIRQ Position */ -#define CMSDK_UART_CTRL_TXORIRQ_Msk (0x01ul << CMSDK_UART_CTRL_TXORIRQ_Pos) /* CMSDK_UART CTRL: TXORIRQ Mask */ + #define CMSDK_UART_CTRL_TXORIRQ_Pos 2 /* CMSDK_UART CTRL: TXORIRQ Position */ + #define CMSDK_UART_CTRL_TXORIRQ_Msk ( 0x01ul << CMSDK_UART_CTRL_TXORIRQ_Pos ) /* CMSDK_UART CTRL: TXORIRQ Mask */ -#define CMSDK_UART_CTRL_RXIRQ_Pos 1 /* CMSDK_UART CTRL: RXIRQ Position */ -#define CMSDK_UART_CTRL_RXIRQ_Msk (0x01ul << CMSDK_UART_CTRL_RXIRQ_Pos) /* CMSDK_UART CTRL: RXIRQ Mask */ + #define CMSDK_UART_CTRL_RXIRQ_Pos 1 /* CMSDK_UART CTRL: RXIRQ Position */ + #define CMSDK_UART_CTRL_RXIRQ_Msk ( 0x01ul << CMSDK_UART_CTRL_RXIRQ_Pos ) /* CMSDK_UART CTRL: RXIRQ Mask */ -#define CMSDK_UART_CTRL_TXIRQ_Pos 0 /* CMSDK_UART CTRL: TXIRQ Position */ -#define CMSDK_UART_CTRL_TXIRQ_Msk (0x01ul << CMSDK_UART_CTRL_TXIRQ_Pos) /* CMSDK_UART CTRL: TXIRQ Mask */ + #define CMSDK_UART_CTRL_TXIRQ_Pos 0 /* CMSDK_UART CTRL: TXIRQ Position */ + #define CMSDK_UART_CTRL_TXIRQ_Msk ( 0x01ul << CMSDK_UART_CTRL_TXIRQ_Pos ) /* CMSDK_UART CTRL: TXIRQ Mask */ -#define CMSDK_UART_BAUDDIV_Pos 0 /* CMSDK_UART BAUDDIV: BAUDDIV Position */ -#define CMSDK_UART_BAUDDIV_Msk (0xFFFFFul << CMSDK_UART_BAUDDIV_Pos) /* CMSDK_UART BAUDDIV: BAUDDIV Mask */ + #define CMSDK_UART_BAUDDIV_Pos 0 /* CMSDK_UART BAUDDIV: BAUDDIV Position */ + #define CMSDK_UART_BAUDDIV_Msk ( 0xFFFFFul << CMSDK_UART_BAUDDIV_Pos ) /* CMSDK_UART BAUDDIV: BAUDDIV Mask */ /*----------------------------- Timer (TIMER) -------------------------------*/ -typedef struct -{ - __IO uint32_t CTRL; /* Offset: 0x000 (R/W) Control Register */ - __IO uint32_t VALUE; /* Offset: 0x004 (R/W) Current Value Register */ - __IO uint32_t RELOAD; /* Offset: 0x008 (R/W) Reload Value Register */ - union { - __I uint32_t INTSTATUS; /* Offset: 0x00C (R/ ) Interrupt Status Register */ - __O uint32_t INTCLEAR; /* Offset: 0x00C ( /W) Interrupt Clear Register */ - }; - -} CMSDK_TIMER_TypeDef; + typedef struct + { + __IO uint32_t CTRL; /* Offset: 0x000 (R/W) Control Register */ + __IO uint32_t VALUE; /* Offset: 0x004 (R/W) Current Value Register */ + __IO uint32_t RELOAD; /* Offset: 0x008 (R/W) Reload Value Register */ + union + { + __I uint32_t INTSTATUS; /* Offset: 0x00C (R/ ) Interrupt Status Register */ + __O uint32_t INTCLEAR; /* Offset: 0x00C ( /W) Interrupt Clear Register */ + }; + } CMSDK_TIMER_TypeDef; /* CMSDK_TIMER CTRL Register Definitions */ -#define CMSDK_TIMER_CTRL_IRQEN_Pos 3 /* CMSDK_TIMER CTRL: IRQEN Position */ -#define CMSDK_TIMER_CTRL_IRQEN_Msk (0x01ul << CMSDK_TIMER_CTRL_IRQEN_Pos) /* CMSDK_TIMER CTRL: IRQEN Mask */ + #define CMSDK_TIMER_CTRL_IRQEN_Pos 3 /* CMSDK_TIMER CTRL: IRQEN Position */ + #define CMSDK_TIMER_CTRL_IRQEN_Msk ( 0x01ul << CMSDK_TIMER_CTRL_IRQEN_Pos ) /* CMSDK_TIMER CTRL: IRQEN Mask */ -#define CMSDK_TIMER_CTRL_SELEXTCLK_Pos 2 /* CMSDK_TIMER CTRL: SELEXTCLK Position */ -#define CMSDK_TIMER_CTRL_SELEXTCLK_Msk (0x01ul << CMSDK_TIMER_CTRL_SELEXTCLK_Pos) /* CMSDK_TIMER CTRL: SELEXTCLK Mask */ + #define CMSDK_TIMER_CTRL_SELEXTCLK_Pos 2 /* CMSDK_TIMER CTRL: SELEXTCLK Position */ + #define CMSDK_TIMER_CTRL_SELEXTCLK_Msk ( 0x01ul << CMSDK_TIMER_CTRL_SELEXTCLK_Pos ) /* CMSDK_TIMER CTRL: SELEXTCLK Mask */ -#define CMSDK_TIMER_CTRL_SELEXTEN_Pos 1 /* CMSDK_TIMER CTRL: SELEXTEN Position */ -#define CMSDK_TIMER_CTRL_SELEXTEN_Msk (0x01ul << CMSDK_TIMER_CTRL_SELEXTEN_Pos) /* CMSDK_TIMER CTRL: SELEXTEN Mask */ + #define CMSDK_TIMER_CTRL_SELEXTEN_Pos 1 /* CMSDK_TIMER CTRL: SELEXTEN Position */ + #define CMSDK_TIMER_CTRL_SELEXTEN_Msk ( 0x01ul << CMSDK_TIMER_CTRL_SELEXTEN_Pos ) /* CMSDK_TIMER CTRL: SELEXTEN Mask */ -#define CMSDK_TIMER_CTRL_EN_Pos 0 /* CMSDK_TIMER CTRL: EN Position */ -#define CMSDK_TIMER_CTRL_EN_Msk (0x01ul << CMSDK_TIMER_CTRL_EN_Pos) /* CMSDK_TIMER CTRL: EN Mask */ + #define CMSDK_TIMER_CTRL_EN_Pos 0 /* CMSDK_TIMER CTRL: EN Position */ + #define CMSDK_TIMER_CTRL_EN_Msk ( 0x01ul << CMSDK_TIMER_CTRL_EN_Pos ) /* CMSDK_TIMER CTRL: EN Mask */ -#define CMSDK_TIMER_VAL_CURRENT_Pos 0 /* CMSDK_TIMER VALUE: CURRENT Position */ -#define CMSDK_TIMER_VAL_CURRENT_Msk (0xFFFFFFFFul << CMSDK_TIMER_VAL_CURRENT_Pos) /* CMSDK_TIMER VALUE: CURRENT Mask */ + #define CMSDK_TIMER_VAL_CURRENT_Pos 0 /* CMSDK_TIMER VALUE: CURRENT Position */ + #define CMSDK_TIMER_VAL_CURRENT_Msk ( 0xFFFFFFFFul << CMSDK_TIMER_VAL_CURRENT_Pos ) /* CMSDK_TIMER VALUE: CURRENT Mask */ -#define CMSDK_TIMER_RELOAD_VAL_Pos 0 /* CMSDK_TIMER RELOAD: RELOAD Position */ -#define CMSDK_TIMER_RELOAD_VAL_Msk (0xFFFFFFFFul << CMSDK_TIMER_RELOAD_VAL_Pos) /* CMSDK_TIMER RELOAD: RELOAD Mask */ + #define CMSDK_TIMER_RELOAD_VAL_Pos 0 /* CMSDK_TIMER RELOAD: RELOAD Position */ + #define CMSDK_TIMER_RELOAD_VAL_Msk ( 0xFFFFFFFFul << CMSDK_TIMER_RELOAD_VAL_Pos ) /* CMSDK_TIMER RELOAD: RELOAD Mask */ -#define CMSDK_TIMER_INTSTATUS_Pos 0 /* CMSDK_TIMER INTSTATUS: INTSTATUSPosition */ -#define CMSDK_TIMER_INTSTATUS_Msk (0x01ul << CMSDK_TIMER_INTSTATUS_Pos) /* CMSDK_TIMER INTSTATUS: INTSTATUSMask */ + #define CMSDK_TIMER_INTSTATUS_Pos 0 /* CMSDK_TIMER INTSTATUS: INTSTATUSPosition */ + #define CMSDK_TIMER_INTSTATUS_Msk ( 0x01ul << CMSDK_TIMER_INTSTATUS_Pos ) /* CMSDK_TIMER INTSTATUS: INTSTATUSMask */ -#define CMSDK_TIMER_INTCLEAR_Pos 0 /* CMSDK_TIMER INTCLEAR: INTCLEAR Position */ -#define CMSDK_TIMER_INTCLEAR_Msk (0x01ul << CMSDK_TIMER_INTCLEAR_Pos) /* CMSDK_TIMER INTCLEAR: INTCLEAR Mask */ + #define CMSDK_TIMER_INTCLEAR_Pos 0 /* CMSDK_TIMER INTCLEAR: INTCLEAR Position */ + #define CMSDK_TIMER_INTCLEAR_Msk ( 0x01ul << CMSDK_TIMER_INTCLEAR_Pos ) /* CMSDK_TIMER INTCLEAR: INTCLEAR Mask */ /*------------- Timer (TIM) --------------------------------------------------*/ -typedef struct -{ - __IO uint32_t Timer1Load; /* Offset: 0x000 (R/W) Timer 1 Load */ - __I uint32_t Timer1Value; /* Offset: 0x004 (R/ ) Timer 1 Counter Current Value */ - __IO uint32_t Timer1Control; /* Offset: 0x008 (R/W) Timer 1 Control */ - __O uint32_t Timer1IntClr; /* Offset: 0x00C ( /W) Timer 1 Interrupt Clear */ - __I uint32_t Timer1RIS; /* Offset: 0x010 (R/ ) Timer 1 Raw Interrupt Status */ - __I uint32_t Timer1MIS; /* Offset: 0x014 (R/ ) Timer 1 Masked Interrupt Status */ - __IO uint32_t Timer1BGLoad; /* Offset: 0x018 (R/W) Background Load Register */ - uint32_t RESERVED0; - __IO uint32_t Timer2Load; /* Offset: 0x020 (R/W) Timer 2 Load */ - __I uint32_t Timer2Value; /* Offset: 0x024 (R/ ) Timer 2 Counter Current Value */ - __IO uint32_t Timer2Control; /* Offset: 0x028 (R/W) Timer 2 Control */ - __O uint32_t Timer2IntClr; /* Offset: 0x02C ( /W) Timer 2 Interrupt Clear */ - __I uint32_t Timer2RIS; /* Offset: 0x030 (R/ ) Timer 2 Raw Interrupt Status */ - __I uint32_t Timer2MIS; /* Offset: 0x034 (R/ ) Timer 2 Masked Interrupt Status */ - __IO uint32_t Timer2BGLoad; /* Offset: 0x038 (R/W) Background Load Register */ - uint32_t RESERVED1[945]; - __IO uint32_t ITCR; /* Offset: 0xF00 (R/W) Integration Test Control Register */ - __O uint32_t ITOP; /* Offset: 0xF04 ( /W) Integration Test Output Set Register */ -} CMSDK_DUALTIMER_BOTH_TypeDef; + typedef struct + { + __IO uint32_t Timer1Load; /* Offset: 0x000 (R/W) Timer 1 Load */ + __I uint32_t Timer1Value; /* Offset: 0x004 (R/ ) Timer 1 Counter Current Value */ + __IO uint32_t Timer1Control; /* Offset: 0x008 (R/W) Timer 1 Control */ + __O uint32_t Timer1IntClr; /* Offset: 0x00C ( /W) Timer 1 Interrupt Clear */ + __I uint32_t Timer1RIS; /* Offset: 0x010 (R/ ) Timer 1 Raw Interrupt Status */ + __I uint32_t Timer1MIS; /* Offset: 0x014 (R/ ) Timer 1 Masked Interrupt Status */ + __IO uint32_t Timer1BGLoad; /* Offset: 0x018 (R/W) Background Load Register */ + uint32_t RESERVED0; + __IO uint32_t Timer2Load; /* Offset: 0x020 (R/W) Timer 2 Load */ + __I uint32_t Timer2Value; /* Offset: 0x024 (R/ ) Timer 2 Counter Current Value */ + __IO uint32_t Timer2Control; /* Offset: 0x028 (R/W) Timer 2 Control */ + __O uint32_t Timer2IntClr; /* Offset: 0x02C ( /W) Timer 2 Interrupt Clear */ + __I uint32_t Timer2RIS; /* Offset: 0x030 (R/ ) Timer 2 Raw Interrupt Status */ + __I uint32_t Timer2MIS; /* Offset: 0x034 (R/ ) Timer 2 Masked Interrupt Status */ + __IO uint32_t Timer2BGLoad; /* Offset: 0x038 (R/W) Background Load Register */ + uint32_t RESERVED1[ 945 ]; + __IO uint32_t ITCR; /* Offset: 0xF00 (R/W) Integration Test Control Register */ + __O uint32_t ITOP; /* Offset: 0xF04 ( /W) Integration Test Output Set Register */ + } CMSDK_DUALTIMER_BOTH_TypeDef; -#define CMSDK_DUALTIMER1_LOAD_Pos 0 /* CMSDK_DUALTIMER1 LOAD: LOAD Position */ -#define CMSDK_DUALTIMER1_LOAD_Msk (0xFFFFFFFFul << CMSDK_DUALTIMER1_LOAD_Pos) /* CMSDK_DUALTIMER1 LOAD: LOAD Mask */ + #define CMSDK_DUALTIMER1_LOAD_Pos 0 /* CMSDK_DUALTIMER1 LOAD: LOAD Position */ + #define CMSDK_DUALTIMER1_LOAD_Msk ( 0xFFFFFFFFul << CMSDK_DUALTIMER1_LOAD_Pos ) /* CMSDK_DUALTIMER1 LOAD: LOAD Mask */ -#define CMSDK_DUALTIMER1_VALUE_Pos 0 /* CMSDK_DUALTIMER1 VALUE: VALUE Position */ -#define CMSDK_DUALTIMER1_VALUE_Msk (0xFFFFFFFFul << CMSDK_DUALTIMER1_VALUE_Pos) /* CMSDK_DUALTIMER1 VALUE: VALUE Mask */ + #define CMSDK_DUALTIMER1_VALUE_Pos 0 /* CMSDK_DUALTIMER1 VALUE: VALUE Position */ + #define CMSDK_DUALTIMER1_VALUE_Msk ( 0xFFFFFFFFul << CMSDK_DUALTIMER1_VALUE_Pos ) /* CMSDK_DUALTIMER1 VALUE: VALUE Mask */ -#define CMSDK_DUALTIMER1_CTRL_EN_Pos 7 /* CMSDK_DUALTIMER1 CTRL_EN: CTRL Enable Position */ -#define CMSDK_DUALTIMER1_CTRL_EN_Msk (0x1ul << CMSDK_DUALTIMER1_CTRL_EN_Pos) /* CMSDK_DUALTIMER1 CTRL_EN: CTRL Enable Mask */ + #define CMSDK_DUALTIMER1_CTRL_EN_Pos 7 /* CMSDK_DUALTIMER1 CTRL_EN: CTRL Enable Position */ + #define CMSDK_DUALTIMER1_CTRL_EN_Msk ( 0x1ul << CMSDK_DUALTIMER1_CTRL_EN_Pos ) /* CMSDK_DUALTIMER1 CTRL_EN: CTRL Enable Mask */ -#define CMSDK_DUALTIMER1_CTRL_MODE_Pos 6 /* CMSDK_DUALTIMER1 CTRL_MODE: CTRL MODE Position */ -#define CMSDK_DUALTIMER1_CTRL_MODE_Msk (0x1ul << CMSDK_DUALTIMER1_CTRL_MODE_Pos) /* CMSDK_DUALTIMER1 CTRL_MODE: CTRL MODE Mask */ + #define CMSDK_DUALTIMER1_CTRL_MODE_Pos 6 /* CMSDK_DUALTIMER1 CTRL_MODE: CTRL MODE Position */ + #define CMSDK_DUALTIMER1_CTRL_MODE_Msk ( 0x1ul << CMSDK_DUALTIMER1_CTRL_MODE_Pos ) /* CMSDK_DUALTIMER1 CTRL_MODE: CTRL MODE Mask */ -#define CMSDK_DUALTIMER1_CTRL_INTEN_Pos 5 /* CMSDK_DUALTIMER1 CTRL_INTEN: CTRL Int Enable Position */ -#define CMSDK_DUALTIMER1_CTRL_INTEN_Msk (0x1ul << CMSDK_DUALTIMER1_CTRL_INTEN_Pos) /* CMSDK_DUALTIMER1 CTRL_INTEN: CTRL Int Enable Mask */ + #define CMSDK_DUALTIMER1_CTRL_INTEN_Pos 5 /* CMSDK_DUALTIMER1 CTRL_INTEN: CTRL Int Enable Position */ + #define CMSDK_DUALTIMER1_CTRL_INTEN_Msk ( 0x1ul << CMSDK_DUALTIMER1_CTRL_INTEN_Pos ) /* CMSDK_DUALTIMER1 CTRL_INTEN: CTRL Int Enable Mask */ -#define CMSDK_DUALTIMER1_CTRL_PRESCALE_Pos 2 /* CMSDK_DUALTIMER1 CTRL_PRESCALE: CTRL PRESCALE Position */ -#define CMSDK_DUALTIMER1_CTRL_PRESCALE_Msk (0x3ul << CMSDK_DUALTIMER1_CTRL_PRESCALE_Pos) /* CMSDK_DUALTIMER1 CTRL_PRESCALE: CTRL PRESCALE Mask */ + #define CMSDK_DUALTIMER1_CTRL_PRESCALE_Pos 2 /* CMSDK_DUALTIMER1 CTRL_PRESCALE: CTRL PRESCALE Position */ + #define CMSDK_DUALTIMER1_CTRL_PRESCALE_Msk ( 0x3ul << CMSDK_DUALTIMER1_CTRL_PRESCALE_Pos ) /* CMSDK_DUALTIMER1 CTRL_PRESCALE: CTRL PRESCALE Mask */ -#define CMSDK_DUALTIMER1_CTRL_SIZE_Pos 1 /* CMSDK_DUALTIMER1 CTRL_SIZE: CTRL SIZE Position */ -#define CMSDK_DUALTIMER1_CTRL_SIZE_Msk (0x1ul << CMSDK_DUALTIMER1_CTRL_SIZE_Pos) /* CMSDK_DUALTIMER1 CTRL_SIZE: CTRL SIZE Mask */ + #define CMSDK_DUALTIMER1_CTRL_SIZE_Pos 1 /* CMSDK_DUALTIMER1 CTRL_SIZE: CTRL SIZE Position */ + #define CMSDK_DUALTIMER1_CTRL_SIZE_Msk ( 0x1ul << CMSDK_DUALTIMER1_CTRL_SIZE_Pos ) /* CMSDK_DUALTIMER1 CTRL_SIZE: CTRL SIZE Mask */ -#define CMSDK_DUALTIMER1_CTRL_ONESHOOT_Pos 0 /* CMSDK_DUALTIMER1 CTRL_ONESHOOT: CTRL ONESHOOT Position */ -#define CMSDK_DUALTIMER1_CTRL_ONESHOOT_Msk (0x1ul << CMSDK_DUALTIMER1_CTRL_ONESHOOT_Pos) /* CMSDK_DUALTIMER1 CTRL_ONESHOOT: CTRL ONESHOOT Mask */ + #define CMSDK_DUALTIMER1_CTRL_ONESHOOT_Pos 0 /* CMSDK_DUALTIMER1 CTRL_ONESHOOT: CTRL ONESHOOT Position */ + #define CMSDK_DUALTIMER1_CTRL_ONESHOOT_Msk ( 0x1ul << CMSDK_DUALTIMER1_CTRL_ONESHOOT_Pos ) /* CMSDK_DUALTIMER1 CTRL_ONESHOOT: CTRL ONESHOOT Mask */ -#define CMSDK_DUALTIMER1_INTCLR_Pos 0 /* CMSDK_DUALTIMER1 INTCLR: INT Clear Position */ -#define CMSDK_DUALTIMER1_INTCLR_Msk (0x1ul << CMSDK_DUALTIMER1_INTCLR_Pos) /* CMSDK_DUALTIMER1 INTCLR: INT Clear Mask */ + #define CMSDK_DUALTIMER1_INTCLR_Pos 0 /* CMSDK_DUALTIMER1 INTCLR: INT Clear Position */ + #define CMSDK_DUALTIMER1_INTCLR_Msk ( 0x1ul << CMSDK_DUALTIMER1_INTCLR_Pos ) /* CMSDK_DUALTIMER1 INTCLR: INT Clear Mask */ -#define CMSDK_DUALTIMER1_RAWINTSTAT_Pos 0 /* CMSDK_DUALTIMER1 RAWINTSTAT: Raw Int Status Position */ -#define CMSDK_DUALTIMER1_RAWINTSTAT_Msk (0x1ul << CMSDK_DUALTIMER1_RAWINTSTAT_Pos) /* CMSDK_DUALTIMER1 RAWINTSTAT: Raw Int Status Mask */ + #define CMSDK_DUALTIMER1_RAWINTSTAT_Pos 0 /* CMSDK_DUALTIMER1 RAWINTSTAT: Raw Int Status Position */ + #define CMSDK_DUALTIMER1_RAWINTSTAT_Msk ( 0x1ul << CMSDK_DUALTIMER1_RAWINTSTAT_Pos ) /* CMSDK_DUALTIMER1 RAWINTSTAT: Raw Int Status Mask */ -#define CMSDK_DUALTIMER1_MASKINTSTAT_Pos 0 /* CMSDK_DUALTIMER1 MASKINTSTAT: Mask Int Status Position */ -#define CMSDK_DUALTIMER1_MASKINTSTAT_Msk (0x1ul << CMSDK_DUALTIMER1_MASKINTSTAT_Pos) /* CMSDK_DUALTIMER1 MASKINTSTAT: Mask Int Status Mask */ + #define CMSDK_DUALTIMER1_MASKINTSTAT_Pos 0 /* CMSDK_DUALTIMER1 MASKINTSTAT: Mask Int Status Position */ + #define CMSDK_DUALTIMER1_MASKINTSTAT_Msk ( 0x1ul << CMSDK_DUALTIMER1_MASKINTSTAT_Pos ) /* CMSDK_DUALTIMER1 MASKINTSTAT: Mask Int Status Mask */ -#define CMSDK_DUALTIMER1_BGLOAD_Pos 0 /* CMSDK_DUALTIMER1 BGLOAD: Background Load Position */ -#define CMSDK_DUALTIMER1_BGLOAD_Msk (0xFFFFFFFFul << CMSDK_DUALTIMER1_BGLOAD_Pos) /* CMSDK_DUALTIMER1 BGLOAD: Background Load Mask */ + #define CMSDK_DUALTIMER1_BGLOAD_Pos 0 /* CMSDK_DUALTIMER1 BGLOAD: Background Load Position */ + #define CMSDK_DUALTIMER1_BGLOAD_Msk ( 0xFFFFFFFFul << CMSDK_DUALTIMER1_BGLOAD_Pos ) /* CMSDK_DUALTIMER1 BGLOAD: Background Load Mask */ -#define CMSDK_DUALTIMER2_LOAD_Pos 0 /* CMSDK_DUALTIMER2 LOAD: LOAD Position */ -#define CMSDK_DUALTIMER2_LOAD_Msk (0xFFFFFFFFul << CMSDK_DUALTIMER2_LOAD_Pos) /* CMSDK_DUALTIMER2 LOAD: LOAD Mask */ + #define CMSDK_DUALTIMER2_LOAD_Pos 0 /* CMSDK_DUALTIMER2 LOAD: LOAD Position */ + #define CMSDK_DUALTIMER2_LOAD_Msk ( 0xFFFFFFFFul << CMSDK_DUALTIMER2_LOAD_Pos ) /* CMSDK_DUALTIMER2 LOAD: LOAD Mask */ -#define CMSDK_DUALTIMER2_VALUE_Pos 0 /* CMSDK_DUALTIMER2 VALUE: VALUE Position */ -#define CMSDK_DUALTIMER2_VALUE_Msk (0xFFFFFFFFul << CMSDK_DUALTIMER2_VALUE_Pos) /* CMSDK_DUALTIMER2 VALUE: VALUE Mask */ + #define CMSDK_DUALTIMER2_VALUE_Pos 0 /* CMSDK_DUALTIMER2 VALUE: VALUE Position */ + #define CMSDK_DUALTIMER2_VALUE_Msk ( 0xFFFFFFFFul << CMSDK_DUALTIMER2_VALUE_Pos ) /* CMSDK_DUALTIMER2 VALUE: VALUE Mask */ -#define CMSDK_DUALTIMER2_CTRL_EN_Pos 7 /* CMSDK_DUALTIMER2 CTRL_EN: CTRL Enable Position */ -#define CMSDK_DUALTIMER2_CTRL_EN_Msk (0x1ul << CMSDK_DUALTIMER2_CTRL_EN_Pos) /* CMSDK_DUALTIMER2 CTRL_EN: CTRL Enable Mask */ + #define CMSDK_DUALTIMER2_CTRL_EN_Pos 7 /* CMSDK_DUALTIMER2 CTRL_EN: CTRL Enable Position */ + #define CMSDK_DUALTIMER2_CTRL_EN_Msk ( 0x1ul << CMSDK_DUALTIMER2_CTRL_EN_Pos ) /* CMSDK_DUALTIMER2 CTRL_EN: CTRL Enable Mask */ -#define CMSDK_DUALTIMER2_CTRL_MODE_Pos 6 /* CMSDK_DUALTIMER2 CTRL_MODE: CTRL MODE Position */ -#define CMSDK_DUALTIMER2_CTRL_MODE_Msk (0x1ul << CMSDK_DUALTIMER2_CTRL_MODE_Pos) /* CMSDK_DUALTIMER2 CTRL_MODE: CTRL MODE Mask */ + #define CMSDK_DUALTIMER2_CTRL_MODE_Pos 6 /* CMSDK_DUALTIMER2 CTRL_MODE: CTRL MODE Position */ + #define CMSDK_DUALTIMER2_CTRL_MODE_Msk ( 0x1ul << CMSDK_DUALTIMER2_CTRL_MODE_Pos ) /* CMSDK_DUALTIMER2 CTRL_MODE: CTRL MODE Mask */ -#define CMSDK_DUALTIMER2_CTRL_INTEN_Pos 5 /* CMSDK_DUALTIMER2 CTRL_INTEN: CTRL Int Enable Position */ -#define CMSDK_DUALTIMER2_CTRL_INTEN_Msk (0x1ul << CMSDK_DUALTIMER2_CTRL_INTEN_Pos) /* CMSDK_DUALTIMER2 CTRL_INTEN: CTRL Int Enable Mask */ + #define CMSDK_DUALTIMER2_CTRL_INTEN_Pos 5 /* CMSDK_DUALTIMER2 CTRL_INTEN: CTRL Int Enable Position */ + #define CMSDK_DUALTIMER2_CTRL_INTEN_Msk ( 0x1ul << CMSDK_DUALTIMER2_CTRL_INTEN_Pos ) /* CMSDK_DUALTIMER2 CTRL_INTEN: CTRL Int Enable Mask */ -#define CMSDK_DUALTIMER2_CTRL_PRESCALE_Pos 2 /* CMSDK_DUALTIMER2 CTRL_PRESCALE: CTRL PRESCALE Position */ -#define CMSDK_DUALTIMER2_CTRL_PRESCALE_Msk (0x3ul << CMSDK_DUALTIMER2_CTRL_PRESCALE_Pos) /* CMSDK_DUALTIMER2 CTRL_PRESCALE: CTRL PRESCALE Mask */ + #define CMSDK_DUALTIMER2_CTRL_PRESCALE_Pos 2 /* CMSDK_DUALTIMER2 CTRL_PRESCALE: CTRL PRESCALE Position */ + #define CMSDK_DUALTIMER2_CTRL_PRESCALE_Msk ( 0x3ul << CMSDK_DUALTIMER2_CTRL_PRESCALE_Pos ) /* CMSDK_DUALTIMER2 CTRL_PRESCALE: CTRL PRESCALE Mask */ -#define CMSDK_DUALTIMER2_CTRL_SIZE_Pos 1 /* CMSDK_DUALTIMER2 CTRL_SIZE: CTRL SIZE Position */ -#define CMSDK_DUALTIMER2_CTRL_SIZE_Msk (0x1ul << CMSDK_DUALTIMER2_CTRL_SIZE_Pos) /* CMSDK_DUALTIMER2 CTRL_SIZE: CTRL SIZE Mask */ + #define CMSDK_DUALTIMER2_CTRL_SIZE_Pos 1 /* CMSDK_DUALTIMER2 CTRL_SIZE: CTRL SIZE Position */ + #define CMSDK_DUALTIMER2_CTRL_SIZE_Msk ( 0x1ul << CMSDK_DUALTIMER2_CTRL_SIZE_Pos ) /* CMSDK_DUALTIMER2 CTRL_SIZE: CTRL SIZE Mask */ -#define CMSDK_DUALTIMER2_CTRL_ONESHOOT_Pos 0 /* CMSDK_DUALTIMER2 CTRL_ONESHOOT: CTRL ONESHOOT Position */ -#define CMSDK_DUALTIMER2_CTRL_ONESHOOT_Msk (0x1ul << CMSDK_DUALTIMER2_CTRL_ONESHOOT_Pos) /* CMSDK_DUALTIMER2 CTRL_ONESHOOT: CTRL ONESHOOT Mask */ + #define CMSDK_DUALTIMER2_CTRL_ONESHOOT_Pos 0 /* CMSDK_DUALTIMER2 CTRL_ONESHOOT: CTRL ONESHOOT Position */ + #define CMSDK_DUALTIMER2_CTRL_ONESHOOT_Msk ( 0x1ul << CMSDK_DUALTIMER2_CTRL_ONESHOOT_Pos ) /* CMSDK_DUALTIMER2 CTRL_ONESHOOT: CTRL ONESHOOT Mask */ -#define CMSDK_DUALTIMER2_INTCLR_Pos 0 /* CMSDK_DUALTIMER2 INTCLR: INT Clear Position */ -#define CMSDK_DUALTIMER2_INTCLR_Msk (0x1ul << CMSDK_DUALTIMER2_INTCLR_Pos) /* CMSDK_DUALTIMER2 INTCLR: INT Clear Mask */ + #define CMSDK_DUALTIMER2_INTCLR_Pos 0 /* CMSDK_DUALTIMER2 INTCLR: INT Clear Position */ + #define CMSDK_DUALTIMER2_INTCLR_Msk ( 0x1ul << CMSDK_DUALTIMER2_INTCLR_Pos ) /* CMSDK_DUALTIMER2 INTCLR: INT Clear Mask */ -#define CMSDK_DUALTIMER2_RAWINTSTAT_Pos 0 /* CMSDK_DUALTIMER2 RAWINTSTAT: Raw Int Status Position */ -#define CMSDK_DUALTIMER2_RAWINTSTAT_Msk (0x1ul << CMSDK_DUALTIMER2_RAWINTSTAT_Pos) /* CMSDK_DUALTIMER2 RAWINTSTAT: Raw Int Status Mask */ + #define CMSDK_DUALTIMER2_RAWINTSTAT_Pos 0 /* CMSDK_DUALTIMER2 RAWINTSTAT: Raw Int Status Position */ + #define CMSDK_DUALTIMER2_RAWINTSTAT_Msk ( 0x1ul << CMSDK_DUALTIMER2_RAWINTSTAT_Pos ) /* CMSDK_DUALTIMER2 RAWINTSTAT: Raw Int Status Mask */ -#define CMSDK_DUALTIMER2_MASKINTSTAT_Pos 0 /* CMSDK_DUALTIMER2 MASKINTSTAT: Mask Int Status Position */ -#define CMSDK_DUALTIMER2_MASKINTSTAT_Msk (0x1ul << CMSDK_DUALTIMER2_MASKINTSTAT_Pos) /* CMSDK_DUALTIMER2 MASKINTSTAT: Mask Int Status Mask */ + #define CMSDK_DUALTIMER2_MASKINTSTAT_Pos 0 /* CMSDK_DUALTIMER2 MASKINTSTAT: Mask Int Status Position */ + #define CMSDK_DUALTIMER2_MASKINTSTAT_Msk ( 0x1ul << CMSDK_DUALTIMER2_MASKINTSTAT_Pos ) /* CMSDK_DUALTIMER2 MASKINTSTAT: Mask Int Status Mask */ -#define CMSDK_DUALTIMER2_BGLOAD_Pos 0 /* CMSDK_DUALTIMER2 BGLOAD: Background Load Position */ -#define CMSDK_DUALTIMER2_BGLOAD_Msk (0xFFFFFFFFul << CMSDK_DUALTIMER2_BGLOAD_Pos) /* CMSDK_DUALTIMER2 BGLOAD: Background Load Mask */ + #define CMSDK_DUALTIMER2_BGLOAD_Pos 0 /* CMSDK_DUALTIMER2 BGLOAD: Background Load Position */ + #define CMSDK_DUALTIMER2_BGLOAD_Msk ( 0xFFFFFFFFul << CMSDK_DUALTIMER2_BGLOAD_Pos ) /* CMSDK_DUALTIMER2 BGLOAD: Background Load Mask */ -typedef struct -{ - __IO uint32_t TimerLoad; /* Offset: 0x000 (R/W) Timer Load */ - __I uint32_t TimerValue; /* Offset: 0x000 (R/W) Timer Counter Current Value */ - __IO uint32_t TimerControl; /* Offset: 0x000 (R/W) Timer Control */ - __O uint32_t TimerIntClr; /* Offset: 0x000 (R/W) Timer Interrupt Clear */ - __I uint32_t TimerRIS; /* Offset: 0x000 (R/W) Timer Raw Interrupt Status */ - __I uint32_t TimerMIS; /* Offset: 0x000 (R/W) Timer Masked Interrupt Status */ - __IO uint32_t TimerBGLoad; /* Offset: 0x000 (R/W) Background Load Register */ -} CMSDK_DUALTIMER_SINGLE_TypeDef; + typedef struct + { + __IO uint32_t TimerLoad; /* Offset: 0x000 (R/W) Timer Load */ + __I uint32_t TimerValue; /* Offset: 0x000 (R/W) Timer Counter Current Value */ + __IO uint32_t TimerControl; /* Offset: 0x000 (R/W) Timer Control */ + __O uint32_t TimerIntClr; /* Offset: 0x000 (R/W) Timer Interrupt Clear */ + __I uint32_t TimerRIS; /* Offset: 0x000 (R/W) Timer Raw Interrupt Status */ + __I uint32_t TimerMIS; /* Offset: 0x000 (R/W) Timer Masked Interrupt Status */ + __IO uint32_t TimerBGLoad; /* Offset: 0x000 (R/W) Background Load Register */ + } CMSDK_DUALTIMER_SINGLE_TypeDef; -#define CMSDK_DUALTIMER_LOAD_Pos 0 /* CMSDK_DUALTIMER LOAD: LOAD Position */ -#define CMSDK_DUALTIMER_LOAD_Msk (0xFFFFFFFFul << CMSDK_DUALTIMER_LOAD_Pos) /* CMSDK_DUALTIMER LOAD: LOAD Mask */ + #define CMSDK_DUALTIMER_LOAD_Pos 0 /* CMSDK_DUALTIMER LOAD: LOAD Position */ + #define CMSDK_DUALTIMER_LOAD_Msk ( 0xFFFFFFFFul << CMSDK_DUALTIMER_LOAD_Pos ) /* CMSDK_DUALTIMER LOAD: LOAD Mask */ -#define CMSDK_DUALTIMER_VALUE_Pos 0 /* CMSDK_DUALTIMER VALUE: VALUE Position */ -#define CMSDK_DUALTIMER_VALUE_Msk (0xFFFFFFFFul << CMSDK_DUALTIMER_VALUE_Pos) /* CMSDK_DUALTIMER VALUE: VALUE Mask */ + #define CMSDK_DUALTIMER_VALUE_Pos 0 /* CMSDK_DUALTIMER VALUE: VALUE Position */ + #define CMSDK_DUALTIMER_VALUE_Msk ( 0xFFFFFFFFul << CMSDK_DUALTIMER_VALUE_Pos ) /* CMSDK_DUALTIMER VALUE: VALUE Mask */ -#define CMSDK_DUALTIMER_CTRL_EN_Pos 7 /* CMSDK_DUALTIMER CTRL_EN: CTRL Enable Position */ -#define CMSDK_DUALTIMER_CTRL_EN_Msk (0x1ul << CMSDK_DUALTIMER_CTRL_EN_Pos) /* CMSDK_DUALTIMER CTRL_EN: CTRL Enable Mask */ + #define CMSDK_DUALTIMER_CTRL_EN_Pos 7 /* CMSDK_DUALTIMER CTRL_EN: CTRL Enable Position */ + #define CMSDK_DUALTIMER_CTRL_EN_Msk ( 0x1ul << CMSDK_DUALTIMER_CTRL_EN_Pos ) /* CMSDK_DUALTIMER CTRL_EN: CTRL Enable Mask */ -#define CMSDK_DUALTIMER_CTRL_MODE_Pos 6 /* CMSDK_DUALTIMER CTRL_MODE: CTRL MODE Position */ -#define CMSDK_DUALTIMER_CTRL_MODE_Msk (0x1ul << CMSDK_DUALTIMER_CTRL_MODE_Pos) /* CMSDK_DUALTIMER CTRL_MODE: CTRL MODE Mask */ + #define CMSDK_DUALTIMER_CTRL_MODE_Pos 6 /* CMSDK_DUALTIMER CTRL_MODE: CTRL MODE Position */ + #define CMSDK_DUALTIMER_CTRL_MODE_Msk ( 0x1ul << CMSDK_DUALTIMER_CTRL_MODE_Pos ) /* CMSDK_DUALTIMER CTRL_MODE: CTRL MODE Mask */ -#define CMSDK_DUALTIMER_CTRL_INTEN_Pos 5 /* CMSDK_DUALTIMER CTRL_INTEN: CTRL Int Enable Position */ -#define CMSDK_DUALTIMER_CTRL_INTEN_Msk (0x1ul << CMSDK_DUALTIMER_CTRL_INTEN_Pos) /* CMSDK_DUALTIMER CTRL_INTEN: CTRL Int Enable Mask */ + #define CMSDK_DUALTIMER_CTRL_INTEN_Pos 5 /* CMSDK_DUALTIMER CTRL_INTEN: CTRL Int Enable Position */ + #define CMSDK_DUALTIMER_CTRL_INTEN_Msk ( 0x1ul << CMSDK_DUALTIMER_CTRL_INTEN_Pos ) /* CMSDK_DUALTIMER CTRL_INTEN: CTRL Int Enable Mask */ -#define CMSDK_DUALTIMER_CTRL_PRESCALE_Pos 2 /* CMSDK_DUALTIMER CTRL_PRESCALE: CTRL PRESCALE Position */ -#define CMSDK_DUALTIMER_CTRL_PRESCALE_Msk (0x3ul << CMSDK_DUALTIMER_CTRL_PRESCALE_Pos) /* CMSDK_DUALTIMER CTRL_PRESCALE: CTRL PRESCALE Mask */ + #define CMSDK_DUALTIMER_CTRL_PRESCALE_Pos 2 /* CMSDK_DUALTIMER CTRL_PRESCALE: CTRL PRESCALE Position */ + #define CMSDK_DUALTIMER_CTRL_PRESCALE_Msk ( 0x3ul << CMSDK_DUALTIMER_CTRL_PRESCALE_Pos ) /* CMSDK_DUALTIMER CTRL_PRESCALE: CTRL PRESCALE Mask */ -#define CMSDK_DUALTIMER_CTRL_SIZE_Pos 1 /* CMSDK_DUALTIMER CTRL_SIZE: CTRL SIZE Position */ -#define CMSDK_DUALTIMER_CTRL_SIZE_Msk (0x1ul << CMSDK_DUALTIMER_CTRL_SIZE_Pos) /* CMSDK_DUALTIMER CTRL_SIZE: CTRL SIZE Mask */ + #define CMSDK_DUALTIMER_CTRL_SIZE_Pos 1 /* CMSDK_DUALTIMER CTRL_SIZE: CTRL SIZE Position */ + #define CMSDK_DUALTIMER_CTRL_SIZE_Msk ( 0x1ul << CMSDK_DUALTIMER_CTRL_SIZE_Pos ) /* CMSDK_DUALTIMER CTRL_SIZE: CTRL SIZE Mask */ -#define CMSDK_DUALTIMER_CTRL_ONESHOOT_Pos 0 /* CMSDK_DUALTIMER CTRL_ONESHOOT: CTRL ONESHOOT Position */ -#define CMSDK_DUALTIMER_CTRL_ONESHOOT_Msk (0x1ul << CMSDK_DUALTIMER_CTRL_ONESHOOT_Pos) /* CMSDK_DUALTIMER CTRL_ONESHOOT: CTRL ONESHOOT Mask */ + #define CMSDK_DUALTIMER_CTRL_ONESHOOT_Pos 0 /* CMSDK_DUALTIMER CTRL_ONESHOOT: CTRL ONESHOOT Position */ + #define CMSDK_DUALTIMER_CTRL_ONESHOOT_Msk ( 0x1ul << CMSDK_DUALTIMER_CTRL_ONESHOOT_Pos ) /* CMSDK_DUALTIMER CTRL_ONESHOOT: CTRL ONESHOOT Mask */ -#define CMSDK_DUALTIMER_INTCLR_Pos 0 /* CMSDK_DUALTIMER INTCLR: INT Clear Position */ -#define CMSDK_DUALTIMER_INTCLR_Msk (0x1ul << CMSDK_DUALTIMER_INTCLR_Pos) /* CMSDK_DUALTIMER INTCLR: INT Clear Mask */ + #define CMSDK_DUALTIMER_INTCLR_Pos 0 /* CMSDK_DUALTIMER INTCLR: INT Clear Position */ + #define CMSDK_DUALTIMER_INTCLR_Msk ( 0x1ul << CMSDK_DUALTIMER_INTCLR_Pos ) /* CMSDK_DUALTIMER INTCLR: INT Clear Mask */ -#define CMSDK_DUALTIMER_RAWINTSTAT_Pos 0 /* CMSDK_DUALTIMER RAWINTSTAT: Raw Int Status Position */ -#define CMSDK_DUALTIMER_RAWINTSTAT_Msk (0x1ul << CMSDK_DUALTIMER_RAWINTSTAT_Pos) /* CMSDK_DUALTIMER RAWINTSTAT: Raw Int Status Mask */ + #define CMSDK_DUALTIMER_RAWINTSTAT_Pos 0 /* CMSDK_DUALTIMER RAWINTSTAT: Raw Int Status Position */ + #define CMSDK_DUALTIMER_RAWINTSTAT_Msk ( 0x1ul << CMSDK_DUALTIMER_RAWINTSTAT_Pos ) /* CMSDK_DUALTIMER RAWINTSTAT: Raw Int Status Mask */ -#define CMSDK_DUALTIMER_MASKINTSTAT_Pos 0 /* CMSDK_DUALTIMER MASKINTSTAT: Mask Int Status Position */ -#define CMSDK_DUALTIMER_MASKINTSTAT_Msk (0x1ul << CMSDK_DUALTIMER_MASKINTSTAT_Pos) /* CMSDK_DUALTIMER MASKINTSTAT: Mask Int Status Mask */ + #define CMSDK_DUALTIMER_MASKINTSTAT_Pos 0 /* CMSDK_DUALTIMER MASKINTSTAT: Mask Int Status Position */ + #define CMSDK_DUALTIMER_MASKINTSTAT_Msk ( 0x1ul << CMSDK_DUALTIMER_MASKINTSTAT_Pos ) /* CMSDK_DUALTIMER MASKINTSTAT: Mask Int Status Mask */ -#define CMSDK_DUALTIMER_BGLOAD_Pos 0 /* CMSDK_DUALTIMER BGLOAD: Background Load Position */ -#define CMSDK_DUALTIMER_BGLOAD_Msk (0xFFFFFFFFul << CMSDK_DUALTIMER_BGLOAD_Pos) /* CMSDK_DUALTIMER BGLOAD: Background Load Mask */ + #define CMSDK_DUALTIMER_BGLOAD_Pos 0 /* CMSDK_DUALTIMER BGLOAD: Background Load Position */ + #define CMSDK_DUALTIMER_BGLOAD_Msk ( 0xFFFFFFFFul << CMSDK_DUALTIMER_BGLOAD_Pos ) /* CMSDK_DUALTIMER BGLOAD: Background Load Mask */ /*-------------------- General Purpose Input Output (GPIO) -------------------*/ -typedef struct -{ - __IO uint32_t DATA; /* Offset: 0x000 (R/W) DATA Register */ - __IO uint32_t DATAOUT; /* Offset: 0x004 (R/W) Data Output Latch Register */ - uint32_t RESERVED0[2]; - __IO uint32_t OUTENABLESET; /* Offset: 0x010 (R/W) Output Enable Set Register */ - __IO uint32_t OUTENABLECLR; /* Offset: 0x014 (R/W) Output Enable Clear Register */ - __IO uint32_t ALTFUNCSET; /* Offset: 0x018 (R/W) Alternate Function Set Register */ - __IO uint32_t ALTFUNCCLR; /* Offset: 0x01C (R/W) Alternate Function Clear Register */ - __IO uint32_t INTENSET; /* Offset: 0x020 (R/W) Interrupt Enable Set Register */ - __IO uint32_t INTENCLR; /* Offset: 0x024 (R/W) Interrupt Enable Clear Register */ - __IO uint32_t INTTYPESET; /* Offset: 0x028 (R/W) Interrupt Type Set Register */ - __IO uint32_t INTTYPECLR; /* Offset: 0x02C (R/W) Interrupt Type Clear Register */ - __IO uint32_t INTPOLSET; /* Offset: 0x030 (R/W) Interrupt Polarity Set Register */ - __IO uint32_t INTPOLCLR; /* Offset: 0x034 (R/W) Interrupt Polarity Clear Register */ - union { - __I uint32_t INTSTATUS; /* Offset: 0x038 (R/ ) Interrupt Status Register */ - __O uint32_t INTCLEAR; /* Offset: 0x038 ( /W) Interrupt Clear Register */ - }; - uint32_t RESERVED1[241]; - __IO uint32_t LB_MASKED[256]; /* Offset: 0x400 - 0x7FC Lower byte Masked Access Register (R/W) */ - __IO uint32_t UB_MASKED[256]; /* Offset: 0x800 - 0xBFC Upper byte Masked Access Register (R/W) */ -} CMSDK_GPIO_TypeDef; + typedef struct + { + __IO uint32_t DATA; /* Offset: 0x000 (R/W) DATA Register */ + __IO uint32_t DATAOUT; /* Offset: 0x004 (R/W) Data Output Latch Register */ + uint32_t RESERVED0[ 2 ]; + __IO uint32_t OUTENABLESET; /* Offset: 0x010 (R/W) Output Enable Set Register */ + __IO uint32_t OUTENABLECLR; /* Offset: 0x014 (R/W) Output Enable Clear Register */ + __IO uint32_t ALTFUNCSET; /* Offset: 0x018 (R/W) Alternate Function Set Register */ + __IO uint32_t ALTFUNCCLR; /* Offset: 0x01C (R/W) Alternate Function Clear Register */ + __IO uint32_t INTENSET; /* Offset: 0x020 (R/W) Interrupt Enable Set Register */ + __IO uint32_t INTENCLR; /* Offset: 0x024 (R/W) Interrupt Enable Clear Register */ + __IO uint32_t INTTYPESET; /* Offset: 0x028 (R/W) Interrupt Type Set Register */ + __IO uint32_t INTTYPECLR; /* Offset: 0x02C (R/W) Interrupt Type Clear Register */ + __IO uint32_t INTPOLSET; /* Offset: 0x030 (R/W) Interrupt Polarity Set Register */ + __IO uint32_t INTPOLCLR; /* Offset: 0x034 (R/W) Interrupt Polarity Clear Register */ + union + { + __I uint32_t INTSTATUS; /* Offset: 0x038 (R/ ) Interrupt Status Register */ + __O uint32_t INTCLEAR; /* Offset: 0x038 ( /W) Interrupt Clear Register */ + }; + uint32_t RESERVED1[ 241 ]; + __IO uint32_t LB_MASKED[ 256 ]; /* Offset: 0x400 - 0x7FC Lower byte Masked Access Register (R/W) */ + __IO uint32_t UB_MASKED[ 256 ]; /* Offset: 0x800 - 0xBFC Upper byte Masked Access Register (R/W) */ + } CMSDK_GPIO_TypeDef; -#define CMSDK_GPIO_DATA_Pos 0 /* CMSDK_GPIO DATA: DATA Position */ -#define CMSDK_GPIO_DATA_Msk (0xFFFFul << CMSDK_GPIO_DATA_Pos) /* CMSDK_GPIO DATA: DATA Mask */ + #define CMSDK_GPIO_DATA_Pos 0 /* CMSDK_GPIO DATA: DATA Position */ + #define CMSDK_GPIO_DATA_Msk ( 0xFFFFul << CMSDK_GPIO_DATA_Pos ) /* CMSDK_GPIO DATA: DATA Mask */ -#define CMSDK_GPIO_DATAOUT_Pos 0 /* CMSDK_GPIO DATAOUT: DATAOUT Position */ -#define CMSDK_GPIO_DATAOUT_Msk (0xFFFFul << CMSDK_GPIO_DATAOUT_Pos) /* CMSDK_GPIO DATAOUT: DATAOUT Mask */ + #define CMSDK_GPIO_DATAOUT_Pos 0 /* CMSDK_GPIO DATAOUT: DATAOUT Position */ + #define CMSDK_GPIO_DATAOUT_Msk ( 0xFFFFul << CMSDK_GPIO_DATAOUT_Pos ) /* CMSDK_GPIO DATAOUT: DATAOUT Mask */ -#define CMSDK_GPIO_OUTENSET_Pos 0 /* CMSDK_GPIO OUTEN: OUTEN Position */ -#define CMSDK_GPIO_OUTENSET_Msk (0xFFFFul << CMSDK_GPIO_OUTEN_Pos) /* CMSDK_GPIO OUTEN: OUTEN Mask */ + #define CMSDK_GPIO_OUTENSET_Pos 0 /* CMSDK_GPIO OUTEN: OUTEN Position */ + #define CMSDK_GPIO_OUTENSET_Msk ( 0xFFFFul << CMSDK_GPIO_OUTEN_Pos ) /* CMSDK_GPIO OUTEN: OUTEN Mask */ -#define CMSDK_GPIO_OUTENCLR_Pos 0 /* CMSDK_GPIO OUTEN: OUTEN Position */ -#define CMSDK_GPIO_OUTENCLR_Msk (0xFFFFul << CMSDK_GPIO_OUTEN_Pos) /* CMSDK_GPIO OUTEN: OUTEN Mask */ + #define CMSDK_GPIO_OUTENCLR_Pos 0 /* CMSDK_GPIO OUTEN: OUTEN Position */ + #define CMSDK_GPIO_OUTENCLR_Msk ( 0xFFFFul << CMSDK_GPIO_OUTEN_Pos ) /* CMSDK_GPIO OUTEN: OUTEN Mask */ -#define CMSDK_GPIO_ALTFUNCSET_Pos 0 /* CMSDK_GPIO ALTFUNC: ALTFUNC Position */ -#define CMSDK_GPIO_ALTFUNCSET_Msk (0xFFFFul << CMSDK_GPIO_ALTFUNC_Pos) /* CMSDK_GPIO ALTFUNC: ALTFUNC Mask */ + #define CMSDK_GPIO_ALTFUNCSET_Pos 0 /* CMSDK_GPIO ALTFUNC: ALTFUNC Position */ + #define CMSDK_GPIO_ALTFUNCSET_Msk ( 0xFFFFul << CMSDK_GPIO_ALTFUNC_Pos ) /* CMSDK_GPIO ALTFUNC: ALTFUNC Mask */ -#define CMSDK_GPIO_ALTFUNCCLR_Pos 0 /* CMSDK_GPIO ALTFUNC: ALTFUNC Position */ -#define CMSDK_GPIO_ALTFUNCCLR_Msk (0xFFFFul << CMSDK_GPIO_ALTFUNC_Pos) /* CMSDK_GPIO ALTFUNC: ALTFUNC Mask */ + #define CMSDK_GPIO_ALTFUNCCLR_Pos 0 /* CMSDK_GPIO ALTFUNC: ALTFUNC Position */ + #define CMSDK_GPIO_ALTFUNCCLR_Msk ( 0xFFFFul << CMSDK_GPIO_ALTFUNC_Pos ) /* CMSDK_GPIO ALTFUNC: ALTFUNC Mask */ -#define CMSDK_GPIO_INTENSET_Pos 0 /* CMSDK_GPIO INTEN: INTEN Position */ -#define CMSDK_GPIO_INTENSET_Msk (0xFFFFul << CMSDK_GPIO_INTEN_Pos) /* CMSDK_GPIO INTEN: INTEN Mask */ + #define CMSDK_GPIO_INTENSET_Pos 0 /* CMSDK_GPIO INTEN: INTEN Position */ + #define CMSDK_GPIO_INTENSET_Msk ( 0xFFFFul << CMSDK_GPIO_INTEN_Pos ) /* CMSDK_GPIO INTEN: INTEN Mask */ -#define CMSDK_GPIO_INTENCLR_Pos 0 /* CMSDK_GPIO INTEN: INTEN Position */ -#define CMSDK_GPIO_INTENCLR_Msk (0xFFFFul << CMSDK_GPIO_INTEN_Pos) /* CMSDK_GPIO INTEN: INTEN Mask */ + #define CMSDK_GPIO_INTENCLR_Pos 0 /* CMSDK_GPIO INTEN: INTEN Position */ + #define CMSDK_GPIO_INTENCLR_Msk ( 0xFFFFul << CMSDK_GPIO_INTEN_Pos ) /* CMSDK_GPIO INTEN: INTEN Mask */ -#define CMSDK_GPIO_INTTYPESET_Pos 0 /* CMSDK_GPIO INTTYPE: INTTYPE Position */ -#define CMSDK_GPIO_INTTYPESET_Msk (0xFFFFul << CMSDK_GPIO_INTTYPE_Pos) /* CMSDK_GPIO INTTYPE: INTTYPE Mask */ + #define CMSDK_GPIO_INTTYPESET_Pos 0 /* CMSDK_GPIO INTTYPE: INTTYPE Position */ + #define CMSDK_GPIO_INTTYPESET_Msk ( 0xFFFFul << CMSDK_GPIO_INTTYPE_Pos ) /* CMSDK_GPIO INTTYPE: INTTYPE Mask */ -#define CMSDK_GPIO_INTTYPECLR_Pos 0 /* CMSDK_GPIO INTTYPE: INTTYPE Position */ -#define CMSDK_GPIO_INTTYPECLR_Msk (0xFFFFul << CMSDK_GPIO_INTTYPE_Pos) /* CMSDK_GPIO INTTYPE: INTTYPE Mask */ + #define CMSDK_GPIO_INTTYPECLR_Pos 0 /* CMSDK_GPIO INTTYPE: INTTYPE Position */ + #define CMSDK_GPIO_INTTYPECLR_Msk ( 0xFFFFul << CMSDK_GPIO_INTTYPE_Pos ) /* CMSDK_GPIO INTTYPE: INTTYPE Mask */ -#define CMSDK_GPIO_INTPOLSET_Pos 0 /* CMSDK_GPIO INTPOL: INTPOL Position */ -#define CMSDK_GPIO_INTPOLSET_Msk (0xFFFFul << CMSDK_GPIO_INTPOL_Pos) /* CMSDK_GPIO INTPOL: INTPOL Mask */ + #define CMSDK_GPIO_INTPOLSET_Pos 0 /* CMSDK_GPIO INTPOL: INTPOL Position */ + #define CMSDK_GPIO_INTPOLSET_Msk ( 0xFFFFul << CMSDK_GPIO_INTPOL_Pos ) /* CMSDK_GPIO INTPOL: INTPOL Mask */ -#define CMSDK_GPIO_INTPOLCLR_Pos 0 /* CMSDK_GPIO INTPOL: INTPOL Position */ -#define CMSDK_GPIO_INTPOLCLR_Msk (0xFFFFul << CMSDK_GPIO_INTPOL_Pos) /* CMSDK_GPIO INTPOL: INTPOL Mask */ + #define CMSDK_GPIO_INTPOLCLR_Pos 0 /* CMSDK_GPIO INTPOL: INTPOL Position */ + #define CMSDK_GPIO_INTPOLCLR_Msk ( 0xFFFFul << CMSDK_GPIO_INTPOL_Pos ) /* CMSDK_GPIO INTPOL: INTPOL Mask */ -#define CMSDK_GPIO_INTSTATUS_Pos 0 /* CMSDK_GPIO INTSTATUS: INTSTATUS Position */ -#define CMSDK_GPIO_INTSTATUS_Msk (0xFFul << CMSDK_GPIO_INTSTATUS_Pos) /* CMSDK_GPIO INTSTATUS: INTSTATUS Mask */ + #define CMSDK_GPIO_INTSTATUS_Pos 0 /* CMSDK_GPIO INTSTATUS: INTSTATUS Position */ + #define CMSDK_GPIO_INTSTATUS_Msk ( 0xFFul << CMSDK_GPIO_INTSTATUS_Pos ) /* CMSDK_GPIO INTSTATUS: INTSTATUS Mask */ -#define CMSDK_GPIO_INTCLEAR_Pos 0 /* CMSDK_GPIO INTCLEAR: INTCLEAR Position */ -#define CMSDK_GPIO_INTCLEAR_Msk (0xFFul << CMSDK_GPIO_INTCLEAR_Pos) /* CMSDK_GPIO INTCLEAR: INTCLEAR Mask */ + #define CMSDK_GPIO_INTCLEAR_Pos 0 /* CMSDK_GPIO INTCLEAR: INTCLEAR Position */ + #define CMSDK_GPIO_INTCLEAR_Msk ( 0xFFul << CMSDK_GPIO_INTCLEAR_Pos ) /* CMSDK_GPIO INTCLEAR: INTCLEAR Mask */ -#define CMSDK_GPIO_MASKLOWBYTE_Pos 0 /* CMSDK_GPIO MASKLOWBYTE: MASKLOWBYTE Position */ -#define CMSDK_GPIO_MASKLOWBYTE_Msk (0x00FFul << CMSDK_GPIO_MASKLOWBYTE_Pos) /* CMSDK_GPIO MASKLOWBYTE: MASKLOWBYTE Mask */ + #define CMSDK_GPIO_MASKLOWBYTE_Pos 0 /* CMSDK_GPIO MASKLOWBYTE: MASKLOWBYTE Position */ + #define CMSDK_GPIO_MASKLOWBYTE_Msk ( 0x00FFul << CMSDK_GPIO_MASKLOWBYTE_Pos ) /* CMSDK_GPIO MASKLOWBYTE: MASKLOWBYTE Mask */ -#define CMSDK_GPIO_MASKHIGHBYTE_Pos 0 /* CMSDK_GPIO MASKHIGHBYTE: MASKHIGHBYTE Position */ -#define CMSDK_GPIO_MASKHIGHBYTE_Msk (0xFF00ul << CMSDK_GPIO_MASKHIGHBYTE_Pos) /* CMSDK_GPIO MASKHIGHBYTE: MASKHIGHBYTE Mask */ + #define CMSDK_GPIO_MASKHIGHBYTE_Pos 0 /* CMSDK_GPIO MASKHIGHBYTE: MASKHIGHBYTE Position */ + #define CMSDK_GPIO_MASKHIGHBYTE_Msk ( 0xFF00ul << CMSDK_GPIO_MASKHIGHBYTE_Pos ) /* CMSDK_GPIO MASKHIGHBYTE: MASKHIGHBYTE Mask */ /*------------- System Control (SYSCON) --------------------------------------*/ -typedef struct -{ - __IO uint32_t REMAP; /* Offset: 0x000 (R/W) Remap Control Register */ - __IO uint32_t PMUCTRL; /* Offset: 0x004 (R/W) PMU Control Register */ - __IO uint32_t RESETOP; /* Offset: 0x008 (R/W) Reset Option Register */ - __IO uint32_t EMICTRL; /* Offset: 0x00C (R/W) EMI Control Register */ - __IO uint32_t RSTINFO; /* Offset: 0x010 (R/W) Reset Information Register */ -} CMSDK_SYSCON_TypeDef; + typedef struct + { + __IO uint32_t REMAP; /* Offset: 0x000 (R/W) Remap Control Register */ + __IO uint32_t PMUCTRL; /* Offset: 0x004 (R/W) PMU Control Register */ + __IO uint32_t RESETOP; /* Offset: 0x008 (R/W) Reset Option Register */ + __IO uint32_t EMICTRL; /* Offset: 0x00C (R/W) EMI Control Register */ + __IO uint32_t RSTINFO; /* Offset: 0x010 (R/W) Reset Information Register */ + } CMSDK_SYSCON_TypeDef; -#define CMSDK_SYSCON_REMAP_Pos 0 -#define CMSDK_SYSCON_REMAP_Msk (0x01ul << CMSDK_SYSCON_REMAP_Pos) /* CMSDK_SYSCON MEME_CTRL: REMAP Mask */ + #define CMSDK_SYSCON_REMAP_Pos 0 + #define CMSDK_SYSCON_REMAP_Msk ( 0x01ul << CMSDK_SYSCON_REMAP_Pos ) /* CMSDK_SYSCON MEME_CTRL: REMAP Mask */ -#define CMSDK_SYSCON_PMUCTRL_EN_Pos 0 -#define CMSDK_SYSCON_PMUCTRL_EN_Msk (0x01ul << CMSDK_SYSCON_PMUCTRL_EN_Pos) /* CMSDK_SYSCON PMUCTRL: PMUCTRL ENABLE Mask */ + #define CMSDK_SYSCON_PMUCTRL_EN_Pos 0 + #define CMSDK_SYSCON_PMUCTRL_EN_Msk ( 0x01ul << CMSDK_SYSCON_PMUCTRL_EN_Pos ) /* CMSDK_SYSCON PMUCTRL: PMUCTRL ENABLE Mask */ -#define CMSDK_SYSCON_LOCKUPRST_RESETOP_Pos 0 -#define CMSDK_SYSCON_LOCKUPRST_RESETOP_Msk (0x01ul << CMSDK_SYSCON_LOCKUPRST_RESETOP_Pos) /* CMSDK_SYSCON SYS_CTRL: LOCKUP RESET ENABLE Mask */ + #define CMSDK_SYSCON_LOCKUPRST_RESETOP_Pos 0 + #define CMSDK_SYSCON_LOCKUPRST_RESETOP_Msk ( 0x01ul << CMSDK_SYSCON_LOCKUPRST_RESETOP_Pos ) /* CMSDK_SYSCON SYS_CTRL: LOCKUP RESET ENABLE Mask */ -#define CMSDK_SYSCON_EMICTRL_SIZE_Pos 24 -#define CMSDK_SYSCON_EMICTRL_SIZE_Msk (0x00001ul << CMSDK_SYSCON_EMICTRL_SIZE_Pos) /* CMSDK_SYSCON EMICTRL: SIZE Mask */ + #define CMSDK_SYSCON_EMICTRL_SIZE_Pos 24 + #define CMSDK_SYSCON_EMICTRL_SIZE_Msk ( 0x00001ul << CMSDK_SYSCON_EMICTRL_SIZE_Pos ) /* CMSDK_SYSCON EMICTRL: SIZE Mask */ -#define CMSDK_SYSCON_EMICTRL_TACYC_Pos 16 -#define CMSDK_SYSCON_EMICTRL_TACYC_Msk (0x00007ul << CMSDK_SYSCON_EMICTRL_TACYC_Pos) /* CMSDK_SYSCON EMICTRL: TURNAROUNDCYCLE Mask */ + #define CMSDK_SYSCON_EMICTRL_TACYC_Pos 16 + #define CMSDK_SYSCON_EMICTRL_TACYC_Msk ( 0x00007ul << CMSDK_SYSCON_EMICTRL_TACYC_Pos ) /* CMSDK_SYSCON EMICTRL: TURNAROUNDCYCLE Mask */ -#define CMSDK_SYSCON_EMICTRL_WCYC_Pos 8 -#define CMSDK_SYSCON_EMICTRL_WCYC_Msk (0x00003ul << CMSDK_SYSCON_EMICTRL_WCYC_Pos) /* CMSDK_SYSCON EMICTRL: WRITECYCLE Mask */ + #define CMSDK_SYSCON_EMICTRL_WCYC_Pos 8 + #define CMSDK_SYSCON_EMICTRL_WCYC_Msk ( 0x00003ul << CMSDK_SYSCON_EMICTRL_WCYC_Pos ) /* CMSDK_SYSCON EMICTRL: WRITECYCLE Mask */ -#define CMSDK_SYSCON_EMICTRL_RCYC_Pos 0 -#define CMSDK_SYSCON_EMICTRL_RCYC_Msk (0x00007ul << CMSDK_SYSCON_EMICTRL_RCYC_Pos) /* CMSDK_SYSCON EMICTRL: READCYCLE Mask */ + #define CMSDK_SYSCON_EMICTRL_RCYC_Pos 0 + #define CMSDK_SYSCON_EMICTRL_RCYC_Msk ( 0x00007ul << CMSDK_SYSCON_EMICTRL_RCYC_Pos ) /* CMSDK_SYSCON EMICTRL: READCYCLE Mask */ -#define CMSDK_SYSCON_RSTINFO_SYSRESETREQ_Pos 0 -#define CMSDK_SYSCON_RSTINFO_SYSRESETREQ_Msk (0x00001ul << CMSDK_SYSCON_RSTINFO_SYSRESETREQ_Pos) /* CMSDK_SYSCON RSTINFO: SYSRESETREQ Mask */ + #define CMSDK_SYSCON_RSTINFO_SYSRESETREQ_Pos 0 + #define CMSDK_SYSCON_RSTINFO_SYSRESETREQ_Msk ( 0x00001ul << CMSDK_SYSCON_RSTINFO_SYSRESETREQ_Pos ) /* CMSDK_SYSCON RSTINFO: SYSRESETREQ Mask */ -#define CMSDK_SYSCON_RSTINFO_WDOGRESETREQ_Pos 1 -#define CMSDK_SYSCON_RSTINFO_WDOGRESETREQ_Msk (0x00001ul << CMSDK_SYSCON_RSTINFO_WDOGRESETREQ_Pos) /* CMSDK_SYSCON RSTINFO: WDOGRESETREQ Mask */ + #define CMSDK_SYSCON_RSTINFO_WDOGRESETREQ_Pos 1 + #define CMSDK_SYSCON_RSTINFO_WDOGRESETREQ_Msk ( 0x00001ul << CMSDK_SYSCON_RSTINFO_WDOGRESETREQ_Pos ) /* CMSDK_SYSCON RSTINFO: WDOGRESETREQ Mask */ -#define CMSDK_SYSCON_RSTINFO_LOCKUPRESET_Pos 2 -#define CMSDK_SYSCON_RSTINFO_LOCKUPRESET_Msk (0x00001ul << CMSDK_SYSCON_RSTINFO_LOCKUPRESET_Pos) /* CMSDK_SYSCON RSTINFO: LOCKUPRESET Mask */ + #define CMSDK_SYSCON_RSTINFO_LOCKUPRESET_Pos 2 + #define CMSDK_SYSCON_RSTINFO_LOCKUPRESET_Msk ( 0x00001ul << CMSDK_SYSCON_RSTINFO_LOCKUPRESET_Pos ) /* CMSDK_SYSCON RSTINFO: LOCKUPRESET Mask */ /*------------- PL230 uDMA (PL230) --------------------------------------*/ -typedef struct -{ - __I uint32_t DMA_STATUS; /* Offset: 0x000 (R/W) DMA status Register */ - __O uint32_t DMA_CFG; /* Offset: 0x004 ( /W) DMA configuration Register */ - __IO uint32_t CTRL_BASE_PTR; /* Offset: 0x008 (R/W) Channel Control Data Base Pointer Register */ - __I uint32_t ALT_CTRL_BASE_PTR; /* Offset: 0x00C (R/ ) Channel Alternate Control Data Base Pointer Register */ - __I uint32_t DMA_WAITONREQ_STATUS; /* Offset: 0x010 (R/ ) Channel Wait On Request Status Register */ - __O uint32_t CHNL_SW_REQUEST; /* Offset: 0x014 ( /W) Channel Software Request Register */ - __IO uint32_t CHNL_USEBURST_SET; /* Offset: 0x018 (R/W) Channel UseBurst Set Register */ - __O uint32_t CHNL_USEBURST_CLR; /* Offset: 0x01C ( /W) Channel UseBurst Clear Register */ - __IO uint32_t CHNL_REQ_MASK_SET; /* Offset: 0x020 (R/W) Channel Request Mask Set Register */ - __O uint32_t CHNL_REQ_MASK_CLR; /* Offset: 0x024 ( /W) Channel Request Mask Clear Register */ - __IO uint32_t CHNL_ENABLE_SET; /* Offset: 0x028 (R/W) Channel Enable Set Register */ - __O uint32_t CHNL_ENABLE_CLR; /* Offset: 0x02C ( /W) Channel Enable Clear Register */ - __IO uint32_t CHNL_PRI_ALT_SET; /* Offset: 0x030 (R/W) Channel Primary-Alterante Set Register */ - __O uint32_t CHNL_PRI_ALT_CLR; /* Offset: 0x034 ( /W) Channel Primary-Alterante Clear Register */ - __IO uint32_t CHNL_PRIORITY_SET; /* Offset: 0x038 (R/W) Channel Priority Set Register */ - __O uint32_t CHNL_PRIORITY_CLR; /* Offset: 0x03C ( /W) Channel Priority Clear Register */ - uint32_t RESERVED0[3]; - __IO uint32_t ERR_CLR; /* Offset: 0x04C Bus Error Clear Register (R/W) */ + typedef struct + { + __I uint32_t DMA_STATUS; /* Offset: 0x000 (R/W) DMA status Register */ + __O uint32_t DMA_CFG; /* Offset: 0x004 ( /W) DMA configuration Register */ + __IO uint32_t CTRL_BASE_PTR; /* Offset: 0x008 (R/W) Channel Control Data Base Pointer Register */ + __I uint32_t ALT_CTRL_BASE_PTR; /* Offset: 0x00C (R/ ) Channel Alternate Control Data Base Pointer Register */ + __I uint32_t DMA_WAITONREQ_STATUS; /* Offset: 0x010 (R/ ) Channel Wait On Request Status Register */ + __O uint32_t CHNL_SW_REQUEST; /* Offset: 0x014 ( /W) Channel Software Request Register */ + __IO uint32_t CHNL_USEBURST_SET; /* Offset: 0x018 (R/W) Channel UseBurst Set Register */ + __O uint32_t CHNL_USEBURST_CLR; /* Offset: 0x01C ( /W) Channel UseBurst Clear Register */ + __IO uint32_t CHNL_REQ_MASK_SET; /* Offset: 0x020 (R/W) Channel Request Mask Set Register */ + __O uint32_t CHNL_REQ_MASK_CLR; /* Offset: 0x024 ( /W) Channel Request Mask Clear Register */ + __IO uint32_t CHNL_ENABLE_SET; /* Offset: 0x028 (R/W) Channel Enable Set Register */ + __O uint32_t CHNL_ENABLE_CLR; /* Offset: 0x02C ( /W) Channel Enable Clear Register */ + __IO uint32_t CHNL_PRI_ALT_SET; /* Offset: 0x030 (R/W) Channel Primary-Alterante Set Register */ + __O uint32_t CHNL_PRI_ALT_CLR; /* Offset: 0x034 ( /W) Channel Primary-Alterante Clear Register */ + __IO uint32_t CHNL_PRIORITY_SET; /* Offset: 0x038 (R/W) Channel Priority Set Register */ + __O uint32_t CHNL_PRIORITY_CLR; /* Offset: 0x03C ( /W) Channel Priority Clear Register */ + uint32_t RESERVED0[ 3 ]; + __IO uint32_t ERR_CLR; /* Offset: 0x04C Bus Error Clear Register (R/W) */ + } CMSDK_PL230_TypeDef; -} CMSDK_PL230_TypeDef; + #define PL230_DMA_CHNL_BITS 0 -#define PL230_DMA_CHNL_BITS 0 + #define CMSDK_PL230_DMA_STATUS_MSTREN_Pos 0 /* CMSDK_PL230 DMA STATUS: MSTREN Position */ + #define CMSDK_PL230_DMA_STATUS_MSTREN_Msk ( 0x00000001ul << CMSDK_PL230_DMA_STATUS_MSTREN_Pos ) /* CMSDK_PL230 DMA STATUS: MSTREN Mask */ -#define CMSDK_PL230_DMA_STATUS_MSTREN_Pos 0 /* CMSDK_PL230 DMA STATUS: MSTREN Position */ -#define CMSDK_PL230_DMA_STATUS_MSTREN_Msk (0x00000001ul << CMSDK_PL230_DMA_STATUS_MSTREN_Pos) /* CMSDK_PL230 DMA STATUS: MSTREN Mask */ + #define CMSDK_PL230_DMA_STATUS_STATE_Pos 0 /* CMSDK_PL230 DMA STATUS: STATE Position */ + #define CMSDK_PL230_DMA_STATUS_STATE_Msk ( 0x0000000Ful << CMSDK_PL230_DMA_STATUS_STATE_Pos ) /* CMSDK_PL230 DMA STATUS: STATE Mask */ -#define CMSDK_PL230_DMA_STATUS_STATE_Pos 0 /* CMSDK_PL230 DMA STATUS: STATE Position */ -#define CMSDK_PL230_DMA_STATUS_STATE_Msk (0x0000000Ful << CMSDK_PL230_DMA_STATUS_STATE_Pos) /* CMSDK_PL230 DMA STATUS: STATE Mask */ + #define CMSDK_PL230_DMA_STATUS_CHNLS_MINUS1_Pos 0 /* CMSDK_PL230 DMA STATUS: CHNLS_MINUS1 Position */ + #define CMSDK_PL230_DMA_STATUS_CHNLS_MINUS1_Msk ( 0x0000001Ful << CMSDK_PL230_DMA_STATUS_CHNLS_MINUS1_Pos ) /* CMSDK_PL230 DMA STATUS: CHNLS_MINUS1 Mask */ -#define CMSDK_PL230_DMA_STATUS_CHNLS_MINUS1_Pos 0 /* CMSDK_PL230 DMA STATUS: CHNLS_MINUS1 Position */ -#define CMSDK_PL230_DMA_STATUS_CHNLS_MINUS1_Msk (0x0000001Ful << CMSDK_PL230_DMA_STATUS_CHNLS_MINUS1_Pos) /* CMSDK_PL230 DMA STATUS: CHNLS_MINUS1 Mask */ + #define CMSDK_PL230_DMA_STATUS_TEST_STATUS_Pos 0 /* CMSDK_PL230 DMA STATUS: TEST_STATUS Position */ + #define CMSDK_PL230_DMA_STATUS_TEST_STATUS_Msk ( 0x00000001ul << CMSDK_PL230_DMA_STATUS_TEST_STATUS_Pos ) /* CMSDK_PL230 DMA STATUS: TEST_STATUS Mask */ -#define CMSDK_PL230_DMA_STATUS_TEST_STATUS_Pos 0 /* CMSDK_PL230 DMA STATUS: TEST_STATUS Position */ -#define CMSDK_PL230_DMA_STATUS_TEST_STATUS_Msk (0x00000001ul << CMSDK_PL230_DMA_STATUS_TEST_STATUS_Pos) /* CMSDK_PL230 DMA STATUS: TEST_STATUS Mask */ + #define CMSDK_PL230_DMA_CFG_MSTREN_Pos 0 /* CMSDK_PL230 DMA CFG: MSTREN Position */ + #define CMSDK_PL230_DMA_CFG_MSTREN_Msk ( 0x00000001ul << CMSDK_PL230_DMA_CFG_MSTREN_Pos ) /* CMSDK_PL230 DMA CFG: MSTREN Mask */ -#define CMSDK_PL230_DMA_CFG_MSTREN_Pos 0 /* CMSDK_PL230 DMA CFG: MSTREN Position */ -#define CMSDK_PL230_DMA_CFG_MSTREN_Msk (0x00000001ul << CMSDK_PL230_DMA_CFG_MSTREN_Pos) /* CMSDK_PL230 DMA CFG: MSTREN Mask */ + #define CMSDK_PL230_DMA_CFG_CPCCACHE_Pos 2 /* CMSDK_PL230 DMA CFG: CPCCACHE Position */ + #define CMSDK_PL230_DMA_CFG_CPCCACHE_Msk ( 0x00000001ul << CMSDK_PL230_DMA_CFG_CPCCACHE_Pos ) /* CMSDK_PL230 DMA CFG: CPCCACHE Mask */ -#define CMSDK_PL230_DMA_CFG_CPCCACHE_Pos 2 /* CMSDK_PL230 DMA CFG: CPCCACHE Position */ -#define CMSDK_PL230_DMA_CFG_CPCCACHE_Msk (0x00000001ul << CMSDK_PL230_DMA_CFG_CPCCACHE_Pos) /* CMSDK_PL230 DMA CFG: CPCCACHE Mask */ + #define CMSDK_PL230_DMA_CFG_CPCBUF_Pos 1 /* CMSDK_PL230 DMA CFG: CPCBUF Position */ + #define CMSDK_PL230_DMA_CFG_CPCBUF_Msk ( 0x00000001ul << CMSDK_PL230_DMA_CFG_CPCBUF_Pos ) /* CMSDK_PL230 DMA CFG: CPCBUF Mask */ -#define CMSDK_PL230_DMA_CFG_CPCBUF_Pos 1 /* CMSDK_PL230 DMA CFG: CPCBUF Position */ -#define CMSDK_PL230_DMA_CFG_CPCBUF_Msk (0x00000001ul << CMSDK_PL230_DMA_CFG_CPCBUF_Pos) /* CMSDK_PL230 DMA CFG: CPCBUF Mask */ + #define CMSDK_PL230_DMA_CFG_CPCPRIV_Pos 0 /* CMSDK_PL230 DMA CFG: CPCPRIV Position */ + #define CMSDK_PL230_DMA_CFG_CPCPRIV_Msk ( 0x00000001ul << CMSDK_PL230_DMA_CFG_CPCPRIV_Pos ) /* CMSDK_PL230 DMA CFG: CPCPRIV Mask */ -#define CMSDK_PL230_DMA_CFG_CPCPRIV_Pos 0 /* CMSDK_PL230 DMA CFG: CPCPRIV Position */ -#define CMSDK_PL230_DMA_CFG_CPCPRIV_Msk (0x00000001ul << CMSDK_PL230_DMA_CFG_CPCPRIV_Pos) /* CMSDK_PL230 DMA CFG: CPCPRIV Mask */ + #define CMSDK_PL230_CTRL_BASE_PTR_Pos PL230_DMA_CHNL_BITS + 5 /* CMSDK_PL230 STATUS: BASE_PTR Position */ + #define CMSDK_PL230_CTRL_BASE_PTR_Msk ( 0x0FFFFFFFul << CMSDK_PL230_CTRL_BASE_PTR_Pos ) /* CMSDK_PL230 STATUS: BASE_PTR Mask */ -#define CMSDK_PL230_CTRL_BASE_PTR_Pos PL230_DMA_CHNL_BITS + 5 /* CMSDK_PL230 STATUS: BASE_PTR Position */ -#define CMSDK_PL230_CTRL_BASE_PTR_Msk (0x0FFFFFFFul << CMSDK_PL230_CTRL_BASE_PTR_Pos) /* CMSDK_PL230 STATUS: BASE_PTR Mask */ + #define CMSDK_PL230_ALT_CTRL_BASE_PTR_Pos 0 /* CMSDK_PL230 STATUS: MSTREN Position */ + #define CMSDK_PL230_ALT_CTRL_BASE_PTR_Msk ( 0xFFFFFFFFul << CMSDK_PL230_ALT_CTRL_BASE_PTR_Pos ) /* CMSDK_PL230 STATUS: MSTREN Mask */ -#define CMSDK_PL230_ALT_CTRL_BASE_PTR_Pos 0 /* CMSDK_PL230 STATUS: MSTREN Position */ -#define CMSDK_PL230_ALT_CTRL_BASE_PTR_Msk (0xFFFFFFFFul << CMSDK_PL230_ALT_CTRL_BASE_PTR_Pos) /* CMSDK_PL230 STATUS: MSTREN Mask */ + #define CMSDK_PL230_DMA_WAITONREQ_STATUS_Pos 0 /* CMSDK_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Position */ + #define CMSDK_PL230_DMA_WAITONREQ_STATUS_Msk ( 0xFFFFFFFFul << CMSDK_PL230_DMA_WAITONREQ_STATUS_Pos ) /* CMSDK_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Mask */ -#define CMSDK_PL230_DMA_WAITONREQ_STATUS_Pos 0 /* CMSDK_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Position */ -#define CMSDK_PL230_DMA_WAITONREQ_STATUS_Msk (0xFFFFFFFFul << CMSDK_PL230_DMA_WAITONREQ_STATUS_Pos) /* CMSDK_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Mask */ + #define CMSDK_PL230_CHNL_SW_REQUEST_Pos 0 /* CMSDK_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Position */ + #define CMSDK_PL230_CHNL_SW_REQUEST_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_SW_REQUEST_Pos ) /* CMSDK_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Mask */ -#define CMSDK_PL230_CHNL_SW_REQUEST_Pos 0 /* CMSDK_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Position */ -#define CMSDK_PL230_CHNL_SW_REQUEST_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_SW_REQUEST_Pos) /* CMSDK_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Mask */ + #define CMSDK_PL230_CHNL_USEBURST_SET_Pos 0 /* CMSDK_PL230 CHNL_USEBURST: SET Position */ + #define CMSDK_PL230_CHNL_USEBURST_SET_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_USEBURST_SET_Pos ) /* CMSDK_PL230 CHNL_USEBURST: SET Mask */ -#define CMSDK_PL230_CHNL_USEBURST_SET_Pos 0 /* CMSDK_PL230 CHNL_USEBURST: SET Position */ -#define CMSDK_PL230_CHNL_USEBURST_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_USEBURST_SET_Pos) /* CMSDK_PL230 CHNL_USEBURST: SET Mask */ + #define CMSDK_PL230_CHNL_USEBURST_CLR_Pos 0 /* CMSDK_PL230 CHNL_USEBURST: CLR Position */ + #define CMSDK_PL230_CHNL_USEBURST_CLR_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_USEBURST_CLR_Pos ) /* CMSDK_PL230 CHNL_USEBURST: CLR Mask */ -#define CMSDK_PL230_CHNL_USEBURST_CLR_Pos 0 /* CMSDK_PL230 CHNL_USEBURST: CLR Position */ -#define CMSDK_PL230_CHNL_USEBURST_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_USEBURST_CLR_Pos) /* CMSDK_PL230 CHNL_USEBURST: CLR Mask */ + #define CMSDK_PL230_CHNL_REQ_MASK_SET_Pos 0 /* CMSDK_PL230 CHNL_REQ_MASK: SET Position */ + #define CMSDK_PL230_CHNL_REQ_MASK_SET_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_REQ_MASK_SET_Pos ) /* CMSDK_PL230 CHNL_REQ_MASK: SET Mask */ -#define CMSDK_PL230_CHNL_REQ_MASK_SET_Pos 0 /* CMSDK_PL230 CHNL_REQ_MASK: SET Position */ -#define CMSDK_PL230_CHNL_REQ_MASK_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_REQ_MASK_SET_Pos) /* CMSDK_PL230 CHNL_REQ_MASK: SET Mask */ + #define CMSDK_PL230_CHNL_REQ_MASK_CLR_Pos 0 /* CMSDK_PL230 CHNL_REQ_MASK: CLR Position */ + #define CMSDK_PL230_CHNL_REQ_MASK_CLR_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_REQ_MASK_CLR_Pos ) /* CMSDK_PL230 CHNL_REQ_MASK: CLR Mask */ -#define CMSDK_PL230_CHNL_REQ_MASK_CLR_Pos 0 /* CMSDK_PL230 CHNL_REQ_MASK: CLR Position */ -#define CMSDK_PL230_CHNL_REQ_MASK_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_REQ_MASK_CLR_Pos) /* CMSDK_PL230 CHNL_REQ_MASK: CLR Mask */ + #define CMSDK_PL230_CHNL_ENABLE_SET_Pos 0 /* CMSDK_PL230 CHNL_ENABLE: SET Position */ + #define CMSDK_PL230_CHNL_ENABLE_SET_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_ENABLE_SET_Pos ) /* CMSDK_PL230 CHNL_ENABLE: SET Mask */ -#define CMSDK_PL230_CHNL_ENABLE_SET_Pos 0 /* CMSDK_PL230 CHNL_ENABLE: SET Position */ -#define CMSDK_PL230_CHNL_ENABLE_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_ENABLE_SET_Pos) /* CMSDK_PL230 CHNL_ENABLE: SET Mask */ + #define CMSDK_PL230_CHNL_ENABLE_CLR_Pos 0 /* CMSDK_PL230 CHNL_ENABLE: CLR Position */ + #define CMSDK_PL230_CHNL_ENABLE_CLR_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_ENABLE_CLR_Pos ) /* CMSDK_PL230 CHNL_ENABLE: CLR Mask */ -#define CMSDK_PL230_CHNL_ENABLE_CLR_Pos 0 /* CMSDK_PL230 CHNL_ENABLE: CLR Position */ -#define CMSDK_PL230_CHNL_ENABLE_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_ENABLE_CLR_Pos) /* CMSDK_PL230 CHNL_ENABLE: CLR Mask */ + #define CMSDK_PL230_CHNL_PRI_ALT_SET_Pos 0 /* CMSDK_PL230 CHNL_PRI_ALT: SET Position */ + #define CMSDK_PL230_CHNL_PRI_ALT_SET_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_PRI_ALT_SET_Pos ) /* CMSDK_PL230 CHNL_PRI_ALT: SET Mask */ -#define CMSDK_PL230_CHNL_PRI_ALT_SET_Pos 0 /* CMSDK_PL230 CHNL_PRI_ALT: SET Position */ -#define CMSDK_PL230_CHNL_PRI_ALT_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_PRI_ALT_SET_Pos) /* CMSDK_PL230 CHNL_PRI_ALT: SET Mask */ + #define CMSDK_PL230_CHNL_PRI_ALT_CLR_Pos 0 /* CMSDK_PL230 CHNL_PRI_ALT: CLR Position */ + #define CMSDK_PL230_CHNL_PRI_ALT_CLR_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_PRI_ALT_CLR_Pos ) /* CMSDK_PL230 CHNL_PRI_ALT: CLR Mask */ -#define CMSDK_PL230_CHNL_PRI_ALT_CLR_Pos 0 /* CMSDK_PL230 CHNL_PRI_ALT: CLR Position */ -#define CMSDK_PL230_CHNL_PRI_ALT_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_PRI_ALT_CLR_Pos) /* CMSDK_PL230 CHNL_PRI_ALT: CLR Mask */ + #define CMSDK_PL230_CHNL_PRIORITY_SET_Pos 0 /* CMSDK_PL230 CHNL_PRIORITY: SET Position */ + #define CMSDK_PL230_CHNL_PRIORITY_SET_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_PRIORITY_SET_Pos ) /* CMSDK_PL230 CHNL_PRIORITY: SET Mask */ -#define CMSDK_PL230_CHNL_PRIORITY_SET_Pos 0 /* CMSDK_PL230 CHNL_PRIORITY: SET Position */ -#define CMSDK_PL230_CHNL_PRIORITY_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_PRIORITY_SET_Pos) /* CMSDK_PL230 CHNL_PRIORITY: SET Mask */ + #define CMSDK_PL230_CHNL_PRIORITY_CLR_Pos 0 /* CMSDK_PL230 CHNL_PRIORITY: CLR Position */ + #define CMSDK_PL230_CHNL_PRIORITY_CLR_Msk ( 0xFFFFFFFFul << CMSDK_PL230_CHNL_PRIORITY_CLR_Pos ) /* CMSDK_PL230 CHNL_PRIORITY: CLR Mask */ -#define CMSDK_PL230_CHNL_PRIORITY_CLR_Pos 0 /* CMSDK_PL230 CHNL_PRIORITY: CLR Position */ -#define CMSDK_PL230_CHNL_PRIORITY_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_PRIORITY_CLR_Pos) /* CMSDK_PL230 CHNL_PRIORITY: CLR Mask */ - -#define CMSDK_PL230_ERR_CLR_Pos 0 /* CMSDK_PL230 ERR: CLR Position */ -#define CMSDK_PL230_ERR_CLR_Msk (0x00000001ul << CMSDK_PL230_ERR_CLR_Pos) /* CMSDK_PL230 ERR: CLR Mask */ + #define CMSDK_PL230_ERR_CLR_Pos 0 /* CMSDK_PL230 ERR: CLR Position */ + #define CMSDK_PL230_ERR_CLR_Msk ( 0x00000001ul << CMSDK_PL230_ERR_CLR_Pos ) /* CMSDK_PL230 ERR: CLR Mask */ /*------------------- Watchdog ----------------------------------------------*/ -typedef struct -{ + typedef struct + { + __IO uint32_t LOAD; /* Offset: 0x000 (R/W) Watchdog Load Register */ + __I uint32_t VALUE; /* Offset: 0x004 (R/ ) Watchdog Value Register */ + __IO uint32_t CTRL; /* Offset: 0x008 (R/W) Watchdog Control Register */ + __O uint32_t INTCLR; /* Offset: 0x00C ( /W) Watchdog Clear Interrupt Register */ + __I uint32_t RAWINTSTAT; /* Offset: 0x010 (R/ ) Watchdog Raw Interrupt Status Register */ + __I uint32_t MASKINTSTAT; /* Offset: 0x014 (R/ ) Watchdog Interrupt Status Register */ + uint32_t RESERVED0[ 762 ]; + __IO uint32_t LOCK; /* Offset: 0xC00 (R/W) Watchdog Lock Register */ + uint32_t RESERVED1[ 191 ]; + __IO uint32_t ITCR; /* Offset: 0xF00 (R/W) Watchdog Integration Test Control Register */ + __O uint32_t ITOP; /* Offset: 0xF04 ( /W) Watchdog Integration Test Output Set Register */ + } CMSDK_WATCHDOG_TypeDef; - __IO uint32_t LOAD; /* Offset: 0x000 (R/W) Watchdog Load Register */ - __I uint32_t VALUE; /* Offset: 0x004 (R/ ) Watchdog Value Register */ - __IO uint32_t CTRL; /* Offset: 0x008 (R/W) Watchdog Control Register */ - __O uint32_t INTCLR; /* Offset: 0x00C ( /W) Watchdog Clear Interrupt Register */ - __I uint32_t RAWINTSTAT; /* Offset: 0x010 (R/ ) Watchdog Raw Interrupt Status Register */ - __I uint32_t MASKINTSTAT; /* Offset: 0x014 (R/ ) Watchdog Interrupt Status Register */ - uint32_t RESERVED0[762]; - __IO uint32_t LOCK; /* Offset: 0xC00 (R/W) Watchdog Lock Register */ - uint32_t RESERVED1[191]; - __IO uint32_t ITCR; /* Offset: 0xF00 (R/W) Watchdog Integration Test Control Register */ - __O uint32_t ITOP; /* Offset: 0xF04 ( /W) Watchdog Integration Test Output Set Register */ -}CMSDK_WATCHDOG_TypeDef; + #define CMSDK_Watchdog_LOAD_Pos 0 /* CMSDK_Watchdog LOAD: LOAD Position */ + #define CMSDK_Watchdog_LOAD_Msk ( 0xFFFFFFFFul << CMSDK_Watchdog_LOAD_Pos ) /* CMSDK_Watchdog LOAD: LOAD Mask */ -#define CMSDK_Watchdog_LOAD_Pos 0 /* CMSDK_Watchdog LOAD: LOAD Position */ -#define CMSDK_Watchdog_LOAD_Msk (0xFFFFFFFFul << CMSDK_Watchdog_LOAD_Pos) /* CMSDK_Watchdog LOAD: LOAD Mask */ + #define CMSDK_Watchdog_VALUE_Pos 0 /* CMSDK_Watchdog VALUE: VALUE Position */ + #define CMSDK_Watchdog_VALUE_Msk ( 0xFFFFFFFFul << CMSDK_Watchdog_VALUE_Pos ) /* CMSDK_Watchdog VALUE: VALUE Mask */ -#define CMSDK_Watchdog_VALUE_Pos 0 /* CMSDK_Watchdog VALUE: VALUE Position */ -#define CMSDK_Watchdog_VALUE_Msk (0xFFFFFFFFul << CMSDK_Watchdog_VALUE_Pos) /* CMSDK_Watchdog VALUE: VALUE Mask */ + #define CMSDK_Watchdog_CTRL_RESEN_Pos 1 /* CMSDK_Watchdog CTRL_RESEN: Enable Reset Output Position */ + #define CMSDK_Watchdog_CTRL_RESEN_Msk ( 0x1ul << CMSDK_Watchdog_CTRL_RESEN_Pos ) /* CMSDK_Watchdog CTRL_RESEN: Enable Reset Output Mask */ -#define CMSDK_Watchdog_CTRL_RESEN_Pos 1 /* CMSDK_Watchdog CTRL_RESEN: Enable Reset Output Position */ -#define CMSDK_Watchdog_CTRL_RESEN_Msk (0x1ul << CMSDK_Watchdog_CTRL_RESEN_Pos) /* CMSDK_Watchdog CTRL_RESEN: Enable Reset Output Mask */ + #define CMSDK_Watchdog_CTRL_INTEN_Pos 0 /* CMSDK_Watchdog CTRL_INTEN: Int Enable Position */ + #define CMSDK_Watchdog_CTRL_INTEN_Msk ( 0x1ul << CMSDK_Watchdog_CTRL_INTEN_Pos ) /* CMSDK_Watchdog CTRL_INTEN: Int Enable Mask */ -#define CMSDK_Watchdog_CTRL_INTEN_Pos 0 /* CMSDK_Watchdog CTRL_INTEN: Int Enable Position */ -#define CMSDK_Watchdog_CTRL_INTEN_Msk (0x1ul << CMSDK_Watchdog_CTRL_INTEN_Pos) /* CMSDK_Watchdog CTRL_INTEN: Int Enable Mask */ + #define CMSDK_Watchdog_INTCLR_Pos 0 /* CMSDK_Watchdog INTCLR: Int Clear Position */ + #define CMSDK_Watchdog_INTCLR_Msk ( 0x1ul << CMSDK_Watchdog_INTCLR_Pos ) /* CMSDK_Watchdog INTCLR: Int Clear Mask */ -#define CMSDK_Watchdog_INTCLR_Pos 0 /* CMSDK_Watchdog INTCLR: Int Clear Position */ -#define CMSDK_Watchdog_INTCLR_Msk (0x1ul << CMSDK_Watchdog_INTCLR_Pos) /* CMSDK_Watchdog INTCLR: Int Clear Mask */ + #define CMSDK_Watchdog_RAWINTSTAT_Pos 0 /* CMSDK_Watchdog RAWINTSTAT: Raw Int Status Position */ + #define CMSDK_Watchdog_RAWINTSTAT_Msk ( 0x1ul << CMSDK_Watchdog_RAWINTSTAT_Pos ) /* CMSDK_Watchdog RAWINTSTAT: Raw Int Status Mask */ -#define CMSDK_Watchdog_RAWINTSTAT_Pos 0 /* CMSDK_Watchdog RAWINTSTAT: Raw Int Status Position */ -#define CMSDK_Watchdog_RAWINTSTAT_Msk (0x1ul << CMSDK_Watchdog_RAWINTSTAT_Pos) /* CMSDK_Watchdog RAWINTSTAT: Raw Int Status Mask */ + #define CMSDK_Watchdog_MASKINTSTAT_Pos 0 /* CMSDK_Watchdog MASKINTSTAT: Mask Int Status Position */ + #define CMSDK_Watchdog_MASKINTSTAT_Msk ( 0x1ul << CMSDK_Watchdog_MASKINTSTAT_Pos ) /* CMSDK_Watchdog MASKINTSTAT: Mask Int Status Mask */ -#define CMSDK_Watchdog_MASKINTSTAT_Pos 0 /* CMSDK_Watchdog MASKINTSTAT: Mask Int Status Position */ -#define CMSDK_Watchdog_MASKINTSTAT_Msk (0x1ul << CMSDK_Watchdog_MASKINTSTAT_Pos) /* CMSDK_Watchdog MASKINTSTAT: Mask Int Status Mask */ + #define CMSDK_Watchdog_LOCK_Pos 0 /* CMSDK_Watchdog LOCK: LOCK Position */ + #define CMSDK_Watchdog_LOCK_Msk ( 0x1ul << CMSDK_Watchdog_LOCK_Pos ) /* CMSDK_Watchdog LOCK: LOCK Mask */ -#define CMSDK_Watchdog_LOCK_Pos 0 /* CMSDK_Watchdog LOCK: LOCK Position */ -#define CMSDK_Watchdog_LOCK_Msk (0x1ul << CMSDK_Watchdog_LOCK_Pos) /* CMSDK_Watchdog LOCK: LOCK Mask */ + #define CMSDK_Watchdog_INTEGTESTEN_Pos 0 /* CMSDK_Watchdog INTEGTESTEN: Integration Test Enable Position */ + #define CMSDK_Watchdog_INTEGTESTEN_Msk ( 0x1ul << CMSDK_Watchdog_INTEGTESTEN_Pos ) /* CMSDK_Watchdog INTEGTESTEN: Integration Test Enable Mask */ -#define CMSDK_Watchdog_INTEGTESTEN_Pos 0 /* CMSDK_Watchdog INTEGTESTEN: Integration Test Enable Position */ -#define CMSDK_Watchdog_INTEGTESTEN_Msk (0x1ul << CMSDK_Watchdog_INTEGTESTEN_Pos) /* CMSDK_Watchdog INTEGTESTEN: Integration Test Enable Mask */ - -#define CMSDK_Watchdog_INTEGTESTOUTSET_Pos 1 /* CMSDK_Watchdog INTEGTESTOUTSET: Integration Test Output Set Position */ -#define CMSDK_Watchdog_INTEGTESTOUTSET_Msk (0x1ul << CMSDK_Watchdog_INTEGTESTOUTSET_Pos) /* CMSDK_Watchdog INTEGTESTOUTSET: Integration Test Output Set Mask */ + #define CMSDK_Watchdog_INTEGTESTOUTSET_Pos 1 /* CMSDK_Watchdog INTEGTESTOUTSET: Integration Test Output Set Position */ + #define CMSDK_Watchdog_INTEGTESTOUTSET_Msk ( 0x1ul << CMSDK_Watchdog_INTEGTESTOUTSET_Pos ) /* CMSDK_Watchdog INTEGTESTOUTSET: Integration Test Output Set Mask */ /* -------------------- End of section using anonymous unions ------------------- */ -#if defined ( __CC_ARM ) - #pragma pop -#elif defined(__ICCARM__) - /* leave anonymous unions enabled */ -#elif defined(__GNUC__) - /* anonymous unions are enabled by default */ -#elif defined(__TMS470__) - /* anonymous unions are enabled by default */ -#elif defined(__TASKING__) - #pragma warning restore -#else - #warning Not supported compiler type -#endif - + #if defined( __CC_ARM ) + #pragma pop + #elif defined( __ICCARM__ ) + /* leave anonymous unions enabled */ + #elif defined( __GNUC__ ) + /* anonymous unions are enabled by default */ + #elif defined( __TMS470__ ) + /* anonymous unions are enabled by default */ + #elif defined( __TASKING__ ) + #pragma warning restore + #else + #warning Not supported compiler type + #endif /* if defined( __CC_ARM ) */ @@ -663,61 +661,61 @@ typedef struct /* ================================================================================ */ /* Peripheral and SRAM base address */ -#define CMSDK_FLASH_BASE (0x00000000UL) -#define CMSDK_SRAM_BASE (0x20000000UL) -#define CMSDK_PERIPH_BASE (0x40000000UL) + #define CMSDK_FLASH_BASE ( 0x00000000UL ) + #define CMSDK_SRAM_BASE ( 0x20000000UL ) + #define CMSDK_PERIPH_BASE ( 0x40000000UL ) -#define CMSDK_RAM_BASE (0x20000000UL) -#define CMSDK_APB_BASE (0x40000000UL) -#define CMSDK_AHB_BASE (0x40010000UL) + #define CMSDK_RAM_BASE ( 0x20000000UL ) + #define CMSDK_APB_BASE ( 0x40000000UL ) + #define CMSDK_AHB_BASE ( 0x40010000UL ) /* APB peripherals */ -#define CMSDK_TIMER0_BASE (CMSDK_APB_BASE + 0x0000UL) -#define CMSDK_TIMER1_BASE (CMSDK_APB_BASE + 0x1000UL) -#define CMSDK_DUALTIMER_BASE (CMSDK_APB_BASE + 0x2000UL) -#define CMSDK_DUALTIMER_1_BASE (CMSDK_DUALTIMER_BASE) -#define CMSDK_DUALTIMER_2_BASE (CMSDK_DUALTIMER_BASE + 0x20UL) -#define CMSDK_UART0_BASE (CMSDK_APB_BASE + 0x4000UL) -#define CMSDK_UART1_BASE (CMSDK_APB_BASE + 0x5000UL) -#define CMSDK_UART2_BASE (CMSDK_APB_BASE + 0x6000UL) -#define CMSDK_UART3_BASE (CMSDK_APB_BASE + 0x7000UL) -#define CMSDK_WATCHDOG_BASE (CMSDK_APB_BASE + 0x8000UL) -#define CMSDK_UART4_BASE (CMSDK_APB_BASE + 0x9000UL) -#define CMSDK_PL230_BASE (CMSDK_APB_BASE + 0xF000UL) + #define CMSDK_TIMER0_BASE ( CMSDK_APB_BASE + 0x0000UL ) + #define CMSDK_TIMER1_BASE ( CMSDK_APB_BASE + 0x1000UL ) + #define CMSDK_DUALTIMER_BASE ( CMSDK_APB_BASE + 0x2000UL ) + #define CMSDK_DUALTIMER_1_BASE ( CMSDK_DUALTIMER_BASE ) + #define CMSDK_DUALTIMER_2_BASE ( CMSDK_DUALTIMER_BASE + 0x20UL ) + #define CMSDK_UART0_BASE ( CMSDK_APB_BASE + 0x4000UL ) + #define CMSDK_UART1_BASE ( CMSDK_APB_BASE + 0x5000UL ) + #define CMSDK_UART2_BASE ( CMSDK_APB_BASE + 0x6000UL ) + #define CMSDK_UART3_BASE ( CMSDK_APB_BASE + 0x7000UL ) + #define CMSDK_WATCHDOG_BASE ( CMSDK_APB_BASE + 0x8000UL ) + #define CMSDK_UART4_BASE ( CMSDK_APB_BASE + 0x9000UL ) + #define CMSDK_PL230_BASE ( CMSDK_APB_BASE + 0xF000UL ) /* AHB peripherals */ -#define CMSDK_GPIO0_BASE (CMSDK_AHB_BASE + 0x0000UL) -#define CMSDK_GPIO1_BASE (CMSDK_AHB_BASE + 0x1000UL) -#define CMSDK_GPIO2_BASE (CMSDK_AHB_BASE + 0x2000UL) -#define CMSDK_GPIO3_BASE (CMSDK_AHB_BASE + 0x3000UL) -#define CMSDK_SYSCTRL_BASE (CMSDK_AHB_BASE + 0xF000UL) + #define CMSDK_GPIO0_BASE ( CMSDK_AHB_BASE + 0x0000UL ) + #define CMSDK_GPIO1_BASE ( CMSDK_AHB_BASE + 0x1000UL ) + #define CMSDK_GPIO2_BASE ( CMSDK_AHB_BASE + 0x2000UL ) + #define CMSDK_GPIO3_BASE ( CMSDK_AHB_BASE + 0x3000UL ) + #define CMSDK_SYSCTRL_BASE ( CMSDK_AHB_BASE + 0xF000UL ) /* ================================================================================ */ /* ================ Peripheral declaration ================ */ /* ================================================================================ */ -#define CMSDK_UART0 ((CMSDK_UART_TypeDef *) CMSDK_UART0_BASE ) -#define CMSDK_UART1 ((CMSDK_UART_TypeDef *) CMSDK_UART1_BASE ) -#define CMSDK_UART2 ((CMSDK_UART_TypeDef *) CMSDK_UART2_BASE ) -#define CMSDK_UART3 ((CMSDK_UART_TypeDef *) CMSDK_UART3_BASE ) -#define CMSDK_UART4 ((CMSDK_UART_TypeDef *) CMSDK_UART4_BASE ) -#define CMSDK_TIMER0 ((CMSDK_TIMER_TypeDef *) CMSDK_TIMER0_BASE ) -#define CMSDK_TIMER1 ((CMSDK_TIMER_TypeDef *) CMSDK_TIMER1_BASE ) -#define CMSDK_DUALTIMER ((CMSDK_DUALTIMER_BOTH_TypeDef *) CMSDK_DUALTIMER_BASE ) -#define CMSDK_DUALTIMER1 ((CMSDK_DUALTIMER_SINGLE_TypeDef *) CMSDK_DUALTIMER_1_BASE ) -#define CMSDK_DUALTIMER2 ((CMSDK_DUALTIMER_SINGLE_TypeDef *) CMSDK_DUALTIMER_2_BASE ) -#define CMSDK_WATCHDOG ((CMSDK_WATCHDOG_TypeDef *) CMSDK_WATCHDOG_BASE ) -#define CMSDK_DMA ((CMSDK_PL230_TypeDef *) CMSDK_PL230_BASE ) -#define CMSDK_GPIO0 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO0_BASE ) -#define CMSDK_GPIO1 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO1_BASE ) -#define CMSDK_GPIO2 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO2_BASE ) -#define CMSDK_GPIO3 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO3_BASE ) -#define CMSDK_SYSCON ((CMSDK_SYSCON_TypeDef *) CMSDK_SYSCTRL_BASE ) + #define CMSDK_UART0 ( ( CMSDK_UART_TypeDef * ) CMSDK_UART0_BASE ) + #define CMSDK_UART1 ( ( CMSDK_UART_TypeDef * ) CMSDK_UART1_BASE ) + #define CMSDK_UART2 ( ( CMSDK_UART_TypeDef * ) CMSDK_UART2_BASE ) + #define CMSDK_UART3 ( ( CMSDK_UART_TypeDef * ) CMSDK_UART3_BASE ) + #define CMSDK_UART4 ( ( CMSDK_UART_TypeDef * ) CMSDK_UART4_BASE ) + #define CMSDK_TIMER0 ( ( CMSDK_TIMER_TypeDef * ) CMSDK_TIMER0_BASE ) + #define CMSDK_TIMER1 ( ( CMSDK_TIMER_TypeDef * ) CMSDK_TIMER1_BASE ) + #define CMSDK_DUALTIMER ( ( CMSDK_DUALTIMER_BOTH_TypeDef * ) CMSDK_DUALTIMER_BASE ) + #define CMSDK_DUALTIMER1 ( ( CMSDK_DUALTIMER_SINGLE_TypeDef * ) CMSDK_DUALTIMER_1_BASE ) + #define CMSDK_DUALTIMER2 ( ( CMSDK_DUALTIMER_SINGLE_TypeDef * ) CMSDK_DUALTIMER_2_BASE ) + #define CMSDK_WATCHDOG ( ( CMSDK_WATCHDOG_TypeDef * ) CMSDK_WATCHDOG_BASE ) + #define CMSDK_DMA ( ( CMSDK_PL230_TypeDef * ) CMSDK_PL230_BASE ) + #define CMSDK_GPIO0 ( ( CMSDK_GPIO_TypeDef * ) CMSDK_GPIO0_BASE ) + #define CMSDK_GPIO1 ( ( CMSDK_GPIO_TypeDef * ) CMSDK_GPIO1_BASE ) + #define CMSDK_GPIO2 ( ( CMSDK_GPIO_TypeDef * ) CMSDK_GPIO2_BASE ) + #define CMSDK_GPIO3 ( ( CMSDK_GPIO_TypeDef * ) CMSDK_GPIO3_BASE ) + #define CMSDK_SYSCON ( ( CMSDK_SYSCON_TypeDef * ) CMSDK_SYSCTRL_BASE ) -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif /* CMSDK_CM3_H */ +#endif /* CMSDK_CM3_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/SMM_MPS2.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/SMM_MPS2.h index a8f86f2de..8c2a576ab 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/SMM_MPS2.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/SMM_MPS2.h @@ -1,164 +1,164 @@ /* -* copyright (c) 2006-2016 ARM Limited -* SPDX-License-Identifier: BSD-3-Clause -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* File: smm_mps2.h -* Release: Version 1.1 -*******************************************************************************/ + * copyright (c) 2006-2016 ARM Limited + * SPDX-License-Identifier: BSD-3-Clause + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + * File: smm_mps2.h + * Release: Version 1.1 + *******************************************************************************/ #ifndef __SMM_MPS2_H #define __SMM_MPS2_H -#include "CMSDK_CM3.h" /* device specific header file */ +#include "CMSDK_CM3.h" /* device specific header file */ -#if defined ( __CC_ARM ) -#pragma anon_unions +#if defined( __CC_ARM ) + #pragma anon_unions #endif /******************************************************************************/ /* FPGA System Register declaration */ /******************************************************************************/ -typedef struct +typedef struct { - __IO uint32_t LED; // Offset: 0x000 (R/W) LED connections - // [31:2] : Reserved - // [1:0] : LEDs - uint32_t RESERVED1[1]; - __IO uint32_t BUTTON; // Offset: 0x008 (R/W) Buttons - // [31:2] : Reserved - // [1:0] : Buttons - uint32_t RESERVED2[1]; - __IO uint32_t CLK1HZ; // Offset: 0x010 (R/W) 1Hz up counter - __IO uint32_t CLK100HZ; // Offset: 0x014 (R/W) 100Hz up counter - __IO uint32_t COUNTER; // Offset: 0x018 (R/W) Cycle Up Counter - // Increments when 32-bit prescale counter reach zero - uint32_t RESERVED3[1]; - __IO uint32_t PRESCALE; // Offset: 0x020 (R/W) Prescaler - // Bit[31:0] : reload value for prescale counter - __IO uint32_t PSCNTR; // Offset: 0x024 (R/W) 32-bit Prescale counter - // current value of the pre-scaler counter - // The Cycle Up Counter increment when the prescale down counter reach 0 - // The pre-scaler counter is reloaded with PRESCALE after reaching 0. - uint32_t RESERVED4[9]; - __IO uint32_t MISC; // Offset: 0x04C (R/W) Misc control */ - // [31:10] : Reserved - // [9] : SHIELD_1_SPI_nCS - // [8] : SHIELD_0_SPI_nCS - // [7] : ADC_SPI_nCS - // [6] : CLCD_BL_CTRL - // [5] : CLCD_RD - // [4] : CLCD_RS - // [3] : CLCD_RESET - // [2] : RESERVED - // [1] : SPI_nSS - // [0] : CLCD_CS + __IO uint32_t LED; /* Offset: 0x000 (R/W) LED connections */ + /* [31:2] : Reserved */ + /* [1:0] : LEDs */ + uint32_t RESERVED1[ 1 ]; + __IO uint32_t BUTTON; /* Offset: 0x008 (R/W) Buttons */ + /* [31:2] : Reserved */ + /* [1:0] : Buttons */ + uint32_t RESERVED2[ 1 ]; + __IO uint32_t CLK1HZ; /* Offset: 0x010 (R/W) 1Hz up counter */ + __IO uint32_t CLK100HZ; /* Offset: 0x014 (R/W) 100Hz up counter */ + __IO uint32_t COUNTER; /* Offset: 0x018 (R/W) Cycle Up Counter */ + /* Increments when 32-bit prescale counter reach zero */ + uint32_t RESERVED3[ 1 ]; + __IO uint32_t PRESCALE; /* Offset: 0x020 (R/W) Prescaler */ + /* Bit[31:0] : reload value for prescale counter */ + __IO uint32_t PSCNTR; /* Offset: 0x024 (R/W) 32-bit Prescale counter */ + /* current value of the pre-scaler counter */ + /* The Cycle Up Counter increment when the prescale down counter reach 0 */ + /* The pre-scaler counter is reloaded with PRESCALE after reaching 0. */ + uint32_t RESERVED4[ 9 ]; + __IO uint32_t MISC; /* Offset: 0x04C (R/W) Misc control * / */ + /* [31:10] : Reserved */ + /* [9] : SHIELD_1_SPI_nCS */ + /* [8] : SHIELD_0_SPI_nCS */ + /* [7] : ADC_SPI_nCS */ + /* [6] : CLCD_BL_CTRL */ + /* [5] : CLCD_RD */ + /* [4] : CLCD_RS */ + /* [3] : CLCD_RESET */ + /* [2] : RESERVED */ + /* [1] : SPI_nSS */ + /* [0] : CLCD_CS */ } MPS2_FPGAIO_TypeDef; -// MISC register bit definitions +/* MISC register bit definitions */ -#define CLCD_CS_Pos 0 -#define CLCD_CS_Msk (1UL< CONTROL - // TX Enable - // <0=> TX disabled - // <1=> TX enabled - // TX IRQ Enable - // <0=> TX IRQ disabled - // <1=> TX IRQ enabled - // RX Enable - // <0=> RX disabled - // <1=> RX enabled - // RX IRQ Enable - // <0=> RX IRQ disabled - // <1=> RX IRQ enabled - // TX Buffer Water Level - // <0=> / IRQ triggers when any space available - // <1=> / IRQ triggers when more than 1 space available - // <2=> / IRQ triggers when more than 2 space available - // <3=> / IRQ triggers when more than 3 space available - // <4=> Undefined! - // <5=> Undefined! - // <6=> Undefined! - // <7=> Undefined! - // RX Buffer Water Level - // <0=> Undefined! - // <1=> / IRQ triggers when less than 1 space available - // <2=> / IRQ triggers when less than 2 space available - // <3=> / IRQ triggers when less than 3 space available - // <4=> / IRQ triggers when less than 4 space available - // <5=> Undefined! - // <6=> Undefined! - // <7=> Undefined! - // FIFO reset - // <0=> Normal operation - // <1=> FIFO reset - // Audio Codec reset - // <0=> Normal operation - // <1=> Assert audio Codec reset - /*!< Offset: 0x004 STATUS Register (R/ ) */ - __I uint32_t STATUS; // STATUS - // TX Buffer alert - // <0=> TX buffer don't need service yet - // <1=> TX buffer need service - // RX Buffer alert - // <0=> RX buffer don't need service yet - // <1=> RX buffer need service - // TX Buffer Empty - // <0=> TX buffer have data - // <1=> TX buffer empty - // TX Buffer Full - // <0=> TX buffer not full - // <1=> TX buffer full - // RX Buffer Empty - // <0=> RX buffer have data - // <1=> RX buffer empty - // RX Buffer Full - // <0=> RX buffer not full - // <1=> RX buffer full - union { - /*!< Offset: 0x008 Error Status Register (R/ ) */ - __I uint32_t ERROR; // ERROR - // TX error - // <0=> Okay - // <1=> TX overrun/underrun - // RX error - // <0=> Okay - // <1=> RX overrun/underrun - /*!< Offset: 0x008 Error Clear Register ( /W) */ - __O uint32_t ERRORCLR; // ERRORCLR - // TX error - // <0=> Okay - // <1=> Clear TX error - // RX error - // <0=> Okay - // <1=> Clear RX error + /*!< Offset: 0x000 CONTROL Register (R/W) */ + __IO uint32_t CONTROL; /* CONTROL */ + /* TX Enable */ + /* <0=> TX disabled */ + /* <1=> TX enabled */ + /* TX IRQ Enable */ + /* <0=> TX IRQ disabled */ + /* <1=> TX IRQ enabled */ + /* RX Enable */ + /* <0=> RX disabled */ + /* <1=> RX enabled */ + /* RX IRQ Enable */ + /* <0=> RX IRQ disabled */ + /* <1=> RX IRQ enabled */ + /* TX Buffer Water Level */ + /* <0=> / IRQ triggers when any space available */ + /* <1=> / IRQ triggers when more than 1 space available */ + /* <2=> / IRQ triggers when more than 2 space available */ + /* <3=> / IRQ triggers when more than 3 space available */ + /* <4=> Undefined! */ + /* <5=> Undefined! */ + /* <6=> Undefined! */ + /* <7=> Undefined! */ + /* RX Buffer Water Level */ + /* <0=> Undefined! */ + /* <1=> / IRQ triggers when less than 1 space available */ + /* <2=> / IRQ triggers when less than 2 space available */ + /* <3=> / IRQ triggers when less than 3 space available */ + /* <4=> / IRQ triggers when less than 4 space available */ + /* <5=> Undefined! */ + /* <6=> Undefined! */ + /* <7=> Undefined! */ + /* FIFO reset */ + /* <0=> Normal operation */ + /* <1=> FIFO reset */ + /* Audio Codec reset */ + /* <0=> Normal operation */ + /* <1=> Assert audio Codec reset */ + /*!< Offset: 0x004 STATUS Register (R/ ) */ + __I uint32_t STATUS; /* STATUS */ + /* TX Buffer alert */ + /* <0=> TX buffer don't need service yet */ + /* <1=> TX buffer need service */ + /* RX Buffer alert */ + /* <0=> RX buffer don't need service yet */ + /* <1=> RX buffer need service */ + /* TX Buffer Empty */ + /* <0=> TX buffer have data */ + /* <1=> TX buffer empty */ + /* TX Buffer Full */ + /* <0=> TX buffer not full */ + /* <1=> TX buffer full */ + /* RX Buffer Empty */ + /* <0=> RX buffer have data */ + /* <1=> RX buffer empty */ + /* RX Buffer Full */ + /* <0=> RX buffer not full */ + /* <1=> RX buffer full */ + union + { + /*!< Offset: 0x008 Error Status Register (R/ ) */ + __I uint32_t ERROR; /* ERROR */ + /* TX error */ + /* <0=> Okay */ + /* <1=> TX overrun/underrun */ + /* RX error */ + /* <0=> Okay */ + /* <1=> RX overrun/underrun */ + /*!< Offset: 0x008 Error Clear Register ( /W) */ + __O uint32_t ERRORCLR; /* ERRORCLR */ + /* TX error */ + /* <0=> Okay */ + /* <1=> Clear TX error */ + /* RX error */ + /* <0=> Okay */ + /* <1=> Clear RX error */ }; - /*!< Offset: 0x00C Divide ratio Register (R/W) */ - __IO uint32_t DIVIDE; // Divide ratio for Left/Right clock - // TX error (default 0x80) - /*!< Offset: 0x010 Transmit Buffer ( /W) */ - __O uint32_t TXBUF; // Transmit buffer - // Right channel - // Left channel - /*!< Offset: 0x014 Receive Buffer (R/ ) */ - __I uint32_t RXBUF; // Receive buffer - // Right channel - // Left channel - uint32_t RESERVED1[186]; - __IO uint32_t ITCR; // Integration Test Control Register - // ITEN - // <0=> Normal operation - // <1=> Integration Test mode enable - __O uint32_t ITIP1; // Integration Test Input Register 1 - // SDIN - __O uint32_t ITOP1; // Integration Test Output Register 1 - // SDOUT - // SCLK - // LRCK - // IRQOUT + /*!< Offset: 0x00C Divide ratio Register (R/W) */ + __IO uint32_t DIVIDE; /* Divide ratio for Left/Right clock */ + /* TX error (default 0x80) */ + /*!< Offset: 0x010 Transmit Buffer ( /W) */ + __O uint32_t TXBUF; /* Transmit buffer */ + /* Right channel */ + /* Left channel */ + /*!< Offset: 0x014 Receive Buffer (R/ ) */ + __I uint32_t RXBUF; /* Receive buffer */ + /* Right channel */ + /* Left channel */ + uint32_t RESERVED1[ 186 ]; + __IO uint32_t ITCR; /* Integration Test Control Register */ + /* ITEN */ + /* <0=> Normal operation */ + /* <1=> Integration Test mode enable */ + __O uint32_t ITIP1; /* Integration Test Input Register 1 */ + /* SDIN */ + __O uint32_t ITOP1; /* Integration Test Output Register 1 */ + /* SDOUT */ + /* SCLK */ + /* LRCK */ + /* IRQOUT */ } MPS2_I2S_TypeDef; #define I2S_CONTROL_TXEN_Pos 0 -#define I2S_CONTROL_TXEN_Msk (1UL<= 6010050) && (__ARMCC_VERSION < 6100100) - #include "cmsis_armclang_ltm.h" +#elif defined( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) && ( __ARMCC_VERSION < 6100100 ) + #include "cmsis_armclang_ltm.h" - /* +/* * Arm Compiler above 6.10.1 (armclang) */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) - #include "cmsis_armclang.h" +#elif defined( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6100100 ) + #include "cmsis_armclang.h" /* * GNU Compiler */ -#elif defined ( __GNUC__ ) - #include "cmsis_gcc.h" +#elif defined( __GNUC__ ) + #include "cmsis_gcc.h" /* * IAR Compiler */ -#elif defined ( __ICCARM__ ) - #include +#elif defined( __ICCARM__ ) + #include /* * TI Arm Compiler */ -#elif defined ( __TI_ARM__ ) - #include +#elif defined( __TI_ARM__ ) + #include - #ifndef __ASM - #define __ASM __asm - #endif - #ifndef __INLINE - #define __INLINE inline - #endif - #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline - #endif - #ifndef __STATIC_FORCEINLINE - #define __STATIC_FORCEINLINE __STATIC_INLINE - #endif - #ifndef __NO_RETURN - #define __NO_RETURN __attribute__((noreturn)) - #endif - #ifndef __USED - #define __USED __attribute__((used)) - #endif - #ifndef __WEAK - #define __WEAK __attribute__((weak)) - #endif - #ifndef __PACKED - #define __PACKED __attribute__((packed)) - #endif - #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT struct __attribute__((packed)) - #endif - #ifndef __PACKED_UNION - #define __PACKED_UNION union __attribute__((packed)) - #endif - #ifndef __UNALIGNED_UINT32 /* deprecated */ - struct __attribute__((packed)) T_UINT32 { uint32_t v; }; - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) - #endif - #ifndef __UNALIGNED_UINT16_WRITE - __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; - #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) - #endif - #ifndef __UNALIGNED_UINT16_READ - __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; - #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) - #endif - #ifndef __UNALIGNED_UINT32_WRITE - __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; - #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) - #endif - #ifndef __UNALIGNED_UINT32_READ - __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; - #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) - #endif - #ifndef __ALIGNED - #define __ALIGNED(x) __attribute__((aligned(x))) - #endif - #ifndef __RESTRICT - #define __RESTRICT __restrict - #endif - #ifndef __COMPILER_BARRIER - #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. - #define __COMPILER_BARRIER() (void)0 - #endif + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__( ( noreturn ) ) + #endif + #ifndef __USED + #define __USED __attribute__( ( used ) ) + #endif + #ifndef __WEAK + #define __WEAK __attribute__( ( weak ) ) + #endif + #ifndef __PACKED + #define __PACKED __attribute__( ( packed ) ) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__( ( packed ) ) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__( ( packed ) ) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__( ( packed ) ) T_UINT32 + { + uint32_t v; + }; + #define __UNALIGNED_UINT32( x ) ( ( ( struct T_UINT32 * ) ( x ) )->v ) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { + uint16_t v; + }; + #define __UNALIGNED_UINT16_WRITE( addr, val ) ( void ) ( ( ( ( struct T_UINT16_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) ) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { + uint16_t v; + }; + #define __UNALIGNED_UINT16_READ( addr ) ( ( ( const struct T_UINT16_READ * ) ( const void * ) ( addr ) )->v ) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { + uint32_t v; + }; + #define __UNALIGNED_UINT32_WRITE( addr, val ) ( void ) ( ( ( ( struct T_UINT32_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) ) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { + uint32_t v; + }; + #define __UNALIGNED_UINT32_READ( addr ) ( ( ( const struct T_UINT32_READ * ) ( const void * ) ( addr ) )->v ) + #endif + #ifndef __ALIGNED + #define __ALIGNED( x ) __attribute__( ( aligned( x ) ) ) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() ( void ) 0 + #endif /* * TASKING Compiler */ -#elif defined ( __TASKING__ ) - /* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all intrinsics, - * Including the CMSIS ones. - */ +#elif defined( __TASKING__ ) - #ifndef __ASM - #define __ASM __asm - #endif - #ifndef __INLINE - #define __INLINE inline - #endif - #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline - #endif - #ifndef __STATIC_FORCEINLINE - #define __STATIC_FORCEINLINE __STATIC_INLINE - #endif - #ifndef __NO_RETURN - #define __NO_RETURN __attribute__((noreturn)) - #endif - #ifndef __USED - #define __USED __attribute__((used)) - #endif - #ifndef __WEAK - #define __WEAK __attribute__((weak)) - #endif - #ifndef __PACKED - #define __PACKED __packed__ - #endif - #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT struct __packed__ - #endif - #ifndef __PACKED_UNION - #define __PACKED_UNION union __packed__ - #endif - #ifndef __UNALIGNED_UINT32 /* deprecated */ - struct __packed__ T_UINT32 { uint32_t v; }; - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) - #endif - #ifndef __UNALIGNED_UINT16_WRITE - __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; - #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) - #endif - #ifndef __UNALIGNED_UINT16_READ - __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; - #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) - #endif - #ifndef __UNALIGNED_UINT32_WRITE - __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; - #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) - #endif - #ifndef __UNALIGNED_UINT32_READ - __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; - #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) - #endif - #ifndef __ALIGNED - #define __ALIGNED(x) __align(x) - #endif - #ifndef __RESTRICT - #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. - #define __RESTRICT - #endif - #ifndef __COMPILER_BARRIER - #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. - #define __COMPILER_BARRIER() (void)0 - #endif +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__( ( noreturn ) ) + #endif + #ifndef __USED + #define __USED __attribute__( ( used ) ) + #endif + #ifndef __WEAK + #define __WEAK __attribute__( ( weak ) ) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 + { + uint32_t v; + }; + #define __UNALIGNED_UINT32( x ) ( ( ( struct T_UINT32 * ) ( x ) )->v ) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { + uint16_t v; + }; + #define __UNALIGNED_UINT16_WRITE( addr, val ) ( void ) ( ( ( ( struct T_UINT16_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) ) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { + uint16_t v; + }; + #define __UNALIGNED_UINT16_READ( addr ) ( ( ( const struct T_UINT16_READ * ) ( const void * ) ( addr ) )->v ) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { + uint32_t v; + }; + #define __UNALIGNED_UINT32_WRITE( addr, val ) ( void ) ( ( ( ( struct T_UINT32_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) ) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { + uint32_t v; + }; + #define __UNALIGNED_UINT32_READ( addr ) ( ( ( const struct T_UINT32_READ * ) ( const void * ) ( addr ) )->v ) + #endif + #ifndef __ALIGNED + #define __ALIGNED( x ) __align( x ) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() ( void ) 0 + #endif /* * COSMIC Compiler */ -#elif defined ( __CSMC__ ) - #include +#elif defined( __CSMC__ ) + #include - #ifndef __ASM - #define __ASM _asm - #endif - #ifndef __INLINE - #define __INLINE inline - #endif - #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline - #endif - #ifndef __STATIC_FORCEINLINE - #define __STATIC_FORCEINLINE __STATIC_INLINE - #endif - #ifndef __NO_RETURN - // NO RETURN is automatically detected hence no warning here - #define __NO_RETURN - #endif - #ifndef __USED - #warning No compiler specific solution for __USED. __USED is ignored. - #define __USED - #endif - #ifndef __WEAK - #define __WEAK __weak - #endif - #ifndef __PACKED - #define __PACKED @packed - #endif - #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT @packed struct - #endif - #ifndef __PACKED_UNION - #define __PACKED_UNION @packed union - #endif - #ifndef __UNALIGNED_UINT32 /* deprecated */ - @packed struct T_UINT32 { uint32_t v; }; - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) - #endif - #ifndef __UNALIGNED_UINT16_WRITE - __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; - #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) - #endif - #ifndef __UNALIGNED_UINT16_READ - __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; - #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) - #endif - #ifndef __UNALIGNED_UINT32_WRITE - __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; - #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) - #endif - #ifndef __UNALIGNED_UINT32_READ - __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; - #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) - #endif - #ifndef __ALIGNED - #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. - #define __ALIGNED(x) - #endif - #ifndef __RESTRICT - #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. - #define __RESTRICT - #endif - #ifndef __COMPILER_BARRIER - #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. - #define __COMPILER_BARRIER() (void)0 - #endif + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + /* NO RETURN is automatically detected hence no warning here */ + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 + { + uint32_t v; + }; + #define __UNALIGNED_UINT32( x ) ( ( ( struct T_UINT32 * ) ( x ) )->v ) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { + uint16_t v; + }; + #define __UNALIGNED_UINT16_WRITE( addr, val ) ( void ) ( ( ( ( struct T_UINT16_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) ) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { + uint16_t v; + }; + #define __UNALIGNED_UINT16_READ( addr ) ( ( ( const struct T_UINT16_READ * ) ( const void * ) ( addr ) )->v ) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { + uint32_t v; + }; + #define __UNALIGNED_UINT32_WRITE( addr, val ) ( void ) ( ( ( ( struct T_UINT32_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) ) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { + uint32_t v; + }; + #define __UNALIGNED_UINT32_READ( addr ) ( ( ( const struct T_UINT32_READ * ) ( const void * ) ( addr ) )->v ) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED( x ) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() ( void ) 0 + #endif -#else - #error Unknown compiler. -#endif +#else /* if defined( __CC_ARM ) */ + #error Unknown compiler. +#endif /* if defined( __CC_ARM ) */ #endif /* __CMSIS_COMPILER_H */ - diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/cmsis_gcc.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/cmsis_gcc.h index 199336b04..24de16109 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/cmsis_gcc.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/cmsis_gcc.h @@ -1,9 +1,10 @@ /**************************************************************************//** - * @file cmsis_gcc.h - * @brief CMSIS compiler GCC header file - * @version V5.3.0 - * @date 26. March 2020 - ******************************************************************************/ +* @file cmsis_gcc.h +* @brief CMSIS compiler GCC header file +* @version V5.3.0 +* @date 26. March 2020 +******************************************************************************/ + /* * Copyright (c) 2009-2020 Arm Limited. All rights reserved. * @@ -33,88 +34,99 @@ /* Fallback for __has_builtin */ #ifndef __has_builtin - #define __has_builtin(x) (0) + #define __has_builtin( x ) ( 0 ) #endif /* CMSIS compiler specific defines */ #ifndef __ASM - #define __ASM __asm + #define __ASM __asm #endif #ifndef __INLINE - #define __INLINE inline + #define __INLINE inline #endif #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__( ( always_inline ) ) static inline #endif -#ifndef __STATIC_FORCEINLINE - #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline -#endif #ifndef __NO_RETURN - #define __NO_RETURN __attribute__((__noreturn__)) + #define __NO_RETURN __attribute__( ( __noreturn__ ) ) #endif #ifndef __USED - #define __USED __attribute__((used)) + #define __USED __attribute__( ( used ) ) #endif #ifndef __WEAK - #define __WEAK __attribute__((weak)) + #define __WEAK __attribute__( ( weak ) ) #endif #ifndef __PACKED - #define __PACKED __attribute__((packed, aligned(1))) + #define __PACKED __attribute__( ( packed, aligned( 1 ) ) ) #endif #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #define __PACKED_STRUCT struct __attribute__( ( packed, aligned( 1 ) ) ) #endif #ifndef __PACKED_UNION - #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #define __PACKED_UNION union __attribute__( ( packed, aligned( 1 ) ) ) #endif -#ifndef __UNALIGNED_UINT32 /* deprecated */ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpacked" - #pragma GCC diagnostic ignored "-Wattributes" - struct __attribute__((packed)) T_UINT32 { uint32_t v; }; - #pragma GCC diagnostic pop - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__( ( packed ) ) T_UINT32 + { + uint32_t v; + }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32( x ) ( ( ( struct T_UINT32 * ) ( x ) )->v ) #endif #ifndef __UNALIGNED_UINT16_WRITE - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpacked" - #pragma GCC diagnostic ignored "-Wattributes" - __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; - #pragma GCC diagnostic pop - #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { + uint16_t v; + }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE( addr, val ) ( void ) ( ( ( ( struct T_UINT16_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) ) #endif #ifndef __UNALIGNED_UINT16_READ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpacked" - #pragma GCC diagnostic ignored "-Wattributes" - __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; - #pragma GCC diagnostic pop - #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { + uint16_t v; + }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ( addr ) ( ( ( const struct T_UINT16_READ * ) ( const void * ) ( addr ) )->v ) #endif #ifndef __UNALIGNED_UINT32_WRITE - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpacked" - #pragma GCC diagnostic ignored "-Wattributes" - __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; - #pragma GCC diagnostic pop - #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { + uint32_t v; + }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE( addr, val ) ( void ) ( ( ( ( struct T_UINT32_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) ) #endif #ifndef __UNALIGNED_UINT32_READ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpacked" - #pragma GCC diagnostic ignored "-Wattributes" - __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; - #pragma GCC diagnostic pop - #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { + uint32_t v; + }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ( addr ) ( ( ( const struct T_UINT32_READ * ) ( const void * ) ( addr ) )->v ) #endif #ifndef __ALIGNED - #define __ALIGNED(x) __attribute__((aligned(x))) + #define __ALIGNED( x ) __attribute__( ( aligned( x ) ) ) #endif #ifndef __RESTRICT - #define __RESTRICT __restrict + #define __RESTRICT __restrict #endif #ifndef __COMPILER_BARRIER - #define __COMPILER_BARRIER() __ASM volatile("":::"memory") + #define __COMPILER_BARRIER() __ASM volatile ( "" ::: "memory" ) #endif /* ######################### Startup and Lowlevel Init ######################## */ @@ -122,755 +134,796 @@ #ifndef __PROGRAM_START /** - \brief Initializes data and bss sections - \details This default implementations initialized all data and additional bss - sections relying on .copy.table and .zero.table specified properly - in the used linker script. - + * \brief Initializes data and bss sections + * \details This default implementations initialized all data and additional bss + * sections relying on .copy.table and .zero.table specified properly + * in the used linker script. + * */ -__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) -{ - extern void _start(void) __NO_RETURN; - - typedef struct { - uint32_t const* src; - uint32_t* dest; - uint32_t wlen; - } __copy_table_t; - - typedef struct { - uint32_t* dest; - uint32_t wlen; - } __zero_table_t; - - extern const __copy_table_t __copy_table_start__; - extern const __copy_table_t __copy_table_end__; - extern const __zero_table_t __zero_table_start__; - extern const __zero_table_t __zero_table_end__; + __STATIC_FORCEINLINE __NO_RETURN void __cmsis_start( void ) + { + extern void _start( void ) __NO_RETURN; - for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { - for(uint32_t i=0u; iwlen; ++i) { - pTable->dest[i] = pTable->src[i]; + typedef struct + { + uint32_t const * src; + uint32_t * dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct + { + uint32_t * dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for( __copy_table_t const * pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable ) + { + for( uint32_t i = 0u; i < pTable->wlen; ++i ) + { + pTable->dest[ i ] = pTable->src[ i ]; + } + } + + for( __zero_table_t const * pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable ) + { + for( uint32_t i = 0u; i < pTable->wlen; ++i ) + { + pTable->dest[ i ] = 0u; + } + } + + _start(); } - } - - for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { - for(uint32_t i=0u; iwlen; ++i) { - pTable->dest[i] = 0u; - } - } - - _start(); -} - -#define __PROGRAM_START __cmsis_start -#endif + + #define __PROGRAM_START __cmsis_start +#endif /* ifndef __PROGRAM_START */ #ifndef __INITIAL_SP -#define __INITIAL_SP __StackTop + #define __INITIAL_SP __StackTop #endif #ifndef __STACK_LIMIT -#define __STACK_LIMIT __StackLimit + #define __STACK_LIMIT __StackLimit #endif #ifndef __VECTOR_TABLE -#define __VECTOR_TABLE __Vectors + #define __VECTOR_TABLE __Vectors #endif #ifndef __VECTOR_TABLE_ATTRIBUTE -#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) + #define __VECTOR_TABLE_ATTRIBUTE __attribute__( ( used, section( ".vectors" ) ) ) #endif /* ########################### Core Function Access ########################### */ + /** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions - @{ + * \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + * @{ */ /** - \brief Enable IRQ Interrupts - \details Enables IRQ interrupts by clearing the I-bit in the CPSR. - Can only be executed in Privileged modes. + * \brief Enable IRQ Interrupts + * \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + * Can only be executed in Privileged modes. */ -__STATIC_FORCEINLINE void __enable_irq(void) +__STATIC_FORCEINLINE void __enable_irq( void ) { - __ASM volatile ("cpsie i" : : : "memory"); + __ASM volatile ( "cpsie i" : : : "memory" ); } /** - \brief Disable IRQ Interrupts - \details Disables IRQ interrupts by setting the I-bit in the CPSR. - Can only be executed in Privileged modes. + * \brief Disable IRQ Interrupts + * \details Disables IRQ interrupts by setting the I-bit in the CPSR. + * Can only be executed in Privileged modes. */ -__STATIC_FORCEINLINE void __disable_irq(void) +__STATIC_FORCEINLINE void __disable_irq( void ) { - __ASM volatile ("cpsid i" : : : "memory"); + __ASM volatile ( "cpsid i" : : : "memory" ); } /** - \brief Get Control Register - \details Returns the content of the Control Register. - \return Control Register value + * \brief Get Control Register + * \details Returns the content of the Control Register. + * \return Control Register value */ -__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +__STATIC_FORCEINLINE uint32_t __get_CONTROL( void ) { - uint32_t result; + uint32_t result; - __ASM volatile ("MRS %0, control" : "=r" (result) ); - return(result); + __ASM volatile ( "MRS %0, control" : "=r" ( result ) ); + + return( result ); } -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +#if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + /** - \brief Get Control Register (non-secure) - \details Returns the content of the non-secure Control Register when in secure mode. - \return non-secure Control Register value + * \brief Get Control Register (non-secure) + * \details Returns the content of the non-secure Control Register when in secure mode. + * \return non-secure Control Register value */ -__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS( void ) + { + uint32_t result; - __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); - return(result); + __ASM volatile ( "MRS %0, control_ns" : "=r" ( result ) ); + + return( result ); + } +#endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ + + +/** + * \brief Set Control Register + * \details Writes the given value to the Control Register. + * \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL( uint32_t control ) +{ + __ASM volatile ( "MSR control, %0" : : "r" ( control ) : "memory" ); } + + +#if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + +/** + * \brief Set Control Register (non-secure) + * \details Writes the given value to the non-secure Control Register when in secure state. + * \param [in] control Control Register value to set + */ + __STATIC_FORCEINLINE void __TZ_set_CONTROL_NS( uint32_t control ) + { + __ASM volatile ( "MSR control_ns, %0" : : "r" ( control ) : "memory" ); + } #endif /** - \brief Set Control Register - \details Writes the given value to the Control Register. - \param [in] control Control Register value to set + * \brief Get IPSR Register + * \details Returns the content of the IPSR Register. + * \return IPSR Register value */ -__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +__STATIC_FORCEINLINE uint32_t __get_IPSR( void ) { - __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + uint32_t result; + + __ASM volatile ( "MRS %0, ipsr" : "=r" ( result ) ); + + return( result ); } -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** - \brief Set Control Register (non-secure) - \details Writes the given value to the non-secure Control Register when in secure state. - \param [in] control Control Register value to set + * \brief Get APSR Register + * \details Returns the content of the APSR Register. + * \return APSR Register value */ -__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +__STATIC_FORCEINLINE uint32_t __get_APSR( void ) { - __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + uint32_t result; + + __ASM volatile ( "MRS %0, apsr" : "=r" ( result ) ); + + return( result ); } + + +/** + * \brief Get xPSR Register + * \details Returns the content of the xPSR Register. + * \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR( void ) +{ + uint32_t result; + + __ASM volatile ( "MRS %0, xpsr" : "=r" ( result ) ); + + return( result ); +} + + +/** + * \brief Get Process Stack Pointer + * \details Returns the current value of the Process Stack Pointer (PSP). + * \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP( void ) +{ + uint32_t result; + + __ASM volatile ( "MRS %0, psp" : "=r" ( result ) ); + + return( result ); +} + + +#if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + +/** + * \brief Get Process Stack Pointer (non-secure) + * \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + * \return PSP Register value + */ + __STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS( void ) + { + uint32_t result; + + __ASM volatile ( "MRS %0, psp_ns" : "=r" ( result ) ); + + return( result ); + } +#endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ + + +/** + * \brief Set Process Stack Pointer + * \details Assigns the given value to the Process Stack Pointer (PSP). + * \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP( uint32_t topOfProcStack ) +{ + __ASM volatile ( "MSR psp, %0" : : "r" ( topOfProcStack ) : ); +} + + +#if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + +/** + * \brief Set Process Stack Pointer (non-secure) + * \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + * \param [in] topOfProcStack Process Stack Pointer value to set + */ + __STATIC_FORCEINLINE void __TZ_set_PSP_NS( uint32_t topOfProcStack ) + { + __ASM volatile ( "MSR psp_ns, %0" : : "r" ( topOfProcStack ) : ); + } #endif /** - \brief Get IPSR Register - \details Returns the content of the IPSR Register. - \return IPSR Register value + * \brief Get Main Stack Pointer + * \details Returns the current value of the Main Stack Pointer (MSP). + * \return MSP Register value */ -__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +__STATIC_FORCEINLINE uint32_t __get_MSP( void ) { - uint32_t result; + uint32_t result; - __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); - return(result); + __ASM volatile ( "MRS %0, msp" : "=r" ( result ) ); + + return( result ); } +#if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + +/** + * \brief Get Main Stack Pointer (non-secure) + * \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + * \return MSP Register value + */ + __STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS( void ) + { + uint32_t result; + + __ASM volatile ( "MRS %0, msp_ns" : "=r" ( result ) ); + + return( result ); + } +#endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ + + /** - \brief Get APSR Register - \details Returns the content of the APSR Register. - \return APSR Register value + * \brief Set Main Stack Pointer + * \details Assigns the given value to the Main Stack Pointer (MSP). + * \param [in] topOfMainStack Main Stack Pointer value to set */ -__STATIC_FORCEINLINE uint32_t __get_APSR(void) +__STATIC_FORCEINLINE void __set_MSP( uint32_t topOfMainStack ) { - uint32_t result; - - __ASM volatile ("MRS %0, apsr" : "=r" (result) ); - return(result); + __ASM volatile ( "MSR msp, %0" : : "r" ( topOfMainStack ) : ); } +#if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + /** - \brief Get xPSR Register - \details Returns the content of the xPSR Register. - \return xPSR Register value + * \brief Set Main Stack Pointer (non-secure) + * \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + * \param [in] topOfMainStack Main Stack Pointer value to set */ -__STATIC_FORCEINLINE uint32_t __get_xPSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); - return(result); -} - - -/** - \brief Get Process Stack Pointer - \details Returns the current value of the Process Stack Pointer (PSP). - \return PSP Register value - */ -__STATIC_FORCEINLINE uint32_t __get_PSP(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, psp" : "=r" (result) ); - return(result); -} - - -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) -/** - \brief Get Process Stack Pointer (non-secure) - \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. - \return PSP Register value - */ -__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); - return(result); -} + __STATIC_FORCEINLINE void __TZ_set_MSP_NS( uint32_t topOfMainStack ) + { + __ASM volatile ( "MSR msp_ns, %0" : : "r" ( topOfMainStack ) : ); + } #endif +#if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + /** - \brief Set Process Stack Pointer - \details Assigns the given value to the Process Stack Pointer (PSP). - \param [in] topOfProcStack Process Stack Pointer value to set + * \brief Get Stack Pointer (non-secure) + * \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + * \return SP Register value */ -__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) + __STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS( void ) + { + uint32_t result; + + __ASM volatile ( "MRS %0, sp_ns" : "=r" ( result ) ); + + return( result ); + } + + +/** + * \brief Set Stack Pointer (non-secure) + * \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + * \param [in] topOfStack Stack Pointer value to set + */ + __STATIC_FORCEINLINE void __TZ_set_SP_NS( uint32_t topOfStack ) + { + __ASM volatile ( "MSR sp_ns, %0" : : "r" ( topOfStack ) : ); + } +#endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ + + +/** + * \brief Get Priority Mask + * \details Returns the current state of the priority mask bit from the Priority Mask Register. + * \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK( void ) { - __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); + uint32_t result; + + __ASM volatile ( "MRS %0, primask" : "=r" ( result ) ); + + return( result ); } -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +#if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + /** - \brief Set Process Stack Pointer (non-secure) - \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. - \param [in] topOfProcStack Process Stack Pointer value to set + * \brief Get Priority Mask (non-secure) + * \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + * \return Priority Mask value */ -__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) + __STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS( void ) + { + uint32_t result; + + __ASM volatile ( "MRS %0, primask_ns" : "=r" ( result ) ); + + return( result ); + } +#endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ + + +/** + * \brief Set Priority Mask + * \details Assigns the given value to the Priority Mask Register. + * \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK( uint32_t priMask ) { - __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); + __ASM volatile ( "MSR primask, %0" : : "r" ( priMask ) : "memory" ); } + + +#if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + +/** + * \brief Set Priority Mask (non-secure) + * \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + * \param [in] priMask Priority Mask + */ + __STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS( uint32_t priMask ) + { + __ASM volatile ( "MSR primask_ns, %0" : : "r" ( priMask ) : "memory" ); + } #endif +#if ( ( defined( __ARM_ARCH_7M__ ) && ( __ARM_ARCH_7M__ == 1 ) ) || \ + ( defined( __ARM_ARCH_7EM__ ) && ( __ARM_ARCH_7EM__ == 1 ) ) || \ + ( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) ) + /** - \brief Get Main Stack Pointer - \details Returns the current value of the Main Stack Pointer (MSP). - \return MSP Register value + * \brief Enable FIQ + * \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + * Can only be executed in Privileged modes. */ -__STATIC_FORCEINLINE uint32_t __get_MSP(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, msp" : "=r" (result) ); - return(result); -} - - -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) -/** - \brief Get Main Stack Pointer (non-secure) - \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. - \return MSP Register value - */ -__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); - return(result); -} -#endif + __STATIC_FORCEINLINE void __enable_fault_irq( void ) + { + __ASM volatile ( "cpsie f" : : : "memory" ); + } /** - \brief Set Main Stack Pointer - \details Assigns the given value to the Main Stack Pointer (MSP). - \param [in] topOfMainStack Main Stack Pointer value to set + * \brief Disable FIQ + * \details Disables FIQ interrupts by setting the F-bit in the CPSR. + * Can only be executed in Privileged modes. */ -__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) -{ - __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); -} - - -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) -/** - \brief Set Main Stack Pointer (non-secure) - \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. - \param [in] topOfMainStack Main Stack Pointer value to set - */ -__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) -{ - __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); -} -#endif - - -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) -/** - \brief Get Stack Pointer (non-secure) - \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. - \return SP Register value - */ -__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); - return(result); -} + __STATIC_FORCEINLINE void __disable_fault_irq( void ) + { + __ASM volatile ( "cpsid f" : : : "memory" ); + } /** - \brief Set Stack Pointer (non-secure) - \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. - \param [in] topOfStack Stack Pointer value to set + * \brief Get Base Priority + * \details Returns the current value of the Base Priority register. + * \return Base Priority register value */ -__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) -{ - __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); -} -#endif + __STATIC_FORCEINLINE uint32_t __get_BASEPRI( void ) + { + uint32_t result; + + __ASM volatile ( "MRS %0, basepri" : "=r" ( result ) ); + + return( result ); + } + + + #if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + +/** + * \brief Get Base Priority (non-secure) + * \details Returns the current value of the non-secure Base Priority register when in secure state. + * \return Base Priority register value + */ + __STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS( void ) + { + uint32_t result; + + __ASM volatile ( "MRS %0, basepri_ns" : "=r" ( result ) ); + + return( result ); + } + #endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ /** - \brief Get Priority Mask - \details Returns the current state of the priority mask bit from the Priority Mask Register. - \return Priority Mask value + * \brief Set Base Priority + * \details Assigns the given value to the Base Priority register. + * \param [in] basePri Base Priority value to set */ -__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, primask" : "=r" (result) ); - return(result); -} + __STATIC_FORCEINLINE void __set_BASEPRI( uint32_t basePri ) + { + __ASM volatile ( "MSR basepri, %0" : : "r" ( basePri ) : "memory" ); + } -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) + #if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + /** - \brief Get Priority Mask (non-secure) - \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. - \return Priority Mask value + * \brief Set Base Priority (non-secure) + * \details Assigns the given value to the non-secure Base Priority register when in secure state. + * \param [in] basePri Base Priority value to set */ -__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); - return(result); -} -#endif + __STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS( uint32_t basePri ) + { + __ASM volatile ( "MSR basepri_ns, %0" : : "r" ( basePri ) : "memory" ); + } + #endif /** - \brief Set Priority Mask - \details Assigns the given value to the Priority Mask Register. - \param [in] priMask Priority Mask + * \brief Set Base Priority with condition + * \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + * or the new value increases the BASEPRI priority level. + * \param [in] basePri Base Priority value to set */ -__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) -{ - __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); -} - - -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) -/** - \brief Set Priority Mask (non-secure) - \details Assigns the given value to the non-secure Priority Mask Register when in secure state. - \param [in] priMask Priority Mask - */ -__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) -{ - __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); -} -#endif - - -#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) -/** - \brief Enable FIQ - \details Enables FIQ interrupts by clearing the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__STATIC_FORCEINLINE void __enable_fault_irq(void) -{ - __ASM volatile ("cpsie f" : : : "memory"); -} + __STATIC_FORCEINLINE void __set_BASEPRI_MAX( uint32_t basePri ) + { + __ASM volatile ( "MSR basepri_max, %0" : : "r" ( basePri ) : "memory" ); + } /** - \brief Disable FIQ - \details Disables FIQ interrupts by setting the F-bit in the CPSR. - Can only be executed in Privileged modes. + * \brief Get Fault Mask + * \details Returns the current value of the Fault Mask register. + * \return Fault Mask register value */ -__STATIC_FORCEINLINE void __disable_fault_irq(void) -{ - __ASM volatile ("cpsid f" : : : "memory"); -} + __STATIC_FORCEINLINE uint32_t __get_FAULTMASK( void ) + { + uint32_t result; + + __ASM volatile ( "MRS %0, faultmask" : "=r" ( result ) ); + + return( result ); + } + + + #if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + +/** + * \brief Get Fault Mask (non-secure) + * \details Returns the current value of the non-secure Fault Mask register when in secure state. + * \return Fault Mask register value + */ + __STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS( void ) + { + uint32_t result; + + __ASM volatile ( "MRS %0, faultmask_ns" : "=r" ( result ) ); + + return( result ); + } + #endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ /** - \brief Get Base Priority - \details Returns the current value of the Base Priority register. - \return Base Priority register value + * \brief Set Fault Mask + * \details Assigns the given value to the Fault Mask register. + * \param [in] faultMask Fault Mask value to set */ -__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, basepri" : "=r" (result) ); - return(result); -} + __STATIC_FORCEINLINE void __set_FAULTMASK( uint32_t faultMask ) + { + __ASM volatile ( "MSR faultmask, %0" : : "r" ( faultMask ) : "memory" ); + } -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) -/** - \brief Get Base Priority (non-secure) - \details Returns the current value of the non-secure Base Priority register when in secure state. - \return Base Priority register value - */ -__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); - return(result); -} -#endif - + #if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) /** - \brief Set Base Priority - \details Assigns the given value to the Base Priority register. - \param [in] basePri Base Priority value to set + * \brief Set Fault Mask (non-secure) + * \details Assigns the given value to the non-secure Fault Mask register when in secure state. + * \param [in] faultMask Fault Mask value to set */ -__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) -{ - __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); -} - - -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) -/** - \brief Set Base Priority (non-secure) - \details Assigns the given value to the non-secure Base Priority register when in secure state. - \param [in] basePri Base Priority value to set - */ -__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) -{ - __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); -} -#endif - - -/** - \brief Set Base Priority with condition - \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, - or the new value increases the BASEPRI priority level. - \param [in] basePri Base Priority value to set - */ -__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) -{ - __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); -} - - -/** - \brief Get Fault Mask - \details Returns the current value of the Fault Mask register. - \return Fault Mask register value - */ -__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); - return(result); -} - - -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) -/** - \brief Get Fault Mask (non-secure) - \details Returns the current value of the non-secure Fault Mask register when in secure state. - \return Fault Mask register value - */ -__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); - return(result); -} -#endif - - -/** - \brief Set Fault Mask - \details Assigns the given value to the Fault Mask register. - \param [in] faultMask Fault Mask value to set - */ -__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) -{ - __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); -} - - -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) -/** - \brief Set Fault Mask (non-secure) - \details Assigns the given value to the non-secure Fault Mask register when in secure state. - \param [in] faultMask Fault Mask value to set - */ -__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) -{ - __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); -} -#endif + __STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS( uint32_t faultMask ) + { + __ASM volatile ( "MSR faultmask_ns, %0" : : "r" ( faultMask ) : "memory" ); + } + #endif #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + * (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + * (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ -#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ - (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +#if ( ( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) || \ + ( defined( __ARM_ARCH_8M_BASE__ ) && ( __ARM_ARCH_8M_BASE__ == 1 ) ) ) /** - \brief Get Process Stack Pointer Limit - Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure - Stack Pointer Limit register hence zero is returned always in non-secure - mode. - - \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). - \return PSPLIM Register value + * \brief Get Process Stack Pointer Limit + * Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + * Stack Pointer Limit register hence zero is returned always in non-secure + * mode. + * + * \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + * \return PSPLIM Register value */ -__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) -{ -#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ - (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) - // without main extensions, the non-secure PSPLIM is RAZ/WI - return 0U; -#else - uint32_t result; - __ASM volatile ("MRS %0, psplim" : "=r" (result) ); - return result; -#endif -} + __STATIC_FORCEINLINE uint32_t __get_PSPLIM( void ) + { + #if ( !( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) && \ + ( !defined( __ARM_FEATURE_CMSE ) || ( __ARM_FEATURE_CMSE < 3 ) ) ) + /* without main extensions, the non-secure PSPLIM is RAZ/WI */ + return 0U; + #else + uint32_t result; + __ASM volatile ( "MRS %0, psplim" : "=r" ( result ) ); + return result; + #endif + } + + #if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) -#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) /** - \brief Get Process Stack Pointer Limit (non-secure) - Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure - Stack Pointer Limit register hence zero is returned always. - - \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. - \return PSPLIM Register value + * \brief Get Process Stack Pointer Limit (non-secure) + * Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + * Stack Pointer Limit register hence zero is returned always. + * + * \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + * \return PSPLIM Register value */ -__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) -{ -#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) - // without main extensions, the non-secure PSPLIM is RAZ/WI - return 0U; -#else - uint32_t result; - __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); - return result; -#endif -} -#endif + __STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS( void ) + { + #if ( !( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) ) + /* without main extensions, the non-secure PSPLIM is RAZ/WI */ + return 0U; + #else + uint32_t result; + __ASM volatile ( "MRS %0, psplim_ns" : "=r" ( result ) ); + return result; + #endif + } + #endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ /** - \brief Set Process Stack Pointer Limit - Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure - Stack Pointer Limit register hence the write is silently ignored in non-secure - mode. - - \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). - \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + * \brief Set Process Stack Pointer Limit + * Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + * Stack Pointer Limit register hence the write is silently ignored in non-secure + * mode. + * + * \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + * \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ -__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) -{ -#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ - (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) - // without main extensions, the non-secure PSPLIM is RAZ/WI - (void)ProcStackPtrLimit; -#else - __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); -#endif -} + __STATIC_FORCEINLINE void __set_PSPLIM( uint32_t ProcStackPtrLimit ) + { + #if ( !( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) && \ + ( !defined( __ARM_FEATURE_CMSE ) || ( __ARM_FEATURE_CMSE < 3 ) ) ) + /* without main extensions, the non-secure PSPLIM is RAZ/WI */ + ( void ) ProcStackPtrLimit; + #else + __ASM volatile ( "MSR psplim, %0" : : "r" ( ProcStackPtrLimit ) ); + #endif + } -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) + #if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + /** - \brief Set Process Stack Pointer (non-secure) - Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure - Stack Pointer Limit register hence the write is silently ignored. - - \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. - \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + * \brief Set Process Stack Pointer (non-secure) + * Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + * Stack Pointer Limit register hence the write is silently ignored. + * + * \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + * \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ -__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) -{ -#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) - // without main extensions, the non-secure PSPLIM is RAZ/WI - (void)ProcStackPtrLimit; -#else - __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); -#endif -} -#endif + __STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS( uint32_t ProcStackPtrLimit ) + { + #if ( !( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) ) + /* without main extensions, the non-secure PSPLIM is RAZ/WI */ + ( void ) ProcStackPtrLimit; + #else + __ASM volatile ( "MSR psplim_ns, %0\n" : : "r" ( ProcStackPtrLimit ) ); + #endif + } + #endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ /** - \brief Get Main Stack Pointer Limit - Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure - Stack Pointer Limit register hence zero is returned always in non-secure - mode. - - \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). - \return MSPLIM Register value + * \brief Get Main Stack Pointer Limit + * Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + * Stack Pointer Limit register hence zero is returned always in non-secure + * mode. + * + * \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + * \return MSPLIM Register value */ -__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) -{ -#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ - (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) - // without main extensions, the non-secure MSPLIM is RAZ/WI - return 0U; -#else - uint32_t result; - __ASM volatile ("MRS %0, msplim" : "=r" (result) ); - return result; -#endif -} + __STATIC_FORCEINLINE uint32_t __get_MSPLIM( void ) + { + #if ( !( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) && \ + ( !defined( __ARM_FEATURE_CMSE ) || ( __ARM_FEATURE_CMSE < 3 ) ) ) + /* without main extensions, the non-secure MSPLIM is RAZ/WI */ + return 0U; + #else + uint32_t result; + __ASM volatile ( "MRS %0, msplim" : "=r" ( result ) ); + return result; + #endif + } -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) + #if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + /** - \brief Get Main Stack Pointer Limit (non-secure) - Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure - Stack Pointer Limit register hence zero is returned always. - - \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. - \return MSPLIM Register value + * \brief Get Main Stack Pointer Limit (non-secure) + * Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + * Stack Pointer Limit register hence zero is returned always. + * + * \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + * \return MSPLIM Register value */ -__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) -{ -#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) - // without main extensions, the non-secure MSPLIM is RAZ/WI - return 0U; -#else - uint32_t result; - __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); - return result; -#endif -} -#endif + __STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS( void ) + { + #if ( !( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) ) + /* without main extensions, the non-secure MSPLIM is RAZ/WI */ + return 0U; + #else + uint32_t result; + __ASM volatile ( "MRS %0, msplim_ns" : "=r" ( result ) ); + return result; + #endif + } + #endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ /** - \brief Set Main Stack Pointer Limit - Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure - Stack Pointer Limit register hence the write is silently ignored in non-secure - mode. - - \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). - \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + * \brief Set Main Stack Pointer Limit + * Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + * Stack Pointer Limit register hence the write is silently ignored in non-secure + * mode. + * + * \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + * \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set */ -__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) -{ -#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ - (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) - // without main extensions, the non-secure MSPLIM is RAZ/WI - (void)MainStackPtrLimit; -#else - __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); -#endif -} + __STATIC_FORCEINLINE void __set_MSPLIM( uint32_t MainStackPtrLimit ) + { + #if ( !( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) && \ + ( !defined( __ARM_FEATURE_CMSE ) || ( __ARM_FEATURE_CMSE < 3 ) ) ) + /* without main extensions, the non-secure MSPLIM is RAZ/WI */ + ( void ) MainStackPtrLimit; + #else + __ASM volatile ( "MSR msplim, %0" : : "r" ( MainStackPtrLimit ) ); + #endif + } -#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) + #if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) + /** - \brief Set Main Stack Pointer Limit (non-secure) - Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure - Stack Pointer Limit register hence the write is silently ignored. - - \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. - \param [in] MainStackPtrLimit Main Stack Pointer value to set + * \brief Set Main Stack Pointer Limit (non-secure) + * Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + * Stack Pointer Limit register hence the write is silently ignored. + * + * \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + * \param [in] MainStackPtrLimit Main Stack Pointer value to set */ -__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) -{ -#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) - // without main extensions, the non-secure MSPLIM is RAZ/WI - (void)MainStackPtrLimit; -#else - __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); -#endif -} -#endif + __STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS( uint32_t MainStackPtrLimit ) + { + #if ( !( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) ) + /* without main extensions, the non-secure MSPLIM is RAZ/WI */ + ( void ) MainStackPtrLimit; + #else + __ASM volatile ( "MSR msplim_ns, %0" : : "r" ( MainStackPtrLimit ) ); + #endif + } + #endif /* if ( defined( __ARM_FEATURE_CMSE ) && ( __ARM_FEATURE_CMSE == 3 ) ) */ #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ - (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + * (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /** - \brief Get FPSCR - \details Returns the current value of the Floating Point Status/Control register. - \return Floating Point Status/Control register value + * \brief Get FPSCR + * \details Returns the current value of the Floating Point Status/Control register. + * \return Floating Point Status/Control register value */ -__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +__STATIC_FORCEINLINE uint32_t __get_FPSCR( void ) { -#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ - (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) -#if __has_builtin(__builtin_arm_get_fpscr) -// Re-enable using built-in when GCC has been fixed -// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) - /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ - return __builtin_arm_get_fpscr(); -#else - uint32_t result; + #if ( ( defined( __FPU_PRESENT ) && ( __FPU_PRESENT == 1U ) ) && \ + ( defined( __FPU_USED ) && ( __FPU_USED == 1U ) ) ) + #if __has_builtin( __builtin_arm_get_fpscr ) +/* Re-enable using built-in when GCC has been fixed */ +/* || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) */ + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); + #else + uint32_t result; - __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); - return(result); -#endif -#else - return(0U); -#endif + __ASM volatile ( "VMRS %0, fpscr" : "=r" ( result ) ); + return( result ); + #endif + #else /* if ( ( defined( __FPU_PRESENT ) && ( __FPU_PRESENT == 1U ) ) && ( defined( __FPU_USED ) && ( __FPU_USED == 1U ) ) ) */ + return( 0U ); + #endif /* if ( ( defined( __FPU_PRESENT ) && ( __FPU_PRESENT == 1U ) ) && ( defined( __FPU_USED ) && ( __FPU_USED == 1U ) ) ) */ } /** - \brief Set FPSCR - \details Assigns the given value to the Floating Point Status/Control register. - \param [in] fpscr Floating Point Status/Control value to set + * \brief Set FPSCR + * \details Assigns the given value to the Floating Point Status/Control register. + * \param [in] fpscr Floating Point Status/Control value to set */ -__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +__STATIC_FORCEINLINE void __set_FPSCR( uint32_t fpscr ) { -#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ - (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) -#if __has_builtin(__builtin_arm_set_fpscr) -// Re-enable using built-in when GCC has been fixed -// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) - /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ - __builtin_arm_set_fpscr(fpscr); -#else - __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); -#endif -#else - (void)fpscr; -#endif + #if ( ( defined( __FPU_PRESENT ) && ( __FPU_PRESENT == 1U ) ) && \ + ( defined( __FPU_USED ) && ( __FPU_USED == 1U ) ) ) + #if __has_builtin( __builtin_arm_set_fpscr ) +/* Re-enable using built-in when GCC has been fixed */ +/* || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) */ + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr( fpscr ); + #else + __ASM volatile ( "VMSR fpscr, %0" : : "r" ( fpscr ) : "vfpcc", "memory" ); + #endif + #else + ( void ) fpscr; + #endif /* if ( ( defined( __FPU_PRESENT ) && ( __FPU_PRESENT == 1U ) ) && ( defined( __FPU_USED ) && ( __FPU_USED == 1U ) ) ) */ } @@ -878,1291 +931,1445 @@ __STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) /* ########################## Core Instruction Access ######################### */ + /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface - Access to dedicated instructions - @{ -*/ + * Access to dedicated instructions + * @{ + */ /* Define macros for porting to both thumb1 and thumb2. * For thumb1, use low register (r0-r7), specified by constraint "l" * Otherwise, use general registers, specified by constraint "r" */ -#if defined (__thumb__) && !defined (__thumb2__) -#define __CMSIS_GCC_OUT_REG(r) "=l" (r) -#define __CMSIS_GCC_RW_REG(r) "+l" (r) -#define __CMSIS_GCC_USE_REG(r) "l" (r) +#if defined( __thumb__ ) && !defined( __thumb2__ ) + #define __CMSIS_GCC_OUT_REG( r ) "=l" ( r ) + #define __CMSIS_GCC_RW_REG( r ) "+l" ( r ) + #define __CMSIS_GCC_USE_REG( r ) "l" ( r ) #else -#define __CMSIS_GCC_OUT_REG(r) "=r" (r) -#define __CMSIS_GCC_RW_REG(r) "+r" (r) -#define __CMSIS_GCC_USE_REG(r) "r" (r) + #define __CMSIS_GCC_OUT_REG( r ) "=r" ( r ) + #define __CMSIS_GCC_RW_REG( r ) "+r" ( r ) + #define __CMSIS_GCC_USE_REG( r ) "r" ( r ) #endif /** - \brief No Operation - \details No Operation does nothing. This instruction can be used for code alignment purposes. + * \brief No Operation + * \details No Operation does nothing. This instruction can be used for code alignment purposes. */ -#define __NOP() __ASM volatile ("nop") +#define __NOP() __ASM volatile ( "nop" ) /** - \brief Wait For Interrupt - \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + * \brief Wait For Interrupt + * \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. */ -#define __WFI() __ASM volatile ("wfi":::"memory") +#define __WFI() __ASM volatile ( "wfi" ::: "memory" ) /** - \brief Wait For Event - \details Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. + * \brief Wait For Event + * \details Wait For Event is a hint instruction that permits the processor to enter + * a low-power state until one of a number of events occurs. */ -#define __WFE() __ASM volatile ("wfe":::"memory") +#define __WFE() __ASM volatile ( "wfe" ::: "memory" ) /** - \brief Send Event - \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + * \brief Send Event + * \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. */ -#define __SEV() __ASM volatile ("sev") +#define __SEV() __ASM volatile ( "sev" ) /** - \brief Instruction Synchronization Barrier - \details Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or memory, - after the instruction has been completed. + * \brief Instruction Synchronization Barrier + * \details Instruction Synchronization Barrier flushes the pipeline in the processor, + * so that all instructions following the ISB are fetched from cache or memory, + * after the instruction has been completed. */ -__STATIC_FORCEINLINE void __ISB(void) +__STATIC_FORCEINLINE void __ISB( void ) { - __ASM volatile ("isb 0xF":::"memory"); + __ASM volatile ( "isb 0xF" ::: "memory" ); } /** - \brief Data Synchronization Barrier - \details Acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. + * \brief Data Synchronization Barrier + * \details Acts as a special kind of Data Memory Barrier. + * It completes when all explicit memory accesses before this instruction complete. */ -__STATIC_FORCEINLINE void __DSB(void) +__STATIC_FORCEINLINE void __DSB( void ) { - __ASM volatile ("dsb 0xF":::"memory"); + __ASM volatile ( "dsb 0xF" ::: "memory" ); } /** - \brief Data Memory Barrier - \details Ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. + * \brief Data Memory Barrier + * \details Ensures the apparent order of the explicit memory operations before + * and after the instruction, without ensuring their completion. */ -__STATIC_FORCEINLINE void __DMB(void) +__STATIC_FORCEINLINE void __DMB( void ) { - __ASM volatile ("dmb 0xF":::"memory"); + __ASM volatile ( "dmb 0xF" ::: "memory" ); } /** - \brief Reverse byte order (32 bit) - \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. - \param [in] value Value to reverse - \return Reversed value + * \brief Reverse byte order (32 bit) + * \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + * \param [in] value Value to reverse + * \return Reversed value */ -__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +__STATIC_FORCEINLINE uint32_t __REV( uint32_t value ) { -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) - return __builtin_bswap32(value); -#else - uint32_t result; + #if ( __GNUC__ > 4 ) || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 5 ) + return __builtin_bswap32( value ); + #else + uint32_t result; - __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return result; -#endif + __ASM( "rev %0, %1" : __CMSIS_GCC_OUT_REG( result ) : __CMSIS_GCC_USE_REG( value ) ); + return result; + #endif } /** - \brief Reverse byte order (16 bit) - \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. - \param [in] value Value to reverse - \return Reversed value + * \brief Reverse byte order (16 bit) + * \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + * \param [in] value Value to reverse + * \return Reversed value */ -__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) -{ - uint32_t result; - - __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return result; -} - - -/** - \brief Reverse byte order (16 bit) - \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. - \param [in] value Value to reverse - \return Reversed value - */ -__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) -{ -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - return (int16_t)__builtin_bswap16(value); -#else - int16_t result; - - __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return result; -#endif -} - - -/** - \brief Rotate Right in unsigned value (32 bit) - \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - \param [in] op1 Value to rotate - \param [in] op2 Number of Bits to rotate - \return Rotated value - */ -__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) -{ - op2 %= 32U; - if (op2 == 0U) - { - return op1; - } - return (op1 >> op2) | (op1 << (32U - op2)); -} - - -/** - \brief Breakpoint - \details Causes the processor to enter Debug state. - Debug tools can use this to investigate system state when the instruction at a particular address is reached. - \param [in] value is ignored by the processor. - If required, a debugger can use it to store additional information about the breakpoint. - */ -#define __BKPT(value) __ASM volatile ("bkpt "#value) - - -/** - \brief Reverse bit order of value - \details Reverses the bit order of the given value. - \param [in] value Value to reverse - \return Reversed value - */ -__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - -#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) - __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); -#else - uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ - - result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value != 0U; value >>= 1U) - { - result <<= 1U; - result |= value & 1U; - s--; - } - result <<= s; /* shift when v's highest bits are zero */ -#endif - return result; -} - - -/** - \brief Count leading zeros - \details Counts the number of leading zeros of a data value. - \param [in] value Value to count the leading zeros - \return number of leading zeros in value - */ -__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) -{ - /* Even though __builtin_clz produces a CLZ instruction on ARM, formally - __builtin_clz(0) is undefined behaviour, so handle this case specially. - This guarantees ARM-compatible results if happening to compile on a non-ARM - target, and ensures the compiler doesn't decide to activate any - optimisations using the logic "value was passed to __builtin_clz, so it - is non-zero". - ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a - single CLZ instruction. - */ - if (value == 0U) - { - return 32U; - } - return __builtin_clz(value); -} - - -#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ - (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) -/** - \brief LDR Exclusive (8 bit) - \details Executes a exclusive LDR instruction for 8 bit value. - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +__STATIC_FORCEINLINE uint32_t __REV16( uint32_t value ) { uint32_t result; -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint8_t) result); /* Add explicit type cast here */ + __ASM( "rev16 %0, %1" : __CMSIS_GCC_OUT_REG( result ) : __CMSIS_GCC_USE_REG( value ) ); + return result; } /** - \brief LDR Exclusive (16 bit) - \details Executes a exclusive LDR instruction for 16 bit values. - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) + * \brief Reverse byte order (16 bit) + * \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + * \param [in] value Value to reverse + * \return Reversed value */ -__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +__STATIC_FORCEINLINE int16_t __REVSH( int16_t value ) +{ + #if ( __GNUC__ > 4 ) || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 8 ) + return ( int16_t ) __builtin_bswap16( value ); + #else + int16_t result; + + __ASM( "revsh %0, %1" : __CMSIS_GCC_OUT_REG( result ) : __CMSIS_GCC_USE_REG( value ) ); + return result; + #endif +} + + +/** + * \brief Rotate Right in unsigned value (32 bit) + * \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + * \param [in] op1 Value to rotate + * \param [in] op2 Number of Bits to rotate + * \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR( uint32_t op1, + uint32_t op2 ) +{ + op2 %= 32U; + + if( op2 == 0U ) + { + return op1; + } + + return ( op1 >> op2 ) | ( op1 << ( 32U - op2 ) ); +} + + +/** + * \brief Breakpoint + * \details Causes the processor to enter Debug state. + * Debug tools can use this to investigate system state when the instruction at a particular address is reached. + * \param [in] value is ignored by the processor. + * If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT( value ) __ASM volatile ( "bkpt "# value ) + + +/** + * \brief Reverse bit order of value + * \details Reverses the bit order of the given value. + * \param [in] value Value to reverse + * \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT( uint32_t value ) { uint32_t result; -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint16_t) result); /* Add explicit type cast here */ + #if ( ( defined( __ARM_ARCH_7M__ ) && ( __ARM_ARCH_7M__ == 1 ) ) || \ + ( defined( __ARM_ARCH_7EM__ ) && ( __ARM_ARCH_7EM__ == 1 ) ) || \ + ( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) ) + __ASM( "rbit %0, %1" : "=r" ( result ) : "r" ( value ) ); + #else + uint32_t s = ( 4U /*sizeof(v)*/ * 8U ) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + + for( value >>= 1U; value != 0U; value >>= 1U ) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + #endif /* if ( ( defined( __ARM_ARCH_7M__ ) && ( __ARM_ARCH_7M__ == 1 ) ) || ( defined( __ARM_ARCH_7EM__ ) && ( __ARM_ARCH_7EM__ == 1 ) ) || ( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) ) */ + return result; } /** - \brief LDR Exclusive (32 bit) - \details Executes a exclusive LDR instruction for 32 bit values. - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) + * \brief Count leading zeros + * \details Counts the number of leading zeros of a data value. + * \param [in] value Value to count the leading zeros + * \return number of leading zeros in value */ -__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +__STATIC_FORCEINLINE uint8_t __CLZ( uint32_t value ) { - uint32_t result; + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + * __builtin_clz(0) is undefined behaviour, so handle this case specially. + * This guarantees ARM-compatible results if happening to compile on a non-ARM + * target, and ensures the compiler doesn't decide to activate any + * optimisations using the logic "value was passed to __builtin_clz, so it + * is non-zero". + * ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + * single CLZ instruction. + */ + if( value == 0U ) + { + return 32U; + } - __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); - return(result); + return __builtin_clz( value ); } +#if ( ( defined( __ARM_ARCH_7M__ ) && ( __ARM_ARCH_7M__ == 1 ) ) || \ + ( defined( __ARM_ARCH_7EM__ ) && ( __ARM_ARCH_7EM__ == 1 ) ) || \ + ( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) || \ + ( defined( __ARM_ARCH_8M_BASE__ ) && ( __ARM_ARCH_8M_BASE__ == 1 ) ) ) + +/** + * \brief LDR Exclusive (8 bit) + * \details Executes a exclusive LDR instruction for 8 bit value. + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) + */ + __STATIC_FORCEINLINE uint8_t __LDREXB( volatile uint8_t * addr ) + { + uint32_t result; + + #if ( __GNUC__ > 4 ) || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 8 ) + __ASM volatile ( "ldrexb %0, %1" : "=r" ( result ) : "Q" ( *addr ) ); + #else + + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + * accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ( "ldrexb %0, [%1]" : "=r" ( result ) : "r" ( addr ) : "memory" ); + #endif + return( ( uint8_t ) result ); /* Add explicit type cast here */ + } + + /** - \brief STR Exclusive (8 bit) - \details Executes a exclusive STR instruction for 8 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed + * \brief LDR Exclusive (16 bit) + * \details Executes a exclusive LDR instruction for 16 bit values. + * \param [in] ptr Pointer to data + * \return value of type uint16_t at (*ptr) */ -__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint16_t __LDREXH( volatile uint16_t * addr ) + { + uint32_t result; - __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); - return(result); -} + #if ( __GNUC__ > 4 ) || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 8 ) + __ASM volatile ( "ldrexh %0, %1" : "=r" ( result ) : "Q" ( *addr ) ); + #else + + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + * accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ( "ldrexh %0, [%1]" : "=r" ( result ) : "r" ( addr ) : "memory" ); + #endif + return( ( uint16_t ) result ); /* Add explicit type cast here */ + } /** - \brief STR Exclusive (16 bit) - \details Executes a exclusive STR instruction for 16 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed + * \brief LDR Exclusive (32 bit) + * \details Executes a exclusive LDR instruction for 32 bit values. + * \param [in] ptr Pointer to data + * \return value of type uint32_t at (*ptr) */ -__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __LDREXW( volatile uint32_t * addr ) + { + uint32_t result; - __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); - return(result); -} + __ASM volatile ( "ldrex %0, %1" : "=r" ( result ) : "Q" ( *addr ) ); + + return( result ); + } /** - \brief STR Exclusive (32 bit) - \details Executes a exclusive STR instruction for 32 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed + * \brief STR Exclusive (8 bit) + * \details Executes a exclusive STR instruction for 8 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function failed */ -__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __STREXB( uint8_t value, + volatile uint8_t * addr ) + { + uint32_t result; - __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); - return(result); -} + __ASM volatile ( "strexb %0, %2, %1" : "=&r" ( result ), "=Q" ( *addr ) : "r" ( ( uint32_t ) value ) ); + + return( result ); + } /** - \brief Remove the exclusive lock - \details Removes the exclusive lock which is created by LDREX. + * \brief STR Exclusive (16 bit) + * \details Executes a exclusive STR instruction for 16 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function failed */ -__STATIC_FORCEINLINE void __CLREX(void) -{ - __ASM volatile ("clrex" ::: "memory"); -} + __STATIC_FORCEINLINE uint32_t __STREXH( uint16_t value, + volatile uint16_t * addr ) + { + uint32_t result; + + __ASM volatile ( "strexh %0, %2, %1" : "=&r" ( result ), "=Q" ( *addr ) : "r" ( ( uint32_t ) value ) ); + + return( result ); + } + + +/** + * \brief STR Exclusive (32 bit) + * \details Executes a exclusive STR instruction for 32 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function failed + */ + __STATIC_FORCEINLINE uint32_t __STREXW( uint32_t value, + volatile uint32_t * addr ) + { + uint32_t result; + + __ASM volatile ( "strex %0, %2, %1" : "=&r" ( result ), "=Q" ( *addr ) : "r" ( value ) ); + + return( result ); + } + + +/** + * \brief Remove the exclusive lock + * \details Removes the exclusive lock which is created by LDREX. + */ + __STATIC_FORCEINLINE void __CLREX( void ) + { + __ASM volatile ( "clrex" ::: "memory" ); + } #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ - (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + * (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + * (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + * (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ -#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +#if ( ( defined( __ARM_ARCH_7M__ ) && ( __ARM_ARCH_7M__ == 1 ) ) || \ + ( defined( __ARM_ARCH_7EM__ ) && ( __ARM_ARCH_7EM__ == 1 ) ) || \ + ( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) ) + /** - \brief Signed Saturate - \details Saturates a signed value. - \param [in] ARG1 Value to be saturated - \param [in] ARG2 Bit position to saturate to (1..32) - \return Saturated value + * \brief Signed Saturate + * \details Saturates a signed value. + * \param [in] ARG1 Value to be saturated + * \param [in] ARG2 Bit position to saturate to (1..32) + * \return Saturated value */ -#define __SSAT(ARG1, ARG2) \ -__extension__ \ -({ \ - int32_t __RES, __ARG1 = (ARG1); \ - __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ - __RES; \ - }) + #define __SSAT( ARG1, ARG2 ) \ + __extension__ \ + ( { \ + int32_t __RES, __ARG1 = ( ARG1 ); \ + __ASM volatile ( "ssat %0, %1, %2" : "=r" ( __RES ) : "I" ( ARG2 ), "r" ( __ARG1 ) : "cc" ); \ + __RES; \ + } ) /** - \brief Unsigned Saturate - \details Saturates an unsigned value. - \param [in] ARG1 Value to be saturated - \param [in] ARG2 Bit position to saturate to (0..31) - \return Saturated value + * \brief Unsigned Saturate + * \details Saturates an unsigned value. + * \param [in] ARG1 Value to be saturated + * \param [in] ARG2 Bit position to saturate to (0..31) + * \return Saturated value */ -#define __USAT(ARG1, ARG2) \ - __extension__ \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ - __RES; \ - }) + #define __USAT( ARG1, ARG2 ) \ + __extension__ \ + ( { \ + uint32_t __RES, __ARG1 = ( ARG1 ); \ + __ASM volatile ( "usat %0, %1, %2" : "=r" ( __RES ) : "I" ( ARG2 ), "r" ( __ARG1 ) : "cc" ); \ + __RES; \ + } ) /** - \brief Rotate Right with Extend (32 bit) - \details Moves each bit of a bitstring right by one bit. - The carry input is shifted in at the left end of the bitstring. - \param [in] value Value to rotate - \return Rotated value + * \brief Rotate Right with Extend (32 bit) + * \details Moves each bit of a bitstring right by one bit. + * The carry input is shifted in at the left end of the bitstring. + * \param [in] value Value to rotate + * \return Rotated value */ -__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -} - - -/** - \brief LDRT Unprivileged (8 bit) - \details Executes a Unprivileged LDRT instruction for 8 bit value. - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); -#endif - return ((uint8_t) result); /* Add explicit type cast here */ -} - - -/** - \brief LDRT Unprivileged (16 bit) - \details Executes a Unprivileged LDRT instruction for 16 bit values. - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); -#endif - return ((uint16_t) result); /* Add explicit type cast here */ -} - - -/** - \brief LDRT Unprivileged (32 bit) - \details Executes a Unprivileged LDRT instruction for 32 bit values. - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) -{ - uint32_t result; - - __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); - return(result); -} - - -/** - \brief STRT Unprivileged (8 bit) - \details Executes a Unprivileged STRT instruction for 8 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) -{ - __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); -} - - -/** - \brief STRT Unprivileged (16 bit) - \details Executes a Unprivileged STRT instruction for 16 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) -{ - __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); -} - - -/** - \brief STRT Unprivileged (32 bit) - \details Executes a Unprivileged STRT instruction for 32 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) -{ - __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); -} - -#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ - -/** - \brief Signed Saturate - \details Saturates a signed value. - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) -{ - if ((sat >= 1U) && (sat <= 32U)) - { - const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); - const int32_t min = -1 - max ; - if (val > max) + __STATIC_FORCEINLINE uint32_t __RRX( uint32_t value ) { - return max; + uint32_t result; + + __ASM volatile ( "rrx %0, %1" : __CMSIS_GCC_OUT_REG( result ) : __CMSIS_GCC_USE_REG( value ) ); + + return( result ); } - else if (val < min) - { - return min; - } - } - return val; -} + /** - \brief Unsigned Saturate - \details Saturates an unsigned value. - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value + * \brief LDRT Unprivileged (8 bit) + * \details Executes a Unprivileged LDRT instruction for 8 bit value. + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) */ -__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) -{ - if (sat <= 31U) - { - const uint32_t max = ((1U << sat) - 1U); - if (val > (int32_t)max) + __STATIC_FORCEINLINE uint8_t __LDRBT( volatile uint8_t * ptr ) { - return max; + uint32_t result; + + #if ( __GNUC__ > 4 ) || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 8 ) + __ASM volatile ( "ldrbt %0, %1" : "=r" ( result ) : "Q" ( *ptr ) ); + #else + + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + * accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ( "ldrbt %0, [%1]" : "=r" ( result ) : "r" ( ptr ) : "memory" ); + #endif + return( ( uint8_t ) result ); /* Add explicit type cast here */ } - else if (val < 0) + + +/** + * \brief LDRT Unprivileged (16 bit) + * \details Executes a Unprivileged LDRT instruction for 16 bit values. + * \param [in] ptr Pointer to data + * \return value of type uint16_t at (*ptr) + */ + __STATIC_FORCEINLINE uint16_t __LDRHT( volatile uint16_t * ptr ) { - return 0U; + uint32_t result; + + #if ( __GNUC__ > 4 ) || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 8 ) + __ASM volatile ( "ldrht %0, %1" : "=r" ( result ) : "Q" ( *ptr ) ); + #else + + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + * accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ( "ldrht %0, [%1]" : "=r" ( result ) : "r" ( ptr ) : "memory" ); + #endif + return( ( uint16_t ) result ); /* Add explicit type cast here */ + } + + +/** + * \brief LDRT Unprivileged (32 bit) + * \details Executes a Unprivileged LDRT instruction for 32 bit values. + * \param [in] ptr Pointer to data + * \return value of type uint32_t at (*ptr) + */ + __STATIC_FORCEINLINE uint32_t __LDRT( volatile uint32_t * ptr ) + { + uint32_t result; + + __ASM volatile ( "ldrt %0, %1" : "=r" ( result ) : "Q" ( *ptr ) ); + + return( result ); + } + + +/** + * \brief STRT Unprivileged (8 bit) + * \details Executes a Unprivileged STRT instruction for 8 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + */ + __STATIC_FORCEINLINE void __STRBT( uint8_t value, + volatile uint8_t * ptr ) + { + __ASM volatile ( "strbt %1, %0" : "=Q" ( *ptr ) : "r" ( ( uint32_t ) value ) ); + } + + +/** + * \brief STRT Unprivileged (16 bit) + * \details Executes a Unprivileged STRT instruction for 16 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + */ + __STATIC_FORCEINLINE void __STRHT( uint16_t value, + volatile uint16_t * ptr ) + { + __ASM volatile ( "strht %1, %0" : "=Q" ( *ptr ) : "r" ( ( uint32_t ) value ) ); + } + + +/** + * \brief STRT Unprivileged (32 bit) + * \details Executes a Unprivileged STRT instruction for 32 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + */ + __STATIC_FORCEINLINE void __STRT( uint32_t value, + volatile uint32_t * ptr ) + { + __ASM volatile ( "strt %1, %0" : "=Q" ( *ptr ) : "r" ( value ) ); + } + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + * (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + * (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + * \brief Signed Saturate + * \details Saturates a signed value. + * \param [in] value Value to be saturated + * \param [in] sat Bit position to saturate to (1..32) + * \return Saturated value + */ + __STATIC_FORCEINLINE int32_t __SSAT( int32_t val, + uint32_t sat ) + { + if( ( sat >= 1U ) && ( sat <= 32U ) ) + { + const int32_t max = ( int32_t ) ( ( 1U << ( sat - 1U ) ) - 1U ); + const int32_t min = -1 - max; + + if( val > max ) + { + return max; + } + else if( val < min ) + { + return min; + } + } + + return val; + } + +/** + * \brief Unsigned Saturate + * \details Saturates an unsigned value. + * \param [in] value Value to be saturated + * \param [in] sat Bit position to saturate to (0..31) + * \return Saturated value + */ + __STATIC_FORCEINLINE uint32_t __USAT( int32_t val, + uint32_t sat ) + { + if( sat <= 31U ) + { + const uint32_t max = ( ( 1U << sat ) - 1U ); + + if( val > ( int32_t ) max ) + { + return max; + } + else if( val < 0 ) + { + return 0U; + } + } + + return ( uint32_t ) val; } - } - return (uint32_t)val; -} #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + * (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + * (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ -#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ - (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +#if ( ( defined( __ARM_ARCH_8M_MAIN__ ) && ( __ARM_ARCH_8M_MAIN__ == 1 ) ) || \ + ( defined( __ARM_ARCH_8M_BASE__ ) && ( __ARM_ARCH_8M_BASE__ == 1 ) ) ) + /** - \brief Load-Acquire (8 bit) - \details Executes a LDAB instruction for 8 bit value. - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) + * \brief Load-Acquire (8 bit) + * \details Executes a LDAB instruction for 8 bit value. + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) */ -__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint8_t __LDAB( volatile uint8_t * ptr ) + { + uint32_t result; - __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); - return ((uint8_t) result); -} + __ASM volatile ( "ldab %0, %1" : "=r" ( result ) : "Q" ( *ptr ) : "memory" ); + + return( ( uint8_t ) result ); + } /** - \brief Load-Acquire (16 bit) - \details Executes a LDAH instruction for 16 bit values. - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) + * \brief Load-Acquire (16 bit) + * \details Executes a LDAH instruction for 16 bit values. + * \param [in] ptr Pointer to data + * \return value of type uint16_t at (*ptr) */ -__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint16_t __LDAH( volatile uint16_t * ptr ) + { + uint32_t result; - __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); - return ((uint16_t) result); -} + __ASM volatile ( "ldah %0, %1" : "=r" ( result ) : "Q" ( *ptr ) : "memory" ); + + return( ( uint16_t ) result ); + } /** - \brief Load-Acquire (32 bit) - \details Executes a LDA instruction for 32 bit values. - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) + * \brief Load-Acquire (32 bit) + * \details Executes a LDA instruction for 32 bit values. + * \param [in] ptr Pointer to data + * \return value of type uint32_t at (*ptr) */ -__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __LDA( volatile uint32_t * ptr ) + { + uint32_t result; - __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); - return(result); -} + __ASM volatile ( "lda %0, %1" : "=r" ( result ) : "Q" ( *ptr ) : "memory" ); + + return( result ); + } /** - \brief Store-Release (8 bit) - \details Executes a STLB instruction for 8 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location + * \brief Store-Release (8 bit) + * \details Executes a STLB instruction for 8 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location */ -__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) -{ - __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); -} + __STATIC_FORCEINLINE void __STLB( uint8_t value, + volatile uint8_t * ptr ) + { + __ASM volatile ( "stlb %1, %0" : "=Q" ( *ptr ) : "r" ( ( uint32_t ) value ) : "memory" ); + } /** - \brief Store-Release (16 bit) - \details Executes a STLH instruction for 16 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location + * \brief Store-Release (16 bit) + * \details Executes a STLH instruction for 16 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location */ -__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) -{ - __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); -} + __STATIC_FORCEINLINE void __STLH( uint16_t value, + volatile uint16_t * ptr ) + { + __ASM volatile ( "stlh %1, %0" : "=Q" ( *ptr ) : "r" ( ( uint32_t ) value ) : "memory" ); + } /** - \brief Store-Release (32 bit) - \details Executes a STL instruction for 32 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location + * \brief Store-Release (32 bit) + * \details Executes a STL instruction for 32 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location */ -__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) -{ - __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); -} + __STATIC_FORCEINLINE void __STL( uint32_t value, + volatile uint32_t * ptr ) + { + __ASM volatile ( "stl %1, %0" : "=Q" ( *ptr ) : "r" ( ( uint32_t ) value ) : "memory" ); + } /** - \brief Load-Acquire Exclusive (8 bit) - \details Executes a LDAB exclusive instruction for 8 bit value. - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) + * \brief Load-Acquire Exclusive (8 bit) + * \details Executes a LDAB exclusive instruction for 8 bit value. + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) */ -__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint8_t __LDAEXB( volatile uint8_t * ptr ) + { + uint32_t result; - __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); - return ((uint8_t) result); -} + __ASM volatile ( "ldaexb %0, %1" : "=r" ( result ) : "Q" ( *ptr ) : "memory" ); + + return( ( uint8_t ) result ); + } /** - \brief Load-Acquire Exclusive (16 bit) - \details Executes a LDAH exclusive instruction for 16 bit values. - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) + * \brief Load-Acquire Exclusive (16 bit) + * \details Executes a LDAH exclusive instruction for 16 bit values. + * \param [in] ptr Pointer to data + * \return value of type uint16_t at (*ptr) */ -__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint16_t __LDAEXH( volatile uint16_t * ptr ) + { + uint32_t result; - __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); - return ((uint16_t) result); -} + __ASM volatile ( "ldaexh %0, %1" : "=r" ( result ) : "Q" ( *ptr ) : "memory" ); + + return( ( uint16_t ) result ); + } /** - \brief Load-Acquire Exclusive (32 bit) - \details Executes a LDA exclusive instruction for 32 bit values. - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) + * \brief Load-Acquire Exclusive (32 bit) + * \details Executes a LDA exclusive instruction for 32 bit values. + * \param [in] ptr Pointer to data + * \return value of type uint32_t at (*ptr) */ -__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __LDAEX( volatile uint32_t * ptr ) + { + uint32_t result; - __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); - return(result); -} + __ASM volatile ( "ldaex %0, %1" : "=r" ( result ) : "Q" ( *ptr ) : "memory" ); + + return( result ); + } /** - \brief Store-Release Exclusive (8 bit) - \details Executes a STLB exclusive instruction for 8 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed + * \brief Store-Release Exclusive (8 bit) + * \details Executes a STLB exclusive instruction for 8 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function failed */ -__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __STLEXB( uint8_t value, + volatile uint8_t * ptr ) + { + uint32_t result; - __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); - return(result); -} + __ASM volatile ( "stlexb %0, %2, %1" : "=&r" ( result ), "=Q" ( *ptr ) : "r" ( ( uint32_t ) value ) : "memory" ); + + return( result ); + } /** - \brief Store-Release Exclusive (16 bit) - \details Executes a STLH exclusive instruction for 16 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed + * \brief Store-Release Exclusive (16 bit) + * \details Executes a STLH exclusive instruction for 16 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function failed */ -__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __STLEXH( uint16_t value, + volatile uint16_t * ptr ) + { + uint32_t result; - __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); - return(result); -} + __ASM volatile ( "stlexh %0, %2, %1" : "=&r" ( result ), "=Q" ( *ptr ) : "r" ( ( uint32_t ) value ) : "memory" ); + + return( result ); + } /** - \brief Store-Release Exclusive (32 bit) - \details Executes a STL exclusive instruction for 32 bit values. - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed + * \brief Store-Release Exclusive (32 bit) + * \details Executes a STL exclusive instruction for 32 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function failed */ -__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __STLEX( uint32_t value, + volatile uint32_t * ptr ) + { + uint32_t result; - __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); - return(result); -} + __ASM volatile ( "stlex %0, %2, %1" : "=&r" ( result ), "=Q" ( *ptr ) : "r" ( ( uint32_t ) value ) : "memory" ); + + return( result ); + } #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ - (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + * (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ /* ################### Compiler specific Intrinsics ########################### */ + /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics - Access to dedicated SIMD instructions - @{ -*/ + * Access to dedicated SIMD instructions + * @{ + */ -#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) +#if ( defined( __ARM_FEATURE_DSP ) && ( __ARM_FEATURE_DSP == 1 ) ) -__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __SADD8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; - __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __ASM volatile ( "sadd8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); -__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + return( result ); + } - __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __QADD8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "qadd8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __SHADD8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "shadd8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __UADD8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM volatile ( "uadd8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); - __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + return( result ); + } -__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __UQADD8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; - __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __ASM( "uqadd8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + __STATIC_FORCEINLINE uint32_t __UHADD8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "uhadd8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} -__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __SSUB8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; - __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __ASM volatile ( "ssub8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); -__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + return( result ); + } - __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __QSUB8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "qsub8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __SHSUB8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "shsub8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __USUB8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM volatile ( "usub8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); - __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + return( result ); + } + __STATIC_FORCEINLINE uint32_t __UQSUB8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "uqsub8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __UHSUB8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "uhsub8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} -__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __SADD16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; - __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __ASM volatile ( "sadd16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); -__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + return( result ); + } - __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __QADD16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "qadd16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __SHADD16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "shadd16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __UADD16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM volatile ( "uadd16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); - __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + return( result ); + } -__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __UQADD16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; - __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __ASM( "uqadd16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } -__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __UHADD16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; - __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __ASM( "uhadd16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } -__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __SSUB16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; - __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __ASM volatile ( "ssub16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); -__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + return( result ); + } - __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __QSUB16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "qsub16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __SHSUB16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM( "shsub16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } - __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + __STATIC_FORCEINLINE uint32_t __USUB16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; -__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __ASM volatile ( "usub16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); - __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} + return( result ); + } -__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; + __STATIC_FORCEINLINE uint32_t __UQSUB16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; - __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SSAT16(ARG1, ARG2) \ -({ \ - int32_t __RES, __ARG1 = (ARG1); \ - __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ - __RES; \ - }) - -#define __USAT16(ARG1, ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ - __RES; \ - }) - -__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate) -{ - uint32_t result; - if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { - __ASM volatile ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); - } else { - result = __SXTB16(__ROR(op1, rotate)) ; - } - return result; -} - -__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ /* Little endian */ - __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else /* Big endian */ - __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ /* Little endian */ - __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else /* Big endian */ - __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ /* Little endian */ - __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else /* Big endian */ - __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ /* Little endian */ - __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else /* Big endian */ - __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) -{ - int32_t result; - - __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) -{ - int32_t result; - - __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - - -#define __PKHBT(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -#define __PKHTB(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - if (ARG3 == 0) \ - __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ - else \ - __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - - -__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) -{ - int32_t result; - - __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} + __ASM( "uqsub16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __UHSUB16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "uhsub16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SASX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM volatile ( "sasx %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __QASX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "qasx %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SHASX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "shasx %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __UASX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM volatile ( "uasx %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __UQASX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "uqasx %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __UHASX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "uhasx %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SSAX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM volatile ( "ssax %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __QSAX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "qsax %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SHSAX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "shsax %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __USAX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM volatile ( "usax %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __UQSAX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "uqsax %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __UHSAX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "uhsax %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __USAD8( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "usad8 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __USADA8( uint32_t op1, + uint32_t op2, + uint32_t op3 ) + { + uint32_t result; + + __ASM( "usada8 %0, %1, %2, %3" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ), "r" ( op3 ) ); + return( result ); + } + + #define __SSAT16( ARG1, ARG2 ) \ + ( { \ + int32_t __RES, __ARG1 = ( ARG1 ); \ + __ASM volatile ( "ssat16 %0, %1, %2" : "=r" ( __RES ) : "I" ( ARG2 ), "r" ( __ARG1 ) : "cc" ); \ + __RES; \ + } ) + + #define __USAT16( ARG1, ARG2 ) \ + ( { \ + uint32_t __RES, __ARG1 = ( ARG1 ); \ + __ASM volatile ( "usat16 %0, %1, %2" : "=r" ( __RES ) : "I" ( ARG2 ), "r" ( __ARG1 ) : "cc" ); \ + __RES; \ + } ) + + __STATIC_FORCEINLINE uint32_t __UXTB16( uint32_t op1 ) + { + uint32_t result; + + __ASM( "uxtb16 %0, %1" : "=r" ( result ) : "r" ( op1 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __UXTAB16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "uxtab16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SXTB16( uint32_t op1 ) + { + uint32_t result; + + __ASM( "sxtb16 %0, %1" : "=r" ( result ) : "r" ( op1 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SXTB16_RORn( uint32_t op1, + uint32_t rotate ) + { + uint32_t result; + + if( __builtin_constant_p( rotate ) && ( ( rotate == 8U ) || ( rotate == 16U ) || ( rotate == 24U ) ) ) + { + __ASM volatile ( "sxtb16 %0, %1, ROR %2" : "=r" ( result ) : "r" ( op1 ), "i" ( rotate ) ); + } + else + { + result = __SXTB16( __ROR( op1, rotate ) ); + } + + return result; + } + + __STATIC_FORCEINLINE uint32_t __SXTAB16( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM( "sxtab16 %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SMUAD( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM volatile ( "smuad %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SMUADX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM volatile ( "smuadx %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SMLAD( uint32_t op1, + uint32_t op2, + uint32_t op3 ) + { + uint32_t result; + + __ASM volatile ( "smlad %0, %1, %2, %3" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ), "r" ( op3 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SMLADX( uint32_t op1, + uint32_t op2, + uint32_t op3 ) + { + uint32_t result; + + __ASM volatile ( "smladx %0, %1, %2, %3" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ), "r" ( op3 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint64_t __SMLALD( uint32_t op1, + uint32_t op2, + uint64_t acc ) + { + union llreg_u + { + uint32_t w32[ 2 ]; + uint64_t w64; + } + llr; + + llr.w64 = acc; + + #ifndef __ARMEB__ /* Little endian */ + __ASM volatile ( "smlald %0, %1, %2, %3" : "=r" ( llr.w32[ 0 ] ), "=r" ( llr.w32[ 1 ] ) : "r" ( op1 ), "r" ( op2 ), "0" ( llr.w32[ 0 ] ), "1" ( llr.w32[ 1 ] ) ); + #else /* Big endian */ + __ASM volatile ( "smlald %0, %1, %2, %3" : "=r" ( llr.w32[ 1 ] ), "=r" ( llr.w32[ 0 ] ) : "r" ( op1 ), "r" ( op2 ), "0" ( llr.w32[ 1 ] ), "1" ( llr.w32[ 0 ] ) ); + #endif + + return( llr.w64 ); + } + + __STATIC_FORCEINLINE uint64_t __SMLALDX( uint32_t op1, + uint32_t op2, + uint64_t acc ) + { + union llreg_u + { + uint32_t w32[ 2 ]; + uint64_t w64; + } + llr; + + llr.w64 = acc; + + #ifndef __ARMEB__ /* Little endian */ + __ASM volatile ( "smlaldx %0, %1, %2, %3" : "=r" ( llr.w32[ 0 ] ), "=r" ( llr.w32[ 1 ] ) : "r" ( op1 ), "r" ( op2 ), "0" ( llr.w32[ 0 ] ), "1" ( llr.w32[ 1 ] ) ); + #else /* Big endian */ + __ASM volatile ( "smlaldx %0, %1, %2, %3" : "=r" ( llr.w32[ 1 ] ), "=r" ( llr.w32[ 0 ] ) : "r" ( op1 ), "r" ( op2 ), "0" ( llr.w32[ 1 ] ), "1" ( llr.w32[ 0 ] ) ); + #endif + + return( llr.w64 ); + } + + __STATIC_FORCEINLINE uint32_t __SMUSD( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM volatile ( "smusd %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SMUSDX( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM volatile ( "smusdx %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SMLSD( uint32_t op1, + uint32_t op2, + uint32_t op3 ) + { + uint32_t result; + + __ASM volatile ( "smlsd %0, %1, %2, %3" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ), "r" ( op3 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint32_t __SMLSDX( uint32_t op1, + uint32_t op2, + uint32_t op3 ) + { + uint32_t result; + + __ASM volatile ( "smlsdx %0, %1, %2, %3" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ), "r" ( op3 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE uint64_t __SMLSLD( uint32_t op1, + uint32_t op2, + uint64_t acc ) + { + union llreg_u + { + uint32_t w32[ 2 ]; + uint64_t w64; + } + llr; + + llr.w64 = acc; + + #ifndef __ARMEB__ /* Little endian */ + __ASM volatile ( "smlsld %0, %1, %2, %3" : "=r" ( llr.w32[ 0 ] ), "=r" ( llr.w32[ 1 ] ) : "r" ( op1 ), "r" ( op2 ), "0" ( llr.w32[ 0 ] ), "1" ( llr.w32[ 1 ] ) ); + #else /* Big endian */ + __ASM volatile ( "smlsld %0, %1, %2, %3" : "=r" ( llr.w32[ 1 ] ), "=r" ( llr.w32[ 0 ] ) : "r" ( op1 ), "r" ( op2 ), "0" ( llr.w32[ 1 ] ), "1" ( llr.w32[ 0 ] ) ); + #endif + + return( llr.w64 ); + } + + __STATIC_FORCEINLINE uint64_t __SMLSLDX( uint32_t op1, + uint32_t op2, + uint64_t acc ) + { + union llreg_u + { + uint32_t w32[ 2 ]; + uint64_t w64; + } + llr; + + llr.w64 = acc; + + #ifndef __ARMEB__ /* Little endian */ + __ASM volatile ( "smlsldx %0, %1, %2, %3" : "=r" ( llr.w32[ 0 ] ), "=r" ( llr.w32[ 1 ] ) : "r" ( op1 ), "r" ( op2 ), "0" ( llr.w32[ 0 ] ), "1" ( llr.w32[ 1 ] ) ); + #else /* Big endian */ + __ASM volatile ( "smlsldx %0, %1, %2, %3" : "=r" ( llr.w32[ 1 ] ), "=r" ( llr.w32[ 0 ] ) : "r" ( op1 ), "r" ( op2 ), "0" ( llr.w32[ 1 ] ), "1" ( llr.w32[ 0 ] ) ); + #endif + + return( llr.w64 ); + } + + __STATIC_FORCEINLINE uint32_t __SEL( uint32_t op1, + uint32_t op2 ) + { + uint32_t result; + + __ASM volatile ( "sel %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE int32_t __QADD( int32_t op1, + int32_t op2 ) + { + int32_t result; + + __ASM volatile ( "qadd %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + __STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, + int32_t op2 ) + { + int32_t result; + + __ASM volatile ( "qsub %0, %1, %2" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ) ); + + return( result ); + } + + + #define __PKHBT( ARG1, ARG2, ARG3 ) \ + ( { \ + uint32_t __RES, __ARG1 = ( ARG1 ), __ARG2 = ( ARG2 ); \ + __ASM( "pkhbt %0, %1, %2, lsl %3" : "=r" ( __RES ) : "r" ( __ARG1 ), "r" ( __ARG2 ), "I" ( ARG3 ) ); \ + __RES; \ + } ) + + #define __PKHTB( ARG1, ARG2, ARG3 ) \ + ( { \ + uint32_t __RES, __ARG1 = ( ARG1 ), __ARG2 = ( ARG2 ); \ + if( ARG3 == 0 ) \ + __ASM( "pkhtb %0, %1, %2" : "=r" ( __RES ) : "r" ( __ARG1 ), "r" ( __ARG2 ) ); \ + else \ + __ASM( "pkhtb %0, %1, %2, asr %3" : "=r" ( __RES ) : "r" ( __ARG1 ), "r" ( __ARG2 ), "I" ( ARG3 ) ); \ + __RES; \ + } ) + + + __STATIC_FORCEINLINE int32_t __SMMLA( int32_t op1, + int32_t op2, + int32_t op3 ) + { + int32_t result; + + __ASM( "smmla %0, %1, %2, %3" : "=r" ( result ) : "r" ( op1 ), "r" ( op2 ), "r" ( op3 ) ); + return( result ); + } #endif /* (__ARM_FEATURE_DSP == 1) */ /*@} end of group CMSIS_SIMD_intrinsics */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/cmsis_version.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/cmsis_version.h index 2f048e455..35710644f 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/cmsis_version.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/cmsis_version.h @@ -1,9 +1,10 @@ /**************************************************************************//** - * @file cmsis_version.h - * @brief CMSIS Core(M) Version definitions - * @version V5.0.4 - * @date 23. July 2019 - ******************************************************************************/ +* @file cmsis_version.h +* @brief CMSIS Core(M) Version definitions +* @version V5.0.4 +* @date 23. July 2019 +******************************************************************************/ + /* * Copyright (c) 2009-2019 ARM Limited. All rights reserved. * @@ -22,18 +23,19 @@ * limitations under the License. */ -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__clang__) - #pragma clang system_header /* treat file as system include file */ +#if defined( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined( __clang__ ) + #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CMSIS_VERSION_H -#define __CMSIS_VERSION_H + #define __CMSIS_VERSION_H /* CMSIS Version definitions */ -#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ -#define __CM_CMSIS_VERSION_SUB ( 4U) /*!< [15:0] CMSIS Core(M) sub version */ -#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ - __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ + #define __CM_CMSIS_VERSION_MAIN ( 5U ) /*!< [31:16] CMSIS Core(M) main version */ + #define __CM_CMSIS_VERSION_SUB ( 4U ) /*!< [15:0] CMSIS Core(M) sub version */ + #define __CM_CMSIS_VERSION \ + ( ( __CM_CMSIS_VERSION_MAIN << 16U ) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ #endif diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/core_cm3.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/core_cm3.h index 24453a886..299dd0a83 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/core_cm3.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/core_cm3.h @@ -1,9 +1,10 @@ /**************************************************************************//** - * @file core_cm3.h - * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File - * @version V5.1.1 - * @date 27. March 2020 - ******************************************************************************/ +* @file core_cm3.h +* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File +* @version V5.1.1 +* @date 27. March 2020 +******************************************************************************/ + /* * Copyright (c) 2009-2020 Arm Limited. All rights reserved. * @@ -22,162 +23,165 @@ * limitations under the License. */ -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__clang__) - #pragma clang system_header /* treat file as system include file */ +#if defined( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined( __clang__ ) + #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM3_H_GENERIC -#define __CORE_CM3_H_GENERIC + #define __CORE_CM3_H_GENERIC -#include + #include -#ifdef __cplusplus - extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /** - \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. + * \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + * CMSIS violates the following MISRA-C:2004 rules: + * + * \li Required Rule 8.5, object/function definition in header file.
+ * Function definitions in header files are used to allow 'inlining'. + * + * \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ * Unions are used for effective representation of core registers. + * + * \li Advisory Rule 19.7, Function-like macro defined.
+ * Function-like macros are used to allow more efficient code. */ /******************************************************************************* * CMSIS definitions ******************************************************************************/ + /** - \ingroup Cortex_M3 - @{ + * \ingroup Cortex_M3 + * @{ */ -#include "cmsis_version.h" + #include "cmsis_version.h" /* CMSIS CM3 definitions */ -#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ -#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ -#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ - __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + #define __CM3_CMSIS_VERSION_MAIN ( __CM_CMSIS_VERSION_MAIN ) /*!< \deprecated [31:16] CMSIS HAL main version */ + #define __CM3_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB ) /*!< \deprecated [15:0] CMSIS HAL sub version */ + #define __CM3_CMSIS_VERSION \ + ( ( __CM3_CMSIS_VERSION_MAIN << 16U ) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ -#define __CORTEX_M (3U) /*!< Cortex-M Core */ + #define __CORTEX_M ( 3U ) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. - This core does not support an FPU at all -*/ -#define __FPU_USED 0U + * This core does not support an FPU at all + */ + #define __FPU_USED 0U -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif + #if defined( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #if defined __ARM_FP - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif + #elif defined( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif + #elif defined( __GNUC__ ) + #if defined( __VFP_FP__ ) && !defined( __SOFTFP__ ) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif + #elif defined( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif -#elif defined ( __TI_ARM__ ) - #if defined __TI_VFP_SUPPORT__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif + #elif defined( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif + #elif defined( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif -#elif defined ( __CSMC__ ) - #if ( __CSMC__ & 0x400U) - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif + #elif defined( __CSMC__ ) + #if ( __CSMC__ & 0x400U ) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif -#endif + #endif /* if defined( __CC_ARM ) */ -#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif /* __CORE_CM3_H_GENERIC */ #ifndef __CMSIS_GENERIC -#ifndef __CORE_CM3_H_DEPENDANT -#define __CORE_CM3_H_DEPENDANT + #ifndef __CORE_CM3_H_DEPENDANT + #define __CORE_CM3_H_DEPENDANT -#ifdef __cplusplus - extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM3_REV - #define __CM3_REV 0x0200U - #warning "__CM3_REV not defined in device header file; using default!" - #endif + #if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0U - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif - #ifndef __VTOR_PRESENT - #define __VTOR_PRESENT 1U - #warning "__VTOR_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 3U - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0U - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + #endif /* if defined __CHECK_DEVICE_DEFINES */ /* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ +/** + * \defgroup CMSIS_glob_defs CMSIS Global Defines + * + * IO Type Qualifiers are used + * \li to specify the access to peripheral variables. + * \li for automatic generation of peripheral register debug information. + */ + #ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ + #else + #define __I volatile const /*!< Defines 'read only' permissions */ + #endif + #define __O volatile /*!< Defines 'write only' permissions */ + #define __IO volatile /*!< Defines 'read / write' permissions */ /* following defines should be used for structure members */ -#define __IM volatile const /*! Defines 'read only' structure member permissions */ -#define __OM volatile /*! Defines 'write only' structure member permissions */ -#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + #define __IM volatile const /*! Defines 'read only' structure member permissions */ + #define __OM volatile /*! Defines 'write only' structure member permissions */ + #define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex_M3 */ @@ -185,1220 +189,1222 @@ /******************************************************************************* * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register + * Core Register contain: + * - Core Register + * - Core NVIC Register + * - Core SCB Register + * - Core SysTick Register + * - Core Debug Register + * - Core MPU Register ******************************************************************************/ -/** - \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ + * \defgroup CMSIS_core_register Defines and Type Definitions + * \brief Type definitions and defines for Cortex-M processor based devices. */ /** - \brief Union type to access the Application Program Status Register (APSR). + * \ingroup CMSIS_core_register + * \defgroup CMSIS_CORE Status and Control Registers + * \brief Core Register type definitions. + * @{ */ -typedef union -{ - struct - { - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; + +/** + * \brief Union type to access the Application Program Status Register (APSR). + */ + typedef union + { + struct + { + uint32_t _reserved0 : 27; /*!< bit: 0..26 Reserved */ + uint32_t Q : 1; /*!< bit: 27 Saturation condition flag */ + uint32_t V : 1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C : 1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z : 1; /*!< bit: 30 Zero condition code flag */ + uint32_t N : 1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ + } APSR_Type; /* APSR Register Definitions */ -#define APSR_N_Pos 31U /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + #define APSR_N_Pos 31U /*!< APSR: N Position */ + #define APSR_N_Msk ( 1UL << APSR_N_Pos ) /*!< APSR: N Mask */ -#define APSR_Z_Pos 30U /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + #define APSR_Z_Pos 30U /*!< APSR: Z Position */ + #define APSR_Z_Msk ( 1UL << APSR_Z_Pos ) /*!< APSR: Z Mask */ -#define APSR_C_Pos 29U /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + #define APSR_C_Pos 29U /*!< APSR: C Position */ + #define APSR_C_Msk ( 1UL << APSR_C_Pos ) /*!< APSR: C Mask */ -#define APSR_V_Pos 28U /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + #define APSR_V_Pos 28U /*!< APSR: V Position */ + #define APSR_V_Msk ( 1UL << APSR_V_Pos ) /*!< APSR: V Mask */ -#define APSR_Q_Pos 27U /*!< APSR: Q Position */ -#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + #define APSR_Q_Pos 27U /*!< APSR: Q Position */ + #define APSR_Q_Msk ( 1UL << APSR_Q_Pos ) /*!< APSR: Q Mask */ /** - \brief Union type to access the Interrupt Program Status Register (IPSR). + * \brief Union type to access the Interrupt Program Status Register (IPSR). */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; + typedef union + { + struct + { + uint32_t ISR : 9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0 : 23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ + } IPSR_Type; /* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ + #define IPSR_ISR_Msk ( 0x1FFUL /*<< IPSR_ISR_Pos*/ ) /*!< IPSR: ISR Mask */ /** - \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + * \brief Union type to access the Special-Purpose Program Status Registers (xPSR). */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:1; /*!< bit: 9 Reserved */ - uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ - uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit */ - uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; + typedef union + { + struct + { + uint32_t ISR : 9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0 : 1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1 : 6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1 : 8; /*!< bit: 16..23 Reserved */ + uint32_t T : 1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2 : 2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q : 1; /*!< bit: 27 Saturation condition flag */ + uint32_t V : 1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C : 1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z : 1; /*!< bit: 30 Zero condition code flag */ + uint32_t N : 1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ + } xPSR_Type; /* xPSR Register Definitions */ -#define xPSR_N_Pos 31U /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + #define xPSR_N_Pos 31U /*!< xPSR: N Position */ + #define xPSR_N_Msk ( 1UL << xPSR_N_Pos ) /*!< xPSR: N Mask */ -#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ + #define xPSR_Z_Msk ( 1UL << xPSR_Z_Pos ) /*!< xPSR: Z Mask */ -#define xPSR_C_Pos 29U /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + #define xPSR_C_Pos 29U /*!< xPSR: C Position */ + #define xPSR_C_Msk ( 1UL << xPSR_C_Pos ) /*!< xPSR: C Mask */ -#define xPSR_V_Pos 28U /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + #define xPSR_V_Pos 28U /*!< xPSR: V Position */ + #define xPSR_V_Msk ( 1UL << xPSR_V_Pos ) /*!< xPSR: V Mask */ -#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ -#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ + #define xPSR_Q_Msk ( 1UL << xPSR_Q_Pos ) /*!< xPSR: Q Mask */ -#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ -#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + #define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ + #define xPSR_ICI_IT_2_Msk ( 3UL << xPSR_ICI_IT_2_Pos ) /*!< xPSR: ICI/IT part 2 Mask */ -#define xPSR_T_Pos 24U /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + #define xPSR_T_Pos 24U /*!< xPSR: T Position */ + #define xPSR_T_Msk ( 1UL << xPSR_T_Pos ) /*!< xPSR: T Mask */ -#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ -#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + #define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ + #define xPSR_ICI_IT_1_Msk ( 0x3FUL << xPSR_ICI_IT_1_Pos ) /*!< xPSR: ICI/IT part 1 Mask */ -#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ + #define xPSR_ISR_Msk ( 0x1FFUL /*<< xPSR_ISR_Pos*/ ) /*!< xPSR: ISR Mask */ /** - \brief Union type to access the Control Registers (CONTROL). + * \brief Union type to access the Control Registers (CONTROL). */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; + typedef union + { + struct + { + uint32_t nPRIV : 1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL : 1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1 : 30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ + } CONTROL_Type; /* CONTROL Register Definitions */ -#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ + #define CONTROL_SPSEL_Msk ( 1UL << CONTROL_SPSEL_Pos ) /*!< CONTROL: SPSEL Mask */ -#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ -#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + #define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ + #define CONTROL_nPRIV_Msk ( 1UL /*<< CONTROL_nPRIV_Pos*/ ) /*!< CONTROL: nPRIV Mask */ /*@} end of group CMSIS_CORE */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + * \brief Type definitions for the NVIC Registers + * @{ */ /** - \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + * \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). */ -typedef struct -{ - __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24U]; - __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RESERVED1[24U]; - __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24U]; - __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24U]; - __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56U]; - __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644U]; - __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; + typedef struct + { + __IOM uint32_t ISER[ 8U ]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[ 24U ]; + __IOM uint32_t ICER[ 8U ]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[ 24U ]; + __IOM uint32_t ISPR[ 8U ]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[ 24U ]; + __IOM uint32_t ICPR[ 8U ]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[ 24U ]; + __IOM uint32_t IABR[ 8U ]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[ 56U ]; + __IOM uint8_t IP[ 240U ]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[ 644U ]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ + } NVIC_Type; /* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + #define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ + #define NVIC_STIR_INTID_Msk ( 0x1FFUL /*<< NVIC_STIR_INTID_Pos*/ ) /*!< STIR: INTLINESNUM Mask */ /*@} end of group CMSIS_NVIC */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_SCB System Control Block (SCB) + * \brief Type definitions for the System Control Block Registers + * @{ */ /** - \brief Structure type to access the System Control Block (SCB). + * \brief Structure type to access the System Control Block (SCB). */ -typedef struct -{ - __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5U]; - __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ -} SCB_Type; + typedef struct + { + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[ 12U ]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[ 2U ]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[ 4U ]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[ 5U ]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[ 5U ]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + } SCB_Type; /* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ + #define SCB_CPUID_IMPLEMENTER_Msk ( 0xFFUL << SCB_CPUID_IMPLEMENTER_Pos ) /*!< SCB CPUID: IMPLEMENTER Mask */ -#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ + #define SCB_CPUID_VARIANT_Msk ( 0xFUL << SCB_CPUID_VARIANT_Pos ) /*!< SCB CPUID: VARIANT Mask */ -#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ + #define SCB_CPUID_ARCHITECTURE_Msk ( 0xFUL << SCB_CPUID_ARCHITECTURE_Pos ) /*!< SCB CPUID: ARCHITECTURE Mask */ -#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ + #define SCB_CPUID_PARTNO_Msk ( 0xFFFUL << SCB_CPUID_PARTNO_Pos ) /*!< SCB CPUID: PARTNO Mask */ -#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ + #define SCB_CPUID_REVISION_Msk ( 0xFUL /*<< SCB_CPUID_REVISION_Pos*/ ) /*!< SCB CPUID: REVISION Mask */ /* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ + #define SCB_ICSR_NMIPENDSET_Msk ( 1UL << SCB_ICSR_NMIPENDSET_Pos ) /*!< SCB ICSR: NMIPENDSET Mask */ -#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ + #define SCB_ICSR_PENDSVSET_Msk ( 1UL << SCB_ICSR_PENDSVSET_Pos ) /*!< SCB ICSR: PENDSVSET Mask */ -#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ + #define SCB_ICSR_PENDSVCLR_Msk ( 1UL << SCB_ICSR_PENDSVCLR_Pos ) /*!< SCB ICSR: PENDSVCLR Mask */ -#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ + #define SCB_ICSR_PENDSTSET_Msk ( 1UL << SCB_ICSR_PENDSTSET_Pos ) /*!< SCB ICSR: PENDSTSET Mask */ -#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ + #define SCB_ICSR_PENDSTCLR_Msk ( 1UL << SCB_ICSR_PENDSTCLR_Pos ) /*!< SCB ICSR: PENDSTCLR Mask */ -#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ + #define SCB_ICSR_ISRPREEMPT_Msk ( 1UL << SCB_ICSR_ISRPREEMPT_Pos ) /*!< SCB ICSR: ISRPREEMPT Mask */ -#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ + #define SCB_ICSR_ISRPENDING_Msk ( 1UL << SCB_ICSR_ISRPENDING_Pos ) /*!< SCB ICSR: ISRPENDING Mask */ -#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ + #define SCB_ICSR_VECTPENDING_Msk ( 0x1FFUL << SCB_ICSR_VECTPENDING_Pos ) /*!< SCB ICSR: VECTPENDING Mask */ -#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + #define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ + #define SCB_ICSR_RETTOBASE_Msk ( 1UL << SCB_ICSR_RETTOBASE_Pos ) /*!< SCB ICSR: RETTOBASE Mask */ -#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ + #define SCB_ICSR_VECTACTIVE_Msk ( 0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/ ) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ -#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ -#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ -#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + #if defined( __CM3_REV ) && ( __CM3_REV < 0x0201U ) /* core r2p1 */ + #define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ + #define SCB_VTOR_TBLBASE_Msk ( 1UL << SCB_VTOR_TBLBASE_Pos ) /*!< SCB VTOR: TBLBASE Mask */ -#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ -#else -#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ -#endif + #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ + #define SCB_VTOR_TBLOFF_Msk ( 0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos ) /*!< SCB VTOR: TBLOFF Mask */ + #else + #define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ + #define SCB_VTOR_TBLOFF_Msk ( 0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos ) /*!< SCB VTOR: TBLOFF Mask */ + #endif /* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ + #define SCB_AIRCR_VECTKEY_Msk ( 0xFFFFUL << SCB_AIRCR_VECTKEY_Pos ) /*!< SCB AIRCR: VECTKEY Mask */ -#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ + #define SCB_AIRCR_VECTKEYSTAT_Msk ( 0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos ) /*!< SCB AIRCR: VECTKEYSTAT Mask */ -#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ + #define SCB_AIRCR_ENDIANESS_Msk ( 1UL << SCB_AIRCR_ENDIANESS_Pos ) /*!< SCB AIRCR: ENDIANESS Mask */ -#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + #define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ + #define SCB_AIRCR_PRIGROUP_Msk ( 7UL << SCB_AIRCR_PRIGROUP_Pos ) /*!< SCB AIRCR: PRIGROUP Mask */ -#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ + #define SCB_AIRCR_SYSRESETREQ_Msk ( 1UL << SCB_AIRCR_SYSRESETREQ_Pos ) /*!< SCB AIRCR: SYSRESETREQ Mask */ -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ + #define SCB_AIRCR_VECTCLRACTIVE_Msk ( 1UL << SCB_AIRCR_VECTCLRACTIVE_Pos ) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ -#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + #define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ + #define SCB_AIRCR_VECTRESET_Msk ( 1UL /*<< SCB_AIRCR_VECTRESET_Pos*/ ) /*!< SCB AIRCR: VECTRESET Mask */ /* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ + #define SCB_SCR_SEVONPEND_Msk ( 1UL << SCB_SCR_SEVONPEND_Pos ) /*!< SCB SCR: SEVONPEND Mask */ -#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ + #define SCB_SCR_SLEEPDEEP_Msk ( 1UL << SCB_SCR_SLEEPDEEP_Pos ) /*!< SCB SCR: SLEEPDEEP Mask */ -#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ + #define SCB_SCR_SLEEPONEXIT_Msk ( 1UL << SCB_SCR_SLEEPONEXIT_Pos ) /*!< SCB SCR: SLEEPONEXIT Mask */ /* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ + #define SCB_CCR_STKALIGN_Msk ( 1UL << SCB_CCR_STKALIGN_Pos ) /*!< SCB CCR: STKALIGN Mask */ -#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + #define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ + #define SCB_CCR_BFHFNMIGN_Msk ( 1UL << SCB_CCR_BFHFNMIGN_Pos ) /*!< SCB CCR: BFHFNMIGN Mask */ -#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + #define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ + #define SCB_CCR_DIV_0_TRP_Msk ( 1UL << SCB_CCR_DIV_0_TRP_Pos ) /*!< SCB CCR: DIV_0_TRP Mask */ -#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ + #define SCB_CCR_UNALIGN_TRP_Msk ( 1UL << SCB_CCR_UNALIGN_TRP_Pos ) /*!< SCB CCR: UNALIGN_TRP Mask */ -#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + #define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ + #define SCB_CCR_USERSETMPEND_Msk ( 1UL << SCB_CCR_USERSETMPEND_Pos ) /*!< SCB CCR: USERSETMPEND Mask */ -#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + #define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ + #define SCB_CCR_NONBASETHRDENA_Msk ( 1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/ ) /*!< SCB CCR: NONBASETHRDENA Mask */ /* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + #define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ + #define SCB_SHCSR_USGFAULTENA_Msk ( 1UL << SCB_SHCSR_USGFAULTENA_Pos ) /*!< SCB SHCSR: USGFAULTENA Mask */ -#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + #define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ + #define SCB_SHCSR_BUSFAULTENA_Msk ( 1UL << SCB_SHCSR_BUSFAULTENA_Pos ) /*!< SCB SHCSR: BUSFAULTENA Mask */ -#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + #define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ + #define SCB_SHCSR_MEMFAULTENA_Msk ( 1UL << SCB_SHCSR_MEMFAULTENA_Pos ) /*!< SCB SHCSR: MEMFAULTENA Mask */ -#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ + #define SCB_SHCSR_SVCALLPENDED_Msk ( 1UL << SCB_SHCSR_SVCALLPENDED_Pos ) /*!< SCB SHCSR: SVCALLPENDED Mask */ -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + #define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ + #define SCB_SHCSR_BUSFAULTPENDED_Msk ( 1UL << SCB_SHCSR_BUSFAULTPENDED_Pos ) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + #define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ + #define SCB_SHCSR_MEMFAULTPENDED_Msk ( 1UL << SCB_SHCSR_MEMFAULTPENDED_Pos ) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ -#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + #define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ + #define SCB_SHCSR_USGFAULTPENDED_Msk ( 1UL << SCB_SHCSR_USGFAULTPENDED_Pos ) /*!< SCB SHCSR: USGFAULTPENDED Mask */ -#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + #define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ + #define SCB_SHCSR_SYSTICKACT_Msk ( 1UL << SCB_SHCSR_SYSTICKACT_Pos ) /*!< SCB SHCSR: SYSTICKACT Mask */ -#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + #define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ + #define SCB_SHCSR_PENDSVACT_Msk ( 1UL << SCB_SHCSR_PENDSVACT_Pos ) /*!< SCB SHCSR: PENDSVACT Mask */ -#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + #define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ + #define SCB_SHCSR_MONITORACT_Msk ( 1UL << SCB_SHCSR_MONITORACT_Pos ) /*!< SCB SHCSR: MONITORACT Mask */ -#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + #define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ + #define SCB_SHCSR_SVCALLACT_Msk ( 1UL << SCB_SHCSR_SVCALLACT_Pos ) /*!< SCB SHCSR: SVCALLACT Mask */ -#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + #define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ + #define SCB_SHCSR_USGFAULTACT_Msk ( 1UL << SCB_SHCSR_USGFAULTACT_Pos ) /*!< SCB SHCSR: USGFAULTACT Mask */ -#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + #define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ + #define SCB_SHCSR_BUSFAULTACT_Msk ( 1UL << SCB_SHCSR_BUSFAULTACT_Pos ) /*!< SCB SHCSR: BUSFAULTACT Mask */ -#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + #define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ + #define SCB_SHCSR_MEMFAULTACT_Msk ( 1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/ ) /*!< SCB SHCSR: MEMFAULTACT Mask */ /* SCB Configurable Fault Status Register Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + #define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ + #define SCB_CFSR_USGFAULTSR_Msk ( 0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos ) /*!< SCB CFSR: Usage Fault Status Register Mask */ -#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + #define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ + #define SCB_CFSR_BUSFAULTSR_Msk ( 0xFFUL << SCB_CFSR_BUSFAULTSR_Pos ) /*!< SCB CFSR: Bus Fault Status Register Mask */ -#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ + #define SCB_CFSR_MEMFAULTSR_Msk ( 0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/ ) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ /* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ -#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ -#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + #define SCB_CFSR_MMARVALID_Pos ( SCB_SHCSR_MEMFAULTACT_Pos + 7U ) /*!< SCB CFSR (MMFSR): MMARVALID Position */ + #define SCB_CFSR_MMARVALID_Msk ( 1UL << SCB_CFSR_MMARVALID_Pos ) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ -#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ -#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + #define SCB_CFSR_MSTKERR_Pos ( SCB_SHCSR_MEMFAULTACT_Pos + 4U ) /*!< SCB CFSR (MMFSR): MSTKERR Position */ + #define SCB_CFSR_MSTKERR_Msk ( 1UL << SCB_CFSR_MSTKERR_Pos ) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ -#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ -#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + #define SCB_CFSR_MUNSTKERR_Pos ( SCB_SHCSR_MEMFAULTACT_Pos + 3U ) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ + #define SCB_CFSR_MUNSTKERR_Msk ( 1UL << SCB_CFSR_MUNSTKERR_Pos ) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ -#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ -#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + #define SCB_CFSR_DACCVIOL_Pos ( SCB_SHCSR_MEMFAULTACT_Pos + 1U ) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ + #define SCB_CFSR_DACCVIOL_Msk ( 1UL << SCB_CFSR_DACCVIOL_Pos ) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ -#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ -#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + #define SCB_CFSR_IACCVIOL_Pos ( SCB_SHCSR_MEMFAULTACT_Pos + 0U ) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ + #define SCB_CFSR_IACCVIOL_Msk ( 1UL /*<< SCB_CFSR_IACCVIOL_Pos*/ ) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ /* BusFault Status Register (part of SCB Configurable Fault Status Register) */ -#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ -#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + #define SCB_CFSR_BFARVALID_Pos ( SCB_CFSR_BUSFAULTSR_Pos + 7U ) /*!< SCB CFSR (BFSR): BFARVALID Position */ + #define SCB_CFSR_BFARVALID_Msk ( 1UL << SCB_CFSR_BFARVALID_Pos ) /*!< SCB CFSR (BFSR): BFARVALID Mask */ -#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ -#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + #define SCB_CFSR_STKERR_Pos ( SCB_CFSR_BUSFAULTSR_Pos + 4U ) /*!< SCB CFSR (BFSR): STKERR Position */ + #define SCB_CFSR_STKERR_Msk ( 1UL << SCB_CFSR_STKERR_Pos ) /*!< SCB CFSR (BFSR): STKERR Mask */ -#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ -#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + #define SCB_CFSR_UNSTKERR_Pos ( SCB_CFSR_BUSFAULTSR_Pos + 3U ) /*!< SCB CFSR (BFSR): UNSTKERR Position */ + #define SCB_CFSR_UNSTKERR_Msk ( 1UL << SCB_CFSR_UNSTKERR_Pos ) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ -#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ -#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + #define SCB_CFSR_IMPRECISERR_Pos ( SCB_CFSR_BUSFAULTSR_Pos + 2U ) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ + #define SCB_CFSR_IMPRECISERR_Msk ( 1UL << SCB_CFSR_IMPRECISERR_Pos ) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ -#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ -#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + #define SCB_CFSR_PRECISERR_Pos ( SCB_CFSR_BUSFAULTSR_Pos + 1U ) /*!< SCB CFSR (BFSR): PRECISERR Position */ + #define SCB_CFSR_PRECISERR_Msk ( 1UL << SCB_CFSR_PRECISERR_Pos ) /*!< SCB CFSR (BFSR): PRECISERR Mask */ -#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ -#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + #define SCB_CFSR_IBUSERR_Pos ( SCB_CFSR_BUSFAULTSR_Pos + 0U ) /*!< SCB CFSR (BFSR): IBUSERR Position */ + #define SCB_CFSR_IBUSERR_Msk ( 1UL << SCB_CFSR_IBUSERR_Pos ) /*!< SCB CFSR (BFSR): IBUSERR Mask */ /* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ -#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ -#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + #define SCB_CFSR_DIVBYZERO_Pos ( SCB_CFSR_USGFAULTSR_Pos + 9U ) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ + #define SCB_CFSR_DIVBYZERO_Msk ( 1UL << SCB_CFSR_DIVBYZERO_Pos ) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ -#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ -#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + #define SCB_CFSR_UNALIGNED_Pos ( SCB_CFSR_USGFAULTSR_Pos + 8U ) /*!< SCB CFSR (UFSR): UNALIGNED Position */ + #define SCB_CFSR_UNALIGNED_Msk ( 1UL << SCB_CFSR_UNALIGNED_Pos ) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ -#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ -#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + #define SCB_CFSR_NOCP_Pos ( SCB_CFSR_USGFAULTSR_Pos + 3U ) /*!< SCB CFSR (UFSR): NOCP Position */ + #define SCB_CFSR_NOCP_Msk ( 1UL << SCB_CFSR_NOCP_Pos ) /*!< SCB CFSR (UFSR): NOCP Mask */ -#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ -#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + #define SCB_CFSR_INVPC_Pos ( SCB_CFSR_USGFAULTSR_Pos + 2U ) /*!< SCB CFSR (UFSR): INVPC Position */ + #define SCB_CFSR_INVPC_Msk ( 1UL << SCB_CFSR_INVPC_Pos ) /*!< SCB CFSR (UFSR): INVPC Mask */ -#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ -#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + #define SCB_CFSR_INVSTATE_Pos ( SCB_CFSR_USGFAULTSR_Pos + 1U ) /*!< SCB CFSR (UFSR): INVSTATE Position */ + #define SCB_CFSR_INVSTATE_Msk ( 1UL << SCB_CFSR_INVSTATE_Pos ) /*!< SCB CFSR (UFSR): INVSTATE Mask */ -#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ -#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + #define SCB_CFSR_UNDEFINSTR_Pos ( SCB_CFSR_USGFAULTSR_Pos + 0U ) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ + #define SCB_CFSR_UNDEFINSTR_Msk ( 1UL << SCB_CFSR_UNDEFINSTR_Pos ) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ /* SCB Hard Fault Status Register Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ + #define SCB_HFSR_DEBUGEVT_Msk ( 1UL << SCB_HFSR_DEBUGEVT_Pos ) /*!< SCB HFSR: DEBUGEVT Mask */ -#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + #define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ + #define SCB_HFSR_FORCED_Msk ( 1UL << SCB_HFSR_FORCED_Pos ) /*!< SCB HFSR: FORCED Mask */ -#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + #define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ + #define SCB_HFSR_VECTTBL_Msk ( 1UL << SCB_HFSR_VECTTBL_Pos ) /*!< SCB HFSR: VECTTBL Mask */ /* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + #define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ + #define SCB_DFSR_EXTERNAL_Msk ( 1UL << SCB_DFSR_EXTERNAL_Pos ) /*!< SCB DFSR: EXTERNAL Mask */ -#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + #define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ + #define SCB_DFSR_VCATCH_Msk ( 1UL << SCB_DFSR_VCATCH_Pos ) /*!< SCB DFSR: VCATCH Mask */ -#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + #define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ + #define SCB_DFSR_DWTTRAP_Msk ( 1UL << SCB_DFSR_DWTTRAP_Pos ) /*!< SCB DFSR: DWTTRAP Mask */ -#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + #define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ + #define SCB_DFSR_BKPT_Msk ( 1UL << SCB_DFSR_BKPT_Pos ) /*!< SCB DFSR: BKPT Mask */ -#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + #define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ + #define SCB_DFSR_HALTED_Msk ( 1UL /*<< SCB_DFSR_HALTED_Pos*/ ) /*!< SCB DFSR: HALTED Mask */ /*@} end of group CMSIS_SCB */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + * \brief Type definitions for the System Control and ID Register not in the SCB + * @{ */ /** - \brief Structure type to access the System Control and ID Register not in the SCB. + * \brief Structure type to access the System Control and ID Register not in the SCB. */ -typedef struct -{ - uint32_t RESERVED0[1U]; - __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ -#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) - __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -#else - uint32_t RESERVED1[1U]; -#endif -} SCnSCB_Type; + typedef struct + { + uint32_t RESERVED0[ 1U ]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + #if defined( __CM3_REV ) && ( __CM3_REV >= 0x200U ) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + #else + uint32_t RESERVED1[ 1U ]; + #endif + } SCnSCB_Type; /* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + #define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ + #define SCnSCB_ICTR_INTLINESNUM_Msk ( 0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/ ) /*!< ICTR: INTLINESNUM Mask */ /* Auxiliary Control Register Definitions */ -#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) -#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ -#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + #if defined( __CM3_REV ) && ( __CM3_REV >= 0x200U ) + #define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ + #define SCnSCB_ACTLR_DISOOFP_Msk ( 1UL << SCnSCB_ACTLR_DISOOFP_Pos ) /*!< ACTLR: DISOOFP Mask */ -#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ -#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + #define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ + #define SCnSCB_ACTLR_DISFPCA_Msk ( 1UL << SCnSCB_ACTLR_DISFPCA_Pos ) /*!< ACTLR: DISFPCA Mask */ -#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + #define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ + #define SCnSCB_ACTLR_DISFOLD_Msk ( 1UL << SCnSCB_ACTLR_DISFOLD_Pos ) /*!< ACTLR: DISFOLD Mask */ -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + #define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ + #define SCnSCB_ACTLR_DISDEFWBUF_Msk ( 1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos ) /*!< ACTLR: DISDEFWBUF Mask */ -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ -#endif + #define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ + #define SCnSCB_ACTLR_DISMCYCINT_Msk ( 1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/ ) /*!< ACTLR: DISMCYCINT Mask */ + #endif /* if defined( __CM3_REV ) && ( __CM3_REV >= 0x200U ) */ /*@} end of group CMSIS_SCnotSCB */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_SysTick System Tick Timer (SysTick) + * \brief Type definitions for the System Timer Registers. + * @{ */ /** - \brief Structure type to access the System Timer (SysTick). + * \brief Structure type to access the System Timer (SysTick). */ -typedef struct -{ - __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; + typedef struct + { + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ + } SysTick_Type; /* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ + #define SysTick_CTRL_COUNTFLAG_Msk ( 1UL << SysTick_CTRL_COUNTFLAG_Pos ) /*!< SysTick CTRL: COUNTFLAG Mask */ -#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ + #define SysTick_CTRL_CLKSOURCE_Msk ( 1UL << SysTick_CTRL_CLKSOURCE_Pos ) /*!< SysTick CTRL: CLKSOURCE Mask */ -#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ + #define SysTick_CTRL_TICKINT_Msk ( 1UL << SysTick_CTRL_TICKINT_Pos ) /*!< SysTick CTRL: TICKINT Mask */ -#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ + #define SysTick_CTRL_ENABLE_Msk ( 1UL /*<< SysTick_CTRL_ENABLE_Pos*/ ) /*!< SysTick CTRL: ENABLE Mask */ /* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ + #define SysTick_LOAD_RELOAD_Msk ( 0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/ ) /*!< SysTick LOAD: RELOAD Mask */ /* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ + #define SysTick_VAL_CURRENT_Msk ( 0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/ ) /*!< SysTick VAL: CURRENT Mask */ /* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ + #define SysTick_CALIB_NOREF_Msk ( 1UL << SysTick_CALIB_NOREF_Pos ) /*!< SysTick CALIB: NOREF Mask */ -#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ + #define SysTick_CALIB_SKEW_Msk ( 1UL << SysTick_CALIB_SKEW_Pos ) /*!< SysTick CALIB: SKEW Mask */ -#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ + #define SysTick_CALIB_TENMS_Msk ( 0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/ ) /*!< SysTick CALIB: TENMS Mask */ /*@} end of group CMSIS_SysTick */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + * \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + * @{ */ /** - \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + * \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). */ -typedef struct -{ - __OM union - { - __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864U]; - __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15U]; - __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15U]; - __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[32U]; - uint32_t RESERVED4[43U]; - __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6U]; - __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; + typedef struct + { + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT[ 32U ]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[ 864U ]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[ 15U ]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[ 15U ]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[ 32U ]; + uint32_t RESERVED4[ 43U ]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[ 6U ]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ + } ITM_Type; /* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ + #define ITM_TPR_PRIVMASK_Msk ( 0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/ ) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ + #define ITM_TCR_BUSY_Msk ( 1UL << ITM_TCR_BUSY_Pos ) /*!< ITM TCR: BUSY Mask */ -#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + #define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ + #define ITM_TCR_TraceBusID_Msk ( 0x7FUL << ITM_TCR_TraceBusID_Pos ) /*!< ITM TCR: ATBID Mask */ -#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + #define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ + #define ITM_TCR_GTSFREQ_Msk ( 3UL << ITM_TCR_GTSFREQ_Pos ) /*!< ITM TCR: Global timestamp frequency Mask */ -#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + #define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ + #define ITM_TCR_TSPrescale_Msk ( 3UL << ITM_TCR_TSPrescale_Pos ) /*!< ITM TCR: TSPrescale Mask */ -#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + #define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ + #define ITM_TCR_SWOENA_Msk ( 1UL << ITM_TCR_SWOENA_Pos ) /*!< ITM TCR: SWOENA Mask */ -#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + #define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ + #define ITM_TCR_DWTENA_Msk ( 1UL << ITM_TCR_DWTENA_Pos ) /*!< ITM TCR: DWTENA Mask */ -#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + #define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ + #define ITM_TCR_SYNCENA_Msk ( 1UL << ITM_TCR_SYNCENA_Pos ) /*!< ITM TCR: SYNCENA Mask */ -#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + #define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ + #define ITM_TCR_TSENA_Msk ( 1UL << ITM_TCR_TSENA_Pos ) /*!< ITM TCR: TSENA Mask */ -#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ + #define ITM_TCR_ITMENA_Msk ( 1UL /*<< ITM_TCR_ITMENA_Pos*/ ) /*!< ITM TCR: ITM Enable bit Mask */ /* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ + #define ITM_LSR_ByteAcc_Msk ( 1UL << ITM_LSR_ByteAcc_Pos ) /*!< ITM LSR: ByteAcc Mask */ -#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + #define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ + #define ITM_LSR_Access_Msk ( 1UL << ITM_LSR_Access_Pos ) /*!< ITM LSR: Access Mask */ -#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + #define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ + #define ITM_LSR_Present_Msk ( 1UL /*<< ITM_LSR_Present_Pos*/ ) /*!< ITM LSR: Present Mask */ /*@}*/ /* end of group CMSIS_ITM */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + * \brief Type definitions for the Data Watchpoint and Trace (DWT) + * @{ */ /** - \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + * \brief Structure type to access the Data Watchpoint and Trace Register (DWT). */ -typedef struct -{ - __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1U]; - __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1U]; - __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1U]; - __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ -} DWT_Type; + typedef struct + { + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[ 1U ]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[ 1U ]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[ 1U ]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + } DWT_Type; /* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + #define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ + #define DWT_CTRL_NUMCOMP_Msk ( 0xFUL << DWT_CTRL_NUMCOMP_Pos ) /*!< DWT CTRL: NUMCOMP Mask */ -#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + #define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ + #define DWT_CTRL_NOTRCPKT_Msk ( 0x1UL << DWT_CTRL_NOTRCPKT_Pos ) /*!< DWT CTRL: NOTRCPKT Mask */ -#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + #define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ + #define DWT_CTRL_NOEXTTRIG_Msk ( 0x1UL << DWT_CTRL_NOEXTTRIG_Pos ) /*!< DWT CTRL: NOEXTTRIG Mask */ -#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + #define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ + #define DWT_CTRL_NOCYCCNT_Msk ( 0x1UL << DWT_CTRL_NOCYCCNT_Pos ) /*!< DWT CTRL: NOCYCCNT Mask */ -#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + #define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ + #define DWT_CTRL_NOPRFCNT_Msk ( 0x1UL << DWT_CTRL_NOPRFCNT_Pos ) /*!< DWT CTRL: NOPRFCNT Mask */ -#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + #define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ + #define DWT_CTRL_CYCEVTENA_Msk ( 0x1UL << DWT_CTRL_CYCEVTENA_Pos ) /*!< DWT CTRL: CYCEVTENA Mask */ -#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + #define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ + #define DWT_CTRL_FOLDEVTENA_Msk ( 0x1UL << DWT_CTRL_FOLDEVTENA_Pos ) /*!< DWT CTRL: FOLDEVTENA Mask */ -#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + #define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ + #define DWT_CTRL_LSUEVTENA_Msk ( 0x1UL << DWT_CTRL_LSUEVTENA_Pos ) /*!< DWT CTRL: LSUEVTENA Mask */ -#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + #define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ + #define DWT_CTRL_SLEEPEVTENA_Msk ( 0x1UL << DWT_CTRL_SLEEPEVTENA_Pos ) /*!< DWT CTRL: SLEEPEVTENA Mask */ -#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + #define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ + #define DWT_CTRL_EXCEVTENA_Msk ( 0x1UL << DWT_CTRL_EXCEVTENA_Pos ) /*!< DWT CTRL: EXCEVTENA Mask */ -#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + #define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ + #define DWT_CTRL_CPIEVTENA_Msk ( 0x1UL << DWT_CTRL_CPIEVTENA_Pos ) /*!< DWT CTRL: CPIEVTENA Mask */ -#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + #define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ + #define DWT_CTRL_EXCTRCENA_Msk ( 0x1UL << DWT_CTRL_EXCTRCENA_Pos ) /*!< DWT CTRL: EXCTRCENA Mask */ -#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + #define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ + #define DWT_CTRL_PCSAMPLENA_Msk ( 0x1UL << DWT_CTRL_PCSAMPLENA_Pos ) /*!< DWT CTRL: PCSAMPLENA Mask */ -#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + #define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ + #define DWT_CTRL_SYNCTAP_Msk ( 0x3UL << DWT_CTRL_SYNCTAP_Pos ) /*!< DWT CTRL: SYNCTAP Mask */ -#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + #define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ + #define DWT_CTRL_CYCTAP_Msk ( 0x1UL << DWT_CTRL_CYCTAP_Pos ) /*!< DWT CTRL: CYCTAP Mask */ -#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + #define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ + #define DWT_CTRL_POSTINIT_Msk ( 0xFUL << DWT_CTRL_POSTINIT_Pos ) /*!< DWT CTRL: POSTINIT Mask */ -#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + #define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ + #define DWT_CTRL_POSTPRESET_Msk ( 0xFUL << DWT_CTRL_POSTPRESET_Pos ) /*!< DWT CTRL: POSTPRESET Mask */ -#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + #define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ + #define DWT_CTRL_CYCCNTENA_Msk ( 0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/ ) /*!< DWT CTRL: CYCCNTENA Mask */ /* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + #define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ + #define DWT_CPICNT_CPICNT_Msk ( 0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/ ) /*!< DWT CPICNT: CPICNT Mask */ /* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + #define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ + #define DWT_EXCCNT_EXCCNT_Msk ( 0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/ ) /*!< DWT EXCCNT: EXCCNT Mask */ /* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + #define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ + #define DWT_SLEEPCNT_SLEEPCNT_Msk ( 0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/ ) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ /* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + #define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ + #define DWT_LSUCNT_LSUCNT_Msk ( 0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/ ) /*!< DWT LSUCNT: LSUCNT Mask */ /* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + #define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ + #define DWT_FOLDCNT_FOLDCNT_Msk ( 0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/ ) /*!< DWT FOLDCNT: FOLDCNT Mask */ /* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + #define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ + #define DWT_MASK_MASK_Msk ( 0x1FUL /*<< DWT_MASK_MASK_Pos*/ ) /*!< DWT MASK: MASK Mask */ /* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + #define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ + #define DWT_FUNCTION_MATCHED_Msk ( 0x1UL << DWT_FUNCTION_MATCHED_Pos ) /*!< DWT FUNCTION: MATCHED Mask */ -#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + #define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ + #define DWT_FUNCTION_DATAVADDR1_Msk ( 0xFUL << DWT_FUNCTION_DATAVADDR1_Pos ) /*!< DWT FUNCTION: DATAVADDR1 Mask */ -#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + #define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ + #define DWT_FUNCTION_DATAVADDR0_Msk ( 0xFUL << DWT_FUNCTION_DATAVADDR0_Pos ) /*!< DWT FUNCTION: DATAVADDR0 Mask */ -#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + #define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ + #define DWT_FUNCTION_DATAVSIZE_Msk ( 0x3UL << DWT_FUNCTION_DATAVSIZE_Pos ) /*!< DWT FUNCTION: DATAVSIZE Mask */ -#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + #define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ + #define DWT_FUNCTION_LNK1ENA_Msk ( 0x1UL << DWT_FUNCTION_LNK1ENA_Pos ) /*!< DWT FUNCTION: LNK1ENA Mask */ -#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + #define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ + #define DWT_FUNCTION_DATAVMATCH_Msk ( 0x1UL << DWT_FUNCTION_DATAVMATCH_Pos ) /*!< DWT FUNCTION: DATAVMATCH Mask */ -#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + #define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ + #define DWT_FUNCTION_CYCMATCH_Msk ( 0x1UL << DWT_FUNCTION_CYCMATCH_Pos ) /*!< DWT FUNCTION: CYCMATCH Mask */ -#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + #define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ + #define DWT_FUNCTION_EMITRANGE_Msk ( 0x1UL << DWT_FUNCTION_EMITRANGE_Pos ) /*!< DWT FUNCTION: EMITRANGE Mask */ -#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + #define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ + #define DWT_FUNCTION_FUNCTION_Msk ( 0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/ ) /*!< DWT FUNCTION: FUNCTION Mask */ /*@}*/ /* end of group CMSIS_DWT */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_TPI Trace Port Interface (TPI) + * \brief Type definitions for the Trace Port Interface (TPI) + * @{ */ /** - \brief Structure type to access the Trace Port Interface Register (TPI). + * \brief Structure type to access the Trace Port Interface Register (TPI). */ -typedef struct -{ - __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2U]; - __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55U]; - __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131U]; - __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ - __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1U]; - __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39U]; - __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8U]; - __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; + typedef struct + { + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[ 2U ]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[ 55U ]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[ 131U ]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[ 759U ]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[ 1U ]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[ 39U ]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[ 8U ]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ + } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + #define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ + #define TPI_ACPR_PRESCALER_Msk ( 0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/ ) /*!< TPI ACPR: PRESCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ + #define TPI_SPPR_TXMODE_Msk ( 0x3UL /*<< TPI_SPPR_TXMODE_Pos*/ ) /*!< TPI SPPR: TXMODE Mask */ /* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + #define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ + #define TPI_FFSR_FtNonStop_Msk ( 0x1UL << TPI_FFSR_FtNonStop_Pos ) /*!< TPI FFSR: FtNonStop Mask */ -#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + #define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ + #define TPI_FFSR_TCPresent_Msk ( 0x1UL << TPI_FFSR_TCPresent_Pos ) /*!< TPI FFSR: TCPresent Mask */ -#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + #define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ + #define TPI_FFSR_FtStopped_Msk ( 0x1UL << TPI_FFSR_FtStopped_Pos ) /*!< TPI FFSR: FtStopped Mask */ -#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + #define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ + #define TPI_FFSR_FlInProg_Msk ( 0x1UL /*<< TPI_FFSR_FlInProg_Pos*/ ) /*!< TPI FFSR: FlInProg Mask */ /* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ + #define TPI_FFCR_TrigIn_Msk ( 0x1UL << TPI_FFCR_TrigIn_Pos ) /*!< TPI FFCR: TrigIn Mask */ -#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ + #define TPI_FFCR_EnFCont_Msk ( 0x1UL << TPI_FFCR_EnFCont_Pos ) /*!< TPI FFCR: EnFCont Mask */ /* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ + #define TPI_TRIGGER_TRIGGER_Msk ( 0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/ ) /*!< TPI TRIGGER: TRIGGER Mask */ /* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + #define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ + #define TPI_FIFO0_ITM_ATVALID_Msk ( 0x1UL << TPI_FIFO0_ITM_ATVALID_Pos ) /*!< TPI FIFO0: ITM_ATVALID Mask */ -#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + #define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ + #define TPI_FIFO0_ITM_bytecount_Msk ( 0x3UL << TPI_FIFO0_ITM_bytecount_Pos ) /*!< TPI FIFO0: ITM_bytecount Mask */ -#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + #define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ + #define TPI_FIFO0_ETM_ATVALID_Msk ( 0x1UL << TPI_FIFO0_ETM_ATVALID_Pos ) /*!< TPI FIFO0: ETM_ATVALID Mask */ -#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + #define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ + #define TPI_FIFO0_ETM_bytecount_Msk ( 0x3UL << TPI_FIFO0_ETM_bytecount_Pos ) /*!< TPI FIFO0: ETM_bytecount Mask */ -#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + #define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ + #define TPI_FIFO0_ETM2_Msk ( 0xFFUL << TPI_FIFO0_ETM2_Pos ) /*!< TPI FIFO0: ETM2 Mask */ -#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + #define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ + #define TPI_FIFO0_ETM1_Msk ( 0xFFUL << TPI_FIFO0_ETM1_Pos ) /*!< TPI FIFO0: ETM1 Mask */ -#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + #define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ + #define TPI_FIFO0_ETM0_Msk ( 0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/ ) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ -#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + #define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ + #define TPI_ITATBCTR2_ATREADY2_Msk ( 0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/ ) /*!< TPI ITATBCTR2: ATREADY2 Mask */ -#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ -#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + #define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ + #define TPI_ITATBCTR2_ATREADY1_Msk ( 0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/ ) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ + #define TPI_FIFO1_ITM_ATVALID_Msk ( 0x1UL << TPI_FIFO1_ITM_ATVALID_Pos ) /*!< TPI FIFO1: ITM_ATVALID Mask */ -#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + #define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ + #define TPI_FIFO1_ITM_bytecount_Msk ( 0x3UL << TPI_FIFO1_ITM_bytecount_Pos ) /*!< TPI FIFO1: ITM_bytecount Mask */ -#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + #define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ + #define TPI_FIFO1_ETM_ATVALID_Msk ( 0x1UL << TPI_FIFO1_ETM_ATVALID_Pos ) /*!< TPI FIFO1: ETM_ATVALID Mask */ -#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + #define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ + #define TPI_FIFO1_ETM_bytecount_Msk ( 0x3UL << TPI_FIFO1_ETM_bytecount_Pos ) /*!< TPI FIFO1: ETM_bytecount Mask */ -#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + #define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ + #define TPI_FIFO1_ITM2_Msk ( 0xFFUL << TPI_FIFO1_ITM2_Pos ) /*!< TPI FIFO1: ITM2 Mask */ -#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + #define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ + #define TPI_FIFO1_ITM1_Msk ( 0xFFUL << TPI_FIFO1_ITM1_Pos ) /*!< TPI FIFO1: ITM1 Mask */ -#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + #define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ + #define TPI_FIFO1_ITM0_Msk ( 0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/ ) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ -#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + #define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ + #define TPI_ITATBCTR0_ATREADY2_Msk ( 0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/ ) /*!< TPI ITATBCTR0: ATREADY2 Mask */ -#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ -#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + #define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ + #define TPI_ITATBCTR0_ATREADY1_Msk ( 0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/ ) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ + #define TPI_ITCTRL_Mode_Msk ( 0x3UL /*<< TPI_ITCTRL_Mode_Pos*/ ) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ + #define TPI_DEVID_NRZVALID_Msk ( 0x1UL << TPI_DEVID_NRZVALID_Pos ) /*!< TPI DEVID: NRZVALID Mask */ -#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + #define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ + #define TPI_DEVID_MANCVALID_Msk ( 0x1UL << TPI_DEVID_MANCVALID_Pos ) /*!< TPI DEVID: MANCVALID Mask */ -#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ + #define TPI_DEVID_PTINVALID_Msk ( 0x1UL << TPI_DEVID_PTINVALID_Pos ) /*!< TPI DEVID: PTINVALID Mask */ -#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + #define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ + #define TPI_DEVID_MinBufSz_Msk ( 0x7UL << TPI_DEVID_MinBufSz_Pos ) /*!< TPI DEVID: MinBufSz Mask */ -#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + #define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ + #define TPI_DEVID_AsynClkIn_Msk ( 0x1UL << TPI_DEVID_AsynClkIn_Pos ) /*!< TPI DEVID: AsynClkIn Mask */ -#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ + #define TPI_DEVID_NrTraceInput_Msk ( 0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/ ) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + #define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ + #define TPI_DEVTYPE_SubType_Msk ( 0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/ ) /*!< TPI DEVTYPE: SubType Mask */ -#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + #define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ + #define TPI_DEVTYPE_MajorType_Msk ( 0xFUL << TPI_DEVTYPE_MajorType_Pos ) /*!< TPI DEVTYPE: MajorType Mask */ /*@}*/ /* end of group CMSIS_TPI */ -#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #if defined( __MPU_PRESENT ) && ( __MPU_PRESENT == 1U ) + /** - \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_MPU Memory Protection Unit (MPU) + * \brief Type definitions for the Memory Protection Unit (MPU) + * @{ */ /** - \brief Structure type to access the Memory Protection Unit (MPU). + * \brief Structure type to access the Memory Protection Unit (MPU). */ -typedef struct -{ - __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; + typedef struct + { + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ + } MPU_Type; -#define MPU_TYPE_RALIASES 4U + #define MPU_TYPE_RALIASES 4U /* MPU Type Register Definitions */ -#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ + #define MPU_TYPE_IREGION_Msk ( 0xFFUL << MPU_TYPE_IREGION_Pos ) /*!< MPU TYPE: IREGION Mask */ -#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + #define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ + #define MPU_TYPE_DREGION_Msk ( 0xFFUL << MPU_TYPE_DREGION_Pos ) /*!< MPU TYPE: DREGION Mask */ -#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + #define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ + #define MPU_TYPE_SEPARATE_Msk ( 1UL /*<< MPU_TYPE_SEPARATE_Pos*/ ) /*!< MPU TYPE: SEPARATE Mask */ /* MPU Control Register Definitions */ -#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + #define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ + #define MPU_CTRL_PRIVDEFENA_Msk ( 1UL << MPU_CTRL_PRIVDEFENA_Pos ) /*!< MPU CTRL: PRIVDEFENA Mask */ -#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + #define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ + #define MPU_CTRL_HFNMIENA_Msk ( 1UL << MPU_CTRL_HFNMIENA_Pos ) /*!< MPU CTRL: HFNMIENA Mask */ -#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + #define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ + #define MPU_CTRL_ENABLE_Msk ( 1UL /*<< MPU_CTRL_ENABLE_Pos*/ ) /*!< MPU CTRL: ENABLE Mask */ /* MPU Region Number Register Definitions */ -#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + #define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ + #define MPU_RNR_REGION_Msk ( 0xFFUL /*<< MPU_RNR_REGION_Pos*/ ) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ -#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + #define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ + #define MPU_RBAR_ADDR_Msk ( 0x7FFFFFFUL << MPU_RBAR_ADDR_Pos ) /*!< MPU RBAR: ADDR Mask */ -#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + #define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ + #define MPU_RBAR_VALID_Msk ( 1UL << MPU_RBAR_VALID_Pos ) /*!< MPU RBAR: VALID Mask */ -#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + #define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ + #define MPU_RBAR_REGION_Msk ( 0xFUL /*<< MPU_RBAR_REGION_Pos*/ ) /*!< MPU RBAR: REGION Mask */ /* MPU Region Attribute and Size Register Definitions */ -#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + #define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ + #define MPU_RASR_ATTRS_Msk ( 0xFFFFUL << MPU_RASR_ATTRS_Pos ) /*!< MPU RASR: MPU Region Attribute field Mask */ -#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + #define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ + #define MPU_RASR_XN_Msk ( 1UL << MPU_RASR_XN_Pos ) /*!< MPU RASR: ATTRS.XN Mask */ -#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + #define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ + #define MPU_RASR_AP_Msk ( 0x7UL << MPU_RASR_AP_Pos ) /*!< MPU RASR: ATTRS.AP Mask */ -#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + #define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ + #define MPU_RASR_TEX_Msk ( 0x7UL << MPU_RASR_TEX_Pos ) /*!< MPU RASR: ATTRS.TEX Mask */ -#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + #define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ + #define MPU_RASR_S_Msk ( 1UL << MPU_RASR_S_Pos ) /*!< MPU RASR: ATTRS.S Mask */ -#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + #define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ + #define MPU_RASR_C_Msk ( 1UL << MPU_RASR_C_Pos ) /*!< MPU RASR: ATTRS.C Mask */ -#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + #define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ + #define MPU_RASR_B_Msk ( 1UL << MPU_RASR_B_Pos ) /*!< MPU RASR: ATTRS.B Mask */ -#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + #define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ + #define MPU_RASR_SRD_Msk ( 0xFFUL << MPU_RASR_SRD_Pos ) /*!< MPU RASR: Sub-Region Disable Mask */ -#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + #define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ + #define MPU_RASR_SIZE_Msk ( 0x1FUL << MPU_RASR_SIZE_Pos ) /*!< MPU RASR: Region Size Field Mask */ -#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + #define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ + #define MPU_RASR_ENABLE_Msk ( 1UL /*<< MPU_RASR_ENABLE_Pos*/ ) /*!< MPU RASR: Region enable bit Disable Mask */ /*@} end of group CMSIS_MPU */ -#endif + #endif /* if defined( __MPU_PRESENT ) && ( __MPU_PRESENT == 1U ) */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + * \brief Type definitions for the Core Debug Registers + * @{ */ /** - \brief Structure type to access the Core Debug Register (CoreDebug). + * \brief Structure type to access the Core Debug Register (CoreDebug). */ -typedef struct -{ - __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; + typedef struct + { + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + } CoreDebug_Type; /* Debug Halting Control and Status Register Definitions */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + #define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ + #define CoreDebug_DHCSR_DBGKEY_Msk ( 0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos ) /*!< CoreDebug DHCSR: DBGKEY Mask */ -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + #define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ + #define CoreDebug_DHCSR_S_RESET_ST_Msk ( 1UL << CoreDebug_DHCSR_S_RESET_ST_Pos ) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + #define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ + #define CoreDebug_DHCSR_S_RETIRE_ST_Msk ( 1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos ) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + #define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ + #define CoreDebug_DHCSR_S_LOCKUP_Msk ( 1UL << CoreDebug_DHCSR_S_LOCKUP_Pos ) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ -#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + #define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ + #define CoreDebug_DHCSR_S_SLEEP_Msk ( 1UL << CoreDebug_DHCSR_S_SLEEP_Pos ) /*!< CoreDebug DHCSR: S_SLEEP Mask */ -#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + #define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ + #define CoreDebug_DHCSR_S_HALT_Msk ( 1UL << CoreDebug_DHCSR_S_HALT_Pos ) /*!< CoreDebug DHCSR: S_HALT Mask */ -#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + #define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ + #define CoreDebug_DHCSR_S_REGRDY_Msk ( 1UL << CoreDebug_DHCSR_S_REGRDY_Pos ) /*!< CoreDebug DHCSR: S_REGRDY Mask */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + #define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ + #define CoreDebug_DHCSR_C_SNAPSTALL_Msk ( 1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos ) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + #define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ + #define CoreDebug_DHCSR_C_MASKINTS_Msk ( 1UL << CoreDebug_DHCSR_C_MASKINTS_Pos ) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ -#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + #define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ + #define CoreDebug_DHCSR_C_STEP_Msk ( 1UL << CoreDebug_DHCSR_C_STEP_Pos ) /*!< CoreDebug DHCSR: C_STEP Mask */ -#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + #define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ + #define CoreDebug_DHCSR_C_HALT_Msk ( 1UL << CoreDebug_DHCSR_C_HALT_Pos ) /*!< CoreDebug DHCSR: C_HALT Mask */ -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ + #define CoreDebug_DHCSR_C_DEBUGEN_Msk ( 1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/ ) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ /* Debug Core Register Selector Register Definitions */ -#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ + #define CoreDebug_DCRSR_REGWnR_Msk ( 1UL << CoreDebug_DCRSR_REGWnR_Pos ) /*!< CoreDebug DCRSR: REGWnR Mask */ -#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + #define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ + #define CoreDebug_DCRSR_REGSEL_Msk ( 0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/ ) /*!< CoreDebug DCRSR: REGSEL Mask */ /* Debug Exception and Monitor Control Register Definitions */ -#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + #define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ + #define CoreDebug_DEMCR_TRCENA_Msk ( 1UL << CoreDebug_DEMCR_TRCENA_Pos ) /*!< CoreDebug DEMCR: TRCENA Mask */ -#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + #define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ + #define CoreDebug_DEMCR_MON_REQ_Msk ( 1UL << CoreDebug_DEMCR_MON_REQ_Pos ) /*!< CoreDebug DEMCR: MON_REQ Mask */ -#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + #define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ + #define CoreDebug_DEMCR_MON_STEP_Msk ( 1UL << CoreDebug_DEMCR_MON_STEP_Pos ) /*!< CoreDebug DEMCR: MON_STEP Mask */ -#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + #define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ + #define CoreDebug_DEMCR_MON_PEND_Msk ( 1UL << CoreDebug_DEMCR_MON_PEND_Pos ) /*!< CoreDebug DEMCR: MON_PEND Mask */ -#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + #define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ + #define CoreDebug_DEMCR_MON_EN_Msk ( 1UL << CoreDebug_DEMCR_MON_EN_Pos ) /*!< CoreDebug DEMCR: MON_EN Mask */ -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + #define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ + #define CoreDebug_DEMCR_VC_HARDERR_Msk ( 1UL << CoreDebug_DEMCR_VC_HARDERR_Pos ) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ -#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + #define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ + #define CoreDebug_DEMCR_VC_INTERR_Msk ( 1UL << CoreDebug_DEMCR_VC_INTERR_Pos ) /*!< CoreDebug DEMCR: VC_INTERR Mask */ -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + #define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ + #define CoreDebug_DEMCR_VC_BUSERR_Msk ( 1UL << CoreDebug_DEMCR_VC_BUSERR_Pos ) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ -#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + #define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ + #define CoreDebug_DEMCR_VC_STATERR_Msk ( 1UL << CoreDebug_DEMCR_VC_STATERR_Pos ) /*!< CoreDebug DEMCR: VC_STATERR Mask */ -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + #define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ + #define CoreDebug_DEMCR_VC_CHKERR_Msk ( 1UL << CoreDebug_DEMCR_VC_CHKERR_Pos ) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + #define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ + #define CoreDebug_DEMCR_VC_NOCPERR_Msk ( 1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos ) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ -#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + #define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ + #define CoreDebug_DEMCR_VC_MMERR_Msk ( 1UL << CoreDebug_DEMCR_VC_MMERR_Pos ) /*!< CoreDebug DEMCR: VC_MMERR Mask */ -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + #define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ + #define CoreDebug_DEMCR_VC_CORERESET_Msk ( 1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/ ) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ /*@} end of group CMSIS_CoreDebug */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_core_bitfield Core register bit field macros - \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_core_bitfield Core register bit field macros + * \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + * @{ */ /** - \brief Mask and shift a bit field value for use in a register bit range. - \param[in] field Name of the register bit field. - \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. - \return Masked and shifted value. -*/ -#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + * \brief Mask and shift a bit field value for use in a register bit range. + * \param[in] field Name of the register bit field. + * \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + * \return Masked and shifted value. + */ + #define _VAL2FLD( field, value ) ( ( ( uint32_t ) ( value ) << field ## _Pos ) & field ## _Msk ) /** - \brief Mask and shift a register value to extract a bit filed value. - \param[in] field Name of the register bit field. - \param[in] value Value of register. This parameter is interpreted as an uint32_t type. - \return Masked and shifted bit field value. -*/ -#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + * \brief Mask and shift a register value to extract a bit filed value. + * \param[in] field Name of the register bit field. + * \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + * \return Masked and shifted bit field value. + */ + #define _FLD2VAL( field, value ) ( ( ( uint32_t ) ( value ) & field ## _Msk ) >> field ## _Pos ) /*@} end of group CMSIS_core_bitfield */ /** - \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ + * \ingroup CMSIS_core_register + * \defgroup CMSIS_core_base Core Definitions + * \brief Definitions for base addresses, unions, and structures. + * @{ */ /* Memory mapping of Core Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + #define SCS_BASE ( 0xE000E000UL ) /*!< System Control Space Base Address */ + #define ITM_BASE ( 0xE0000000UL ) /*!< ITM Base Address */ + #define DWT_BASE ( 0xE0001000UL ) /*!< DWT Base Address */ + #define TPI_BASE ( 0xE0040000UL ) /*!< TPI Base Address */ + #define CoreDebug_BASE ( 0xE000EDF0UL ) /*!< Core Debug Base Address */ + #define SysTick_BASE ( SCS_BASE + 0x0010UL ) /*!< SysTick Base Address */ + #define NVIC_BASE ( SCS_BASE + 0x0100UL ) /*!< NVIC Base Address */ + #define SCB_BASE ( SCS_BASE + 0x0D00UL ) /*!< System Control Block Base Address */ -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + #define SCnSCB ( ( SCnSCB_Type * ) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ( ( SCB_Type * ) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ( ( SysTick_Type * ) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ( ( NVIC_Type * ) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ( ( ITM_Type * ) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ( ( DWT_Type * ) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ( ( TPI_Type * ) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ( ( CoreDebug_Type * ) CoreDebug_BASE ) /*!< Core Debug configuration struct */ -#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif + #if defined( __MPU_PRESENT ) && ( __MPU_PRESENT == 1U ) + #define MPU_BASE ( SCS_BASE + 0x0D90UL ) /*!< Memory Protection Unit */ + #define MPU ( ( MPU_Type * ) MPU_BASE ) /*!< Memory Protection Unit */ + #endif /*@} */ @@ -1406,406 +1412,417 @@ typedef struct /******************************************************************************* * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions + * Core Function Interface contains: + * - Core NVIC Functions + * - Core SysTick Functions + * - Core Debug Functions + * - Core Register Access Functions ******************************************************************************/ + /** - \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ + * \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference + */ /* ########################## NVIC functions #################################### */ + /** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ + * \ingroup CMSIS_Core_FunctionInterface + * \defgroup CMSIS_Core_NVICFunctions NVIC Functions + * \brief Functions that manage interrupts and exceptions via the NVIC. + * @{ */ -#ifdef CMSIS_NVIC_VIRTUAL - #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE - #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" - #endif - #include CMSIS_NVIC_VIRTUAL_HEADER_FILE -#else - #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping - #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping - #define NVIC_EnableIRQ __NVIC_EnableIRQ - #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ - #define NVIC_DisableIRQ __NVIC_DisableIRQ - #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ - #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ - #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ - #define NVIC_GetActive __NVIC_GetActive - #define NVIC_SetPriority __NVIC_SetPriority - #define NVIC_GetPriority __NVIC_GetPriority - #define NVIC_SystemReset __NVIC_SystemReset -#endif /* CMSIS_NVIC_VIRTUAL */ + #ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE + #else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset + #endif /* CMSIS_NVIC_VIRTUAL */ -#ifdef CMSIS_VECTAB_VIRTUAL - #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE - #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" - #endif - #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE -#else - #define NVIC_SetVector __NVIC_SetVector - #define NVIC_GetVector __NVIC_GetVector -#endif /* (CMSIS_VECTAB_VIRTUAL) */ + #ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector + #endif /* (CMSIS_VECTAB_VIRTUAL) */ -#define NVIC_USER_IRQ_OFFSET 16 + #define NVIC_USER_IRQ_OFFSET 16 /* The following EXC_RETURN values are saved the LR on exception entry */ -#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ -#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ -#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + #define EXC_RETURN_HANDLER ( 0xFFFFFFF1UL ) /* return to Handler mode, uses MSP after return */ + #define EXC_RETURN_THREAD_MSP ( 0xFFFFFFF9UL ) /* return to Thread mode, uses MSP after return */ + #define EXC_RETURN_THREAD_PSP ( 0xFFFFFFFDUL ) /* return to Thread mode, uses PSP after return */ /** - \brief Set Priority Grouping - \details Sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - \param [in] PriorityGroup Priority grouping field. + * \brief Set Priority Grouping + * \details Sets the priority grouping field using the required unlock sequence. + * The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + * Only values from 0..7 are used. + * In case of a conflict between priority grouping and available + * priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + * \param [in] PriorityGroup Priority grouping field. */ -__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + __STATIC_INLINE void __NVIC_SetPriorityGrouping( uint32_t PriorityGroup ) + { + uint32_t reg_value; + uint32_t PriorityGroupTmp = ( PriorityGroup & ( uint32_t ) 0x07UL ); /* only values 0..7 are used */ - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ - SCB->AIRCR = reg_value; -} + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~( ( uint32_t ) ( SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk ) ); /* clear bits to change */ + reg_value = ( reg_value | + ( ( uint32_t ) 0x5FAUL << SCB_AIRCR_VECTKEY_Pos ) | + ( PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos ) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; + } /** - \brief Get Priority Grouping - \details Reads the priority grouping field from the NVIC Interrupt Controller. - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + * \brief Get Priority Grouping + * \details Reads the priority grouping field from the NVIC Interrupt Controller. + * \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ -__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) -{ - return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); -} + __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping( void ) + { + return( ( uint32_t ) ( ( SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk ) >> SCB_AIRCR_PRIGROUP_Pos ) ); + } /** - \brief Enable Interrupt - \details Enables a device specific interrupt in the NVIC interrupt controller. - \param [in] IRQn Device specific interrupt number. - \note IRQn must not be negative. + * \brief Enable Interrupt + * \details Enables a device specific interrupt in the NVIC interrupt controller. + * \param [in] IRQn Device specific interrupt number. + * \note IRQn must not be negative. */ -__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) -{ - if ((int32_t)(IRQn) >= 0) - { - __COMPILER_BARRIER(); - NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); - __COMPILER_BARRIER(); - } -} + __STATIC_INLINE void __NVIC_EnableIRQ( IRQn_Type IRQn ) + { + if( ( int32_t ) ( IRQn ) >= 0 ) + { + __COMPILER_BARRIER(); + NVIC->ISER[ ( ( ( uint32_t ) IRQn ) >> 5UL ) ] = ( uint32_t ) ( 1UL << ( ( ( uint32_t ) IRQn ) & 0x1FUL ) ); + __COMPILER_BARRIER(); + } + } /** - \brief Get Interrupt Enable status - \details Returns a device specific interrupt enable status from the NVIC interrupt controller. - \param [in] IRQn Device specific interrupt number. - \return 0 Interrupt is not enabled. - \return 1 Interrupt is enabled. - \note IRQn must not be negative. + * \brief Get Interrupt Enable status + * \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + * \param [in] IRQn Device specific interrupt number. + * \return 0 Interrupt is not enabled. + * \return 1 Interrupt is enabled. + * \note IRQn must not be negative. */ -__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) -{ - if ((int32_t)(IRQn) >= 0) - { - return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); - } - else - { - return(0U); - } -} + __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ( IRQn_Type IRQn ) + { + if( ( int32_t ) ( IRQn ) >= 0 ) + { + return( ( uint32_t ) ( ( ( NVIC->ISER[ ( ( ( uint32_t ) IRQn ) >> 5UL ) ] & ( 1UL << ( ( ( uint32_t ) IRQn ) & 0x1FUL ) ) ) != 0UL ) ? 1UL : 0UL ) ); + } + else + { + return( 0U ); + } + } /** - \brief Disable Interrupt - \details Disables a device specific interrupt in the NVIC interrupt controller. - \param [in] IRQn Device specific interrupt number. - \note IRQn must not be negative. + * \brief Disable Interrupt + * \details Disables a device specific interrupt in the NVIC interrupt controller. + * \param [in] IRQn Device specific interrupt number. + * \note IRQn must not be negative. */ -__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) -{ - if ((int32_t)(IRQn) >= 0) - { - NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); - __DSB(); - __ISB(); - } -} + __STATIC_INLINE void __NVIC_DisableIRQ( IRQn_Type IRQn ) + { + if( ( int32_t ) ( IRQn ) >= 0 ) + { + NVIC->ICER[ ( ( ( uint32_t ) IRQn ) >> 5UL ) ] = ( uint32_t ) ( 1UL << ( ( ( uint32_t ) IRQn ) & 0x1FUL ) ); + __DSB(); + __ISB(); + } + } /** - \brief Get Pending Interrupt - \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. - \param [in] IRQn Device specific interrupt number. - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - \note IRQn must not be negative. + * \brief Get Pending Interrupt + * \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + * \param [in] IRQn Device specific interrupt number. + * \return 0 Interrupt status is not pending. + * \return 1 Interrupt status is pending. + * \note IRQn must not be negative. */ -__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - if ((int32_t)(IRQn) >= 0) - { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); - } - else - { - return(0U); - } -} + __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ( IRQn_Type IRQn ) + { + if( ( int32_t ) ( IRQn ) >= 0 ) + { + return( ( uint32_t ) ( ( ( NVIC->ISPR[ ( ( ( uint32_t ) IRQn ) >> 5UL ) ] & ( 1UL << ( ( ( uint32_t ) IRQn ) & 0x1FUL ) ) ) != 0UL ) ? 1UL : 0UL ) ); + } + else + { + return( 0U ); + } + } /** - \brief Set Pending Interrupt - \details Sets the pending bit of a device specific interrupt in the NVIC pending register. - \param [in] IRQn Device specific interrupt number. - \note IRQn must not be negative. + * \brief Set Pending Interrupt + * \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + * \param [in] IRQn Device specific interrupt number. + * \note IRQn must not be negative. */ -__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - if ((int32_t)(IRQn) >= 0) - { - NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); - } -} + __STATIC_INLINE void __NVIC_SetPendingIRQ( IRQn_Type IRQn ) + { + if( ( int32_t ) ( IRQn ) >= 0 ) + { + NVIC->ISPR[ ( ( ( uint32_t ) IRQn ) >> 5UL ) ] = ( uint32_t ) ( 1UL << ( ( ( uint32_t ) IRQn ) & 0x1FUL ) ); + } + } /** - \brief Clear Pending Interrupt - \details Clears the pending bit of a device specific interrupt in the NVIC pending register. - \param [in] IRQn Device specific interrupt number. - \note IRQn must not be negative. + * \brief Clear Pending Interrupt + * \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + * \param [in] IRQn Device specific interrupt number. + * \note IRQn must not be negative. */ -__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - if ((int32_t)(IRQn) >= 0) - { - NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); - } -} + __STATIC_INLINE void __NVIC_ClearPendingIRQ( IRQn_Type IRQn ) + { + if( ( int32_t ) ( IRQn ) >= 0 ) + { + NVIC->ICPR[ ( ( ( uint32_t ) IRQn ) >> 5UL ) ] = ( uint32_t ) ( 1UL << ( ( ( uint32_t ) IRQn ) & 0x1FUL ) ); + } + } /** - \brief Get Active Interrupt - \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. - \param [in] IRQn Device specific interrupt number. - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - \note IRQn must not be negative. + * \brief Get Active Interrupt + * \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + * \param [in] IRQn Device specific interrupt number. + * \return 0 Interrupt status is not active. + * \return 1 Interrupt status is active. + * \note IRQn must not be negative. */ -__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) -{ - if ((int32_t)(IRQn) >= 0) - { - return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); - } - else - { - return(0U); - } -} + __STATIC_INLINE uint32_t __NVIC_GetActive( IRQn_Type IRQn ) + { + if( ( int32_t ) ( IRQn ) >= 0 ) + { + return( ( uint32_t ) ( ( ( NVIC->IABR[ ( ( ( uint32_t ) IRQn ) >> 5UL ) ] & ( 1UL << ( ( ( uint32_t ) IRQn ) & 0x1FUL ) ) ) != 0UL ) ? 1UL : 0UL ) ); + } + else + { + return( 0U ); + } + } /** - \brief Set Interrupt Priority - \details Sets the priority of a device specific interrupt or a processor exception. - The interrupt number can be positive to specify a device specific interrupt, - or negative to specify a processor exception. - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - \note The priority cannot be set for every processor exception. + * \brief Set Interrupt Priority + * \details Sets the priority of a device specific interrupt or a processor exception. + * The interrupt number can be positive to specify a device specific interrupt, + * or negative to specify a processor exception. + * \param [in] IRQn Interrupt number. + * \param [in] priority Priority to set. + * \note The priority cannot be set for every processor exception. */ -__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if ((int32_t)(IRQn) >= 0) - { - NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } - else - { - SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } -} + __STATIC_INLINE void __NVIC_SetPriority( IRQn_Type IRQn, + uint32_t priority ) + { + if( ( int32_t ) ( IRQn ) >= 0 ) + { + NVIC->IP[ ( ( uint32_t ) IRQn ) ] = ( uint8_t ) ( ( priority << ( 8U - __NVIC_PRIO_BITS ) ) & ( uint32_t ) 0xFFUL ); + } + else + { + SCB->SHP[ ( ( ( uint32_t ) IRQn ) & 0xFUL ) - 4UL ] = ( uint8_t ) ( ( priority << ( 8U - __NVIC_PRIO_BITS ) ) & ( uint32_t ) 0xFFUL ); + } + } /** - \brief Get Interrupt Priority - \details Reads the priority of a device specific interrupt or a processor exception. - The interrupt number can be positive to specify a device specific interrupt, - or negative to specify a processor exception. - \param [in] IRQn Interrupt number. - \return Interrupt Priority. - Value is aligned automatically to the implemented priority bits of the microcontroller. + * \brief Get Interrupt Priority + * \details Reads the priority of a device specific interrupt or a processor exception. + * The interrupt number can be positive to specify a device specific interrupt, + * or negative to specify a processor exception. + * \param [in] IRQn Interrupt number. + * \return Interrupt Priority. + * Value is aligned automatically to the implemented priority bits of the microcontroller. */ -__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) -{ - - if ((int32_t)(IRQn) >= 0) - { - return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); - } - else - { - return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); - } -} + __STATIC_INLINE uint32_t __NVIC_GetPriority( IRQn_Type IRQn ) + { + if( ( int32_t ) ( IRQn ) >= 0 ) + { + return( ( ( uint32_t ) NVIC->IP[ ( ( uint32_t ) IRQn ) ] >> ( 8U - __NVIC_PRIO_BITS ) ) ); + } + else + { + return( ( ( uint32_t ) SCB->SHP[ ( ( ( uint32_t ) IRQn ) & 0xFUL ) - 4UL ] >> ( 8U - __NVIC_PRIO_BITS ) ) ); + } + } /** - \brief Encode Priority - \details Encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + * \brief Encode Priority + * \details Encodes the priority for an interrupt with the given priority group, + * preemptive priority value, and subpriority value. + * In case of a conflict between priority grouping and available + * priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + * \param [in] PriorityGroup Used priority group. + * \param [in] PreemptPriority Preemptive priority value (starting from 0). + * \param [in] SubPriority Subpriority value (starting from 0). + * \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; + __STATIC_INLINE uint32_t NVIC_EncodePriority( uint32_t PriorityGroup, + uint32_t PreemptPriority, + uint32_t SubPriority ) + { + uint32_t PriorityGroupTmp = ( PriorityGroup & ( uint32_t ) 0x07UL ); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + PreemptPriorityBits = ( ( 7UL - PriorityGroupTmp ) > ( uint32_t ) ( __NVIC_PRIO_BITS ) ) ? ( uint32_t ) ( __NVIC_PRIO_BITS ) : ( uint32_t ) ( 7UL - PriorityGroupTmp ); + SubPriorityBits = ( ( PriorityGroupTmp + ( uint32_t ) ( __NVIC_PRIO_BITS ) ) < ( uint32_t ) 7UL ) ? ( uint32_t ) 0UL : ( uint32_t ) ( ( PriorityGroupTmp - 7UL ) + ( uint32_t ) ( __NVIC_PRIO_BITS ) ); - return ( - ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | - ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) - ); -} + return( + ( ( PreemptPriority & ( uint32_t ) ( ( 1UL << ( PreemptPriorityBits ) ) - 1UL ) ) << SubPriorityBits ) | + ( ( SubPriority & ( uint32_t ) ( ( 1UL << ( SubPriorityBits ) ) - 1UL ) ) ) + ); + } /** - \brief Decode Priority - \details Decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). + * \brief Decode Priority + * \details Decodes an interrupt priority value with a given priority group to + * preemptive priority value and subpriority value. + * In case of a conflict between priority grouping and available + * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + * \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + * \param [in] PriorityGroup Used priority group. + * \param [out] pPreemptPriority Preemptive priority value (starting from 0). + * \param [out] pSubPriority Subpriority value (starting from 0). */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; + __STATIC_INLINE void NVIC_DecodePriority( uint32_t Priority, + uint32_t PriorityGroup, + uint32_t * const pPreemptPriority, + uint32_t * const pSubPriority ) + { + uint32_t PriorityGroupTmp = ( PriorityGroup & ( uint32_t ) 0x07UL ); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + PreemptPriorityBits = ( ( 7UL - PriorityGroupTmp ) > ( uint32_t ) ( __NVIC_PRIO_BITS ) ) ? ( uint32_t ) ( __NVIC_PRIO_BITS ) : ( uint32_t ) ( 7UL - PriorityGroupTmp ); + SubPriorityBits = ( ( PriorityGroupTmp + ( uint32_t ) ( __NVIC_PRIO_BITS ) ) < ( uint32_t ) 7UL ) ? ( uint32_t ) 0UL : ( uint32_t ) ( ( PriorityGroupTmp - 7UL ) + ( uint32_t ) ( __NVIC_PRIO_BITS ) ); - *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); - *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); -} + *pPreemptPriority = ( Priority >> SubPriorityBits ) & ( uint32_t ) ( ( 1UL << ( PreemptPriorityBits ) ) - 1UL ); + *pSubPriority = ( Priority ) & ( uint32_t ) ( ( 1UL << ( SubPriorityBits ) ) - 1UL ); + } /** - \brief Set Interrupt Vector - \details Sets an interrupt vector in SRAM based interrupt vector table. - The interrupt number can be positive to specify a device specific interrupt, - or negative to specify a processor exception. - VTOR must been relocated to SRAM before. - \param [in] IRQn Interrupt number - \param [in] vector Address of interrupt handler function + * \brief Set Interrupt Vector + * \details Sets an interrupt vector in SRAM based interrupt vector table. + * The interrupt number can be positive to specify a device specific interrupt, + * or negative to specify a processor exception. + * VTOR must been relocated to SRAM before. + * \param [in] IRQn Interrupt number + * \param [in] vector Address of interrupt handler function */ -__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t *)SCB->VTOR; - vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; - /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ -} + __STATIC_INLINE void __NVIC_SetVector( IRQn_Type IRQn, + uint32_t vector ) + { + uint32_t * vectors = ( uint32_t * ) SCB->VTOR; + + vectors[ ( int32_t ) IRQn + NVIC_USER_IRQ_OFFSET ] = vector; + /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ + } /** - \brief Get Interrupt Vector - \details Reads an interrupt vector from interrupt vector table. - The interrupt number can be positive to specify a device specific interrupt, - or negative to specify a processor exception. - \param [in] IRQn Interrupt number. - \return Address of interrupt handler function + * \brief Get Interrupt Vector + * \details Reads an interrupt vector from interrupt vector table. + * The interrupt number can be positive to specify a device specific interrupt, + * or negative to specify a processor exception. + * \param [in] IRQn Interrupt number. + * \return Address of interrupt handler function */ -__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t *)SCB->VTOR; - return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; -} + __STATIC_INLINE uint32_t __NVIC_GetVector( IRQn_Type IRQn ) + { + uint32_t * vectors = ( uint32_t * ) SCB->VTOR; + + return vectors[ ( int32_t ) IRQn + NVIC_USER_IRQ_OFFSET ]; + } /** - \brief System Reset - \details Initiates a system reset request to reset the MCU. + * \brief System Reset + * \details Initiates a system reset request to reset the MCU. */ -__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ + __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset( void ) + { + __DSB(); /* Ensure all outstanding memory accesses included + * buffered write are completed before reset */ + SCB->AIRCR = ( uint32_t ) ( ( 0x5FAUL << SCB_AIRCR_VECTKEY_Pos ) | + ( SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk ) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ - for(;;) /* wait until reset */ - { - __NOP(); - } -} + for( ; ; ) /* wait until reset */ + { + __NOP(); + } + } /*@} end of CMSIS_Core_NVICFunctions */ /* ########################## MPU functions #################################### */ -#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #if defined( __MPU_PRESENT ) && ( __MPU_PRESENT == 1U ) -#include "mpu_armv7.h" + #include "mpu_armv7.h" -#endif + #endif /* ########################## FPU functions #################################### */ + /** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_FpuFunctions FPU Functions - \brief Function that provides FPU type. - @{ + * \ingroup CMSIS_Core_FunctionInterface + * \defgroup CMSIS_Core_FpuFunctions FPU Functions + * \brief Function that provides FPU type. + * @{ */ /** - \brief get FPU type - \details returns the FPU type - \returns - - \b 0: No FPU - - \b 1: Single precision FPU - - \b 2: Double + Single precision FPU + * \brief get FPU type + * \details returns the FPU type + * \returns + * - \b 0: No FPU + * - \b 1: Single precision FPU + * - \b 2: Double + Single precision FPU */ -__STATIC_INLINE uint32_t SCB_GetFPUType(void) -{ - return 0U; /* No FPU */ -} + __STATIC_INLINE uint32_t SCB_GetFPUType( void ) + { + return 0U; /* No FPU */ + } /*@} end of CMSIS_Core_FpuFunctions */ @@ -1813,131 +1830,133 @@ __STATIC_INLINE uint32_t SCB_GetFPUType(void) /* ################################## SysTick function ############################################ */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** - \brief System Tick Configuration - \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - \param [in] ticks Number of ticks between two interrupts. - \return 0 Function succeeded. - \return 1 Function failed. - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. + * \ingroup CMSIS_Core_FunctionInterface + * \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + * \brief Functions that configure the System. + * @{ */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) - { - return (1UL); /* Reload value impossible */ - } - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} + #if defined( __Vendor_SysTickConfig ) && ( __Vendor_SysTickConfig == 0U ) -#endif +/** + * \brief System Tick Configuration + * \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + * Counter is in free running mode to generate periodic interrupts. + * \param [in] ticks Number of ticks between two interrupts. + * \return 0 Function succeeded. + * \return 1 Function failed. + * \note When the variable __Vendor_SysTickConfig is set to 1, then the + * function SysTick_Config is not included. In this case, the file device.h + * must contain a vendor-specific implementation of this function. + */ + __STATIC_INLINE uint32_t SysTick_Config( uint32_t ticks ) + { + if( ( ticks - 1UL ) > SysTick_LOAD_RELOAD_Msk ) + { + return( 1UL ); /* Reload value impossible */ + } + + SysTick->LOAD = ( uint32_t ) ( ticks - 1UL ); /* set reload register */ + NVIC_SetPriority( SysTick_IRQn, ( 1UL << __NVIC_PRIO_BITS ) - 1UL ); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return( 0UL ); /* Function successful */ + } + + #endif /* if defined( __Vendor_SysTickConfig ) && ( __Vendor_SysTickConfig == 0U ) */ /*@} end of CMSIS_Core_SysTickFunctions */ /* ##################################### Debug In/Output function ########################################### */ + /** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ + * \ingroup CMSIS_Core_FunctionInterface + * \defgroup CMSIS_core_DebugFunctions ITM Functions + * \brief Functions that access the ITM debug interface. + * @{ */ -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ + #define ITM_RXBUFFER_EMPTY ( ( int32_t ) 0x5AA55AA5U ) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** - \brief ITM Send Character - \details Transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - \param [in] ch Character to transmit. - \returns Character to transmit. + * \brief ITM Send Character + * \details Transmits a character via the ITM channel 0, and + * \li Just returns when no debugger is connected that has booked the output. + * \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + * \param [in] ch Character to transmit. + * \returns Character to transmit. */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ - ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0U].u32 == 0UL) - { - __NOP(); - } - ITM->PORT[0U].u8 = (uint8_t)ch; - } - return (ch); -} + __STATIC_INLINE uint32_t ITM_SendChar( uint32_t ch ) + { + if( ( ( ITM->TCR & ITM_TCR_ITMENA_Msk ) != 0UL ) && /* ITM enabled */ + ( ( ITM->TER & 1UL ) != 0UL ) ) /* ITM Port #0 enabled */ + { + while( ITM->PORT[ 0U ].u32 == 0UL ) + { + __NOP(); + } + + ITM->PORT[ 0U ].u8 = ( uint8_t ) ch; + } + + return( ch ); + } /** - \brief ITM Receive Character - \details Inputs a character via the external variable \ref ITM_RxBuffer. - \return Received character. - \return -1 No character pending. + * \brief ITM Receive Character + * \details Inputs a character via the external variable \ref ITM_RxBuffer. + * \return Received character. + * \return -1 No character pending. */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) -{ - int32_t ch = -1; /* no character available */ + __STATIC_INLINE int32_t ITM_ReceiveChar( void ) + { + int32_t ch = -1; /* no character available */ - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) - { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } + if( ITM_RxBuffer != ITM_RXBUFFER_EMPTY ) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } - return (ch); -} + return( ch ); + } /** - \brief ITM Check Character - \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - \return 0 No character available. - \return 1 Character available. + * \brief ITM Check Character + * \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + * \return 0 No character available. + * \return 1 Character available. */ -__STATIC_INLINE int32_t ITM_CheckChar (void) -{ - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) - { - return (0); /* no character available */ - } - else - { - return (1); /* character available */ - } -} + __STATIC_INLINE int32_t ITM_CheckChar( void ) + { + if( ITM_RxBuffer == ITM_RXBUFFER_EMPTY ) + { + return( 0 ); /* no character available */ + } + else + { + return( 1 ); /* character available */ + } + } /*@} end of CMSIS_core_DebugFunctions */ - -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif /* __CORE_CM3_H_DEPENDANT */ + #endif /* __CORE_CM3_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/mpu_armv7.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/mpu_armv7.h index 1410aa5b3..9d2b52322 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/mpu_armv7.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/CMSIS/mpu_armv7.h @@ -1,9 +1,10 @@ /****************************************************************************** - * @file mpu_armv7.h - * @brief CMSIS MPU API for Armv7-M MPU - * @version V5.1.1 - * @date 10. February 2020 - ******************************************************************************/ +* @file mpu_armv7.h +* @brief CMSIS MPU API for Armv7-M MPU +* @version V5.1.1 +* @date 10. February 2020 +******************************************************************************/ + /* * Copyright (c) 2017-2020 Arm Limited. All rights reserved. * @@ -22,254 +23,265 @@ * limitations under the License. */ -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__clang__) - #pragma clang system_header /* treat file as system include file */ +#if defined( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined( __clang__ ) + #pragma clang system_header /* treat file as system include file */ #endif #ifndef ARM_MPU_ARMV7_H -#define ARM_MPU_ARMV7_H + #define ARM_MPU_ARMV7_H -#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes -#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes -#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes -#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes -#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes -#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte -#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes -#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes -#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes -#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes -#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes -#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes -#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes -#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes -#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes -#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte -#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes -#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes -#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes -#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes -#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes -#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes -#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes -#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes -#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes -#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte -#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes -#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + #define ARM_MPU_REGION_SIZE_32B ( ( uint8_t ) 0x04U ) /*/!< MPU Region Size 32 Bytes */ + #define ARM_MPU_REGION_SIZE_64B ( ( uint8_t ) 0x05U ) /*/!< MPU Region Size 64 Bytes */ + #define ARM_MPU_REGION_SIZE_128B ( ( uint8_t ) 0x06U ) /*/!< MPU Region Size 128 Bytes */ + #define ARM_MPU_REGION_SIZE_256B ( ( uint8_t ) 0x07U ) /*/!< MPU Region Size 256 Bytes */ + #define ARM_MPU_REGION_SIZE_512B ( ( uint8_t ) 0x08U ) /*/!< MPU Region Size 512 Bytes */ + #define ARM_MPU_REGION_SIZE_1KB ( ( uint8_t ) 0x09U ) /*/!< MPU Region Size 1 KByte */ + #define ARM_MPU_REGION_SIZE_2KB ( ( uint8_t ) 0x0AU ) /*/!< MPU Region Size 2 KBytes */ + #define ARM_MPU_REGION_SIZE_4KB ( ( uint8_t ) 0x0BU ) /*/!< MPU Region Size 4 KBytes */ + #define ARM_MPU_REGION_SIZE_8KB ( ( uint8_t ) 0x0CU ) /*/!< MPU Region Size 8 KBytes */ + #define ARM_MPU_REGION_SIZE_16KB ( ( uint8_t ) 0x0DU ) /*/!< MPU Region Size 16 KBytes */ + #define ARM_MPU_REGION_SIZE_32KB ( ( uint8_t ) 0x0EU ) /*/!< MPU Region Size 32 KBytes */ + #define ARM_MPU_REGION_SIZE_64KB ( ( uint8_t ) 0x0FU ) /*/!< MPU Region Size 64 KBytes */ + #define ARM_MPU_REGION_SIZE_128KB ( ( uint8_t ) 0x10U ) /*/!< MPU Region Size 128 KBytes */ + #define ARM_MPU_REGION_SIZE_256KB ( ( uint8_t ) 0x11U ) /*/!< MPU Region Size 256 KBytes */ + #define ARM_MPU_REGION_SIZE_512KB ( ( uint8_t ) 0x12U ) /*/!< MPU Region Size 512 KBytes */ + #define ARM_MPU_REGION_SIZE_1MB ( ( uint8_t ) 0x13U ) /*/!< MPU Region Size 1 MByte */ + #define ARM_MPU_REGION_SIZE_2MB ( ( uint8_t ) 0x14U ) /*/!< MPU Region Size 2 MBytes */ + #define ARM_MPU_REGION_SIZE_4MB ( ( uint8_t ) 0x15U ) /*/!< MPU Region Size 4 MBytes */ + #define ARM_MPU_REGION_SIZE_8MB ( ( uint8_t ) 0x16U ) /*/!< MPU Region Size 8 MBytes */ + #define ARM_MPU_REGION_SIZE_16MB ( ( uint8_t ) 0x17U ) /*/!< MPU Region Size 16 MBytes */ + #define ARM_MPU_REGION_SIZE_32MB ( ( uint8_t ) 0x18U ) /*/!< MPU Region Size 32 MBytes */ + #define ARM_MPU_REGION_SIZE_64MB ( ( uint8_t ) 0x19U ) /*/!< MPU Region Size 64 MBytes */ + #define ARM_MPU_REGION_SIZE_128MB ( ( uint8_t ) 0x1AU ) /*/!< MPU Region Size 128 MBytes */ + #define ARM_MPU_REGION_SIZE_256MB ( ( uint8_t ) 0x1BU ) /*/!< MPU Region Size 256 MBytes */ + #define ARM_MPU_REGION_SIZE_512MB ( ( uint8_t ) 0x1CU ) /*/!< MPU Region Size 512 MBytes */ + #define ARM_MPU_REGION_SIZE_1GB ( ( uint8_t ) 0x1DU ) /*/!< MPU Region Size 1 GByte */ + #define ARM_MPU_REGION_SIZE_2GB ( ( uint8_t ) 0x1EU ) /*/!< MPU Region Size 2 GBytes */ + #define ARM_MPU_REGION_SIZE_4GB ( ( uint8_t ) 0x1FU ) /*/!< MPU Region Size 4 GBytes */ -#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access -#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only -#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only -#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access -#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only -#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + #define ARM_MPU_AP_NONE 0U /*/!< MPU Access Permission no access */ + #define ARM_MPU_AP_PRIV 1U /*/!< MPU Access Permission privileged access only */ + #define ARM_MPU_AP_URO 2U /*/!< MPU Access Permission unprivileged access read-only */ + #define ARM_MPU_AP_FULL 3U /*/!< MPU Access Permission full access */ + #define ARM_MPU_AP_PRO 5U /*/!< MPU Access Permission privileged access read-only */ + #define ARM_MPU_AP_RO 6U /*/!< MPU Access Permission read-only access */ /** MPU Region Base Address Register Value -* -* \param Region The region to be configured, number 0 to 15. -* \param BaseAddress The base address for the region. -*/ -#define ARM_MPU_RBAR(Region, BaseAddress) \ - (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ - ((Region) & MPU_RBAR_REGION_Msk) | \ - (MPU_RBAR_VALID_Msk)) + * + * \param Region The region to be configured, number 0 to 15. + * \param BaseAddress The base address for the region. + */ + #define ARM_MPU_RBAR( Region, BaseAddress ) \ + ( ( ( BaseAddress ) & MPU_RBAR_ADDR_Msk ) | \ + ( ( Region ) & MPU_RBAR_REGION_Msk ) | \ + ( MPU_RBAR_VALID_Msk ) ) /** -* MPU Memory Access Attributes -* -* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. -* \param IsShareable Region is shareable between multiple bus masters. -* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. -* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. -*/ -#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ - ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ - (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ - (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ - (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + * MPU Memory Access Attributes + * + * \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. + * \param IsShareable Region is shareable between multiple bus masters. + * \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. + * \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. + */ + #define ARM_MPU_ACCESS_( TypeExtField, IsShareable, IsCacheable, IsBufferable ) \ + ( ( ( ( TypeExtField ) << MPU_RASR_TEX_Pos ) & MPU_RASR_TEX_Msk ) | \ + ( ( ( IsShareable ) << MPU_RASR_S_Pos ) & MPU_RASR_S_Msk ) | \ + ( ( ( IsCacheable ) << MPU_RASR_C_Pos ) & MPU_RASR_C_Msk ) | \ + ( ( ( IsBufferable ) << MPU_RASR_B_Pos ) & MPU_RASR_B_Msk ) ) /** -* MPU Region Attribute and Size Register Value -* -* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. -* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. -* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. -* \param SubRegionDisable Sub-region disable field. -* \param Size Region size of the region to be configured, for example 4K, 8K. -*/ -#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ - ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ - (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ - (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ - (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ - (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ - (((MPU_RASR_ENABLE_Msk)))) + * MPU Region Attribute and Size Register Value + * + * \param DisableExec Instruction access disable bit, 1= disable instruction fetches. + * \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. + * \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. + * \param SubRegionDisable Sub-region disable field. + * \param Size Region size of the region to be configured, for example 4K, 8K. + */ + #define ARM_MPU_RASR_EX( DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size ) \ + ( ( ( ( DisableExec ) << MPU_RASR_XN_Pos ) & MPU_RASR_XN_Msk ) | \ + ( ( ( AccessPermission ) << MPU_RASR_AP_Pos ) & MPU_RASR_AP_Msk ) | \ + ( ( ( AccessAttributes ) & ( MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk ) ) ) | \ + ( ( ( SubRegionDisable ) << MPU_RASR_SRD_Pos ) & MPU_RASR_SRD_Msk ) | \ + ( ( ( Size ) << MPU_RASR_SIZE_Pos ) & MPU_RASR_SIZE_Msk ) | \ + ( ( ( MPU_RASR_ENABLE_Msk ) ) ) ) /** -* MPU Region Attribute and Size Register Value -* -* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. -* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. -* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. -* \param IsShareable Region is shareable between multiple bus masters. -* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. -* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. -* \param SubRegionDisable Sub-region disable field. -* \param Size Region size of the region to be configured, for example 4K, 8K. -*/ -#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ - ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + * MPU Region Attribute and Size Register Value + * + * \param DisableExec Instruction access disable bit, 1= disable instruction fetches. + * \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. + * \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. + * \param IsShareable Region is shareable between multiple bus masters. + * \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. + * \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. + * \param SubRegionDisable Sub-region disable field. + * \param Size Region size of the region to be configured, for example 4K, 8K. + */ + #define ARM_MPU_RASR( DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size ) \ + ARM_MPU_RASR_EX( DisableExec, AccessPermission, ARM_MPU_ACCESS_( TypeExtField, IsShareable, IsCacheable, IsBufferable ), SubRegionDisable, Size ) /** -* MPU Memory Access Attribute for strongly ordered memory. -* - TEX: 000b -* - Shareable -* - Non-cacheable -* - Non-bufferable -*/ -#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + * MPU Memory Access Attribute for strongly ordered memory. + * - TEX: 000b + * - Shareable + * - Non-cacheable + * - Non-bufferable + */ + #define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_( 0U, 1U, 0U, 0U ) /** -* MPU Memory Access Attribute for device memory. -* - TEX: 000b (if shareable) or 010b (if non-shareable) -* - Shareable or non-shareable -* - Non-cacheable -* - Bufferable (if shareable) or non-bufferable (if non-shareable) -* -* \param IsShareable Configures the device memory as shareable or non-shareable. -*/ -#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + * MPU Memory Access Attribute for device memory. + * - TEX: 000b (if shareable) or 010b (if non-shareable) + * - Shareable or non-shareable + * - Non-cacheable + * - Bufferable (if shareable) or non-bufferable (if non-shareable) + * + * \param IsShareable Configures the device memory as shareable or non-shareable. + */ + #define ARM_MPU_ACCESS_DEVICE( IsShareable ) ( ( IsShareable ) ? ARM_MPU_ACCESS_( 0U, 1U, 0U, 1U ) : ARM_MPU_ACCESS_( 2U, 0U, 0U, 0U ) ) /** -* MPU Memory Access Attribute for normal memory. -* - TEX: 1BBb (reflecting outer cacheability rules) -* - Shareable or non-shareable -* - Cacheable or non-cacheable (reflecting inner cacheability rules) -* - Bufferable or non-bufferable (reflecting inner cacheability rules) -* -* \param OuterCp Configures the outer cache policy. -* \param InnerCp Configures the inner cache policy. -* \param IsShareable Configures the memory as shareable or non-shareable. -*/ -#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U)) + * MPU Memory Access Attribute for normal memory. + * - TEX: 1BBb (reflecting outer cacheability rules) + * - Shareable or non-shareable + * - Cacheable or non-cacheable (reflecting inner cacheability rules) + * - Bufferable or non-bufferable (reflecting inner cacheability rules) + * + * \param OuterCp Configures the outer cache policy. + * \param InnerCp Configures the inner cache policy. + * \param IsShareable Configures the memory as shareable or non-shareable. + */ + #define ARM_MPU_ACCESS_NORMAL( OuterCp, InnerCp, IsShareable ) ARM_MPU_ACCESS_( ( 4U | ( OuterCp ) ), IsShareable, ( ( InnerCp ) >> 1U ), ( ( InnerCp ) & 1U ) ) /** -* MPU Memory Access Attribute non-cacheable policy. -*/ -#define ARM_MPU_CACHEP_NOCACHE 0U + * MPU Memory Access Attribute non-cacheable policy. + */ + #define ARM_MPU_CACHEP_NOCACHE 0U /** -* MPU Memory Access Attribute write-back, write and read allocate policy. -*/ -#define ARM_MPU_CACHEP_WB_WRA 1U + * MPU Memory Access Attribute write-back, write and read allocate policy. + */ + #define ARM_MPU_CACHEP_WB_WRA 1U /** -* MPU Memory Access Attribute write-through, no write allocate policy. -*/ -#define ARM_MPU_CACHEP_WT_NWA 2U + * MPU Memory Access Attribute write-through, no write allocate policy. + */ + #define ARM_MPU_CACHEP_WT_NWA 2U /** -* MPU Memory Access Attribute write-back, no write allocate policy. -*/ -#define ARM_MPU_CACHEP_WB_NWA 3U + * MPU Memory Access Attribute write-back, no write allocate policy. + */ + #define ARM_MPU_CACHEP_WB_NWA 3U /** -* Struct for a single MPU Region -*/ -typedef struct { - uint32_t RBAR; //!< The region base address register value (RBAR) - uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR -} ARM_MPU_Region_t; - + * Struct for a single MPU Region + */ + typedef struct + { + uint32_t RBAR; /*!< The region base address register value (RBAR) */ + uint32_t RASR; /*!< The region attribute and size register value (RASR) \ref MPU_RASR */ + } ARM_MPU_Region_t; + /** Enable the MPU. -* \param MPU_Control Default access permissions for unconfigured regions. -*/ -__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) -{ - __DMB(); - MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; -#ifdef SCB_SHCSR_MEMFAULTENA_Msk - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; -#endif - __DSB(); - __ISB(); -} + * \param MPU_Control Default access permissions for unconfigured regions. + */ + __STATIC_INLINE void ARM_MPU_Enable( uint32_t MPU_Control ) + { + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; + #ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + #endif + __DSB(); + __ISB(); + } /** Disable the MPU. -*/ -__STATIC_INLINE void ARM_MPU_Disable(void) -{ - __DMB(); -#ifdef SCB_SHCSR_MEMFAULTENA_Msk - SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; -#endif - MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; - __DSB(); - __ISB(); -} + */ + __STATIC_INLINE void ARM_MPU_Disable( void ) + { + __DMB(); + #ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; + #endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); + } /** Clear and disable the given MPU region. -* \param rnr Region number to be cleared. -*/ -__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) -{ - MPU->RNR = rnr; - MPU->RASR = 0U; -} + * \param rnr Region number to be cleared. + */ + __STATIC_INLINE void ARM_MPU_ClrRegion( uint32_t rnr ) + { + MPU->RNR = rnr; + MPU->RASR = 0U; + } /** Configure an MPU region. -* \param rbar Value for RBAR register. -* \param rsar Value for RSAR register. -*/ -__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) -{ - MPU->RBAR = rbar; - MPU->RASR = rasr; -} + * \param rbar Value for RBAR register. + * \param rsar Value for RSAR register. + */ + __STATIC_INLINE void ARM_MPU_SetRegion( uint32_t rbar, + uint32_t rasr ) + { + MPU->RBAR = rbar; + MPU->RASR = rasr; + } /** Configure the given MPU region. -* \param rnr Region number to be configured. -* \param rbar Value for RBAR register. -* \param rsar Value for RSAR register. -*/ -__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) -{ - MPU->RNR = rnr; - MPU->RBAR = rbar; - MPU->RASR = rasr; -} + * \param rnr Region number to be configured. + * \param rbar Value for RBAR register. + * \param rsar Value for RSAR register. + */ + __STATIC_INLINE void ARM_MPU_SetRegionEx( uint32_t rnr, + uint32_t rbar, + uint32_t rasr ) + { + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; + } /** Memcopy with strictly ordered memory access, e.g. for register targets. -* \param dst Destination data is copied to. -* \param src Source data is copied from. -* \param len Amount of data words to be copied. -*/ -__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) -{ - uint32_t i; - for (i = 0U; i < len; ++i) - { - dst[i] = src[i]; - } -} + * \param dst Destination data is copied to. + * \param src Source data is copied from. + * \param len Amount of data words to be copied. + */ + __STATIC_INLINE void ARM_MPU_OrderedMemcpy( volatile uint32_t * dst, + const uint32_t * __RESTRICT src, + uint32_t len ) + { + uint32_t i; + + for( i = 0U; i < len; ++i ) + { + dst[ i ] = src[ i ]; + } + } /** Load the given number of MPU regions from a table. -* \param table Pointer to the MPU configuration table. -* \param cnt Amount of regions to be configured. -*/ -__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) -{ - const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; - while (cnt > MPU_TYPE_RALIASES) { - ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); - table += MPU_TYPE_RALIASES; - cnt -= MPU_TYPE_RALIASES; - } - ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); -} + * \param table Pointer to the MPU configuration table. + * \param cnt Amount of regions to be configured. + */ + __STATIC_INLINE void ARM_MPU_Load( ARM_MPU_Region_t const * table, + uint32_t cnt ) + { + const uint32_t rowWordSize = sizeof( ARM_MPU_Region_t ) / 4U; -#endif + while( cnt > MPU_TYPE_RALIASES ) + { + ARM_MPU_OrderedMemcpy( &( MPU->RBAR ), &( table->RBAR ), MPU_TYPE_RALIASES * rowWordSize ); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + + ARM_MPU_OrderedMemcpy( &( MPU->RBAR ), &( table->RBAR ), cnt * rowWordSize ); + } + +#endif /* ifndef ARM_MPU_ARMV7_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/FreeRTOSConfig.h old mode 100755 new mode 100644 index e889705d4..371b5f8dc --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/FreeRTOSConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -28,84 +28,85 @@ #define FREERTOS_CONFIG_H /*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See https://www.freertos.org/a00110.html - *----------------------------------------------------------*/ +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +* +* See https://www.freertos.org/a00110.html +*----------------------------------------------------------*/ -#define configASSERT_DEFINED 1 +#define configASSERT_DEFINED 1 extern void vAssertCalled( void ); -#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( ) +#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( ) -#define configUSE_PREEMPTION 1 -#define configUSE_TIME_SLICING 1 +#define configUSE_PREEMPTION 1 +#define configUSE_TIME_SLICING 1 -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 0 -#define configCPU_CLOCK_HZ ( ( unsigned long ) 20000000 ) -#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) -#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 2000 ) -#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 279000 ) ) -#define configMAX_TASK_NAME_LEN ( 10 ) -#define configUSE_TRACE_FACILITY 0 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 0 -#define configMAX_PRIORITIES ( 10 ) -#define configTIMER_QUEUE_LENGTH 20 -#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 3 ) -#define configUSE_COUNTING_SEMAPHORES 1 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 -#define configNUM_TX_DESCRIPTORS 15 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 20000000 ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 2000 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 279000 ) ) +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configMAX_PRIORITIES ( 10 ) +#define configTIMER_QUEUE_LENGTH 20 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 3 ) +#define configUSE_COUNTING_SEMAPHORES 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configNUM_TX_DESCRIPTORS 15 /* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ + * to exclude the API function. */ -#define configUSE_MALLOC_FAILED_HOOK 1 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define INCLUDE_vTaskPrioritySet 0 -#define INCLUDE_uxTaskPriorityGet 0 -#define INCLUDE_vTaskDelete 0 -#define INCLUDE_vTaskCleanUpResources 0 -#define INCLUDE_vTaskSuspend 0 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 #define configKERNEL_INTERRUPT_PRIORITY 255 + /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ + * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 #define configMAC_INTERRUPT_PRIORITY 5 /* networking definitions */ -#define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 2 ) -#define ipconfigUSE_NETWORK_EVENT_HOOK 1 -//#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME pdMS_TO_TICKS(5000) -#define configNETWORK_INTERFACE_TO_USE 1L +#define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 2 ) +#define ipconfigUSE_NETWORK_EVENT_HOOK 1 +/*#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME pdMS_TO_TICKS(5000) */ +#define configNETWORK_INTERFACE_TO_USE 1L /* The address of an echo server that will be used by the two demo echo client -tasks. -http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html -http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html */ + * tasks. + * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html + * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html */ -#define configECHO_SERVER_ADDR0 10 -#define configECHO_SERVER_ADDR1 136 -#define configECHO_SERVER_ADDR2 206 -#define configECHO_SERVER_ADDR3 133 +#define configECHO_SERVER_ADDR0 10 +#define configECHO_SERVER_ADDR1 136 +#define configECHO_SERVER_ADDR2 206 +#define configECHO_SERVER_ADDR3 133 /* Default MAC address configuration. The demo creates a virtual network -connection that uses this MAC address by accessing the raw Ethernet/WiFi data -to and from a real network connection on the host PC. See the -configNETWORK_INTERFACE_TO_USE definition above for information on how to -configure the real network connection to use. */ + * connection that uses this MAC address by accessing the raw Ethernet/WiFi data + * to and from a real network connection on the host PC. See the + * configNETWORK_INTERFACE_TO_USE definition above for information on how to + * configure the real network connection to use. */ #define configMAC_ADDR0 0x52 #define configMAC_ADDR1 0x54 @@ -115,37 +116,37 @@ configure the real network connection to use. */ #define configMAC_ADDR5 0xAD /* Default IP address configuration. Used in ipconfigUSE_DNS is set to 0, or -ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ + * ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ -#define configIP_ADDR0 10 -#define configIP_ADDR1 211 -#define configIP_ADDR2 55 -#define configIP_ADDR3 5 +#define configIP_ADDR0 10 +#define configIP_ADDR1 211 +#define configIP_ADDR2 55 +#define configIP_ADDR3 5 /* Default gateway IP address configuration. Used in ipconfigUSE_DNS is set to -0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ + * 0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ -#define configGATEWAY_ADDR0 10 -#define configGATEWAY_ADDR1 211 -#define configGATEWAY_ADDR2 55 -#define configGATEWAY_ADDR3 1 +#define configGATEWAY_ADDR0 10 +#define configGATEWAY_ADDR1 211 +#define configGATEWAY_ADDR2 55 +#define configGATEWAY_ADDR3 1 /* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and -208.67.220.220. Used in ipconfigUSE_DNS is set to 0, or ipconfigUSE_DNS is set -to 1 but a DNS server cannot be contacted.*/ + * 208.67.220.220. Used in ipconfigUSE_DNS is set to 0, or ipconfigUSE_DNS is set + * to 1 but a DNS server cannot be contacted.*/ -#define configDNS_SERVER_ADDR0 127 -#define configDNS_SERVER_ADDR1 0 -#define configDNS_SERVER_ADDR2 0 -#define configDNS_SERVER_ADDR3 53 +#define configDNS_SERVER_ADDR0 127 +#define configDNS_SERVER_ADDR1 0 +#define configDNS_SERVER_ADDR2 0 +#define configDNS_SERVER_ADDR3 53 /* Default netmask configuration. Used in ipconfigUSE_DNS is set to 0, or -ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ -#define configNET_MASK0 255 -#define configNET_MASK1 255 -#define configNET_MASK2 255 -#define configNET_MASK3 0 + * ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ +#define configNET_MASK0 255 +#define configNET_MASK1 255 +#define configNET_MASK2 255 +#define configNET_MASK3 0 /* The UDP port to which print messages are sent. */ -#define configPRINT_PORT ( 15000 ) +#define configPRINT_PORT ( 15000 ) #endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/FreeRTOSIPConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/FreeRTOSIPConfig.h index fc4797bc2..08550f8ec 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/FreeRTOSIPConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/FreeRTOSIPConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -26,293 +26,294 @@ /***************************************************************************** - * - * See the following URL for configuration information. - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html - * - *****************************************************************************/ +* +* See the following URL for configuration information. +* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html +* +*****************************************************************************/ #ifndef FREERTOS_IP_CONFIG_H #define FREERTOS_IP_CONFIG_H /* Prototype for the function used to print out. In this case it prints to the -console before the network is connected then a UDP port after the network has -connected. */ -extern void vLoggingPrintf( const char *pcFormatString, ... ); + * console before the network is connected then a UDP port after the network has + * connected. */ +extern void vLoggingPrintf( const char * pcFormatString, + ... ); /* Set to 1 to print out debug messages. If ipconfigHAS_DEBUG_PRINTF is set to -1 then FreeRTOS_debug_printf should be defined to the function used to print -out the debugging messages. */ -#define ipconfigHAS_DEBUG_PRINTF 1 + * 1 then FreeRTOS_debug_printf should be defined to the function used to print + * out the debugging messages. */ +#define ipconfigHAS_DEBUG_PRINTF 1 #ifdef HEAP3 - #define xPortGetMinimumEverFreeHeapSize(x) 0 - #define xPortGetFreeHeapSize() 0 + #define xPortGetMinimumEverFreeHeapSize( x ) 0 + #define xPortGetFreeHeapSize() 0 #endif -#if( ipconfigHAS_DEBUG_PRINTF == 1 ) -#include - #define FreeRTOS_debug_printf(X) \ - printf("%p->%s %d: ", \ - xTaskGetCurrentTaskHandle(), \ - __FUNCTION__, \ - __LINE__); \ - vLoggingPrintf X +#if ( ipconfigHAS_DEBUG_PRINTF == 1 ) + #include + #define FreeRTOS_debug_printf( X ) \ + printf( "%p->%s %d: ", \ + xTaskGetCurrentTaskHandle(), \ + __FUNCTION__, \ + __LINE__ ); \ + vLoggingPrintf X #endif /* Set to 1 to print out non debugging messages, for example the output of the -FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1 -then FreeRTOS_printf should be set to the function used to print out the -messages. */ -#define ipconfigHAS_PRINTF 1 -#if( ipconfigHAS_PRINTF == 1 ) -#include - #define FreeRTOS_printf(X) \ - printf("%p->%s %d: ", \ - xTaskGetCurrentTaskHandle(), \ - __FUNCTION__, \ - __LINE__); \ - vLoggingPrintf X + * FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1 + * then FreeRTOS_printf should be set to the function used to print out the + * messages. */ +#define ipconfigHAS_PRINTF 1 +#if ( ipconfigHAS_PRINTF == 1 ) + #include + #define FreeRTOS_printf( X ) \ + printf( "%p->%s %d: ", \ + xTaskGetCurrentTaskHandle(), \ + __FUNCTION__, \ + __LINE__ ); \ + vLoggingPrintf X #endif /* Define the byte order of the target MCU (the MCU FreeRTOS+TCP is executing -on). Valid options are pdFREERTOS_BIG_ENDIAN and pdFREERTOS_LITTLE_ENDIAN. */ -#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN + * on). Valid options are pdFREERTOS_BIG_ENDIAN and pdFREERTOS_LITTLE_ENDIAN. */ +#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN /* If the network card/driver includes checksum offloading (IP/TCP/UDP checksums) -then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software -stack repeating the checksum calculations. */ -#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1 + * then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software + * stack repeating the checksum calculations. */ +#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1 /* Several API's will block until the result is known, or the action has been -performed, for example FreeRTOS_send() and FreeRTOS_recv(). The timeouts can be -set per socket, using setsockopt(). If not set, the times below will be -used as defaults. */ -#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 5000 ) -#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 5000 ) + * performed, for example FreeRTOS_send() and FreeRTOS_recv(). The timeouts can be + * set per socket, using setsockopt(). If not set, the times below will be + * used as defaults. */ +#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 5000 ) +#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 5000 ) /* Include support for LLMNR: Link-local Multicast Name Resolution -(non-Microsoft) */ -#define ipconfigUSE_LLMNR ( 1 ) + * (non-Microsoft) */ +#define ipconfigUSE_LLMNR ( 1 ) /* Include support for NBNS: NetBIOS Name Service (Microsoft) */ -#define ipconfigUSE_NBNS ( 1 ) +#define ipconfigUSE_NBNS ( 1 ) /* Include support for DNS caching. For TCP, having a small DNS cache is very -useful. When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low -and also DNS may use small timeouts. If a DNS reply comes in after the DNS -socket has been destroyed, the result will be stored into the cache. The next -call to FreeRTOS_gethostbyname() will return immediately, without even creating -a socket. */ -#define ipconfigUSE_DNS_CACHE ( 1 ) -#define ipconfigDNS_CACHE_NAME_LENGTH ( 16 ) -#define ipconfigDNS_CACHE_ENTRIES ( 4 ) -#define ipconfigDNS_REQUEST_ATTEMPTS ( 2 ) + * useful. When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low + * and also DNS may use small timeouts. If a DNS reply comes in after the DNS + * socket has been destroyed, the result will be stored into the cache. The next + * call to FreeRTOS_gethostbyname() will return immediately, without even creating + * a socket. */ +#define ipconfigUSE_DNS_CACHE ( 1 ) +#define ipconfigDNS_CACHE_NAME_LENGTH ( 16 ) +#define ipconfigDNS_CACHE_ENTRIES ( 4 ) +#define ipconfigDNS_REQUEST_ATTEMPTS ( 2 ) /* The IP stack executes it its own task (although any application task can make -use of its services through the published sockets API). ipconfigUDP_TASK_PRIORITY -sets the priority of the task that executes the IP stack. The priority is a -standard FreeRTOS task priority so can take any value from 0 (the lowest -priority) to (configMAX_PRIORITIES - 1) (the highest priority). -configMAX_PRIORITIES is a standard FreeRTOS configuration parameter defined in -FreeRTOSConfig.h, not FreeRTOSIPConfig.h. Consideration needs to be given as to -the priority assigned to the task executing the IP stack relative to the -priority assigned to tasks that use the IP stack. */ -#define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) + * use of its services through the published sockets API). ipconfigUDP_TASK_PRIORITY + * sets the priority of the task that executes the IP stack. The priority is a + * standard FreeRTOS task priority so can take any value from 0 (the lowest + * priority) to (configMAX_PRIORITIES - 1) (the highest priority). + * configMAX_PRIORITIES is a standard FreeRTOS configuration parameter defined in + * FreeRTOSConfig.h, not FreeRTOSIPConfig.h. Consideration needs to be given as to + * the priority assigned to the task executing the IP stack relative to the + * priority assigned to tasks that use the IP stack. */ +#define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) /* The size, in words (not bytes), of the stack allocated to the FreeRTOS+TCP -task. This setting is less important when the FreeRTOS Win32 simulator is used -as the Win32 simulator only stores a fixed amount of information on the task -stack. FreeRTOS includes optional stack overflow detection, see: -http://www.freertos.org/Stacks-and-stack-overflow-checking.html */ -#define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 ) + * task. This setting is less important when the FreeRTOS Win32 simulator is used + * as the Win32 simulator only stores a fixed amount of information on the task + * stack. FreeRTOS includes optional stack overflow detection, see: + * http://www.freertos.org/Stacks-and-stack-overflow-checking.html */ +#define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 ) /* ipconfigRAND32() is called by the IP stack to generate random numbers for -things such as a DHCP transaction number or initial sequence number. Random -number generation is performed via this macro to allow applications to use their -own random number generation method. For example, it might be possible to -generate a random number by sampling noise on an analogue input. */ + * things such as a DHCP transaction number or initial sequence number. Random + * number generation is performed via this macro to allow applications to use their + * own random number generation method. For example, it might be possible to + * generate a random number by sampling noise on an analogue input. */ extern UBaseType_t uxRand(); #define ipconfigRAND32() uxRand() /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the -network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK -is not set to 1 then the network event hook will never be called. See -http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml -*/ -#define ipconfigUSE_NETWORK_EVENT_HOOK 1 + * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK + * is not set to 1 then the network event hook will never be called. See + * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml + */ +#define ipconfigUSE_NETWORK_EVENT_HOOK 1 /* Sockets have a send block time attribute. If FreeRTOS_sendto() is called but -a network buffer cannot be obtained then the calling task is held in the Blocked -state (so other tasks can continue to executed) until either a network buffer -becomes available or the send block time expires. If the send block time expires -then the send operation is aborted. The maximum allowable send block time is -capped to the value set by ipconfigMAX_SEND_BLOCK_TIME_TICKS. Capping the -maximum allowable send block time prevents prevents a deadlock occurring when -all the network buffers are in use and the tasks that process (and subsequently -free) the network buffers are themselves blocked waiting for a network buffer. -ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in -milliseconds can be converted to a time in ticks by dividing the time in -milliseconds by portTICK_PERIOD_MS. */ -#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000U / portTICK_PERIOD_MS ) + * a network buffer cannot be obtained then the calling task is held in the Blocked + * state (so other tasks can continue to executed) until either a network buffer + * becomes available or the send block time expires. If the send block time expires + * then the send operation is aborted. The maximum allowable send block time is + * capped to the value set by ipconfigMAX_SEND_BLOCK_TIME_TICKS. Capping the + * maximum allowable send block time prevents prevents a deadlock occurring when + * all the network buffers are in use and the tasks that process (and subsequently + * free) the network buffers are themselves blocked waiting for a network buffer. + * ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in + * milliseconds can be converted to a time in ticks by dividing the time in + * milliseconds by portTICK_PERIOD_MS. */ +#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000U / portTICK_PERIOD_MS ) /* If ipconfigUSE_DHCP is 1 then FreeRTOS+TCP will attempt to retrieve an IP -address, netmask, DNS server address and gateway address from a DHCP server. If -ipconfigUSE_DHCP is 0 then FreeRTOS+TCP will use a static IP address. The -stack will revert to using the static IP address even when ipconfigUSE_DHCP is -set to 1 if a valid configuration cannot be obtained from a DHCP server for any -reason. The static configuration used is that passed into the stack by the -FreeRTOS_IPInit() function call. */ -#define ipconfigUSE_DHCP 0 + * address, netmask, DNS server address and gateway address from a DHCP server. If + * ipconfigUSE_DHCP is 0 then FreeRTOS+TCP will use a static IP address. The + * stack will revert to using the static IP address even when ipconfigUSE_DHCP is + * set to 1 if a valid configuration cannot be obtained from a DHCP server for any + * reason. The static configuration used is that passed into the stack by the + * FreeRTOS_IPInit() function call. */ +#define ipconfigUSE_DHCP 0 /* When ipconfigUSE_DHCP is set to 1, DHCP requests will be sent out at -increasing time intervals until either a reply is received from a DHCP server -and accepted, or the interval between transmissions reaches -ipconfigMAXIMUM_DISCOVER_TX_PERIOD. The IP stack will revert to using the -static IP address passed as a parameter to FreeRTOS_IPInit() if the -re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without -a DHCP reply being received. */ -#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( 120000U / portTICK_PERIOD_MS ) + * increasing time intervals until either a reply is received from a DHCP server + * and accepted, or the interval between transmissions reaches + * ipconfigMAXIMUM_DISCOVER_TX_PERIOD. The IP stack will revert to using the + * static IP address passed as a parameter to FreeRTOS_IPInit() if the + * re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without + * a DHCP reply being received. */ +#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( 120000U / portTICK_PERIOD_MS ) /* The ARP cache is a table that maps IP addresses to MAC addresses. The IP -stack can only send a UDP message to a remove IP address if it knowns the MAC -address associated with the IP address, or the MAC address of the router used to -contact the remote IP address. When a UDP message is received from a remote IP -address the MAC address and IP address are added to the ARP cache. When a UDP -message is sent to a remote IP address that does not already appear in the ARP -cache then the UDP message is replaced by a ARP message that solicits the -required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum -number of entries that can exist in the ARP table at any one time. */ -#define ipconfigARP_CACHE_ENTRIES 6 + * stack can only send a UDP message to a remove IP address if it knowns the MAC + * address associated with the IP address, or the MAC address of the router used to + * contact the remote IP address. When a UDP message is received from a remote IP + * address the MAC address and IP address are added to the ARP cache. When a UDP + * message is sent to a remote IP address that does not already appear in the ARP + * cache then the UDP message is replaced by a ARP message that solicits the + * required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum + * number of entries that can exist in the ARP table at any one time. */ +#define ipconfigARP_CACHE_ENTRIES 6 /* ARP requests that do not result in an ARP response will be re-transmitted a -maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is -aborted. */ -#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 ) + * maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is + * aborted. */ +#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 ) /* ipconfigMAX_ARP_AGE defines the maximum time between an entry in the ARP -table being created or refreshed and the entry being removed because it is stale. -New ARP requests are sent for ARP cache entries that are nearing their maximum -age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is -equal to 1500 seconds (or 25 minutes). */ -#define ipconfigMAX_ARP_AGE 150 + * table being created or refreshed and the entry being removed because it is stale. + * New ARP requests are sent for ARP cache entries that are nearing their maximum + * age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is + * equal to 1500 seconds (or 25 minutes). */ +#define ipconfigMAX_ARP_AGE 150 /* Implementing FreeRTOS_inet_addr() necessitates the use of string handling -routines, which are relatively large. To save code space the full -FreeRTOS_inet_addr() implementation is made optional, and a smaller and faster -alternative called FreeRTOS_inet_addr_quick() is provided. FreeRTOS_inet_addr() -takes an IP in decimal dot format (for example, "192.168.0.1") as its parameter. -FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets -(for example, 192, 168, 0, 1) as its parameters. If -ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and -FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is -not set to 1 then only FreeRTOS_indet_addr_quick() is available. */ -#define ipconfigINCLUDE_FULL_INET_ADDR 1 + * routines, which are relatively large. To save code space the full + * FreeRTOS_inet_addr() implementation is made optional, and a smaller and faster + * alternative called FreeRTOS_inet_addr_quick() is provided. FreeRTOS_inet_addr() + * takes an IP in decimal dot format (for example, "192.168.0.1") as its parameter. + * FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets + * (for example, 192, 168, 0, 1) as its parameters. If + * ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and + * FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is + * not set to 1 then only FreeRTOS_indet_addr_quick() is available. */ +#define ipconfigINCLUDE_FULL_INET_ADDR 1 /* ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS defines the total number of network buffer that -are available to the IP stack. The total number of network buffers is limited -to ensure the total amount of RAM that can be consumed by the IP stack is capped -to a pre-determinable value. */ -#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60 + * are available to the IP stack. The total number of network buffers is limited + * to ensure the total amount of RAM that can be consumed by the IP stack is capped + * to a pre-determinable value. */ +#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60 /* A FreeRTOS queue is used to send events from application tasks to the IP -stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can -be queued for processing at any one time. The event queue must be a minimum of -5 greater than the total number of network buffers. */ -#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) + * stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can + * be queued for processing at any one time. The event queue must be a minimum of + * 5 greater than the total number of network buffers. */ +#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) /* The address of a socket is the combination of its IP address and its port -number. FreeRTOS_bind() is used to manually allocate a port number to a socket -(to 'bind' the socket to a port), but manual binding is not normally necessary -for client sockets (those sockets that initiate outgoing connections rather than -wait for incoming connections on a known port number). If -ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 then calling -FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP -stack automatically binding the socket to a port number from the range -socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If -ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto() -on a socket that has not yet been bound will result in the send operation being -aborted. */ -#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 + * number. FreeRTOS_bind() is used to manually allocate a port number to a socket + * (to 'bind' the socket to a port), but manual binding is not normally necessary + * for client sockets (those sockets that initiate outgoing connections rather than + * wait for incoming connections on a known port number). If + * ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 then calling + * FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP + * stack automatically binding the socket to a port number from the range + * socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If + * ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto() + * on a socket that has not yet been bound will result in the send operation being + * aborted. */ +#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 /* Defines the Time To Live (TTL) values used in outgoing UDP packets. */ -#define ipconfigUDP_TIME_TO_LIVE 128 -#define ipconfigTCP_TIME_TO_LIVE 128 /* also defined in FreeRTOSIPConfigDefaults.h */ +#define ipconfigUDP_TIME_TO_LIVE 128 +#define ipconfigTCP_TIME_TO_LIVE 128 /* also defined in FreeRTOSIPConfigDefaults.h */ /* USE_TCP: Use TCP and all its features */ -#define ipconfigUSE_TCP ( 1 ) +#define ipconfigUSE_TCP ( 1 ) /* USE_WIN: Let TCP use windowing mechanism. */ -#define ipconfigUSE_TCP_WIN ( 1 ) +#define ipconfigUSE_TCP_WIN ( 1 ) /* The MTU is the maximum number of bytes the payload of a network frame can -contain. For normal Ethernet V2 frames the maximum MTU is 1500. Setting a -lower value can save RAM, depending on the buffer management scheme used. If -ipconfigCAN_FRAGMENT_OUTGOING_PACKETS is 1 then (ipconfigNETWORK_MTU - 28) must -be divisible by 8. */ -#define ipconfigNETWORK_MTU 1200U + * contain. For normal Ethernet V2 frames the maximum MTU is 1500. Setting a + * lower value can save RAM, depending on the buffer management scheme used. If + * ipconfigCAN_FRAGMENT_OUTGOING_PACKETS is 1 then (ipconfigNETWORK_MTU - 28) must + * be divisible by 8. */ +#define ipconfigNETWORK_MTU 1200U /* Set ipconfigUSE_DNS to 1 to include a basic DNS client/resolver. DNS is used -through the FreeRTOS_gethostbyname() API function. */ -#define ipconfigUSE_DNS 1 + * through the FreeRTOS_gethostbyname() API function. */ +#define ipconfigUSE_DNS 1 /* If ipconfigREPLY_TO_INCOMING_PINGS is set to 1 then the IP stack will -generate replies to incoming ICMP echo (ping) requests. */ -#define ipconfigREPLY_TO_INCOMING_PINGS 1 + * generate replies to incoming ICMP echo (ping) requests. */ +#define ipconfigREPLY_TO_INCOMING_PINGS 1 /* If ipconfigSUPPORT_OUTGOING_PINGS is set to 1 then the -FreeRTOS_SendPingRequest() API function is available. */ -#define ipconfigSUPPORT_OUTGOING_PINGS 0 + * FreeRTOS_SendPingRequest() API function is available. */ +#define ipconfigSUPPORT_OUTGOING_PINGS 0 /* If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select() -(and associated) API function is available. */ -#define ipconfigSUPPORT_SELECT_FUNCTION 1 + * (and associated) API function is available. */ +#define ipconfigSUPPORT_SELECT_FUNCTION 1 /* If ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is set to 1 then Ethernet frames -that are not in Ethernet II format will be dropped. This option is included for -potential future IP stack developments. */ -#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1 + * that are not in Ethernet II format will be dropped. This option is included for + * potential future IP stack developments. */ +#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1 /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 then it is the -responsibility of the Ethernet interface to filter out packets that are of no -interest. If the Ethernet interface does not implement this functionality, then -set ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES to 0 to have the IP stack -perform the filtering instead (it is much less efficient for the stack to do it -because the packet will already have been passed into the stack). If the -Ethernet driver does all the necessary filtering in hardware then software -filtering can be removed by using a value other than 1 or 0. */ -#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 + * responsibility of the Ethernet interface to filter out packets that are of no + * interest. If the Ethernet interface does not implement this functionality, then + * set ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES to 0 to have the IP stack + * perform the filtering instead (it is much less efficient for the stack to do it + * because the packet will already have been passed into the stack). If the + * Ethernet driver does all the necessary filtering in hardware then software + * filtering can be removed by using a value other than 1 or 0. */ +#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 /* The Linux simulator cannot really simulate MAC interrupts, and needs to -block occasionally to allow other tasks to run. */ -#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS ) + * block occasionally to allow other tasks to run. */ +#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS ) /* Advanced only: in order to access 32-bit fields in the IP packets with -32-bit memory instructions, all packets will be stored 32-bit-aligned, plus 16-bits. -This has to do with the contents of the IP-packets: all 32-bit fields are -32-bit-aligned, plus 16-bit(!) */ -#define ipconfigPACKET_FILLER_SIZE 2U + * 32-bit memory instructions, all packets will be stored 32-bit-aligned, plus 16-bits. + * This has to do with the contents of the IP-packets: all 32-bit fields are + * 32-bit-aligned, plus 16-bit(!) */ +#define ipconfigPACKET_FILLER_SIZE 2U /* Define the size of the pool of TCP window descriptors. On the average, each -TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6 -outstanding packets (for Rx and Tx). When using up to 10 TP sockets -simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */ -#define ipconfigTCP_WIN_SEG_COUNT 240 + * TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6 + * outstanding packets (for Rx and Tx). When using up to 10 TP sockets + * simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */ +#define ipconfigTCP_WIN_SEG_COUNT 240 /* Each TCP socket has a circular buffers for Rx and Tx, which have a fixed -maximum size. Define the size of Rx buffer for TCP sockets. */ -#define ipconfigTCP_RX_BUFFER_LENGTH ( 10000 ) + * maximum size. Define the size of Rx buffer for TCP sockets. */ +#define ipconfigTCP_RX_BUFFER_LENGTH ( 10000 ) /* Define the size of Tx buffer for TCP sockets. */ -#define ipconfigTCP_TX_BUFFER_LENGTH ( 10000 ) +#define ipconfigTCP_TX_BUFFER_LENGTH ( 10000 ) /* When using call-back handlers, the driver may check if the handler points to -real program memory (RAM or flash) or just has a random non-zero value. */ -#define ipconfigIS_VALID_PROG_ADDRESS(x) ( (x) != NULL ) + * real program memory (RAM or flash) or just has a random non-zero value. */ +#define ipconfigIS_VALID_PROG_ADDRESS( x ) ( ( x ) != NULL ) /* Include support for TCP hang protection. All sockets in a connecting or -disconnecting stage will timeout after a period of non-activity. */ + * disconnecting stage will timeout after a period of non-activity. */ #define ipconfigTCP_HANG_PROTECTION ( 1 ) #define ipconfigTCP_HANG_PROTECTION_TIME ( 30 ) @@ -320,6 +321,6 @@ disconnecting stage will timeout after a period of non-activity. */ #define ipconfigTCP_KEEP_ALIVE ( 1 ) #define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20 ) /* in seconds */ -#define portINLINE __inline +#define portINLINE __inline #endif /* FREERTOS_IP_CONFIG_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/TCPEchoClient_SingleTasks.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/TCPEchoClient_SingleTasks.c old mode 100755 new mode 100644 index bf59f0622..b80d3de09 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/TCPEchoClient_SingleTasks.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/TCPEchoClient_SingleTasks.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -111,7 +111,7 @@ BaseType_t x; /* Set Ethernet interrupt priority to configMAC_INTERRUPT_PRIORITY. */ - NVIC_SetPriority( ETHERNET_IRQn , configMAC_INTERRUPT_PRIORITY ); + NVIC_SetPriority( ETHERNET_IRQn, configMAC_INTERRUPT_PRIORITY ); /* Create the echo client tasks. */ for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) @@ -163,9 +163,9 @@ #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) { xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); } #else { diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/TCPEchoClient_SingleTasks.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/TCPEchoClient_SingleTasks.h index 8764062fe..063821d67 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/TCPEchoClient_SingleTasks.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/TCPEchoClient_SingleTasks.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -31,9 +31,8 @@ * Create the TCP echo client tasks. This is the version where an echo request * is made from the same task that listens for the echo reply. */ -void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority ); +void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ); BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ); #endif /* SINGLE_TASK_TCP_ECHO_CLIENTS_H */ - - diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/main.c index cefec4dcb..cb17a6bf4 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -27,21 +27,22 @@ #include #include -#include +#include #include #include #include -void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); +void vApplicationStackOverflowHook( TaskHandle_t pxTask, + char * pcTaskName ); void vApplicationMallocFailedHook( void ); void main_tcp_echo_client_tasks( void ); void vApplicationIdleHook( void ); void vApplicationTickHook( void ); -extern void initialise_monitor_handles(void); +extern void initialise_monitor_handles( void ); -int main () +int main() { main_tcp_echo_client_tasks(); return 0; @@ -52,39 +53,46 @@ int main () void vApplicationMallocFailedHook( void ) { /* Called if a call to pvPortMalloc() fails because there is insufficient - free memory available in the FreeRTOS heap. pvPortMalloc() is called - internally by FreeRTOS API functions that create tasks, queues, software - timers, and semaphores. The size of the FreeRTOS heap is set by the - configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ + * free memory available in the FreeRTOS heap. pvPortMalloc() is called + * internally by FreeRTOS API functions that create tasks, queues, software + * timers, and semaphores. The size of the FreeRTOS heap is set by the + * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ taskDISABLE_INTERRUPTS(); - for( ;; ){}; + + for( ; ; ) + { + } } /*-----------------------------------------------------------*/ -void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) +void vApplicationStackOverflowHook( TaskHandle_t pxTask, + char * pcTaskName ) { ( void ) pcTaskName; ( void ) pxTask; /* Run time stack overflow checking is performed if - configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook - function is called if a stack overflow is detected. */ + * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook + * function is called if a stack overflow is detected. */ taskDISABLE_INTERRUPTS(); - for( ;; ){}; + + for( ; ; ) + { + } } /*-----------------------------------------------------------*/ void vApplicationIdleHook( void ) { -volatile size_t xFreeHeapSpace; + volatile size_t xFreeHeapSpace; /* This is just a trivial example of an idle hook. It is called on each - cycle of the idle task. It must *NOT* attempt to block. In this case the - idle task just queries the amount of FreeRTOS heap that remains. See the - memory management section on the https://www.FreeRTOS.org web site for memory - management options. If there is a lot of heap memory free then the - configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up - RAM. */ + * cycle of the idle task. It must *NOT* attempt to block. In this case the + * idle task just queries the amount of FreeRTOS heap that remains. See the + * memory management section on the https://www.FreeRTOS.org web site for memory + * management options. If there is a lot of heap memory free then the + * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up + * RAM. */ } /*-----------------------------------------------------------*/ @@ -96,10 +104,11 @@ void vApplicationTickHook( void ) void vAssertCalled( void ) { volatile unsigned long looping = 0; + taskENTER_CRITICAL(); { /* Use the debugger to set ul to a non-zero value in order to step out - of this function to determine why it was called. */ + * of this function to determine why it was called. */ while( looping == 0LU ) { portNOP(); @@ -108,11 +117,12 @@ void vAssertCalled( void ) taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ -void vLoggingPrintf( const char *pcFormat, ... ) +void vLoggingPrintf( const char * pcFormat, + ... ) { - va_list arg; + va_list arg; - va_start( arg, pcFormat ); - vprintf( pcFormat, arg ); - va_end( arg ); + va_start( arg, pcFormat ); + vprintf( pcFormat, arg ); + va_end( arg ); } diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/main_networking.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/main_networking.c index 22f7b6042..293632539 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/main_networking.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/main_networking.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -46,12 +46,12 @@ #include "TCPEchoClient_SingleTasks.h" /* Echo client task parameters */ -#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the linux port. */ -#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the linux port. */ +#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) /* Define a name that will be used for LLMNR and NBNS searches. */ -#define mainHOST_NAME "RTOSDemo" -#define mainDEVICE_NICK_NAME "qemu_demo" +#define mainHOST_NAME "RTOSDemo" +#define mainDEVICE_NICK_NAME "qemu_demo" /* Set the following constants to 1 or 0 to define which tasks to include and * exclude: @@ -64,7 +64,7 @@ * FreeRTOSConfig.h. * */ -#define mainCREATE_TCP_ECHO_TASKS_SINGLE 1 +#define mainCREATE_TCP_ECHO_TASKS_SINGLE 1 /*-----------------------------------------------------------*/ @@ -126,12 +126,12 @@ static UBaseType_t ulNextRand; #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - /* In case multiple interfaces are used, define them statically. */ +/* In case multiple interfaces are used, define them statically. */ - /* There is only 1 physical interface. */ +/* There is only 1 physical interface. */ static NetworkInterface_t xInterfaces[ 1 ]; - /* It will have several end-points. */ +/* It will have several end-points. */ static NetworkEndPoint_t xEndPoints[ 4 ]; #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ @@ -162,26 +162,26 @@ void main_tcp_echo_client_tasks( void ) /* Initialise the network interface.*/ FreeRTOS_debug_printf( ( "FreeRTOS_IPInit\r\n" ) ); -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - /* Initialise the interface descriptor for WinPCap. */ - pxMPS2_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + /* Initialise the interface descriptor for WinPCap. */ + pxMPS2_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); - /* === End-point 0 === */ - FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + /* === End-point 0 === */ + FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); #if ( ipconfigUSE_DHCP != 0 ) - { - /* End-point 0 wants to use DHCPv4. */ - xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; - } - #endif /* ( ipconfigUSE_DHCP != 0 ) */ + { + /* End-point 0 wants to use DHCPv4. */ + xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; + } + #endif /* ( ipconfigUSE_DHCP != 0 ) */ - memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof( ucMACAddress ) ); + memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof( ucMACAddress ) ); - FreeRTOS_IPInit_Multi(); -#else - /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ - FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + FreeRTOS_IPInit_Multi(); + #else /* if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ + FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ /* Start the RTOS scheduler. */ @@ -208,7 +208,7 @@ BaseType_t xTasksAlreadyCreated = pdFALSE; * events are only received if implemented in the MAC driver. */ #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, - struct xNetworkEndPoint * pxEndPoint ) + struct xNetworkEndPoint * pxEndPoint ) #else void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ @@ -323,7 +323,7 @@ static void prvMiscInitialisation( void ) #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, - const char * pcName ) + const char * pcName ) #else BaseType_t xApplicationDNSQueryHook( const char * pcName ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/mps2_m3.ld b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/mps2_m3.ld index ffa96b435..13b1a3d79 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/mps2_m3.ld +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/mps2_m3.ld @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -135,7 +135,7 @@ SECTIONS __StackTop = ORIGIN(RAM) + LENGTH(RAM); __StackLimit = __StackTop - _Min_Stack_Size; PROVIDE(__stack = __StackTop); - + /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= _heap_top, "region RAM overflowed with stack") } diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/startup.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/startup.c index 4632669b2..3dcec37f4 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/startup.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/startup.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -69,7 +69,7 @@ void Reset_Handler( void ) void prvGetRegistersFromStack( uint32_t * pulFaultStackAddress ) { -/* These are volatile to try and prevent the compiler/linker optimising them +/* These are volatile to try and prevent the compiler/linker optimizing them * away as the variables never actually get used. If the debugger won't show the * values of the variables, make them global my moving their declaration outside * of this function. */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/syscalls.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/syscalls.c index 3a092a88c..bfa97f3b8 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/syscalls.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Qemu_mps2/syscalls.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -29,7 +29,8 @@ extern "C" { #include -typedef struct UART_t { +typedef struct UART_t +{ volatile uint32_t DATA; volatile uint32_t STATE; volatile uint32_t CTRL; @@ -37,19 +38,19 @@ typedef struct UART_t { volatile uint32_t BAUDDIV; } UART_t; -#define UART0_ADDR ((UART_t *)(0x40004000)) -#define UART_DR(baseaddr) (*(unsigned int *)(baseaddr)) +#define UART0_ADDR ( ( UART_t * ) ( 0x40004000 ) ) +#define UART_DR( baseaddr ) ( *( unsigned int * ) ( baseaddr ) ) -#define UART_STATE_TXFULL (1 << 0) -#define UART_CTRL_TX_EN (1 << 0) -#define UART_CTRL_RX_EN (1 << 1) +#define UART_STATE_TXFULL ( 1 << 0 ) +#define UART_CTRL_TX_EN ( 1 << 0 ) +#define UART_CTRL_RX_EN ( 1 << 1 ) extern unsigned long _heap_bottom; extern unsigned long _heap_top; extern unsigned long g_ulBase; -static void *heap_end = 0; +static void * heap_end = 0; /** * @brief initializes the UART emulated hardware @@ -65,7 +66,7 @@ void uart_init() * @todo implement if necessary * */ -int _fstat(int file) +int _fstat( int file ) { return 0; } @@ -75,9 +76,11 @@ int _fstat(int file) * @todo implement if necessary * */ -int _read(int file, char *buf, int len) +int _read( int file, + char * buf, + int len ) { - return -1; + return -1; } /** @@ -88,13 +91,17 @@ int _read(int file, char *buf, int len) * @param [in] len length of the buffer * @returns the number of bytes written */ -int _write(int file, char *buf, int len) +int _write( int file, + char * buf, + int len ) { int todo; - for (todo = 0; todo < len; todo++){ - UART_DR(UART0_ADDR) = *buf++; + for( todo = 0; todo < len; todo++ ) + { + UART_DR( UART0_ADDR ) = *buf++; } + return len; } @@ -104,20 +111,20 @@ int _write(int file, char *buf, int len) * @returns the previous top of the heap * @note uses a global variable heap_end to keep track of the previous top */ -void* _sbrk(int incr) +void * _sbrk( int incr ) { - char *prev_heap_end; + char * prev_heap_end; - if (heap_end == 0) + if( heap_end == 0 ) { - heap_end = (void*) &_heap_bottom; + heap_end = ( void * ) &_heap_bottom; } prev_heap_end = heap_end; - if ((heap_end + incr) > (void*)&_heap_top) + if( ( heap_end + incr ) > ( void * ) &_heap_top ) { - return (void*)-1; + return ( void * ) -1; } heap_end += incr; diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOSConfig.h index 5d72d2c60..5e3fc7f13 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOSConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -43,7 +43,7 @@ *----------------------------------------------------------*/ /* Used for IPv6 validation */ -#define configECHO_SERVER_ADDR_STRING "fe80::a53b:3371:d92f:970b" +#define configECHO_SERVER_ADDR_STRING "fe80::a53b:3371:d92f:970b" /* Used for IPv4 validation */ /* #define configECHO_SERVER_ADDR_STRING "192.168.1.3" */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOSIPConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOSIPConfig.h index e8a95e34d..230cbf31f 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOSIPConfig.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOSIPConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOS_Plus_TCP_IPv6_Multi.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOS_Plus_TCP_IPv6_Multi.sln index 99fabe95e..b19a02702 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOS_Plus_TCP_IPv6_Multi.sln +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/FreeRTOS_Plus_TCP_IPv6_Multi.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}" diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/Logging_WinSim.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/Logging_WinSim.c index b4aa2ad5c..e3ed9c411 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/Logging_WinSim.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/Logging_WinSim.c @@ -1,553 +1,553 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * Logging utility that allows FreeRTOS tasks to log to a UDP port, stdout, and - * disk file without making any Win32 system calls themselves. - * - * Messages logged to a UDP port are sent directly (using FreeRTOS+TCP), but as - * FreeRTOS tasks cannot make Win32 system calls messages sent to stdout or a - * disk file are sent via a stream buffer to a Win32 thread which then performs - * the actual output. - */ - -/* Standard includes. */ -#include -#include -#include -#include -#include - -/* FreeRTOS includes. */ -#include -#include "task.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" -#include "FreeRTOS_Stream_Buffer.h" - -/* Demo includes. */ -#include "logging.h" - -/*-----------------------------------------------------------*/ - -/* The maximum size to which the log file may grow, before being renamed - * to .ful. */ -#define dlLOGGING_FILE_SIZE ( 40ul * 1024ul * 1024ul ) - -/* Dimensions the arrays into which print messages are created. */ -#define dlMAX_PRINT_STRING_LENGTH 255 - -/* The size of the stream buffer used to pass messages from FreeRTOS tasks to - * the Win32 thread that is responsible for making any Win32 system calls that are - * necessary for the selected logging method. */ -#define dlLOGGING_STREAM_BUFFER_SIZE 32768 - -/* A block time of zero simply means don't block. */ -#define dlDONT_BLOCK 0 - -/*-----------------------------------------------------------*/ - -/* - * Called from vLoggingInit() to start a new disk log file. - */ -static void prvFileLoggingInit( void ); - -/* - * Attempt to write a message to the file. - */ -static void prvLogToFile( const char * pcMessage, - size_t xLength ); - -/* - * Simply close the logging file, if it is open. - */ -static void prvFileClose( void ); - -/* - * Before the scheduler is started this function is called directly. After the - * scheduler has started it is called from the Windows thread dedicated to - * outputting log messages. Only the windows thread actually performs the - * writing so as not to disrupt the simulation by making Windows system calls - * from FreeRTOS tasks. - */ -static void prvLoggingFlushBuffer( void ); - -/* - * The windows thread that performs the actual writing of messages that require - * Win32 system calls. Only the windows thread can make system calls so as not - * to disrupt the simulation by making Windows calls from FreeRTOS tasks. - */ -static DWORD WINAPI prvWin32LoggingThread( void * pvParam ); - -/* - * Creates the socket to which UDP messages are sent. This function is not - * called directly to prevent the print socket being created from within the IP - * task - which could result in a deadlock. Instead the function call is - * deferred to run in the RTOS daemon task - hence it prototype. - */ -static void prvCreatePrintSocket( void * pvParameter1, - uint32_t ulParameter2 ); - -/*-----------------------------------------------------------*/ - -/* Windows event used to wake the Win32 thread which performs any logging that - * needs Win32 system calls. */ -static void * pvLoggingThreadEvent = NULL; - -/* Stores the selected logging targets passed in as parameters to the - * vLoggingInit() function. */ -BaseType_t xStdoutLoggingUsed = pdFALSE, xDiskFileLoggingUsed = pdFALSE, xUDPLoggingUsed = pdFALSE; - -/* Circular buffer used to pass messages from the FreeRTOS tasks to the Win32 - * thread that is responsible for making Win32 calls (when stdout or a disk log is - * used). */ -static StreamBuffer_t * xLogStreamBuffer = NULL; - -/* Handle to the file used for logging. This is left open while there are - * messages waiting to be logged, then closed again in between logs. */ -static FILE * pxLoggingFileHandle = NULL; - -/* When true prints are performed directly. After start up xDirectPrint is set - * to pdFALSE - at which time prints that require Win32 system calls are done by - * the Win32 thread responsible for logging. */ -BaseType_t xDirectPrint = pdTRUE; - -/* File names for the in use and complete (full) log files. */ -static const char * pcLogFileName = "RTOSDemo.log"; -static const char * pcFullLogFileName = "RTOSDemo.ful"; - -/* As an optimization, the current file size is kept in a variable. */ -static size_t ulSizeOfLoggingFile = 0ul; - -/* The UDP socket and address on/to which print messages are sent. */ -Socket_t xPrintSocket = FREERTOS_INVALID_SOCKET; -struct freertos_sockaddr xPrintUDPAddress; - -/*-----------------------------------------------------------*/ - -void vLoggingInit( BaseType_t xLogToStdout, - BaseType_t xLogToFile, - BaseType_t xLogToUDP, - uint32_t ulRemoteIPAddress, - uint16_t usRemotePort ) -{ - /* Can only be called before the scheduler has started. */ - configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED ); - - #if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) || defined( configPRINTF ) ) - { - HANDLE Win32Thread; - - /* Record which output methods are to be used. */ - xStdoutLoggingUsed = xLogToStdout; - xDiskFileLoggingUsed = xLogToFile; - xUDPLoggingUsed = xLogToUDP; - - /* If a disk file is used then initialize it now. */ - if( xDiskFileLoggingUsed != pdFALSE ) - { - prvFileLoggingInit(); - } - - /* If UDP logging is used then store the address to which the log data - * will be sent - but don't create the socket yet because the network is - * not initialized. */ - if( xUDPLoggingUsed != pdFALSE ) - { - /* Set the address to which the print messages are sent. */ - xPrintUDPAddress.sin_port = FreeRTOS_htons( usRemotePort ); - xPrintUDPAddress.sin_address.ulIP_IPv4 = ulRemoteIPAddress; - } - - /* If a disk file or stdout are to be used then Win32 system calls will - * have to be made. Such system calls cannot be made from FreeRTOS tasks - * so create a stream buffer to pass the messages to a Win32 thread, then - * create the thread itself, along with a Win32 event that can be used to - * unblock the thread. */ - if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) - { - /* Create the buffer. */ - xLogStreamBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) + dlLOGGING_STREAM_BUFFER_SIZE + 1 ); - configASSERT( xLogStreamBuffer ); - memset( xLogStreamBuffer, '\0', sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) ); - xLogStreamBuffer->LENGTH = dlLOGGING_STREAM_BUFFER_SIZE + 1; - - /* Create the Windows event. */ - pvLoggingThreadEvent = CreateEvent( NULL, FALSE, TRUE, "StdoutLoggingEvent" ); - - /* Create the thread itself. */ - Win32Thread = CreateThread( - NULL, /* Pointer to thread security attributes. */ - 0, /* Initial thread stack size, in bytes. */ - prvWin32LoggingThread, /* Pointer to thread function. */ - NULL, /* Argument for new thread. */ - 0, /* Creation flags. */ - NULL ); - - /* Use the cores that are not used by the FreeRTOS tasks. */ - SetThreadAffinityMask( Win32Thread, ~0x01u ); - SetThreadPriorityBoost( Win32Thread, TRUE ); - SetThreadPriority( Win32Thread, THREAD_PRIORITY_IDLE ); - } - } - #else /* if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) || defined( configPRINTF ) ) */ - { - /* FreeRTOSIPConfig is set such that no print messages will be output. - * Avoid compiler warnings about unused parameters. */ - ( void ) xLogToStdout; - ( void ) xLogToFile; - ( void ) xLogToUDP; - ( void ) usRemotePort; - ( void ) ulRemoteIPAddress; - } - #endif /* ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) || defined( configPRINTF ) */ -} -/*-----------------------------------------------------------*/ - -static void prvCreatePrintSocket( void * pvParameter1, - uint32_t ulParameter2 ) -{ - static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 0 ); - Socket_t xSocket; - - /* The function prototype is that of a deferred function, but the parameters - * are not actually used. */ - ( void ) pvParameter1; - ( void ) ulParameter2; - - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - - if( xSocket != FREERTOS_INVALID_SOCKET ) - { - /* FreeRTOS+TCP decides which port to bind to. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); - FreeRTOS_bind( xSocket, NULL, 0 ); - - /* Now the socket is bound it can be assigned to the print socket. */ - xPrintSocket = xSocket; - } -} -/*-----------------------------------------------------------*/ - -static TickType_t ulTicksToMS( TickType_t uxTicks ) -{ - uint64_t ullCount = uxTicks; - - ullCount = ullCount * ( 1000U / configTICK_RATE_HZ ); - return ( uint32_t ) ullCount; -} - -void vLoggingPrintf( const char * pcFormat, - ... ) -{ - char cPrintString[ dlMAX_PRINT_STRING_LENGTH ]; - char cOutputString[ dlMAX_PRINT_STRING_LENGTH ]; - char * pcSource, * pcTarget, * pcBegin; - size_t xLength, xLength2, rc; - static BaseType_t xMessageNumber = 0; - static BaseType_t xAfterLineBreak = pdTRUE; - va_list args; - unsigned ulIPAddress; - const char * pcTaskName; - const char * pcNoTask = "None"; - int iOriginalPriority; - HANDLE xCurrentTask; - - - if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) || ( xUDPLoggingUsed != pdFALSE ) ) - { - /* There are a variable number of parameters. */ - va_start( args, pcFormat ); - - /* Additional info to place at the start of the log. */ - if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED ) - { - pcTaskName = pcTaskGetName( NULL ); - } - else - { - pcTaskName = pcNoTask; - } - - if( ( xAfterLineBreak == pdTRUE ) && ( strcmp( pcFormat, "\r\n" ) != 0 ) ) - { - TickType_t uxTickCount = ulTicksToMS( xTaskGetTickCount() ); - TickType_t ulSeconds = uxTickCount / 1000U; - TickType_t ulMsecs = uxTickCount % 1000U; - xLength = snprintf( cPrintString, dlMAX_PRINT_STRING_LENGTH, "%u %u.%03u [%-*s] ", - ( unsigned ) xMessageNumber++, - ( unsigned ) ulSeconds, - ( unsigned ) ulMsecs, - configMAX_TASK_NAME_LEN, - pcTaskName ); - /* xAfterLineBreak = pdFALSE; */ - } - else - { - xLength = 0; - memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH ); - xAfterLineBreak = pdTRUE; - } - - xLength2 = vsnprintf( cPrintString + xLength, dlMAX_PRINT_STRING_LENGTH - xLength, pcFormat, args ); - - if( xLength2 < 0 ) - { - /* Clean up. */ - xLength2 = dlMAX_PRINT_STRING_LENGTH - 1 - xLength; - cPrintString[ dlMAX_PRINT_STRING_LENGTH - 1 ] = '\0'; - } - - xLength += xLength2; - va_end( args ); - - /* For ease of viewing, copy the string into another buffer, converting - * IP addresses to dot notation on the way. */ - pcSource = cPrintString; - pcTarget = cOutputString; - - while( ( *pcSource ) != '\0' ) - { - *pcTarget = *pcSource; - pcTarget++; - pcSource++; - - /* Look forward for an IP address denoted by 'ip'. */ - if( ( isxdigit( pcSource[ 0 ] ) != pdFALSE ) && ( pcSource[ 1 ] == 'i' ) && ( pcSource[ 2 ] == 'p' ) ) - { - *pcTarget = *pcSource; - pcTarget++; - *pcTarget = '\0'; - pcBegin = pcTarget - 8; - - while( ( pcTarget > pcBegin ) && ( isxdigit( pcTarget[ -1 ] ) != pdFALSE ) ) - { - pcTarget--; - } - - ( void ) sscanf( pcTarget, "%8X", &ulIPAddress ); - rc = sprintf( pcTarget, "%lu.%lu.%lu.%lu", - ( unsigned long ) ( ulIPAddress >> 24UL ), - ( unsigned long ) ( ( ulIPAddress >> 16UL ) & 0xffUL ), - ( unsigned long ) ( ( ulIPAddress >> 8UL ) & 0xffUL ), - ( unsigned long ) ( ulIPAddress & 0xffUL ) ); - pcTarget += rc; - pcSource += 3; /* skip "ip" */ - } - } - - /* How far through the buffer was written? */ - xLength = ( BaseType_t ) ( pcTarget - cOutputString ); - - /* If the message is to be logged to a UDP port then it can be sent directly - * because it only uses FreeRTOS function (not Win32 functions). */ - if( xUDPLoggingUsed != pdFALSE ) - { - #if 0 /* _HT_ Logging doesn't need UDP logging for WinSim. */ - if( ( xPrintSocket == FREERTOS_INVALID_SOCKET ) && ( FreeRTOS_IsNetworkUp() != pdFALSE ) ) - { - /* Create and bind the socket to which print messages are sent. The - * xTimerPendFunctionCall() function is used even though this is - * not an interrupt because this function is called from the IP task - * and the IP task cannot itself wait for a socket to bind. The - * parameters to prvCreatePrintSocket() are not required so set to - * NULL or 0. */ - xTimerPendFunctionCall( prvCreatePrintSocket, NULL, 0, dlDONT_BLOCK ); - } - - if( xPrintSocket != FREERTOS_INVALID_SOCKET ) - { - FreeRTOS_sendto( xPrintSocket, cOutputString, xLength, 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) ); - - /* Just because the UDP data logger I'm using is dumb. */ - FreeRTOS_sendto( xPrintSocket, "\r", sizeof( char ), 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) ); - } - #endif /* 0 */ - } - - /* If logging is also to go to either stdout or a disk file then it cannot - * be output here - so instead write the message to the stream buffer and wake - * the Win32 thread which will read it from the stream buffer and perform the - * actual output. */ - if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) - { - configASSERT( xLogStreamBuffer ); - - /* How much space is in the buffer? */ - xLength2 = uxStreamBufferGetSpace( xLogStreamBuffer ); - - /* There must be enough space to write both the string and the length of - * the string. */ - if( xLength2 >= ( xLength + sizeof( xLength ) ) ) - { - /* First write in the length of the data, then write in the data - * itself. Raising the thread priority is used as a critical section - * as there are potentially multiple writers. The stream buffer is - * only thread safe when there is a single writer (likewise for - * reading from the buffer). */ - xCurrentTask = GetCurrentThread(); - iOriginalPriority = GetThreadPriority( xCurrentTask ); - SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); - uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) &( xLength ), sizeof( xLength ) ); - uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) cOutputString, xLength ); - SetThreadPriority( GetCurrentThread(), iOriginalPriority ); - } - - /* xDirectPrint is initialized to pdTRUE, and while it remains true the - * logging output function is called directly. When the system is running - * the output function cannot be called directly because it would get - * called from both FreeRTOS tasks and Win32 threads - so instead wake the - * Win32 thread responsible for the actual output. */ - if( xDirectPrint != pdFALSE ) - { - /* While starting up, the thread which calls prvWin32LoggingThread() - * is not running yet and xDirectPrint will be pdTRUE. */ - prvLoggingFlushBuffer(); - } - else if( pvLoggingThreadEvent != NULL ) - { - /* While running, wake up prvWin32LoggingThread() to send the - * logging data. */ - SetEvent( pvLoggingThreadEvent ); - } - } - } -} -/*-----------------------------------------------------------*/ - -static void prvLoggingFlushBuffer( void ) -{ - size_t xLength; - char cPrintString[ dlMAX_PRINT_STRING_LENGTH ]; - - /* Is there more than the length value stored in the circular buffer - * used to pass data from the FreeRTOS simulator into this Win32 thread? */ - while( uxStreamBufferGetSize( xLogStreamBuffer ) > sizeof( xLength ) ) - { - memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH ); - uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE ); - uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) cPrintString, xLength, pdFALSE ); - - /* Write the message to standard out if requested to do so when - * vLoggingInit() was called, or if the network is not yet up. */ - if( ( xStdoutLoggingUsed != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) ) - { - /* Write the message to stdout. */ - _write( _fileno( stdout ), cPrintString, strlen( cPrintString ) ); - } - - /* Write the message to a file if requested to do so when - * vLoggingInit() was called. */ - if( xDiskFileLoggingUsed != pdFALSE ) - { - prvLogToFile( cPrintString, xLength ); - } - } - - prvFileClose(); -} -/*-----------------------------------------------------------*/ - -static DWORD WINAPI prvWin32LoggingThread( void * pvParameter ) -{ - const DWORD xMaxWait = 1000; - - ( void ) pvParameter; - - /* From now on, prvLoggingFlushBuffer() will only be called from this - * Windows thread */ - xDirectPrint = pdFALSE; - - for( ; ; ) - { - /* Wait to be told there are message waiting to be logged. */ - WaitForSingleObject( pvLoggingThreadEvent, xMaxWait ); - - /* Write out all waiting messages. */ - prvLoggingFlushBuffer(); - } -} -/*-----------------------------------------------------------*/ - -static void prvFileLoggingInit( void ) -{ - FILE * pxHandle = fopen( pcLogFileName, "a" ); - - if( pxHandle != NULL ) - { - fseek( pxHandle, SEEK_END, 0ul ); - ulSizeOfLoggingFile = ftell( pxHandle ); - fclose( pxHandle ); - } - else - { - ulSizeOfLoggingFile = 0ul; - } -} -/*-----------------------------------------------------------*/ - -static void prvFileClose( void ) -{ - if( pxLoggingFileHandle != NULL ) - { - fclose( pxLoggingFileHandle ); - pxLoggingFileHandle = NULL; - } -} -/*-----------------------------------------------------------*/ - -static void prvLogToFile( const char * pcMessage, - size_t xLength ) -{ - if( pxLoggingFileHandle == NULL ) - { - pxLoggingFileHandle = fopen( pcLogFileName, "a" ); - } - - if( pxLoggingFileHandle != NULL ) - { - fwrite( pcMessage, 1, xLength, pxLoggingFileHandle ); - ulSizeOfLoggingFile += xLength; - - /* If the file has grown to its maximum permissible size then close and - * rename it - then start with a new file. */ - if( ulSizeOfLoggingFile > ( size_t ) dlLOGGING_FILE_SIZE ) - { - prvFileClose(); - - if( _access( pcFullLogFileName, 00 ) == 0 ) - { - remove( pcFullLogFileName ); - } - - rename( pcLogFileName, pcFullLogFileName ); - ulSizeOfLoggingFile = 0; - } - } -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Logging utility that allows FreeRTOS tasks to log to a UDP port, stdout, and + * disk file without making any Win32 system calls themselves. + * + * Messages logged to a UDP port are sent directly (using FreeRTOS+TCP), but as + * FreeRTOS tasks cannot make Win32 system calls messages sent to stdout or a + * disk file are sent via a stream buffer to a Win32 thread which then performs + * the actual output. + */ + +/* Standard includes. */ +#include +#include +#include +#include +#include + +/* FreeRTOS includes. */ +#include +#include "task.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" +#include "FreeRTOS_Stream_Buffer.h" + +/* Demo includes. */ +#include "logging.h" + +/*-----------------------------------------------------------*/ + +/* The maximum size to which the log file may grow, before being renamed + * to .ful. */ +#define dlLOGGING_FILE_SIZE ( 40ul * 1024ul * 1024ul ) + +/* Dimensions the arrays into which print messages are created. */ +#define dlMAX_PRINT_STRING_LENGTH 255 + +/* The size of the stream buffer used to pass messages from FreeRTOS tasks to + * the Win32 thread that is responsible for making any Win32 system calls that are + * necessary for the selected logging method. */ +#define dlLOGGING_STREAM_BUFFER_SIZE 32768 + +/* A block time of zero simply means don't block. */ +#define dlDONT_BLOCK 0 + +/*-----------------------------------------------------------*/ + +/* + * Called from vLoggingInit() to start a new disk log file. + */ +static void prvFileLoggingInit( void ); + +/* + * Attempt to write a message to the file. + */ +static void prvLogToFile( const char * pcMessage, + size_t xLength ); + +/* + * Simply close the logging file, if it is open. + */ +static void prvFileClose( void ); + +/* + * Before the scheduler is started this function is called directly. After the + * scheduler has started it is called from the Windows thread dedicated to + * outputting log messages. Only the windows thread actually performs the + * writing so as not to disrupt the simulation by making Windows system calls + * from FreeRTOS tasks. + */ +static void prvLoggingFlushBuffer( void ); + +/* + * The windows thread that performs the actual writing of messages that require + * Win32 system calls. Only the windows thread can make system calls so as not + * to disrupt the simulation by making Windows calls from FreeRTOS tasks. + */ +static DWORD WINAPI prvWin32LoggingThread( void * pvParam ); + +/* + * Creates the socket to which UDP messages are sent. This function is not + * called directly to prevent the print socket being created from within the IP + * task - which could result in a deadlock. Instead the function call is + * deferred to run in the RTOS daemon task - hence it prototype. + */ +static void prvCreatePrintSocket( void * pvParameter1, + uint32_t ulParameter2 ); + +/*-----------------------------------------------------------*/ + +/* Windows event used to wake the Win32 thread which performs any logging that + * needs Win32 system calls. */ +static void * pvLoggingThreadEvent = NULL; + +/* Stores the selected logging targets passed in as parameters to the + * vLoggingInit() function. */ +BaseType_t xStdoutLoggingUsed = pdFALSE, xDiskFileLoggingUsed = pdFALSE, xUDPLoggingUsed = pdFALSE; + +/* Circular buffer used to pass messages from the FreeRTOS tasks to the Win32 + * thread that is responsible for making Win32 calls (when stdout or a disk log is + * used). */ +static StreamBuffer_t * xLogStreamBuffer = NULL; + +/* Handle to the file used for logging. This is left open while there are + * messages waiting to be logged, then closed again in between logs. */ +static FILE * pxLoggingFileHandle = NULL; + +/* When true prints are performed directly. After start up xDirectPrint is set + * to pdFALSE - at which time prints that require Win32 system calls are done by + * the Win32 thread responsible for logging. */ +BaseType_t xDirectPrint = pdTRUE; + +/* File names for the in use and complete (full) log files. */ +static const char * pcLogFileName = "RTOSDemo.log"; +static const char * pcFullLogFileName = "RTOSDemo.ful"; + +/* As an optimization, the current file size is kept in a variable. */ +static size_t ulSizeOfLoggingFile = 0ul; + +/* The UDP socket and address on/to which print messages are sent. */ +Socket_t xPrintSocket = FREERTOS_INVALID_SOCKET; +struct freertos_sockaddr xPrintUDPAddress; + +/*-----------------------------------------------------------*/ + +void vLoggingInit( BaseType_t xLogToStdout, + BaseType_t xLogToFile, + BaseType_t xLogToUDP, + uint32_t ulRemoteIPAddress, + uint16_t usRemotePort ) +{ + /* Can only be called before the scheduler has started. */ + configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED ); + + #if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) || defined( configPRINTF ) ) + { + HANDLE Win32Thread; + + /* Record which output methods are to be used. */ + xStdoutLoggingUsed = xLogToStdout; + xDiskFileLoggingUsed = xLogToFile; + xUDPLoggingUsed = xLogToUDP; + + /* If a disk file is used then initialize it now. */ + if( xDiskFileLoggingUsed != pdFALSE ) + { + prvFileLoggingInit(); + } + + /* If UDP logging is used then store the address to which the log data + * will be sent - but don't create the socket yet because the network is + * not initialized. */ + if( xUDPLoggingUsed != pdFALSE ) + { + /* Set the address to which the print messages are sent. */ + xPrintUDPAddress.sin_port = FreeRTOS_htons( usRemotePort ); + xPrintUDPAddress.sin_address.ulIP_IPv4 = ulRemoteIPAddress; + } + + /* If a disk file or stdout are to be used then Win32 system calls will + * have to be made. Such system calls cannot be made from FreeRTOS tasks + * so create a stream buffer to pass the messages to a Win32 thread, then + * create the thread itself, along with a Win32 event that can be used to + * unblock the thread. */ + if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) + { + /* Create the buffer. */ + xLogStreamBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) + dlLOGGING_STREAM_BUFFER_SIZE + 1 ); + configASSERT( xLogStreamBuffer ); + memset( xLogStreamBuffer, '\0', sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) ); + xLogStreamBuffer->LENGTH = dlLOGGING_STREAM_BUFFER_SIZE + 1; + + /* Create the Windows event. */ + pvLoggingThreadEvent = CreateEvent( NULL, FALSE, TRUE, "StdoutLoggingEvent" ); + + /* Create the thread itself. */ + Win32Thread = CreateThread( + NULL, /* Pointer to thread security attributes. */ + 0, /* Initial thread stack size, in bytes. */ + prvWin32LoggingThread, /* Pointer to thread function. */ + NULL, /* Argument for new thread. */ + 0, /* Creation flags. */ + NULL ); + + /* Use the cores that are not used by the FreeRTOS tasks. */ + SetThreadAffinityMask( Win32Thread, ~0x01u ); + SetThreadPriorityBoost( Win32Thread, TRUE ); + SetThreadPriority( Win32Thread, THREAD_PRIORITY_IDLE ); + } + } + #else /* if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) || defined( configPRINTF ) ) */ + { + /* FreeRTOSIPConfig is set such that no print messages will be output. + * Avoid compiler warnings about unused parameters. */ + ( void ) xLogToStdout; + ( void ) xLogToFile; + ( void ) xLogToUDP; + ( void ) usRemotePort; + ( void ) ulRemoteIPAddress; + } + #endif /* ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) || defined( configPRINTF ) */ +} +/*-----------------------------------------------------------*/ + +static void prvCreatePrintSocket( void * pvParameter1, + uint32_t ulParameter2 ) +{ + static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 0 ); + Socket_t xSocket; + + /* The function prototype is that of a deferred function, but the parameters + * are not actually used. */ + ( void ) pvParameter1; + ( void ) ulParameter2; + + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + + if( xSocket != FREERTOS_INVALID_SOCKET ) + { + /* FreeRTOS+TCP decides which port to bind to. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); + FreeRTOS_bind( xSocket, NULL, 0 ); + + /* Now the socket is bound it can be assigned to the print socket. */ + xPrintSocket = xSocket; + } +} +/*-----------------------------------------------------------*/ + +static TickType_t ulTicksToMS( TickType_t uxTicks ) +{ + uint64_t ullCount = uxTicks; + + ullCount = ullCount * ( 1000U / configTICK_RATE_HZ ); + return ( uint32_t ) ullCount; +} + +void vLoggingPrintf( const char * pcFormat, + ... ) +{ + char cPrintString[ dlMAX_PRINT_STRING_LENGTH ]; + char cOutputString[ dlMAX_PRINT_STRING_LENGTH ]; + char * pcSource, * pcTarget, * pcBegin; + size_t xLength, xLength2, rc; + static BaseType_t xMessageNumber = 0; + static BaseType_t xAfterLineBreak = pdTRUE; + va_list args; + unsigned ulIPAddress; + const char * pcTaskName; + const char * pcNoTask = "None"; + int iOriginalPriority; + HANDLE xCurrentTask; + + + if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) || ( xUDPLoggingUsed != pdFALSE ) ) + { + /* There are a variable number of parameters. */ + va_start( args, pcFormat ); + + /* Additional info to place at the start of the log. */ + if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED ) + { + pcTaskName = pcTaskGetName( NULL ); + } + else + { + pcTaskName = pcNoTask; + } + + if( ( xAfterLineBreak == pdTRUE ) && ( strcmp( pcFormat, "\r\n" ) != 0 ) ) + { + TickType_t uxTickCount = ulTicksToMS( xTaskGetTickCount() ); + TickType_t ulSeconds = uxTickCount / 1000U; + TickType_t ulMsecs = uxTickCount % 1000U; + xLength = snprintf( cPrintString, dlMAX_PRINT_STRING_LENGTH, "%u %u.%03u [%-*s] ", + ( unsigned ) xMessageNumber++, + ( unsigned ) ulSeconds, + ( unsigned ) ulMsecs, + configMAX_TASK_NAME_LEN, + pcTaskName ); + /* xAfterLineBreak = pdFALSE; */ + } + else + { + xLength = 0; + memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH ); + xAfterLineBreak = pdTRUE; + } + + xLength2 = vsnprintf( cPrintString + xLength, dlMAX_PRINT_STRING_LENGTH - xLength, pcFormat, args ); + + if( xLength2 < 0 ) + { + /* Clean up. */ + xLength2 = dlMAX_PRINT_STRING_LENGTH - 1 - xLength; + cPrintString[ dlMAX_PRINT_STRING_LENGTH - 1 ] = '\0'; + } + + xLength += xLength2; + va_end( args ); + + /* For ease of viewing, copy the string into another buffer, converting + * IP addresses to dot notation on the way. */ + pcSource = cPrintString; + pcTarget = cOutputString; + + while( ( *pcSource ) != '\0' ) + { + *pcTarget = *pcSource; + pcTarget++; + pcSource++; + + /* Look forward for an IP address denoted by 'ip'. */ + if( ( isxdigit( pcSource[ 0 ] ) != pdFALSE ) && ( pcSource[ 1 ] == 'i' ) && ( pcSource[ 2 ] == 'p' ) ) + { + *pcTarget = *pcSource; + pcTarget++; + *pcTarget = '\0'; + pcBegin = pcTarget - 8; + + while( ( pcTarget > pcBegin ) && ( isxdigit( pcTarget[ -1 ] ) != pdFALSE ) ) + { + pcTarget--; + } + + ( void ) sscanf( pcTarget, "%8X", &ulIPAddress ); + rc = sprintf( pcTarget, "%lu.%lu.%lu.%lu", + ( unsigned long ) ( ulIPAddress >> 24UL ), + ( unsigned long ) ( ( ulIPAddress >> 16UL ) & 0xffUL ), + ( unsigned long ) ( ( ulIPAddress >> 8UL ) & 0xffUL ), + ( unsigned long ) ( ulIPAddress & 0xffUL ) ); + pcTarget += rc; + pcSource += 3; /* skip "ip" */ + } + } + + /* How far through the buffer was written? */ + xLength = ( BaseType_t ) ( pcTarget - cOutputString ); + + /* If the message is to be logged to a UDP port then it can be sent directly + * because it only uses FreeRTOS function (not Win32 functions). */ + if( xUDPLoggingUsed != pdFALSE ) + { + #if 0 /* _HT_ Logging doesn't need UDP logging for WinSim. */ + if( ( xPrintSocket == FREERTOS_INVALID_SOCKET ) && ( FreeRTOS_IsNetworkUp() != pdFALSE ) ) + { + /* Create and bind the socket to which print messages are sent. The + * xTimerPendFunctionCall() function is used even though this is + * not an interrupt because this function is called from the IP task + * and the IP task cannot itself wait for a socket to bind. The + * parameters to prvCreatePrintSocket() are not required so set to + * NULL or 0. */ + xTimerPendFunctionCall( prvCreatePrintSocket, NULL, 0, dlDONT_BLOCK ); + } + + if( xPrintSocket != FREERTOS_INVALID_SOCKET ) + { + FreeRTOS_sendto( xPrintSocket, cOutputString, xLength, 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) ); + + /* Just because the UDP data logger I'm using is dumb. */ + FreeRTOS_sendto( xPrintSocket, "\r", sizeof( char ), 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) ); + } + #endif /* 0 */ + } + + /* If logging is also to go to either stdout or a disk file then it cannot + * be output here - so instead write the message to the stream buffer and wake + * the Win32 thread which will read it from the stream buffer and perform the + * actual output. */ + if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) + { + configASSERT( xLogStreamBuffer ); + + /* How much space is in the buffer? */ + xLength2 = uxStreamBufferGetSpace( xLogStreamBuffer ); + + /* There must be enough space to write both the string and the length of + * the string. */ + if( xLength2 >= ( xLength + sizeof( xLength ) ) ) + { + /* First write in the length of the data, then write in the data + * itself. Raising the thread priority is used as a critical section + * as there are potentially multiple writers. The stream buffer is + * only thread safe when there is a single writer (likewise for + * reading from the buffer). */ + xCurrentTask = GetCurrentThread(); + iOriginalPriority = GetThreadPriority( xCurrentTask ); + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); + uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) &( xLength ), sizeof( xLength ) ); + uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) cOutputString, xLength ); + SetThreadPriority( GetCurrentThread(), iOriginalPriority ); + } + + /* xDirectPrint is initialized to pdTRUE, and while it remains true the + * logging output function is called directly. When the system is running + * the output function cannot be called directly because it would get + * called from both FreeRTOS tasks and Win32 threads - so instead wake the + * Win32 thread responsible for the actual output. */ + if( xDirectPrint != pdFALSE ) + { + /* While starting up, the thread which calls prvWin32LoggingThread() + * is not running yet and xDirectPrint will be pdTRUE. */ + prvLoggingFlushBuffer(); + } + else if( pvLoggingThreadEvent != NULL ) + { + /* While running, wake up prvWin32LoggingThread() to send the + * logging data. */ + SetEvent( pvLoggingThreadEvent ); + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvLoggingFlushBuffer( void ) +{ + size_t xLength; + char cPrintString[ dlMAX_PRINT_STRING_LENGTH ]; + + /* Is there more than the length value stored in the circular buffer + * used to pass data from the FreeRTOS simulator into this Win32 thread? */ + while( uxStreamBufferGetSize( xLogStreamBuffer ) > sizeof( xLength ) ) + { + memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH ); + uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE ); + uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) cPrintString, xLength, pdFALSE ); + + /* Write the message to standard out if requested to do so when + * vLoggingInit() was called, or if the network is not yet up. */ + if( ( xStdoutLoggingUsed != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) ) + { + /* Write the message to stdout. */ + _write( _fileno( stdout ), cPrintString, strlen( cPrintString ) ); + } + + /* Write the message to a file if requested to do so when + * vLoggingInit() was called. */ + if( xDiskFileLoggingUsed != pdFALSE ) + { + prvLogToFile( cPrintString, xLength ); + } + } + + prvFileClose(); +} +/*-----------------------------------------------------------*/ + +static DWORD WINAPI prvWin32LoggingThread( void * pvParameter ) +{ + const DWORD xMaxWait = 1000; + + ( void ) pvParameter; + + /* From now on, prvLoggingFlushBuffer() will only be called from this + * Windows thread */ + xDirectPrint = pdFALSE; + + for( ; ; ) + { + /* Wait to be told there are message waiting to be logged. */ + WaitForSingleObject( pvLoggingThreadEvent, xMaxWait ); + + /* Write out all waiting messages. */ + prvLoggingFlushBuffer(); + } +} +/*-----------------------------------------------------------*/ + +static void prvFileLoggingInit( void ) +{ + FILE * pxHandle = fopen( pcLogFileName, "a" ); + + if( pxHandle != NULL ) + { + fseek( pxHandle, SEEK_END, 0ul ); + ulSizeOfLoggingFile = ftell( pxHandle ); + fclose( pxHandle ); + } + else + { + ulSizeOfLoggingFile = 0ul; + } +} +/*-----------------------------------------------------------*/ + +static void prvFileClose( void ) +{ + if( pxLoggingFileHandle != NULL ) + { + fclose( pxLoggingFileHandle ); + pxLoggingFileHandle = NULL; + } +} +/*-----------------------------------------------------------*/ + +static void prvLogToFile( const char * pcMessage, + size_t xLength ) +{ + if( pxLoggingFileHandle == NULL ) + { + pxLoggingFileHandle = fopen( pcLogFileName, "a" ); + } + + if( pxLoggingFileHandle != NULL ) + { + fwrite( pcMessage, 1, xLength, pxLoggingFileHandle ); + ulSizeOfLoggingFile += xLength; + + /* If the file has grown to its maximum permissible size then close and + * rename it - then start with a new file. */ + if( ulSizeOfLoggingFile > ( size_t ) dlLOGGING_FILE_SIZE ) + { + prvFileClose(); + + if( _access( pcFullLogFileName, 00 ) == 0 ) + { + remove( pcFullLogFileName ); + } + + rename( pcLogFileName, pcFullLogFileName ); + ulSizeOfLoggingFile = 0; + } + } +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/ReadMe.md b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/ReadMe.md index a5aecc386..63fb58f78 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/ReadMe.md +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/ReadMe.md @@ -76,9 +76,9 @@ This demo provides 4 examples: 1. Set `mainCREATE_TCP_ECHO_SERVER_TASK` to 1 in the [main.c](main.c) file. 1. Build the project and run. ``` - 0 0.167 [IP-task ] uxNetworkisUp = 1 - 1 0.167 [IP-task ] uxNetworkisUp = 2 - 2 1.727 [IP-task ] uxNetworkisUp = 3 + 0 0.167 [IP-task ] uxNetworkIsUp = 1 + 1 0.167 [IP-task ] uxNetworkIsUp = 2 + 2 1.727 [IP-task ] uxNetworkIsUp = 3 3 1.727 [IP-task ] IPv4 address = 192.168.1.83 ``` 1. Echo server should now be running and ready to accept incoming connections diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/TCPEchoClient_SingleTasks.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/TCPEchoClient_SingleTasks.c index 8f93bca9d..7b0569cea 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/TCPEchoClient_SingleTasks.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/TCPEchoClient_SingleTasks.c @@ -1,474 +1,474 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * A set of tasks are created that send TCP echo requests to the standard echo - * port (port 7) on the IP address set by the configECHO_SERVER_ADDR0 to - * configECHO_SERVER_ADDR3 constants, then wait for and verify the reply - * (another demo is available that demonstrates the reception being performed in - * a task other than that from with the request was made). - * - * See the following web page for essential demo usage and configuration - * details: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html - */ - -/* Standard includes. */ -#include -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" -#include "FreeRTOS_IP_Private.h" - -/*#include "tcp_echo_config.h" */ - -/* Exclude the whole file if FreeRTOSIPConfig.h is configured to use UDP only. */ -#if ( ipconfigUSE_TCP == 1 ) - -/* The echo tasks create a socket, send out a number of echo requests, listen - * for the echo reply, then close the socket again before starting over. This - * delay is used between each iteration to ensure the network does not get too - * congested. */ - #define echoLOOP_DELAY pdMS_TO_TICKS( 2U ) - -/* The size of the buffers is a multiple of the MSS - the length of the data - * sent is a pseudo random size between 20 and echoBUFFER_SIZES. */ - #define echoBUFFER_SIZE_MULTIPLIER ( 3 ) - #define echoBUFFER_SIZES ( ipconfigTCP_MSS * echoBUFFER_SIZE_MULTIPLIER ) - -/* The number of instances of the echo client task to create. */ - #define echoNUM_ECHO_CLIENTS ( 1 ) - -/*-----------------------------------------------------------*/ - -/* - * Uses a socket to send data to, then receive data from, the standard echo - * port number 7. - */ - static void prvEchoClientTask( void * pvParameters ); - -/* - * Creates a pseudo random sized buffer of data to send to the echo server. - */ - static BaseType_t prvCreateTxData( char * ucBuffer, - uint32_t ulBufferLength ); - -/*-----------------------------------------------------------*/ - -/* Rx and Tx time outs are used to ensure the sockets do not wait too long for - * missing data. */ - static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 4000 ); - static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 4000 ); - static BaseType_t xHasStarted = pdFALSE; - -/* Counters for each created task - for inspection only. */ - static uint32_t ulTxRxCycles[ echoNUM_ECHO_CLIENTS ] = { 0 }, - ulTxRxFailures[ echoNUM_ECHO_CLIENTS ] = { 0 }, - ulConnections[ echoNUM_ECHO_CLIENTS ] = { 0 }; - -/* Rx and Tx buffers for each created task. */ - static char cTxBuffers[ echoNUM_ECHO_CLIENTS ][ echoBUFFER_SIZES ], - cRxBuffers[ echoNUM_ECHO_CLIENTS ][ echoBUFFER_SIZES ]; - -/*-----------------------------------------------------------*/ - - void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, - UBaseType_t uxTaskPriority ) - { - if( xHasStarted == pdFALSE ) - { - BaseType_t xCount = 0; - BaseType_t x; - - xHasStarted = pdTRUE; - - /* Create the echo client tasks. */ - for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) - { - char ucName[ 16 ]; - snprintf( ucName, sizeof ucName, "echo_%02d", ( int ) x ); - BaseType_t rc = xTaskCreate( prvEchoClientTask, /* The function that implements the task. */ - ucName, /* Just a text name for the task to aid debugging. */ - usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ - ( void * ) x, /* The task parameter, not used in this case. */ - uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ - NULL ); /* The task handle is not used. */ - - if( rc == pdPASS ) - { - xCount++; - } - } - - configPRINTF( ( "Started %d / %d tasks\n", ( int ) xCount, ( int ) echoNUM_ECHO_CLIENTS ) ); - } - else - { - configPRINTF( ( "vStartTCPEchoClientTasks_SingleTasks: already started\n" ) ); - } - } -/*-----------------------------------------------------------*/ - - static BaseType_t xIsFatalError( BaseType_t xCode ) - { - BaseType_t xReturn = pdFALSE; - - if( ( xCode < 0 ) && ( xCode != -pdFREERTOS_ERRNO_EWOULDBLOCK ) ) - { - xReturn = pdTRUE; - } - - return xReturn; - } -/*-----------------------------------------------------------*/ - - static void prvEchoClientTask( void * pvParameters ) - { - Socket_t xSocket; - struct freertos_sockaddr xEchoServerAddress; - int32_t lLoopCount = 0UL; - const int32_t lMaxLoopCount = 1; - volatile uint32_t ulTxCount = 0UL; - BaseType_t xReceivedBytes, xReturned = 0, xInstance; - BaseType_t lTransmitted, lStringLength; - char * pcTransmittedString, * pcReceivedString; - WinProperties_t xWinProps; - TickType_t xTimeOnEntering; - TickType_t uxDuration = 0; - size_t xTotalSent = 0U; - size_t xTotalRecv = 0U; - BaseType_t xFamily = FREERTOS_AF_INET; - - /* Fill in the buffer and window sizes that will be used by the socket. */ - #ifdef _WINDOWS_ - xWinProps.lTxBufSize = 8 * ipconfigTCP_MSS; - xWinProps.lTxWinSize = 5; - xWinProps.lRxBufSize = 8 * ipconfigTCP_MSS; - xWinProps.lRxWinSize = 5; - #else - xWinProps.lTxBufSize = 3 * ipconfigTCP_MSS; - xWinProps.lTxWinSize = 2; - xWinProps.lRxBufSize = 3 * ipconfigTCP_MSS; - xWinProps.lRxWinSize = 2; - #endif - - /* This task can be created a number of times. Each instance is numbered - * to enable each instance to use a different Rx and Tx buffer. The number is - * passed in as the task's parameter. */ - xInstance = ( BaseType_t ) pvParameters; - - /* Point to the buffers to be used by this instance of this task. */ - pcTransmittedString = &( cTxBuffers[ xInstance ][ 0 ] ); - pcReceivedString = &( cRxBuffers[ xInstance ][ 0 ] ); - - memset( &xEchoServerAddress, 0, sizeof( xEchoServerAddress ) ); - - /* Echo requests are sent to the echo server. The address of the echo - * server is configured by the constants configECHO_SERVER_ADDR0 to - * configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ - - #ifdef configECHO_SERVER_ADDR_STRING - { - BaseType_t rc = FreeRTOS_inet_pton( FREERTOS_AF_INET6, configECHO_SERVER_ADDR_STRING, ( void * ) xEchoServerAddress.sin_address.xIP_IPv6.ucBytes ); - - if( rc == pdPASS ) - { - xFamily = FREERTOS_AF_INET6; - } - else - { - rc = FreeRTOS_inet_pton( FREERTOS_AF_INET4, configECHO_SERVER_ADDR_STRING, ( void * ) xEchoServerAddress.sin_address.xIP_IPv6.ucBytes ); - configASSERT( rc == pdPASS ); - xFamily = FREERTOS_AF_INET4; - } - } - #else /* ifdef configECHO_SERVER_ADDR_STRING */ - { - xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 ); - } - #endif /* ifdef configECHO_SERVER_ADDR_STRING */ - - xEchoServerAddress.sin_len = sizeof( xEchoServerAddress ); - xEchoServerAddress.sin_port = FreeRTOS_htons( configECHO_SERVER_PORT ); - xEchoServerAddress.sin_family = xFamily; - - for( ; ; ) - { - configPRINTF( ( "-------- Starting New Iteration --------\n" ) ); - BaseType_t xResult; - /* Create a TCP socket. */ - xSocket = FreeRTOS_socket( xFamily, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); - configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); - - /* Set a time out so a missing reply does not cause the task to block - * indefinitely. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); - - /* Set the window and buffer sizes. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); - xTotalSent = 0U; - xTotalRecv = 0U; - - /* Connect to the echo server. */ - xResult = FreeRTOS_connect( xSocket, &xEchoServerAddress, sizeof( xEchoServerAddress ) ); - configPRINTF( ( "FreeRTOS_connect returns %d\n", ( int ) xResult ) ); - - if( xResult == 0 ) - { - ulConnections[ xInstance ]++; - - /* Send a number of echo requests. */ - for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) - { - /* Create the string that is sent to the echo server. */ - lStringLength = prvCreateTxData( pcTransmittedString, echoBUFFER_SIZES ); - - /* Add in some unique text at the front of the string. */ - sprintf( pcTransmittedString, "TxRx message number %u", ( unsigned ) ulTxCount ); - ulTxCount++; - - /* Send the string to the socket. */ - lTransmitted = FreeRTOS_send( xSocket, /* The socket being sent to. */ - ( void * ) pcTransmittedString, /* The data being sent. */ - lStringLength, /* The length of the data being sent. */ - 0 ); /* No flags. */ - configPRINTF( ( "FreeRTOS_send: %u/%u\n", ( unsigned ) lTransmitted, ( unsigned ) lStringLength ) ); - - if( xIsFatalError( lTransmitted ) ) - { - /* Error? */ - break; - } - - xTotalSent += lTransmitted; - - /* Clear the buffer into which the echoed string will be - * placed. */ - memset( ( void * ) pcReceivedString, 0x00, echoBUFFER_SIZES ); - xReceivedBytes = 0; - - /* Receive data echoed back to the socket. */ - while( xReceivedBytes < lTransmitted ) - { - xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ - &( pcReceivedString[ xReceivedBytes ] ), /* The buffer into which the received data will be written. */ - lStringLength - xReceivedBytes, /* The size of the buffer provided to receive the data. */ - 0 ); /* No flags. */ - - if( xIsFatalError( xReturned ) ) - { - /* Error occurred. Latch it so it can be detected - * below. */ - break; - } - - if( xReturned == 0 ) - { - /* Timed out. */ - configPRINTF( ( "recv returned %u\n", ( unsigned ) xReturned ) ); - break; - } - - /* Keep a count of the bytes received so far. */ - xReceivedBytes += xReturned; - xTotalRecv += xReturned; - } - - /* If an error occurred it will be latched in xReceivedBytes, - * otherwise xReceived bytes will be just that - the number of - * bytes received from the echo server. */ - if( xReceivedBytes > 0 ) - { - /* Compare the transmitted string to the received string. */ - configASSERT( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ); - - if( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ) - { - /* The echo reply was received without error. */ - ulTxRxCycles[ xInstance ]++; - } - else - { - /* The received string did not match the transmitted - * string. */ - ulTxRxFailures[ xInstance ]++; - break; - } - } - else if( xIsFatalError( xReturned ) ) - { - /* FreeRTOS_recv() returned an error. */ - break; - } - else - { - /* Timed out without receiving anything? */ - break; - } - } - - /* Finished using the connected socket, initiate a graceful close: - * FIN, FIN+ACK, ACK. */ - FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR ); - - /* Expect FreeRTOS_recv() to return an error once the shutdown is - * complete. */ - xTimeOnEntering = xTaskGetTickCount(); - - do - { - xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ - &( pcReceivedString[ 0 ] ), /* The buffer into which the received data will be written. */ - echoBUFFER_SIZES, /* The size of the buffer provided to receive the data. */ - 0 ); - - uxDuration = ( xTaskGetTickCount() - xTimeOnEntering ); - - if( xReturned < 0 ) - { - break; - } - } while( uxDuration < xReceiveTimeOut ); - } - - configPRINTF( ( "Instance[%u]: Good %u/%u shutdown %u\n", - ( unsigned ) xInstance, - ( unsigned ) ( ulTxRxCycles[ xInstance ] - ulTxRxFailures[ xInstance ] ), - ( unsigned ) ( ulTxRxCycles[ xInstance ] ), - ( unsigned ) uxDuration ) ); - configPRINTF( ( "%u x %u = %u Exchange %u/%u\n", - ( unsigned ) echoBUFFER_SIZE_MULTIPLIER, - ( unsigned ) echoBUFFER_SIZES, - ( unsigned ) ( echoBUFFER_SIZE_MULTIPLIER * echoBUFFER_SIZES ), - ( unsigned ) xTotalSent, - ( unsigned ) xTotalRecv ) ); - configPRINTF( ( "--------------------------------------\n\n" ) ); - - /* Close this socket before looping back to create another. */ - FreeRTOS_closesocket( xSocket ); - - /* Pause for a short while to ensure the network is not too - * congested. */ - vTaskDelay( echoLOOP_DELAY ); - } - } -/*-----------------------------------------------------------*/ - - static BaseType_t prvCreateTxData( char * cBuffer, - uint32_t ulBufferLength ) - { - BaseType_t lCharactersToAdd, lCharacter; - char cChar = '0'; - const BaseType_t lMinimumLength = 60; - uint32_t ulRandomNumber; - static uint32_t ulNextnumber = 1U; - - /* Randomise the number of characters that will be sent in the echo - * request. */ - do - { - ( void ) xApplicationGetRandomNumber( &ulRandomNumber ); - lCharactersToAdd = ulRandomNumber % ( ulBufferLength - 20UL ); - } while( ( lCharactersToAdd == 0 ) || ( lCharactersToAdd < lMinimumLength ) ); /* Must be at least enough to add the unique text to the start of the string later. */ - - /* Fill the buffer. */ - for( lCharacter = 0; lCharacter < lCharactersToAdd; lCharacter++ ) - { - cBuffer[ lCharacter ] = cChar; - cChar++; - - if( cChar > '~' ) - { - cChar = '0'; - } - } - - { - /* Replace the string "0123456789" with an increasing number. */ - char pcBuf[ 16 ]; - char * pcPtr = cBuffer; - const char * ucLast = &( cBuffer[ ulBufferLength ] ); - - for( ; ; ) - { - char * next = strchr( pcPtr, '0' ); - - if( ( next == NULL ) || ( ( next + 10 ) >= ucLast ) ) - { - break; - } - - snprintf( pcBuf, sizeof pcBuf, "%010u", ulNextnumber ); - memcpy( next, pcBuf, 10 ); - ulNextnumber++; - pcPtr = next + 10; - } - } - return lCharactersToAdd; - } -/*-----------------------------------------------------------*/ - - BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ) - { - static uint32_t ulLastEchoSocketCount[ echoNUM_ECHO_CLIENTS ] = { 0 }, ulLastConnections[ echoNUM_ECHO_CLIENTS ] = { 0 }; - BaseType_t xReturn = pdPASS, x; - - /* Return fail is the number of cycles does not increment between - * consecutive calls. */ - for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) - { - if( ulTxRxCycles[ x ] == ulLastEchoSocketCount[ x ] ) - { - xReturn = pdFAIL; - } - else - { - ulLastEchoSocketCount[ x ] = ulTxRxCycles[ x ]; - } - - if( ulConnections[ x ] == ulLastConnections[ x ] ) - { - xReturn = pdFAIL; - } - else - { - ulConnections[ x ] = ulLastConnections[ x ]; - } - } - - return xReturn; - } - -#endif /* ipconfigUSE_TCP */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * A set of tasks are created that send TCP echo requests to the standard echo + * port (port 7) on the IP address set by the configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR3 constants, then wait for and verify the reply + * (another demo is available that demonstrates the reception being performed in + * a task other than that from with the request was made). + * + * See the following web page for essential demo usage and configuration + * details: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html + */ + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" +#include "FreeRTOS_IP_Private.h" + +/*#include "tcp_echo_config.h" */ + +/* Exclude the whole file if FreeRTOSIPConfig.h is configured to use UDP only. */ +#if ( ipconfigUSE_TCP == 1 ) + +/* The echo tasks create a socket, send out a number of echo requests, listen + * for the echo reply, then close the socket again before starting over. This + * delay is used between each iteration to ensure the network does not get too + * congested. */ + #define echoLOOP_DELAY pdMS_TO_TICKS( 2U ) + +/* The size of the buffers is a multiple of the MSS - the length of the data + * sent is a pseudo random size between 20 and echoBUFFER_SIZES. */ + #define echoBUFFER_SIZE_MULTIPLIER ( 3 ) + #define echoBUFFER_SIZES ( ipconfigTCP_MSS * echoBUFFER_SIZE_MULTIPLIER ) + +/* The number of instances of the echo client task to create. */ + #define echoNUM_ECHO_CLIENTS ( 1 ) + +/*-----------------------------------------------------------*/ + +/* + * Uses a socket to send data to, then receive data from, the standard echo + * port number 7. + */ + static void prvEchoClientTask( void * pvParameters ); + +/* + * Creates a pseudo random sized buffer of data to send to the echo server. + */ + static BaseType_t prvCreateTxData( char * ucBuffer, + uint32_t ulBufferLength ); + +/*-----------------------------------------------------------*/ + +/* Rx and Tx time outs are used to ensure the sockets do not wait too long for + * missing data. */ + static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 4000 ); + static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 4000 ); + static BaseType_t xHasStarted = pdFALSE; + +/* Counters for each created task - for inspection only. */ + static uint32_t ulTxRxCycles[ echoNUM_ECHO_CLIENTS ] = { 0 }, + ulTxRxFailures[ echoNUM_ECHO_CLIENTS ] = { 0 }, + ulConnections[ echoNUM_ECHO_CLIENTS ] = { 0 }; + +/* Rx and Tx buffers for each created task. */ + static char cTxBuffers[ echoNUM_ECHO_CLIENTS ][ echoBUFFER_SIZES ], + cRxBuffers[ echoNUM_ECHO_CLIENTS ][ echoBUFFER_SIZES ]; + +/*-----------------------------------------------------------*/ + + void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ) + { + if( xHasStarted == pdFALSE ) + { + BaseType_t xCount = 0; + BaseType_t x; + + xHasStarted = pdTRUE; + + /* Create the echo client tasks. */ + for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) + { + char ucName[ 16 ]; + snprintf( ucName, sizeof ucName, "echo_%02d", ( int ) x ); + BaseType_t rc = xTaskCreate( prvEchoClientTask, /* The function that implements the task. */ + ucName, /* Just a text name for the task to aid debugging. */ + usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ + ( void * ) x, /* The task parameter, not used in this case. */ + uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ + NULL ); /* The task handle is not used. */ + + if( rc == pdPASS ) + { + xCount++; + } + } + + configPRINTF( ( "Started %d / %d tasks\n", ( int ) xCount, ( int ) echoNUM_ECHO_CLIENTS ) ); + } + else + { + configPRINTF( ( "vStartTCPEchoClientTasks_SingleTasks: already started\n" ) ); + } + } +/*-----------------------------------------------------------*/ + + static BaseType_t xIsFatalError( BaseType_t xCode ) + { + BaseType_t xReturn = pdFALSE; + + if( ( xCode < 0 ) && ( xCode != -pdFREERTOS_ERRNO_EWOULDBLOCK ) ) + { + xReturn = pdTRUE; + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + static void prvEchoClientTask( void * pvParameters ) + { + Socket_t xSocket; + struct freertos_sockaddr xEchoServerAddress; + int32_t lLoopCount = 0UL; + const int32_t lMaxLoopCount = 1; + volatile uint32_t ulTxCount = 0UL; + BaseType_t xReceivedBytes, xReturned = 0, xInstance; + BaseType_t lTransmitted, lStringLength; + char * pcTransmittedString, * pcReceivedString; + WinProperties_t xWinProps; + TickType_t xTimeOnEntering; + TickType_t uxDuration = 0; + size_t xTotalSent = 0U; + size_t xTotalRecv = 0U; + BaseType_t xFamily = FREERTOS_AF_INET; + + /* Fill in the buffer and window sizes that will be used by the socket. */ + #ifdef _WINDOWS_ + xWinProps.lTxBufSize = 8 * ipconfigTCP_MSS; + xWinProps.lTxWinSize = 5; + xWinProps.lRxBufSize = 8 * ipconfigTCP_MSS; + xWinProps.lRxWinSize = 5; + #else + xWinProps.lTxBufSize = 3 * ipconfigTCP_MSS; + xWinProps.lTxWinSize = 2; + xWinProps.lRxBufSize = 3 * ipconfigTCP_MSS; + xWinProps.lRxWinSize = 2; + #endif + + /* This task can be created a number of times. Each instance is numbered + * to enable each instance to use a different Rx and Tx buffer. The number is + * passed in as the task's parameter. */ + xInstance = ( BaseType_t ) pvParameters; + + /* Point to the buffers to be used by this instance of this task. */ + pcTransmittedString = &( cTxBuffers[ xInstance ][ 0 ] ); + pcReceivedString = &( cRxBuffers[ xInstance ][ 0 ] ); + + memset( &xEchoServerAddress, 0, sizeof( xEchoServerAddress ) ); + + /* Echo requests are sent to the echo server. The address of the echo + * server is configured by the constants configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ + + #ifdef configECHO_SERVER_ADDR_STRING + { + BaseType_t rc = FreeRTOS_inet_pton( FREERTOS_AF_INET6, configECHO_SERVER_ADDR_STRING, ( void * ) xEchoServerAddress.sin_address.xIP_IPv6.ucBytes ); + + if( rc == pdPASS ) + { + xFamily = FREERTOS_AF_INET6; + } + else + { + rc = FreeRTOS_inet_pton( FREERTOS_AF_INET4, configECHO_SERVER_ADDR_STRING, ( void * ) xEchoServerAddress.sin_address.xIP_IPv6.ucBytes ); + configASSERT( rc == pdPASS ); + xFamily = FREERTOS_AF_INET4; + } + } + #else /* ifdef configECHO_SERVER_ADDR_STRING */ + { + xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 ); + } + #endif /* ifdef configECHO_SERVER_ADDR_STRING */ + + xEchoServerAddress.sin_len = sizeof( xEchoServerAddress ); + xEchoServerAddress.sin_port = FreeRTOS_htons( configECHO_SERVER_PORT ); + xEchoServerAddress.sin_family = xFamily; + + for( ; ; ) + { + configPRINTF( ( "-------- Starting New Iteration --------\n" ) ); + BaseType_t xResult; + /* Create a TCP socket. */ + xSocket = FreeRTOS_socket( xFamily, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); + configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); + + /* Set a time out so a missing reply does not cause the task to block + * indefinitely. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); + + /* Set the window and buffer sizes. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); + xTotalSent = 0U; + xTotalRecv = 0U; + + /* Connect to the echo server. */ + xResult = FreeRTOS_connect( xSocket, &xEchoServerAddress, sizeof( xEchoServerAddress ) ); + configPRINTF( ( "FreeRTOS_connect returns %d\n", ( int ) xResult ) ); + + if( xResult == 0 ) + { + ulConnections[ xInstance ]++; + + /* Send a number of echo requests. */ + for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) + { + /* Create the string that is sent to the echo server. */ + lStringLength = prvCreateTxData( pcTransmittedString, echoBUFFER_SIZES ); + + /* Add in some unique text at the front of the string. */ + sprintf( pcTransmittedString, "TxRx message number %u", ( unsigned ) ulTxCount ); + ulTxCount++; + + /* Send the string to the socket. */ + lTransmitted = FreeRTOS_send( xSocket, /* The socket being sent to. */ + ( void * ) pcTransmittedString, /* The data being sent. */ + lStringLength, /* The length of the data being sent. */ + 0 ); /* No flags. */ + configPRINTF( ( "FreeRTOS_send: %u/%u\n", ( unsigned ) lTransmitted, ( unsigned ) lStringLength ) ); + + if( xIsFatalError( lTransmitted ) ) + { + /* Error? */ + break; + } + + xTotalSent += lTransmitted; + + /* Clear the buffer into which the echoed string will be + * placed. */ + memset( ( void * ) pcReceivedString, 0x00, echoBUFFER_SIZES ); + xReceivedBytes = 0; + + /* Receive data echoed back to the socket. */ + while( xReceivedBytes < lTransmitted ) + { + xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ + &( pcReceivedString[ xReceivedBytes ] ), /* The buffer into which the received data will be written. */ + lStringLength - xReceivedBytes, /* The size of the buffer provided to receive the data. */ + 0 ); /* No flags. */ + + if( xIsFatalError( xReturned ) ) + { + /* Error occurred. Latch it so it can be detected + * below. */ + break; + } + + if( xReturned == 0 ) + { + /* Timed out. */ + configPRINTF( ( "recv returned %u\n", ( unsigned ) xReturned ) ); + break; + } + + /* Keep a count of the bytes received so far. */ + xReceivedBytes += xReturned; + xTotalRecv += xReturned; + } + + /* If an error occurred it will be latched in xReceivedBytes, + * otherwise xReceived bytes will be just that - the number of + * bytes received from the echo server. */ + if( xReceivedBytes > 0 ) + { + /* Compare the transmitted string to the received string. */ + configASSERT( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ); + + if( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ) + { + /* The echo reply was received without error. */ + ulTxRxCycles[ xInstance ]++; + } + else + { + /* The received string did not match the transmitted + * string. */ + ulTxRxFailures[ xInstance ]++; + break; + } + } + else if( xIsFatalError( xReturned ) ) + { + /* FreeRTOS_recv() returned an error. */ + break; + } + else + { + /* Timed out without receiving anything? */ + break; + } + } + + /* Finished using the connected socket, initiate a graceful close: + * FIN, FIN+ACK, ACK. */ + FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR ); + + /* Expect FreeRTOS_recv() to return an error once the shutdown is + * complete. */ + xTimeOnEntering = xTaskGetTickCount(); + + do + { + xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ + &( pcReceivedString[ 0 ] ), /* The buffer into which the received data will be written. */ + echoBUFFER_SIZES, /* The size of the buffer provided to receive the data. */ + 0 ); + + uxDuration = ( xTaskGetTickCount() - xTimeOnEntering ); + + if( xReturned < 0 ) + { + break; + } + } while( uxDuration < xReceiveTimeOut ); + } + + configPRINTF( ( "Instance[%u]: Good %u/%u shutdown %u\n", + ( unsigned ) xInstance, + ( unsigned ) ( ulTxRxCycles[ xInstance ] - ulTxRxFailures[ xInstance ] ), + ( unsigned ) ( ulTxRxCycles[ xInstance ] ), + ( unsigned ) uxDuration ) ); + configPRINTF( ( "%u x %u = %u Exchange %u/%u\n", + ( unsigned ) echoBUFFER_SIZE_MULTIPLIER, + ( unsigned ) echoBUFFER_SIZES, + ( unsigned ) ( echoBUFFER_SIZE_MULTIPLIER * echoBUFFER_SIZES ), + ( unsigned ) xTotalSent, + ( unsigned ) xTotalRecv ) ); + configPRINTF( ( "--------------------------------------\n\n" ) ); + + /* Close this socket before looping back to create another. */ + FreeRTOS_closesocket( xSocket ); + + /* Pause for a short while to ensure the network is not too + * congested. */ + vTaskDelay( echoLOOP_DELAY ); + } + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvCreateTxData( char * cBuffer, + uint32_t ulBufferLength ) + { + BaseType_t lCharactersToAdd, lCharacter; + char cChar = '0'; + const BaseType_t lMinimumLength = 60; + uint32_t ulRandomNumber; + static uint32_t ulNextnumber = 1U; + + /* Randomise the number of characters that will be sent in the echo + * request. */ + do + { + ( void ) xApplicationGetRandomNumber( &ulRandomNumber ); + lCharactersToAdd = ulRandomNumber % ( ulBufferLength - 20UL ); + } while( ( lCharactersToAdd == 0 ) || ( lCharactersToAdd < lMinimumLength ) ); /* Must be at least enough to add the unique text to the start of the string later. */ + + /* Fill the buffer. */ + for( lCharacter = 0; lCharacter < lCharactersToAdd; lCharacter++ ) + { + cBuffer[ lCharacter ] = cChar; + cChar++; + + if( cChar > '~' ) + { + cChar = '0'; + } + } + + { + /* Replace the string "0123456789" with an increasing number. */ + char pcBuf[ 16 ]; + char * pcPtr = cBuffer; + const char * ucLast = &( cBuffer[ ulBufferLength ] ); + + for( ; ; ) + { + char * next = strchr( pcPtr, '0' ); + + if( ( next == NULL ) || ( ( next + 10 ) >= ucLast ) ) + { + break; + } + + snprintf( pcBuf, sizeof pcBuf, "%010u", ulNextnumber ); + memcpy( next, pcBuf, 10 ); + ulNextnumber++; + pcPtr = next + 10; + } + } + return lCharactersToAdd; + } +/*-----------------------------------------------------------*/ + + BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ) + { + static uint32_t ulLastEchoSocketCount[ echoNUM_ECHO_CLIENTS ] = { 0 }, ulLastConnections[ echoNUM_ECHO_CLIENTS ] = { 0 }; + BaseType_t xReturn = pdPASS, x; + + /* Return fail is the number of cycles does not increment between + * consecutive calls. */ + for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) + { + if( ulTxRxCycles[ x ] == ulLastEchoSocketCount[ x ] ) + { + xReturn = pdFAIL; + } + else + { + ulLastEchoSocketCount[ x ] = ulTxRxCycles[ x ]; + } + + if( ulConnections[ x ] == ulLastConnections[ x ] ) + { + xReturn = pdFAIL; + } + else + { + ulConnections[ x ] = ulLastConnections[ x ]; + } + } + + return xReturn; + } + +#endif /* ipconfigUSE_TCP */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/TCPEchoClient_SingleTasks.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/TCPEchoClient_SingleTasks.h index 25965c939..063821d67 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/TCPEchoClient_SingleTasks.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/TCPEchoClient_SingleTasks.h @@ -1,38 +1,38 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef SINGLE_TASK_TCP_ECHO_CLIENTS_H -#define SINGLE_TASK_TCP_ECHO_CLIENTS_H - -/* - * Create the TCP echo client tasks. This is the version where an echo request - * is made from the same task that listens for the echo reply. - */ -void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, - UBaseType_t uxTaskPriority ); -BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ); - -#endif /* SINGLE_TASK_TCP_ECHO_CLIENTS_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef SINGLE_TASK_TCP_ECHO_CLIENTS_H +#define SINGLE_TASK_TCP_ECHO_CLIENTS_H + +/* + * Create the TCP echo client tasks. This is the version where an echo request + * is made from the same task that listens for the echo reply. + */ +void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ); +BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ); + +#endif /* SINGLE_TASK_TCP_ECHO_CLIENTS_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/UDPEchoClient_SingleTasks.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/UDPEchoClient_SingleTasks.c index bab84fc0c..bd2d88a19 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/UDPEchoClient_SingleTasks.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/UDPEchoClient_SingleTasks.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -24,17 +24,17 @@ * */ - /* - * A set of tasks are created that send UDP echo requests to the - * IP address set by the configECHO_SERVER_ADDR0 to - * configECHO_SERVER_ADDR_STRING constant, then wait for and verify the reply - * - * See the following web page for essential demo usage and configuration - * details: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html - */ +/* + * A set of tasks are created that send UDP echo requests to the + * IP address set by the configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR_STRING constant, then wait for and verify the reply + * + * See the following web page for essential demo usage and configuration + * details: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html + */ - /* Standard includes. */ +/* Standard includes. */ #include #include #include @@ -50,240 +50,239 @@ #include "FreeRTOS_IP_Private.h" -#define USE_ZERO_COPY ( 1 ) +#define USE_ZERO_COPY ( 1 ) /* The echo tasks create a socket, send out a number of echo requests, listen -for the echo reply, then close the socket again before starting over. This -delay is used between each iteration to ensure the network does not get too -congested. */ -#define echoLOOP_DELAY pdMS_TO_TICKS( 2U ) + * for the echo reply, then close the socket again before starting over. This + * delay is used between each iteration to ensure the network does not get too + * congested. */ +#define echoLOOP_DELAY pdMS_TO_TICKS( 2U ) /* The number of instances of the echo client task to create. */ -#define echoNUM_ECHO_CLIENTS ( 1 ) +#define echoNUM_ECHO_CLIENTS ( 1 ) -#define TX_RX_STR_SIZE ( 25 ) +#define TX_RX_STR_SIZE ( 25 ) /* Rx and Tx time outs are used to ensure the sockets do not wait too long for -missing data. */ -static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS(4000); -static const TickType_t xSendTimeOut = pdMS_TO_TICKS(4000); + * missing data. */ +static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 4000 ); +static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 4000 ); static BaseType_t xHasStarted = pdFALSE; /* -* UDP echo client task -*/ -static void prvUDPEchoClientTask(void* pvParameters); + * UDP echo client task + */ +static void prvUDPEchoClientTask( void * pvParameters ); -void vStartUDPEchoClientTasks_SingleTasks(uint16_t usTaskStackSize, UBaseType_t uxTaskPriority) +void vStartUDPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ) { - - if (xHasStarted == pdFALSE) + if( xHasStarted == pdFALSE ) { BaseType_t xCount = 0; BaseType_t x; xHasStarted = pdTRUE; + /* Create the echo client tasks. */ - for (x = 0; x < echoNUM_ECHO_CLIENTS; x++) + for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) { - char ucName[16]; - snprintf(ucName, sizeof ucName, "echo_%02d", (int)x); - BaseType_t rc = xTaskCreate(prvUDPEchoClientTask, /* The function that implements the task. */ - ucName, /* Just a text name for the task to aid debugging. */ - usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ - (void*)x, /* The task parameter, not used in this case. */ - uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ - NULL); /* The task handle is not used. */ - if (rc == pdPASS) + char ucName[ 16 ]; + snprintf( ucName, sizeof ucName, "echo_%02d", ( int ) x ); + BaseType_t rc = xTaskCreate( prvUDPEchoClientTask, /* The function that implements the task. */ + ucName, /* Just a text name for the task to aid debugging. */ + usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ + ( void * ) x, /* The task parameter, not used in this case. */ + uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ + NULL ); /* The task handle is not used. */ + + if( rc == pdPASS ) { xCount++; } } - configPRINTF(("Started %d / %d tasks\n", (int)xCount, (int)echoNUM_ECHO_CLIENTS)); + + configPRINTF( ( "Started %d / %d tasks\n", ( int ) xCount, ( int ) echoNUM_ECHO_CLIENTS ) ); } else { - configPRINTF(("vStartUDPEchoClientTasks_SingleTasks: already started\n")); + configPRINTF( ( "vStartUDPEchoClientTasks_SingleTasks: already started\n" ) ); } } /*-----------------------------------------------------------*/ -static void prvUDPEchoClientTask(void* pvParameters) +static void prvUDPEchoClientTask( void * pvParameters ) { Socket_t xSocket; struct freertos_sockaddr xEchoServerAddress, xRxAddress; - int8_t cTxString[TX_RX_STR_SIZE], cRxString[TX_RX_STR_SIZE]; /* Make sure the stack is large enough to hold these. Turn on stack overflow checking during debug to be sure. */ + int8_t cTxString[ TX_RX_STR_SIZE ], cRxString[ TX_RX_STR_SIZE ]; /* Make sure the stack is large enough to hold these. Turn on stack overflow checking during debug to be sure. */ int32_t lLoopCount = 0UL; int32_t lReturned; const int32_t lMaxLoopCount = 50; volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL; - uint32_t xAddressLength = sizeof(xEchoServerAddress); + uint32_t xAddressLength = sizeof( xEchoServerAddress ); BaseType_t xFamily = FREERTOS_AF_INET; uint8_t ucIPType = ipTYPE_IPv4; /* Remove compiler warning about unused parameters. */ - (void)pvParameters; + ( void ) pvParameters; + + memset( &xEchoServerAddress, 0, sizeof( xEchoServerAddress ) ); + memset( &xRxAddress, 0, sizeof( xRxAddress ) ); - memset(&xEchoServerAddress, 0, sizeof(xEchoServerAddress)); - memset(&xRxAddress, 0, sizeof(xRxAddress)); /* Echo requests are sent to the echo server. The address of the echo - server is configured by the constants configECHO_SERVER_ADDR0 to - configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ + * server is configured by the constants configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ -#ifdef configECHO_SERVER_ADDR_STRING + #ifdef configECHO_SERVER_ADDR_STRING { - BaseType_t rc = FreeRTOS_inet_pton(FREERTOS_AF_INET6, configECHO_SERVER_ADDR_STRING, (void*)xEchoServerAddress.sin_address.xIP_IPv6.ucBytes); - if (rc == pdPASS) + BaseType_t rc = FreeRTOS_inet_pton( FREERTOS_AF_INET6, configECHO_SERVER_ADDR_STRING, ( void * ) xEchoServerAddress.sin_address.xIP_IPv6.ucBytes ); + + if( rc == pdPASS ) { xFamily = FREERTOS_AF_INET6; ucIPType = ipTYPE_IPv6; } else { - rc = FreeRTOS_inet_pton(FREERTOS_AF_INET4, configECHO_SERVER_ADDR_STRING, (void*) &(xEchoServerAddress.sin_address.ulIP_IPv4)); - configASSERT(rc == pdPASS); + rc = FreeRTOS_inet_pton( FREERTOS_AF_INET4, configECHO_SERVER_ADDR_STRING, ( void * ) &( xEchoServerAddress.sin_address.ulIP_IPv4 ) ); + configASSERT( rc == pdPASS ); xFamily = FREERTOS_AF_INET4; ucIPType = ipTYPE_IPv4; } } -#else + #else /* ifdef configECHO_SERVER_ADDR_STRING */ { - xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick(configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3); + xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 ); } -#endif + #endif /* ifdef configECHO_SERVER_ADDR_STRING */ - xEchoServerAddress.sin_len = sizeof(xEchoServerAddress); - xEchoServerAddress.sin_port = FreeRTOS_htons(configECHO_SERVER_PORT); + xEchoServerAddress.sin_len = sizeof( xEchoServerAddress ); + xEchoServerAddress.sin_port = FreeRTOS_htons( configECHO_SERVER_PORT ); xEchoServerAddress.sin_family = xFamily; - - for (;; ) + for( ; ; ) { configPRINTF( ( "-------- Starting New Iteration --------\n" ) ); /* Create a socket. */ - xSocket = FreeRTOS_socket(xFamily, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP); - configASSERT(xSocket != FREERTOS_INVALID_SOCKET); + xSocket = FreeRTOS_socket( xFamily, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); /* Set a time out so a missing reply does not cause the task to block - indefinitely. */ - FreeRTOS_setsockopt(xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof(xReceiveTimeOut)); + * indefinitely. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); /* Send a number of echo requests. */ - for (lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++) + for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) { /* Create the string that is sent to the echo server. */ - sprintf((char*)cTxString, "Message number %u\r\n", ulTxCount); + sprintf( ( char * ) cTxString, "Message number %u\r\n", ulTxCount ); -#if USE_ZERO_COPY + #if USE_ZERO_COPY - /* - * First obtain a buffer of adequate length from the TCP/IP stack into which - * the string will be written. */ - uint8_t* pucBuffer = FreeRTOS_GetUDPPayloadBuffer_Multi(TX_RX_STR_SIZE, portMAX_DELAY, ucIPType); - configASSERT(pucBuffer != NULL); - memcpy(pucBuffer, &cTxString, strlen((const char*)cTxString) + 1); + /* + * First obtain a buffer of adequate length from the TCP/IP stack into which + * the string will be written. */ + uint8_t * pucBuffer = FreeRTOS_GetUDPPayloadBuffer_Multi( TX_RX_STR_SIZE, portMAX_DELAY, ucIPType ); + configASSERT( pucBuffer != NULL ); + memcpy( pucBuffer, &cTxString, strlen( ( const char * ) cTxString ) + 1 ); - /* Send the string to the socket. ulFlags is set to 0, so the zero - copy interface is not used. That means the data from cTxString is - copied into a network buffer inside FreeRTOS_sendto(), and cTxString - can be reused as soon as FreeRTOS_sendto() has returned. 1 is added - to ensure the NULL string terminator is sent as part of the message. */ - lReturned = FreeRTOS_sendto(xSocket, /* The socket being sent to. */ - (void*)pucBuffer, /* The data being sent. */ - strlen((const char*)pucBuffer) + 1, /* The length of the data being sent. */ - FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ - &xEchoServerAddress, /* The destination address. */ - sizeof(xEchoServerAddress)); + /* Send the string to the socket. ulFlags is set to 0, so the zero + * copy interface is not used. That means the data from cTxString is + * copied into a network buffer inside FreeRTOS_sendto(), and cTxString + * can be reused as soon as FreeRTOS_sendto() has returned. 1 is added + * to ensure the NULL string terminator is sent as part of the message. */ + lReturned = FreeRTOS_sendto( xSocket, /* The socket being sent to. */ + ( void * ) pucBuffer, /* The data being sent. */ + strlen( ( const char * ) pucBuffer ) + 1, /* The length of the data being sent. */ + FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ + &xEchoServerAddress, /* The destination address. */ + sizeof( xEchoServerAddress ) ); + #else /* if USE_ZERO_COPY */ -#else + /* Send the string to the socket. ulFlags is set to 0, so the zero + * copy interface is not used. That means the data from cTxString is + * copied into a network buffer inside FreeRTOS_sendto(), and cTxString + * can be reused as soon as FreeRTOS_sendto() has returned. 1 is added + * to ensure the NULL string terminator is sent as part of the message. */ + lReturned = FreeRTOS_sendto( xSocket, /* The socket being sent to. */ + ( void * ) cTxString, /* The data being sent. */ + strlen( ( const char * ) cTxString ) + 1, /* The length of the data being sent. */ + 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ + &xEchoServerAddress, /* The destination address. */ + sizeof( xEchoServerAddress ) ); + #endif /* if USE_ZERO_COPY */ - /* Send the string to the socket. ulFlags is set to 0, so the zero - copy interface is not used. That means the data from cTxString is - copied into a network buffer inside FreeRTOS_sendto(), and cTxString - can be reused as soon as FreeRTOS_sendto() has returned. 1 is added - to ensure the NULL string terminator is sent as part of the message. */ - lReturned = FreeRTOS_sendto(xSocket, /* The socket being sent to. */ - (void*)cTxString, /* The data being sent. */ - strlen((const char*)cTxString) + 1, /* The length of the data being sent. */ - 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ - &xEchoServerAddress, /* The destination address. */ - sizeof(xEchoServerAddress)); - -#endif - - if (lReturned == 0) + if( lReturned == 0 ) { /* The send operation failed. */ } else { /* Keep a count of how many echo requests have been transmitted so - it can be compared to the number of echo replies received. It would - be expected to loose at least one to an ARP message the first time - the connection is created. */ + * it can be compared to the number of echo replies received. It would + * be expected to loose at least one to an ARP message the first time + * the connection is created. */ ulTxCount++; /* The send was successful. */ - FreeRTOS_debug_printf(("[Echo Client] Data sent... \r\n")); + FreeRTOS_debug_printf( ( "[Echo Client] Data sent... \r\n" ) ); } /* Receive data echoed back to the socket. ulFlags is zero, so the - zero copy option is not being used and the received data will be - copied into the buffer pointed to by cRxString. xAddressLength is - not actually used (at the time of writing this comment, anyway) by - FreeRTOS_recvfrom(), but is set appropriately in case future - versions do use it. */ + * zero copy option is not being used and the received data will be + * copied into the buffer pointed to by cRxString. xAddressLength is + * not actually used (at the time of writing this comment, anyway) by + * FreeRTOS_recvfrom(), but is set appropriately in case future + * versions do use it. */ - memset((void*)cRxString, 0x00, sizeof(cRxString)); + memset( ( void * ) cRxString, 0x00, sizeof( cRxString ) ); -#if USE_ZERO_COPY + #if USE_ZERO_COPY + uint8_t * pucReceivedUDPPayload = NULL; + lReturned = FreeRTOS_recvfrom( xSocket, + &pucReceivedUDPPayload, + 0, + FREERTOS_ZERO_COPY, + &xRxAddress, + &xAddressLength ); - uint8_t* pucReceivedUDPPayload = NULL; - lReturned = FreeRTOS_recvfrom(xSocket, - &pucReceivedUDPPayload, - 0, - FREERTOS_ZERO_COPY, - &xRxAddress, - &xAddressLength); + if( pucReceivedUDPPayload != NULL ) + { + memcpy( ( void * ) ( cRxString ), pucReceivedUDPPayload, TX_RX_STR_SIZE ); - if (pucReceivedUDPPayload != NULL) { - memcpy((void*)(cRxString), pucReceivedUDPPayload, TX_RX_STR_SIZE); + FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucReceivedUDPPayload ); + } + #else /* if USE_ZERO_COPY */ + lReturned = FreeRTOS_recvfrom( xSocket, /* The socket being received from. */ + cRxString, /* The buffer into which the received data will be written. */ + sizeof( cRxString ), /* The size of the buffer provided to receive the data. */ + 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ + &xRxAddress, /* The address from where the data was sent (the source address). */ + &xAddressLength ); + #endif /* USE_ZERO_COPY */ - FreeRTOS_ReleaseUDPPayloadBuffer((void*)pucReceivedUDPPayload); - } -#else - - lReturned = FreeRTOS_recvfrom(xSocket, /* The socket being received from. */ - cRxString, /* The buffer into which the received data will be written. */ - sizeof(cRxString), /* The size of the buffer provided to receive the data. */ - 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ - &xRxAddress, /* The address from where the data was sent (the source address). */ - &xAddressLength); - -#endif /* USE_ZERO_COPY */ - - - - if (lReturned > 0) + if( lReturned > 0 ) { /* Compare the transmitted string to the received string. */ - if (strcmp((char*)cRxString, (char*)cTxString) == 0) + if( strcmp( ( char * ) cRxString, ( char * ) cTxString ) == 0 ) { /* The echo reply was received without error. */ ulRxCount++; + if( ( ulRxCount % 10 ) == 0 ) { - configPRINTF(("[Echo Client] Data was received correctly.\r\n")); + configPRINTF( ( "[Echo Client] Data was received correctly.\r\n" ) ); } } else { - FreeRTOS_debug_printf(("[Echo Client] Data received was erreneous.\r\n")); + FreeRTOS_debug_printf( ( "[Echo Client] Data received was erroneous.\r\n" ) ); } } else { - FreeRTOS_debug_printf(("[Echo Client] Data was not received\r\n")); + FreeRTOS_debug_printf( ( "[Echo Client] Data was not received\r\n" ) ); } } @@ -291,10 +290,10 @@ static void prvUDPEchoClientTask(void* pvParameters) configPRINTF( ( "--------------------------------------\n\n" ) ); /* Pause for a short while to ensure the network is not too - congested. */ - vTaskDelay(echoLOOP_DELAY); + * congested. */ + vTaskDelay( echoLOOP_DELAY ); /* Close this socket before looping back to create another. */ - FreeRTOS_closesocket(xSocket); + FreeRTOS_closesocket( xSocket ); } } diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/UDPEchoClient_SingleTasks.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/UDPEchoClient_SingleTasks.h index 2dfe52497..f0a291150 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/UDPEchoClient_SingleTasks.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/UDPEchoClient_SingleTasks.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -27,10 +27,11 @@ #ifndef SINGLE_TASK_UDP_ECHO_CLIENTS_H #define SINGLE_TASK_UDP_ECHO_CLIENTS_H - /* - * Create the UDP echo client tasks. This is the version where an echo request - * is made from the same task that listens for the echo reply. - */ -void vStartUDPEchoClientTasks_SingleTasks(uint16_t usTaskStackSize, UBaseType_t uxTaskPriority); +/* + * Create the UDP echo client tasks. This is the version where an echo request + * is made from the same task that listens for the echo reply. + */ +void vStartUDPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ); #endif /* SINGLE_TASK_UDP_ECHO_CLIENTS_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/WIN32.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/WIN32.vcxproj index 933c56a45..e0ef59a3b 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/WIN32.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/WIN32.vcxproj @@ -1,283 +1,283 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {C686325E-3261-42F7-AEB1-DDE5280E1CEB} - RTOSDemo - 10.0 - - - - Application - false - MultiByte - v142 - - - Application - false - MultiByte - v142 - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - .\Debug\ - .\Debug\ - true - .\Release\ - .\Release\ - false - AllRules.ruleset - - - - .\Debug/WIN32.tlb - - - - - Disabled - -$(FREERTOS_INCLUDE_DIR); -$(FREERTOS_SOURCE_DIR)\portable\MSVC-MingW; -$(UTILITIES_SOURCE_DIR)\include; -$(PLUS_TCP_INCLUDE_DIR); -$(PLUS_TCP_SOURCE_DIR)\protocols\include; -$(PLUS_TCP_SOURCE_DIR)\portable\BufferManagement; -$(PLUS_TCP_SOURCE_DIR)\portable\Compiler\MSVC; -$(DEMO_COMMON_SOURCE_DIR)\WinPCap; -$(DEMO_COMMON_SOURCE_DIR)\logging\include; -..\common\NTP\include; -.; -..\common\Logging\windows - - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;ipconfigUSE_PCAP=1;_NO_CRT_STDIO_INLINE;%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDLL - .\Debug/WIN32.pch - .\Debug/ - .\Debug/ - .\Debug/ - Level4 - true - false - ProgramDatabase - /wd4210 /wd4127 /wd4214 /wd4201 /wd4244 /wd4310 %(AdditionalOptions) - true - NotUsing - false - CompileAsC - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c09 - - - .\Debug/RTOSDemo.exe - true - true - .\Debug/WIN32.pdb - Console - MachineX86 - wpcap.lib;%(AdditionalDependencies) - $(DEMO_COMMON_SOURCE_DIR)\WinPCap - false - - - true - .\Debug/WIN32.bsc - - - - - .\Release/WIN32.tlb - - - - - MaxSpeed - OnlyExplicitInline - _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/WIN32.pch - .\Release/ - .\Release/ - .\Release/ - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c09 - - - .\Release/RTOSDemo.exe - true - .\Release/WIN32.pdb - Console - MachineX86 - - - - - - - true - .\Release/WIN32.bsc - - - - - - - /wd4068 %(AdditionalOptions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {C686325E-3261-42F7-AEB1-DDE5280E1CEB} + RTOSDemo + 10.0 + + + + Application + false + MultiByte + v142 + + + Application + false + MultiByte + v142 + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\Debug\ + .\Debug\ + true + .\Release\ + .\Release\ + false + AllRules.ruleset + + + + .\Debug/WIN32.tlb + + + + + Disabled + +$(FREERTOS_INCLUDE_DIR); +$(FREERTOS_SOURCE_DIR)\portable\MSVC-MingW; +$(UTILITIES_SOURCE_DIR)\include; +$(PLUS_TCP_INCLUDE_DIR); +$(PLUS_TCP_SOURCE_DIR)\protocols\include; +$(PLUS_TCP_SOURCE_DIR)\portable\BufferManagement; +$(PLUS_TCP_SOURCE_DIR)\portable\Compiler\MSVC; +$(DEMO_COMMON_SOURCE_DIR)\WinPCap; +$(DEMO_COMMON_SOURCE_DIR)\logging\include; +..\common\NTP\include; +.; +..\common\Logging\windows + + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;ipconfigUSE_PCAP=1;_NO_CRT_STDIO_INLINE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDLL + .\Debug/WIN32.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level4 + true + false + ProgramDatabase + /wd4210 /wd4127 /wd4214 /wd4201 /wd4244 /wd4310 %(AdditionalOptions) + true + NotUsing + false + CompileAsC + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + .\Debug/RTOSDemo.exe + true + true + .\Debug/WIN32.pdb + Console + MachineX86 + wpcap.lib;%(AdditionalDependencies) + $(DEMO_COMMON_SOURCE_DIR)\WinPCap + false + + + true + .\Debug/WIN32.bsc + + + + + .\Release/WIN32.tlb + + + + + MaxSpeed + OnlyExplicitInline + _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Release/WIN32.pch + .\Release/ + .\Release/ + .\Release/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + .\Release/RTOSDemo.exe + true + .\Release/WIN32.pdb + Console + MachineX86 + + + + + + + true + .\Release/WIN32.bsc + + + + + + + /wd4068 %(AdditionalOptions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/WIN32.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/WIN32.vcxproj.filters index 1c915d1ab..24c23113d 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/WIN32.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/WIN32.vcxproj.filters @@ -1,354 +1,354 @@ - - - - - {38712199-cebf-4124-bf15-398f7c3419ea} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - {af3445a1-4908-4170-89ed-39345d90d30c} - - - {f32be356-4763-4cae-9020-974a2638cb08} - *.c - - - {88f409e6-d396-4ac5-94bd-7a99c914be46} - - - {e5ad4ec7-23dc-4295-8add-2acaee488f5a} - - - {d2dcd641-8d91-492b-852f-5563ffadaec6} - - - {8672fa26-b119-481f-8b8d-086419c01a3e} - - - {4570be11-ec96-4b55-ac58-24b50ada980a} - - - {5d93ed51-023a-41ad-9243-8d230165d34b} - - - {b71e974a-9f28-4815-972b-d930ba8a34d0} - - - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP\portable - - - FreeRTOS+\FreeRTOS+TCP\portable - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - - - - - - - - FreeRTOS\Source - - - FreeRTOS\Source - - - FreeRTOS\Source - - - FreeRTOS\Source - - - FreeRTOS\Source - - - FreeRTOS\Source - - - FreeRTOS\Source - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - FreeRTOS+\FreeRTOS+TCP - - - - - - - - - FreeRTOS\Source\include - - - FreeRTOS\Source\include - - - FreeRTOS\Source\include - - - FreeRTOS\Source\include - - - FreeRTOS\Source\include - - - FreeRTOS\Source\include - - - FreeRTOS\Source\include - - - FreeRTOS\Source\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - - + + + + + {38712199-cebf-4124-bf15-398f7c3419ea} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {af3445a1-4908-4170-89ed-39345d90d30c} + + + {f32be356-4763-4cae-9020-974a2638cb08} + *.c + + + {88f409e6-d396-4ac5-94bd-7a99c914be46} + + + {e5ad4ec7-23dc-4295-8add-2acaee488f5a} + + + {d2dcd641-8d91-492b-852f-5563ffadaec6} + + + {8672fa26-b119-481f-8b8d-086419c01a3e} + + + {4570be11-ec96-4b55-ac58-24b50ada980a} + + + {5d93ed51-023a-41ad-9243-8d230165d34b} + + + {b71e974a-9f28-4815-972b-d930ba8a34d0} + + + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP\portable + + + FreeRTOS+\FreeRTOS+TCP\portable + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + + + + + + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + FreeRTOS+\FreeRTOS+TCP + + + + + + + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + FreeRTOS+\FreeRTOS+TCP\include + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/main.c index bbfb53aaa..b2fe91edc 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -162,7 +162,7 @@ static UBaseType_t ulNextRand; #define mainNETWORK_UP_COUNT 1U #endif -static uint32_t uxNetworkisUp = 0U; +static uint32_t uxNetworkIsUp = 0U; /* A semaphore to become idle. */ @@ -218,10 +218,10 @@ int main( void ) /* === End-point 0 === */ FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); #if ( ipconfigUSE_DHCP != 0 ) - { - /* End-point 0 wants to use DHCPv4. */ - xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; - } + { + /* End-point 0 wants to use DHCPv4. */ + xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; + } #endif /* ( ipconfigUSE_DHCP != 0 ) */ /* @@ -231,87 +231,87 @@ int main( void ) * Gateway: fe80::ba27:ebff:fe5a:d751 // obtained from Router Advertisement */ #if ( ipconfigUSE_IPv6 != 0 && USES_IPV6_ENDPOINT != 0 ) + { + IPv6_Address_t xIPAddress; + IPv6_Address_t xPrefix; + IPv6_Address_t xGateWay; + + FreeRTOS_inet_pton6( "2001:470:ed44::", xPrefix.ucBytes ); + + FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, 64, pdTRUE ); + FreeRTOS_inet_pton6( "fe80::ba27:ebff:fe5a:d751", xGateWay.ucBytes ); + + FreeRTOS_FillEndPoint_IPv6( &( xInterfaces[ 0 ] ), + &( xEndPoints[ 1 ] ), + &( xIPAddress ), + &( xPrefix ), + 64uL, /* Prefix length. */ + &( xGateWay ), + NULL, /* pxDNSServerAddress: Not used yet. */ + ucMACAddress ); + FreeRTOS_inet_pton6( "2001:4860:4860::8888", xEndPoints[ 1 ].ipv6_settings.xDNSServerAddresses[ 0 ].ucBytes ); + FreeRTOS_inet_pton6( "fe80::1", xEndPoints[ 1 ].ipv6_settings.xDNSServerAddresses[ 1 ].ucBytes ); + FreeRTOS_inet_pton6( "2001:4860:4860::8888", xEndPoints[ 1 ].ipv6_defaults.xDNSServerAddresses[ 0 ].ucBytes ); + FreeRTOS_inet_pton6( "fe80::1", xEndPoints[ 1 ].ipv6_defaults.xDNSServerAddresses[ 1 ].ucBytes ); + + #if ( ipconfigUSE_RA != 0 ) + { + /* End-point 1 wants to use Router Advertisement */ + xEndPoints[ 1 ].bits.bWantRA = pdTRUE; + } + #endif /* #if( ipconfigUSE_RA != 0 ) */ + #if ( ipconfigUSE_DHCPv6 != 0 ) + { + /* End-point 1 wants to use DHCPv6. */ + xEndPoints[ 1 ].bits.bWantDHCP = pdTRUE; + } + #endif /* ( ipconfigUSE_DHCPv6 != 0 ) */ + } + #endif /* ( ipconfigUSE_IPv6 != 0 ) */ + #if ( ipconfigUSE_IPv6 != 0 && USES_IPV6_ENDPOINT != 0 ) + { + /* + * End-point-3 : private + * Network: fe80::/10 (link-local) + * IPv6 : fe80::d80e:95cc:3154:b76a/128 + * Gateway: - + */ { IPv6_Address_t xIPAddress; IPv6_Address_t xPrefix; - IPv6_Address_t xGateWay; - FreeRTOS_inet_pton6( "2001:470:ed44::", xPrefix.ucBytes ); + FreeRTOS_inet_pton6( "fe80::", xPrefix.ucBytes ); + FreeRTOS_inet_pton6( "fe80::7009", xIPAddress.ucBytes ); - FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, 64, pdTRUE ); - FreeRTOS_inet_pton6( "fe80::ba27:ebff:fe5a:d751", xGateWay.ucBytes ); - - FreeRTOS_FillEndPoint_IPv6( &( xInterfaces[ 0 ] ), - &( xEndPoints[ 1 ] ), - &( xIPAddress ), - &( xPrefix ), - 64uL, /* Prefix length. */ - &( xGateWay ), - NULL, /* pxDNSServerAddress: Not used yet. */ - ucMACAddress ); - FreeRTOS_inet_pton6( "2001:4860:4860::8888", xEndPoints[ 1 ].ipv6_settings.xDNSServerAddresses[ 0 ].ucBytes ); - FreeRTOS_inet_pton6( "fe80::1", xEndPoints[ 1 ].ipv6_settings.xDNSServerAddresses[ 1 ].ucBytes ); - FreeRTOS_inet_pton6( "2001:4860:4860::8888", xEndPoints[ 1 ].ipv6_defaults.xDNSServerAddresses[ 0 ].ucBytes ); - FreeRTOS_inet_pton6( "fe80::1", xEndPoints[ 1 ].ipv6_defaults.xDNSServerAddresses[ 1 ].ucBytes ); - - #if ( ipconfigUSE_RA != 0 ) - { - /* End-point 1 wants to use Router Advertisement */ - xEndPoints[ 1 ].bits.bWantRA = pdTRUE; - } - #endif /* #if( ipconfigUSE_RA != 0 ) */ - #if ( ipconfigUSE_DHCPv6 != 0 ) - { - /* End-point 1 wants to use DHCPv6. */ - xEndPoints[ 1 ].bits.bWantDHCP = pdTRUE; - } - #endif /* ( ipconfigUSE_DHCPv6 != 0 ) */ - } - #endif /* ( ipconfigUSE_IPv6 != 0 ) */ - #if ( ipconfigUSE_IPv6 != 0 && USES_IPV6_ENDPOINT != 0 ) - { - /* - * End-point-3 : private - * Network: fe80::/10 (link-local) - * IPv6 : fe80::d80e:95cc:3154:b76a/128 - * Gateway: - - */ - { - IPv6_Address_t xIPAddress; - IPv6_Address_t xPrefix; - - FreeRTOS_inet_pton6( "fe80::", xPrefix.ucBytes ); - FreeRTOS_inet_pton6( "fe80::7009", xIPAddress.ucBytes ); - - FreeRTOS_FillEndPoint_IPv6( - &( xInterfaces[ 0 ] ), - &( xEndPoints[ 2 ] ), - &( xIPAddress ), - &( xPrefix ), - 10U, /* Prefix length. */ - NULL, /* No gateway */ - NULL, /* pxDNSServerAddress: Not used yet. */ - ucMACAddress ); - } + FreeRTOS_FillEndPoint_IPv6( + &( xInterfaces[ 0 ] ), + &( xEndPoints[ 2 ] ), + &( xIPAddress ), + &( xPrefix ), + 10U, /* Prefix length. */ + NULL, /* No gateway */ + NULL, /* pxDNSServerAddress: Not used yet. */ + ucMACAddress ); } + } #endif /* if ( ipconfigUSE_IPv6 != 0 ) */ /* === End-point 0 === */ #if ( ( mainNETWORK_UP_COUNT >= 4U ) || ( USES_IPV6_ENDPOINT == 0 && mainNETWORK_UP_COUNT >= 2U ) ) + { + /*172.25.201.204 */ + /*netmask 255.255.240.0 */ + const uint8_t ucMACAddress2[ 6 ] = { 0x00, 0x22, 0x22, 0x22, 0x22, 82 }; + const uint8_t ucIPAddress2[ 4 ] = { 192, 168, 2, 210 }; + const uint8_t ucNetMask2[ 4 ] = { 255, 255, 255, 0 }; + const uint8_t ucGatewayAddress2[ 4 ] = { 0, 0, 0, 0 }; + FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 3 ] ), ucIPAddress2, ucNetMask2, ucGatewayAddress2, ucDNSServerAddress, ucMACAddress2 ); + #if ( ipconfigUSE_DHCP != 0 ) { - /*172.25.201.204 */ - /*netmask 255.255.240.0 */ - const uint8_t ucMACAddress2[ 6 ] = { 0x00, 0x22, 0x22, 0x22, 0x22, 82 }; - const uint8_t ucIPAddress2[ 4 ] = { 192, 168, 2, 210 }; - const uint8_t ucNetMask2[ 4 ] = { 255, 255, 255, 0 }; - const uint8_t ucGatewayAddress2[ 4 ] = { 0, 0, 0, 0 }; - FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 3 ] ), ucIPAddress2, ucNetMask2, ucGatewayAddress2, ucDNSServerAddress, ucMACAddress2 ); - #if ( ipconfigUSE_DHCP != 0 ) - { - /* End-point 0 wants to use DHCPv4. */ - xEndPoints[ 3 ].bits.bWantDHCP = pdTRUE; - } - #endif /* ( ipconfigUSE_DHCP != 0 ) */ + /* End-point 0 wants to use DHCPv4. */ + xEndPoints[ 3 ].bits.bWantDHCP = pdTRUE; } + #endif /* ( ipconfigUSE_DHCP != 0 ) */ + } #endif /* ( mainNETWORK_UP_COUNT >= 3U ) */ FreeRTOS_IPInit_Multi(); @@ -386,9 +386,9 @@ void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, { /* Create the tasks that use the IP stack if they have not already been * created. */ - uxNetworkisUp++; + uxNetworkIsUp++; - if( ( xTasksAlreadyCreated == pdFALSE ) && ( uxNetworkisUp == mainNETWORK_UP_COUNT ) ) + if( ( xTasksAlreadyCreated == pdFALSE ) && ( uxNetworkIsUp == mainNETWORK_UP_COUNT ) ) { #if USE_LOG_EVENT iEventLogClear(); @@ -399,22 +399,23 @@ void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, * demo tasks. */ #if ( mainCREATE_TCP_ECHO_TASKS_SINGLE == 1 ) - { - vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY ); - } + { + vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY ); + } #endif /* mainCREATE_TCP_ECHO_TASKS_SINGLE */ #if ( mainCREATE_TCP_ECHO_SERVER_TASK == 1 ) - { - extern void vStartSimpleTCPServerTasks( uint16_t usStackSize, UBaseType_t uxPriority ); - vStartSimpleTCPServerTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY ); - } + { + extern void vStartSimpleTCPServerTasks( uint16_t usStackSize, + UBaseType_t uxPriority ); + vStartSimpleTCPServerTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY ); + } #endif #if ( mainCREATE_UDP_ECHO_TASKS_SINGLE == 1 ) - { - vStartUDPEchoClientTasks_SingleTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY ); - } + { + vStartUDPEchoClientTasks_SingleTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY ); + } #endif #if ( mainCREATE_CLI_TASK == 1 ) @@ -426,7 +427,7 @@ void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, xTasksAlreadyCreated = pdTRUE; } - configPRINTF( ( "uxNetworkisUp = %u\n", ( unsigned ) uxNetworkisUp ) ); + configPRINTF( ( "uxNetworkIsUp = %u\n", ( unsigned ) uxNetworkIsUp ) ); if( pxEndPoint->bits.bIPv6 == 0U ) { @@ -670,7 +671,7 @@ const char * pcCommandList[] = /* "arpqc 192.168.2.10", */ /* "arpqc 172.217.194.100", */ /* "arpqc 2404:6800:4003:c0f::5e", */ - "ifconfig", + "ifconfig", /* "udp 192.168.2.255@2402 Hello", */ /* "udp 192.168.2.255@2402 Hello", */ /* "udp 192.168.2.255@2402 Hello", */ @@ -722,11 +723,11 @@ static void prvCliTask( void * pvArgument ) /* pcap_prepare(); */ /* Wait for all end-points to come up. - * They're counted with 'uxNetworkisUp'. */ + * They're counted with 'uxNetworkIsUp'. */ do { vTaskDelay( pdMS_TO_TICKS( 100U ) ); - } while( uxNetworkisUp != mainNETWORK_UP_COUNT ); + } while( uxNetworkIsUp != mainNETWORK_UP_COUNT ); xDNS_IP_Preference = xPreferenceIPv6; @@ -750,7 +751,7 @@ static void prvCliTask( void * pvArgument ) snprintf( pcCommand, sizeof( pcCommand ), "%s", pcCommandList[ xCommandIndex ] ); configPRINTF( ( "\n" ) ); configPRINTF( ( "/*==================== %s (%d/%d) ====================*/\n", - pcCommand, xCommandIndex + 1, ARRAY_SIZE( pcCommandList ) ) ); + pcCommand, xCommandIndex + 1, ARRAY_SIZE( pcCommandList ) ) ); configPRINTF( ( "\n" ) ); xHandleTestingCommand( pcCommand, sizeof( pcCommand ) ); xCommandIndex++; diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/printf-stdarg.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/printf-stdarg.c index 2fd7223db..0fbf4fa3c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/printf-stdarg.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo/printf-stdarg.c @@ -117,7 +117,7 @@ struct SStringBuf ucBytes : { 0, 1, 2, 3 } }; #else - const static _U32 u32 = { 0, 1, 2, 3 }; +const static _U32 u32 = { 0, 1, 2, 3 }; #endif static void strbuf_init( struct SStringBuf * apStr, diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging.h index ef9b42b63..ce778e4b2 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging_levels.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging_levels.h index 56cdaf6f4..ccc3cbcdb 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging_levels.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging_levels.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging_stack.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging_stack.h index 1150482fd..f912d2760 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging_stack.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/include/logging_stack.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/windows/Logging_WinSim.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/windows/Logging_WinSim.c index 16cb8c9de..5985dd164 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/windows/Logging_WinSim.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/Logging/windows/Logging_WinSim.c @@ -1,553 +1,554 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * Logging utility that allows FreeRTOS tasks to log to a UDP port, stdout, and - * disk file without making any Win32 system calls themselves. - * - * Messages logged to a UDP port are sent directly (using FreeRTOS+TCP), but as - * FreeRTOS tasks cannot make Win32 system calls messages sent to stdout or a - * disk file are sent via a stream buffer to a Win32 thread which then performs - * the actual output. - */ - -/* Standard includes. */ -#include -#include -#include -#include -#include - -/* FreeRTOS includes. */ -#include -#include "task.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" -#include "FreeRTOS_Stream_Buffer.h" - -/* Demo includes. */ -#include "logging.h" - -/*-----------------------------------------------------------*/ - -/* The maximum size to which the log file may grow, before being renamed - * to .ful. */ -#define dlLOGGING_FILE_SIZE ( 40ul * 1024ul * 1024ul ) - -/* Dimensions the arrays into which print messages are created. */ -#define dlMAX_PRINT_STRING_LENGTH 255 - -/* The size of the stream buffer used to pass messages from FreeRTOS tasks to - * the Win32 thread that is responsible for making any Win32 system calls that are - * necessary for the selected logging method. */ -#define dlLOGGING_STREAM_BUFFER_SIZE 32768 - -/* A block time of zero simply means don't block. */ -#define dlDONT_BLOCK 0 - -/*-----------------------------------------------------------*/ - -/* - * Called from vLoggingInit() to start a new disk log file. - */ -static void prvFileLoggingInit( void ); - -/* - * Attempt to write a message to the file. - */ -static void prvLogToFile( const char * pcMessage, - size_t xLength ); - -/* - * Simply close the logging file, if it is open. - */ -static void prvFileClose( void ); - -/* - * Before the scheduler is started this function is called directly. After the - * scheduler has started it is called from the Windows thread dedicated to - * outputting log messages. Only the windows thread actually performs the - * writing so as not to disrupt the simulation by making Windows system calls - * from FreeRTOS tasks. - */ -static void prvLoggingFlushBuffer( void ); - -/* - * The windows thread that performs the actual writing of messages that require - * Win32 system calls. Only the windows thread can make system calls so as not - * to disrupt the simulation by making Windows calls from FreeRTOS tasks. - */ -static DWORD WINAPI prvWin32LoggingThread( void * pvParam ); - -/* - * Creates the socket to which UDP messages are sent. This function is not - * called directly to prevent the print socket being created from within the IP - * task - which could result in a deadlock. Instead the function call is - * deferred to run in the RTOS daemon task - hence it prototype. - */ -static void prvCreatePrintSocket( void * pvParameter1, - uint32_t ulParameter2 ); - -/*-----------------------------------------------------------*/ - -/* Windows event used to wake the Win32 thread which performs any logging that - * needs Win32 system calls. */ -static void * pvLoggingThreadEvent = NULL; - -/* Stores the selected logging targets passed in as parameters to the - * vLoggingInit() function. */ -BaseType_t xStdoutLoggingUsed = pdFALSE, xDiskFileLoggingUsed = pdFALSE, xUDPLoggingUsed = pdFALSE; - -/* Circular buffer used to pass messages from the FreeRTOS tasks to the Win32 - * thread that is responsible for making Win32 calls (when stdout or a disk log is - * used). */ -static StreamBuffer_t * xLogStreamBuffer = NULL; - -/* Handle to the file used for logging. This is left open while there are - * messages waiting to be logged, then closed again in between logs. */ -static FILE * pxLoggingFileHandle = NULL; - -/* When true prints are performed directly. After start up xDirectPrint is set - * to pdFALSE - at which time prints that require Win32 system calls are done by - * the Win32 thread responsible for logging. */ -BaseType_t xDirectPrint = pdTRUE; - -/* File names for the in use and complete (full) log files. */ -static const char * pcLogFileName = "RTOSDemo.log"; -static const char * pcFullLogFileName = "RTOSDemo.ful"; - -/* As an optimization, the current file size is kept in a variable. */ -static size_t ulSizeOfLoggingFile = 0ul; - -/* The UDP socket and address on/to which print messages are sent. */ -Socket_t xPrintSocket = FREERTOS_INVALID_SOCKET; -struct freertos_sockaddr xPrintUDPAddress; - -/*-----------------------------------------------------------*/ - -void vLoggingInit( BaseType_t xLogToStdout, - BaseType_t xLogToFile, - BaseType_t xLogToUDP, - uint32_t ulRemoteIPAddress, - uint16_t usRemotePort ) -{ - /* Can only be called before the scheduler has started. */ - configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED ); - - #if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) ) - { - HANDLE Win32Thread; - - /* Record which output methods are to be used. */ - xStdoutLoggingUsed = xLogToStdout; - xDiskFileLoggingUsed = xLogToFile; - xUDPLoggingUsed = xLogToUDP; - - /* If a disk file is used then initialize it now. */ - if( xDiskFileLoggingUsed != pdFALSE ) - { - prvFileLoggingInit(); - } - - /* If UDP logging is used then store the address to which the log data - * will be sent - but don't create the socket yet because the network is - * not initialized. */ - if( xUDPLoggingUsed != pdFALSE ) - { - /* Set the address to which the print messages are sent. */ - xPrintUDPAddress.sin_port = FreeRTOS_htons( usRemotePort ); - xPrintUDPAddress.sin_address.ulIP_IPv4 = ulRemoteIPAddress; - xPrintUDPAddress.sin_family = FREERTOS_AF_INET; - } - - /* If a disk file or stdout are to be used then Win32 system calls will - * have to be made. Such system calls cannot be made from FreeRTOS tasks - * so create a stream buffer to pass the messages to a Win32 thread, then - * create the thread itself, along with a Win32 event that can be used to - * unblock the thread. */ - if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) - { - /* Create the buffer. */ - xLogStreamBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) + dlLOGGING_STREAM_BUFFER_SIZE + 1 ); - configASSERT( xLogStreamBuffer ); - memset( xLogStreamBuffer, '\0', sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) ); - xLogStreamBuffer->LENGTH = dlLOGGING_STREAM_BUFFER_SIZE + 1; - - /* Create the Windows event. */ - pvLoggingThreadEvent = CreateEvent( NULL, FALSE, TRUE, "StdoutLoggingEvent" ); - - /* Create the thread itself. */ - Win32Thread = CreateThread( - NULL, /* Pointer to thread security attributes. */ - 0, /* Initial thread stack size, in bytes. */ - prvWin32LoggingThread, /* Pointer to thread function. */ - NULL, /* Argument for new thread. */ - 0, /* Creation flags. */ - NULL ); - - /* Use the cores that are not used by the FreeRTOS tasks. */ - SetThreadAffinityMask( Win32Thread, ~0x01u ); - SetThreadPriorityBoost( Win32Thread, TRUE ); - SetThreadPriority( Win32Thread, THREAD_PRIORITY_IDLE ); - } - } - #else /* if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) ) */ - { - /* FreeRTOSIPConfig is set such that no print messages will be output. - * Avoid compiler warnings about unused parameters. */ - ( void ) xLogToStdout; - ( void ) xLogToFile; - ( void ) xLogToUDP; - ( void ) usRemotePort; - ( void ) ulRemoteIPAddress; - } - #endif /* ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) */ -} -/*-----------------------------------------------------------*/ - -static void prvCreatePrintSocket( void * pvParameter1, - uint32_t ulParameter2 ) -{ - static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 0 ); - Socket_t xSocket; - - /* The function prototype is that of a deferred function, but the parameters - * are not actually used. */ - ( void ) pvParameter1; - ( void ) ulParameter2; - - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - - if( xSocket != FREERTOS_INVALID_SOCKET ) - { - /* FreeRTOS+TCP decides which port to bind to. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); - FreeRTOS_bind( xSocket, NULL, 0 ); - - /* Now the socket is bound it can be assigned to the print socket. */ - xPrintSocket = xSocket; - } -} -/*-----------------------------------------------------------*/ - -static TickType_t ulTicksToMS( TickType_t uxTicks ) -{ - uint64_t ullCount = uxTicks; - ullCount = ullCount * (1000U / configTICK_RATE_HZ); - return ( uint32_t )ullCount; -} - -void vLoggingPrintf( const char * pcFormat, - ... ) -{ - char cPrintString[ dlMAX_PRINT_STRING_LENGTH ]; - char cOutputString[ dlMAX_PRINT_STRING_LENGTH ]; - char * pcSource, * pcTarget, * pcBegin; - size_t xLength, xLength2, rc; - static BaseType_t xMessageNumber = 0; - static BaseType_t xAfterLineBreak = pdTRUE; - va_list args; - unsigned ulIPAddress; - const char * pcTaskName; - const char * pcNoTask = "None"; - int iOriginalPriority; - HANDLE xCurrentTask; - - - if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) || ( xUDPLoggingUsed != pdFALSE ) ) - { - /* There are a variable number of parameters. */ - va_start( args, pcFormat ); - - /* Additional info to place at the start of the log. */ - if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED ) - { - pcTaskName = pcTaskGetName( NULL ); - } - else - { - pcTaskName = pcNoTask; - } - - if( ( xAfterLineBreak == pdTRUE ) && ( strcmp( pcFormat, "\r\n" ) != 0 ) ) - { - TickType_t uxTickCount = ulTicksToMS( xTaskGetTickCount() ); - TickType_t ulSeconds = uxTickCount / 1000U; - TickType_t ulMsecs = uxTickCount % 1000U; - xLength = snprintf( cPrintString, dlMAX_PRINT_STRING_LENGTH, "%u %u.%03u [%-*s] ", - ( unsigned ) xMessageNumber++, - ( unsigned ) ulSeconds, - ( unsigned ) ulMsecs, - configMAX_TASK_NAME_LEN, - pcTaskName ); - /* xAfterLineBreak = pdFALSE; */ - } - else - { - xLength = 0; - memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH ); - xAfterLineBreak = pdTRUE; - } - - xLength2 = vsnprintf( cPrintString + xLength, dlMAX_PRINT_STRING_LENGTH - xLength, pcFormat, args ); - - if( xLength2 < 0 ) - { - /* Clean up. */ - xLength2 = dlMAX_PRINT_STRING_LENGTH - 1 - xLength; - cPrintString[ dlMAX_PRINT_STRING_LENGTH - 1 ] = '\0'; - } - - xLength += xLength2; - va_end( args ); - - /* For ease of viewing, copy the string into another buffer, converting - * IP addresses to dot notation on the way. */ - pcSource = cPrintString; - pcTarget = cOutputString; - - while( ( *pcSource ) != '\0' ) - { - *pcTarget = *pcSource; - pcTarget++; - pcSource++; - - /* Look forward for an IP address denoted by 'ip'. */ - if( ( isxdigit( pcSource[ 0 ] ) != pdFALSE ) && ( pcSource[ 1 ] == 'i' ) && ( pcSource[ 2 ] == 'p' ) ) - { - *pcTarget = *pcSource; - pcTarget++; - *pcTarget = '\0'; - pcBegin = pcTarget - 8; - - while( ( pcTarget > pcBegin ) && ( isxdigit( pcTarget[ -1 ] ) != pdFALSE ) ) - { - pcTarget--; - } - - ( void ) sscanf( pcTarget, "%8X", &ulIPAddress ); - rc = sprintf( pcTarget, "%lu.%lu.%lu.%lu", - ( unsigned long ) ( ulIPAddress >> 24UL ), - ( unsigned long ) ( ( ulIPAddress >> 16UL ) & 0xffUL ), - ( unsigned long ) ( ( ulIPAddress >> 8UL ) & 0xffUL ), - ( unsigned long ) ( ulIPAddress & 0xffUL ) ); - pcTarget += rc; - pcSource += 3; /* skip "ip" */ - } - } - - /* How far through the buffer was written? */ - xLength = ( BaseType_t ) ( pcTarget - cOutputString ); - - /* If the message is to be logged to a UDP port then it can be sent directly - * because it only uses FreeRTOS function (not Win32 functions). */ - if( xUDPLoggingUsed != pdFALSE ) - { - #if 0 /* _HT_ Logging doesn't need UDP logging for WinSim. */ - if( ( xPrintSocket == FREERTOS_INVALID_SOCKET ) && ( FreeRTOS_IsNetworkUp() != pdFALSE ) ) - { - /* Create and bind the socket to which print messages are sent. The - * xTimerPendFunctionCall() function is used even though this is - * not an interrupt because this function is called from the IP task - * and the IP task cannot itself wait for a socket to bind. The - * parameters to prvCreatePrintSocket() are not required so set to - * NULL or 0. */ - xTimerPendFunctionCall( prvCreatePrintSocket, NULL, 0, dlDONT_BLOCK ); - } - - if( xPrintSocket != FREERTOS_INVALID_SOCKET ) - { - FreeRTOS_sendto( xPrintSocket, cOutputString, xLength, 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) ); - - /* Just because the UDP data logger I'm using is dumb. */ - FreeRTOS_sendto( xPrintSocket, "\r", sizeof( char ), 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) ); - } - #endif /* 0 */ - } - - /* If logging is also to go to either stdout or a disk file then it cannot - * be output here - so instead write the message to the stream buffer and wake - * the Win32 thread which will read it from the stream buffer and perform the - * actual output. */ - if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) - { - configASSERT( xLogStreamBuffer ); - - /* How much space is in the buffer? */ - xLength2 = uxStreamBufferGetSpace( xLogStreamBuffer ); - - /* There must be enough space to write both the string and the length of - * the string. */ - if( xLength2 >= ( xLength + sizeof( xLength ) ) ) - { - /* First write in the length of the data, then write in the data - * itself. Raising the thread priority is used as a critical section - * as there are potentially multiple writers. The stream buffer is - * only thread safe when there is a single writer (likewise for - * reading from the buffer). */ - xCurrentTask = GetCurrentThread(); - iOriginalPriority = GetThreadPriority( xCurrentTask ); - SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); - uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) &( xLength ), sizeof( xLength ) ); - uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) cOutputString, xLength ); - SetThreadPriority( GetCurrentThread(), iOriginalPriority ); - } - - /* xDirectPrint is initialized to pdTRUE, and while it remains true the - * logging output function is called directly. When the system is running - * the output function cannot be called directly because it would get - * called from both FreeRTOS tasks and Win32 threads - so instead wake the - * Win32 thread responsible for the actual output. */ - if( xDirectPrint != pdFALSE ) - { - /* While starting up, the thread which calls prvWin32LoggingThread() - * is not running yet and xDirectPrint will be pdTRUE. */ - prvLoggingFlushBuffer(); - } - else if( pvLoggingThreadEvent != NULL ) - { - /* While running, wake up prvWin32LoggingThread() to send the - * logging data. */ - SetEvent( pvLoggingThreadEvent ); - } - } - } -} -/*-----------------------------------------------------------*/ - -static void prvLoggingFlushBuffer( void ) -{ - size_t xLength; - char cPrintString[ dlMAX_PRINT_STRING_LENGTH ]; - - /* Is there more than the length value stored in the circular buffer - * used to pass data from the FreeRTOS simulator into this Win32 thread? */ - while( uxStreamBufferGetSize( xLogStreamBuffer ) > sizeof( xLength ) ) - { - memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH ); - uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE ); - uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) cPrintString, xLength, pdFALSE ); - - /* Write the message to standard out if requested to do so when - * vLoggingInit() was called, or if the network is not yet up. */ - if( ( xStdoutLoggingUsed != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) ) - { - /* Write the message to stdout. */ - _write( _fileno( stdout ), cPrintString, strlen( cPrintString ) ); - } - - /* Write the message to a file if requested to do so when - * vLoggingInit() was called. */ - if( xDiskFileLoggingUsed != pdFALSE ) - { - prvLogToFile( cPrintString, xLength ); - } - } - - prvFileClose(); -} -/*-----------------------------------------------------------*/ - -static DWORD WINAPI prvWin32LoggingThread( void * pvParameter ) -{ - const DWORD xMaxWait = 1000; - - ( void ) pvParameter; - - /* From now on, prvLoggingFlushBuffer() will only be called from this - * Windows thread */ - xDirectPrint = pdFALSE; - - for( ; ; ) - { - /* Wait to be told there are message waiting to be logged. */ - WaitForSingleObject( pvLoggingThreadEvent, xMaxWait ); - - /* Write out all waiting messages. */ - prvLoggingFlushBuffer(); - } -} -/*-----------------------------------------------------------*/ - -static void prvFileLoggingInit( void ) -{ - FILE * pxHandle = fopen( pcLogFileName, "a" ); - - if( pxHandle != NULL ) - { - fseek( pxHandle, SEEK_END, 0ul ); - ulSizeOfLoggingFile = ftell( pxHandle ); - fclose( pxHandle ); - } - else - { - ulSizeOfLoggingFile = 0ul; - } -} -/*-----------------------------------------------------------*/ - -static void prvFileClose( void ) -{ - if( pxLoggingFileHandle != NULL ) - { - fclose( pxLoggingFileHandle ); - pxLoggingFileHandle = NULL; - } -} -/*-----------------------------------------------------------*/ - -static void prvLogToFile( const char * pcMessage, - size_t xLength ) -{ - if( pxLoggingFileHandle == NULL ) - { - pxLoggingFileHandle = fopen( pcLogFileName, "a" ); - } - - if( pxLoggingFileHandle != NULL ) - { - fwrite( pcMessage, 1, xLength, pxLoggingFileHandle ); - ulSizeOfLoggingFile += xLength; - - /* If the file has grown to its maximum permissible size then close and - * rename it - then start with a new file. */ - if( ulSizeOfLoggingFile > ( size_t ) dlLOGGING_FILE_SIZE ) - { - prvFileClose(); - - if( _access( pcFullLogFileName, 00 ) == 0 ) - { - remove( pcFullLogFileName ); - } - - rename( pcLogFileName, pcFullLogFileName ); - ulSizeOfLoggingFile = 0; - } - } -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Logging utility that allows FreeRTOS tasks to log to a UDP port, stdout, and + * disk file without making any Win32 system calls themselves. + * + * Messages logged to a UDP port are sent directly (using FreeRTOS+TCP), but as + * FreeRTOS tasks cannot make Win32 system calls messages sent to stdout or a + * disk file are sent via a stream buffer to a Win32 thread which then performs + * the actual output. + */ + +/* Standard includes. */ +#include +#include +#include +#include +#include + +/* FreeRTOS includes. */ +#include +#include "task.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" +#include "FreeRTOS_Stream_Buffer.h" + +/* Demo includes. */ +#include "logging.h" + +/*-----------------------------------------------------------*/ + +/* The maximum size to which the log file may grow, before being renamed + * to .ful. */ +#define dlLOGGING_FILE_SIZE ( 40ul * 1024ul * 1024ul ) + +/* Dimensions the arrays into which print messages are created. */ +#define dlMAX_PRINT_STRING_LENGTH 255 + +/* The size of the stream buffer used to pass messages from FreeRTOS tasks to + * the Win32 thread that is responsible for making any Win32 system calls that are + * necessary for the selected logging method. */ +#define dlLOGGING_STREAM_BUFFER_SIZE 32768 + +/* A block time of zero simply means don't block. */ +#define dlDONT_BLOCK 0 + +/*-----------------------------------------------------------*/ + +/* + * Called from vLoggingInit() to start a new disk log file. + */ +static void prvFileLoggingInit( void ); + +/* + * Attempt to write a message to the file. + */ +static void prvLogToFile( const char * pcMessage, + size_t xLength ); + +/* + * Simply close the logging file, if it is open. + */ +static void prvFileClose( void ); + +/* + * Before the scheduler is started this function is called directly. After the + * scheduler has started it is called from the Windows thread dedicated to + * outputting log messages. Only the windows thread actually performs the + * writing so as not to disrupt the simulation by making Windows system calls + * from FreeRTOS tasks. + */ +static void prvLoggingFlushBuffer( void ); + +/* + * The windows thread that performs the actual writing of messages that require + * Win32 system calls. Only the windows thread can make system calls so as not + * to disrupt the simulation by making Windows calls from FreeRTOS tasks. + */ +static DWORD WINAPI prvWin32LoggingThread( void * pvParam ); + +/* + * Creates the socket to which UDP messages are sent. This function is not + * called directly to prevent the print socket being created from within the IP + * task - which could result in a deadlock. Instead the function call is + * deferred to run in the RTOS daemon task - hence it prototype. + */ +static void prvCreatePrintSocket( void * pvParameter1, + uint32_t ulParameter2 ); + +/*-----------------------------------------------------------*/ + +/* Windows event used to wake the Win32 thread which performs any logging that + * needs Win32 system calls. */ +static void * pvLoggingThreadEvent = NULL; + +/* Stores the selected logging targets passed in as parameters to the + * vLoggingInit() function. */ +BaseType_t xStdoutLoggingUsed = pdFALSE, xDiskFileLoggingUsed = pdFALSE, xUDPLoggingUsed = pdFALSE; + +/* Circular buffer used to pass messages from the FreeRTOS tasks to the Win32 + * thread that is responsible for making Win32 calls (when stdout or a disk log is + * used). */ +static StreamBuffer_t * xLogStreamBuffer = NULL; + +/* Handle to the file used for logging. This is left open while there are + * messages waiting to be logged, then closed again in between logs. */ +static FILE * pxLoggingFileHandle = NULL; + +/* When true prints are performed directly. After start up xDirectPrint is set + * to pdFALSE - at which time prints that require Win32 system calls are done by + * the Win32 thread responsible for logging. */ +BaseType_t xDirectPrint = pdTRUE; + +/* File names for the in use and complete (full) log files. */ +static const char * pcLogFileName = "RTOSDemo.log"; +static const char * pcFullLogFileName = "RTOSDemo.ful"; + +/* As an optimization, the current file size is kept in a variable. */ +static size_t ulSizeOfLoggingFile = 0ul; + +/* The UDP socket and address on/to which print messages are sent. */ +Socket_t xPrintSocket = FREERTOS_INVALID_SOCKET; +struct freertos_sockaddr xPrintUDPAddress; + +/*-----------------------------------------------------------*/ + +void vLoggingInit( BaseType_t xLogToStdout, + BaseType_t xLogToFile, + BaseType_t xLogToUDP, + uint32_t ulRemoteIPAddress, + uint16_t usRemotePort ) +{ + /* Can only be called before the scheduler has started. */ + configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED ); + + #if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) ) + { + HANDLE Win32Thread; + + /* Record which output methods are to be used. */ + xStdoutLoggingUsed = xLogToStdout; + xDiskFileLoggingUsed = xLogToFile; + xUDPLoggingUsed = xLogToUDP; + + /* If a disk file is used then initialize it now. */ + if( xDiskFileLoggingUsed != pdFALSE ) + { + prvFileLoggingInit(); + } + + /* If UDP logging is used then store the address to which the log data + * will be sent - but don't create the socket yet because the network is + * not initialized. */ + if( xUDPLoggingUsed != pdFALSE ) + { + /* Set the address to which the print messages are sent. */ + xPrintUDPAddress.sin_port = FreeRTOS_htons( usRemotePort ); + xPrintUDPAddress.sin_address.ulIP_IPv4 = ulRemoteIPAddress; + xPrintUDPAddress.sin_family = FREERTOS_AF_INET; + } + + /* If a disk file or stdout are to be used then Win32 system calls will + * have to be made. Such system calls cannot be made from FreeRTOS tasks + * so create a stream buffer to pass the messages to a Win32 thread, then + * create the thread itself, along with a Win32 event that can be used to + * unblock the thread. */ + if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) + { + /* Create the buffer. */ + xLogStreamBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) + dlLOGGING_STREAM_BUFFER_SIZE + 1 ); + configASSERT( xLogStreamBuffer ); + memset( xLogStreamBuffer, '\0', sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) ); + xLogStreamBuffer->LENGTH = dlLOGGING_STREAM_BUFFER_SIZE + 1; + + /* Create the Windows event. */ + pvLoggingThreadEvent = CreateEvent( NULL, FALSE, TRUE, "StdoutLoggingEvent" ); + + /* Create the thread itself. */ + Win32Thread = CreateThread( + NULL, /* Pointer to thread security attributes. */ + 0, /* Initial thread stack size, in bytes. */ + prvWin32LoggingThread, /* Pointer to thread function. */ + NULL, /* Argument for new thread. */ + 0, /* Creation flags. */ + NULL ); + + /* Use the cores that are not used by the FreeRTOS tasks. */ + SetThreadAffinityMask( Win32Thread, ~0x01u ); + SetThreadPriorityBoost( Win32Thread, TRUE ); + SetThreadPriority( Win32Thread, THREAD_PRIORITY_IDLE ); + } + } + #else /* if ( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) ) */ + { + /* FreeRTOSIPConfig is set such that no print messages will be output. + * Avoid compiler warnings about unused parameters. */ + ( void ) xLogToStdout; + ( void ) xLogToFile; + ( void ) xLogToUDP; + ( void ) usRemotePort; + ( void ) ulRemoteIPAddress; + } + #endif /* ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) */ +} +/*-----------------------------------------------------------*/ + +static void prvCreatePrintSocket( void * pvParameter1, + uint32_t ulParameter2 ) +{ + static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 0 ); + Socket_t xSocket; + + /* The function prototype is that of a deferred function, but the parameters + * are not actually used. */ + ( void ) pvParameter1; + ( void ) ulParameter2; + + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + + if( xSocket != FREERTOS_INVALID_SOCKET ) + { + /* FreeRTOS+TCP decides which port to bind to. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); + FreeRTOS_bind( xSocket, NULL, 0 ); + + /* Now the socket is bound it can be assigned to the print socket. */ + xPrintSocket = xSocket; + } +} +/*-----------------------------------------------------------*/ + +static TickType_t ulTicksToMS( TickType_t uxTicks ) +{ + uint64_t ullCount = uxTicks; + + ullCount = ullCount * ( 1000U / configTICK_RATE_HZ ); + return ( uint32_t ) ullCount; +} + +void vLoggingPrintf( const char * pcFormat, + ... ) +{ + char cPrintString[ dlMAX_PRINT_STRING_LENGTH ]; + char cOutputString[ dlMAX_PRINT_STRING_LENGTH ]; + char * pcSource, * pcTarget, * pcBegin; + size_t xLength, xLength2, rc; + static BaseType_t xMessageNumber = 0; + static BaseType_t xAfterLineBreak = pdTRUE; + va_list args; + unsigned ulIPAddress; + const char * pcTaskName; + const char * pcNoTask = "None"; + int iOriginalPriority; + HANDLE xCurrentTask; + + + if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) || ( xUDPLoggingUsed != pdFALSE ) ) + { + /* There are a variable number of parameters. */ + va_start( args, pcFormat ); + + /* Additional info to place at the start of the log. */ + if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED ) + { + pcTaskName = pcTaskGetName( NULL ); + } + else + { + pcTaskName = pcNoTask; + } + + if( ( xAfterLineBreak == pdTRUE ) && ( strcmp( pcFormat, "\r\n" ) != 0 ) ) + { + TickType_t uxTickCount = ulTicksToMS( xTaskGetTickCount() ); + TickType_t ulSeconds = uxTickCount / 1000U; + TickType_t ulMsecs = uxTickCount % 1000U; + xLength = snprintf( cPrintString, dlMAX_PRINT_STRING_LENGTH, "%u %u.%03u [%-*s] ", + ( unsigned ) xMessageNumber++, + ( unsigned ) ulSeconds, + ( unsigned ) ulMsecs, + configMAX_TASK_NAME_LEN, + pcTaskName ); + /* xAfterLineBreak = pdFALSE; */ + } + else + { + xLength = 0; + memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH ); + xAfterLineBreak = pdTRUE; + } + + xLength2 = vsnprintf( cPrintString + xLength, dlMAX_PRINT_STRING_LENGTH - xLength, pcFormat, args ); + + if( xLength2 < 0 ) + { + /* Clean up. */ + xLength2 = dlMAX_PRINT_STRING_LENGTH - 1 - xLength; + cPrintString[ dlMAX_PRINT_STRING_LENGTH - 1 ] = '\0'; + } + + xLength += xLength2; + va_end( args ); + + /* For ease of viewing, copy the string into another buffer, converting + * IP addresses to dot notation on the way. */ + pcSource = cPrintString; + pcTarget = cOutputString; + + while( ( *pcSource ) != '\0' ) + { + *pcTarget = *pcSource; + pcTarget++; + pcSource++; + + /* Look forward for an IP address denoted by 'ip'. */ + if( ( isxdigit( pcSource[ 0 ] ) != pdFALSE ) && ( pcSource[ 1 ] == 'i' ) && ( pcSource[ 2 ] == 'p' ) ) + { + *pcTarget = *pcSource; + pcTarget++; + *pcTarget = '\0'; + pcBegin = pcTarget - 8; + + while( ( pcTarget > pcBegin ) && ( isxdigit( pcTarget[ -1 ] ) != pdFALSE ) ) + { + pcTarget--; + } + + ( void ) sscanf( pcTarget, "%8X", &ulIPAddress ); + rc = sprintf( pcTarget, "%lu.%lu.%lu.%lu", + ( unsigned long ) ( ulIPAddress >> 24UL ), + ( unsigned long ) ( ( ulIPAddress >> 16UL ) & 0xffUL ), + ( unsigned long ) ( ( ulIPAddress >> 8UL ) & 0xffUL ), + ( unsigned long ) ( ulIPAddress & 0xffUL ) ); + pcTarget += rc; + pcSource += 3; /* skip "ip" */ + } + } + + /* How far through the buffer was written? */ + xLength = ( BaseType_t ) ( pcTarget - cOutputString ); + + /* If the message is to be logged to a UDP port then it can be sent directly + * because it only uses FreeRTOS function (not Win32 functions). */ + if( xUDPLoggingUsed != pdFALSE ) + { + #if 0 /* _HT_ Logging doesn't need UDP logging for WinSim. */ + if( ( xPrintSocket == FREERTOS_INVALID_SOCKET ) && ( FreeRTOS_IsNetworkUp() != pdFALSE ) ) + { + /* Create and bind the socket to which print messages are sent. The + * xTimerPendFunctionCall() function is used even though this is + * not an interrupt because this function is called from the IP task + * and the IP task cannot itself wait for a socket to bind. The + * parameters to prvCreatePrintSocket() are not required so set to + * NULL or 0. */ + xTimerPendFunctionCall( prvCreatePrintSocket, NULL, 0, dlDONT_BLOCK ); + } + + if( xPrintSocket != FREERTOS_INVALID_SOCKET ) + { + FreeRTOS_sendto( xPrintSocket, cOutputString, xLength, 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) ); + + /* Just because the UDP data logger I'm using is dumb. */ + FreeRTOS_sendto( xPrintSocket, "\r", sizeof( char ), 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) ); + } + #endif /* 0 */ + } + + /* If logging is also to go to either stdout or a disk file then it cannot + * be output here - so instead write the message to the stream buffer and wake + * the Win32 thread which will read it from the stream buffer and perform the + * actual output. */ + if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) ) + { + configASSERT( xLogStreamBuffer ); + + /* How much space is in the buffer? */ + xLength2 = uxStreamBufferGetSpace( xLogStreamBuffer ); + + /* There must be enough space to write both the string and the length of + * the string. */ + if( xLength2 >= ( xLength + sizeof( xLength ) ) ) + { + /* First write in the length of the data, then write in the data + * itself. Raising the thread priority is used as a critical section + * as there are potentially multiple writers. The stream buffer is + * only thread safe when there is a single writer (likewise for + * reading from the buffer). */ + xCurrentTask = GetCurrentThread(); + iOriginalPriority = GetThreadPriority( xCurrentTask ); + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); + uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) &( xLength ), sizeof( xLength ) ); + uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) cOutputString, xLength ); + SetThreadPriority( GetCurrentThread(), iOriginalPriority ); + } + + /* xDirectPrint is initialized to pdTRUE, and while it remains true the + * logging output function is called directly. When the system is running + * the output function cannot be called directly because it would get + * called from both FreeRTOS tasks and Win32 threads - so instead wake the + * Win32 thread responsible for the actual output. */ + if( xDirectPrint != pdFALSE ) + { + /* While starting up, the thread which calls prvWin32LoggingThread() + * is not running yet and xDirectPrint will be pdTRUE. */ + prvLoggingFlushBuffer(); + } + else if( pvLoggingThreadEvent != NULL ) + { + /* While running, wake up prvWin32LoggingThread() to send the + * logging data. */ + SetEvent( pvLoggingThreadEvent ); + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvLoggingFlushBuffer( void ) +{ + size_t xLength; + char cPrintString[ dlMAX_PRINT_STRING_LENGTH ]; + + /* Is there more than the length value stored in the circular buffer + * used to pass data from the FreeRTOS simulator into this Win32 thread? */ + while( uxStreamBufferGetSize( xLogStreamBuffer ) > sizeof( xLength ) ) + { + memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH ); + uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE ); + uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) cPrintString, xLength, pdFALSE ); + + /* Write the message to standard out if requested to do so when + * vLoggingInit() was called, or if the network is not yet up. */ + if( ( xStdoutLoggingUsed != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) ) + { + /* Write the message to stdout. */ + _write( _fileno( stdout ), cPrintString, strlen( cPrintString ) ); + } + + /* Write the message to a file if requested to do so when + * vLoggingInit() was called. */ + if( xDiskFileLoggingUsed != pdFALSE ) + { + prvLogToFile( cPrintString, xLength ); + } + } + + prvFileClose(); +} +/*-----------------------------------------------------------*/ + +static DWORD WINAPI prvWin32LoggingThread( void * pvParameter ) +{ + const DWORD xMaxWait = 1000; + + ( void ) pvParameter; + + /* From now on, prvLoggingFlushBuffer() will only be called from this + * Windows thread */ + xDirectPrint = pdFALSE; + + for( ; ; ) + { + /* Wait to be told there are message waiting to be logged. */ + WaitForSingleObject( pvLoggingThreadEvent, xMaxWait ); + + /* Write out all waiting messages. */ + prvLoggingFlushBuffer(); + } +} +/*-----------------------------------------------------------*/ + +static void prvFileLoggingInit( void ) +{ + FILE * pxHandle = fopen( pcLogFileName, "a" ); + + if( pxHandle != NULL ) + { + fseek( pxHandle, SEEK_END, 0ul ); + ulSizeOfLoggingFile = ftell( pxHandle ); + fclose( pxHandle ); + } + else + { + ulSizeOfLoggingFile = 0ul; + } +} +/*-----------------------------------------------------------*/ + +static void prvFileClose( void ) +{ + if( pxLoggingFileHandle != NULL ) + { + fclose( pxLoggingFileHandle ); + pxLoggingFileHandle = NULL; + } +} +/*-----------------------------------------------------------*/ + +static void prvLogToFile( const char * pcMessage, + size_t xLength ) +{ + if( pxLoggingFileHandle == NULL ) + { + pxLoggingFileHandle = fopen( pcLogFileName, "a" ); + } + + if( pxLoggingFileHandle != NULL ) + { + fwrite( pcMessage, 1, xLength, pxLoggingFileHandle ); + ulSizeOfLoggingFile += xLength; + + /* If the file has grown to its maximum permissible size then close and + * rename it - then start with a new file. */ + if( ulSizeOfLoggingFile > ( size_t ) dlLOGGING_FILE_SIZE ) + { + prvFileClose(); + + if( _access( pcFullLogFileName, 00 ) == 0 ) + { + remove( pcFullLogFileName ); + } + + rename( pcLogFileName, pcFullLogFileName ); + ulSizeOfLoggingFile = 0; + } + } +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/NTPDemo.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/NTPDemo.c index 8f047cc13..5243b858c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/NTPDemo.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/NTPDemo.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -144,9 +144,9 @@ void vNTPClearCache( void ) { ulIPAddressFound = 0U; #if ( ipconfigUSE_IPv6 != 0 ) - { - memset( &( xIPAddressFound ), 0, sizeof xIPAddressFound ); - } + { + memset( &( xIPAddressFound ), 0, sizeof xIPAddressFound ); + } #endif xHasIPAddress = pdFALSE; } @@ -432,7 +432,8 @@ static void prvReadTime( struct SNtpPacket * pxPacket ) #if ( USE_PLUS_FAT != 0 ) FreeRTOS_gmtime_r( &uxCurrentSeconds, &xTimeStruct ); #else - extern struct tm * gmtime_r( const time_t * pxTime, struct tm * tmStruct ); + extern struct tm * gmtime_r( const time_t * pxTime, + struct tm * tmStruct ); gmtime_r( &uxCurrentSeconds, &xTimeStruct ); #endif /* ( USE_PLUS_FAT != 0 ) */ @@ -506,22 +507,22 @@ static void prvNTPTask( void * pvParameters ) xStatus = EStatusLookup; #if ( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) || ( ipconfigUSE_CALLBACKS != 0 ) - { - xNTPWakeupSem = xSemaphoreCreateBinary(); - } + { + xNTPWakeupSem = xSemaphoreCreateBinary(); + } #endif #if ( ipconfigUSE_CALLBACKS != 0 ) - { - memset( &xHandler, '\0', sizeof( xHandler ) ); - xHandler.pxOnUDPReceive = xOnUDPReceive; - FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) ); - } + { + memset( &xHandler, '\0', sizeof( xHandler ) ); + xHandler.pxOnUDPReceive = xOnUDPReceive; + FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) ); + } #endif #if ( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) - { - FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SET_SEMAPHORE, ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) ); - } + { + FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SET_SEMAPHORE, ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) ); + } #endif for( ; ; ) @@ -633,43 +634,43 @@ static void prvNTPTask( void * pvParameters ) } #if ( ipconfigUSE_CALLBACKS != 0 ) - { - xSemaphoreTake( xNTPWakeupSem, 5000 ); - } + { + xSemaphoreTake( xNTPWakeupSem, 5000 ); + } #else + { + uint32_t xAddressSize; + BaseType_t xReturned; + + xAddressSize = sizeof( xAddress ); + xReturned = FreeRTOS_recvfrom( xUDPSocket, ( void * ) cRecvBuffer, sizeof( cRecvBuffer ), 0, &xAddress, &xAddressSize ); + + switch( xReturned ) { - uint32_t xAddressSize; - BaseType_t xReturned; + case 0: + case -pdFREERTOS_ERRNO_EAGAIN: + case -pdFREERTOS_ERRNO_EINTR: + break; - xAddressSize = sizeof( xAddress ); - xReturned = FreeRTOS_recvfrom( xUDPSocket, ( void * ) cRecvBuffer, sizeof( cRecvBuffer ), 0, &xAddress, &xAddressSize ); + default: - switch( xReturned ) - { - case 0: - case -pdFREERTOS_ERRNO_EAGAIN: - case -pdFREERTOS_ERRNO_EINTR: - break; + if( xReturned < sizeof( xNTPPacket ) ) + { + FreeRTOS_printf( ( "FreeRTOS_recvfrom: returns %ld\n", xReturned ) ); + } + else + { + prvReadTime( ( struct SNtpPacket * ) cRecvBuffer ); - default: - - if( xReturned < sizeof( xNTPPacket ) ) + if( xStatus != EStatusPause ) { - FreeRTOS_printf( ( "FreeRTOS_recvfrom: returns %ld\n", xReturned ) ); + xStatus = EStatusPause; } - else - { - prvReadTime( ( struct SNtpPacket * ) cRecvBuffer ); + } - if( xStatus != EStatusPause ) - { - xStatus = EStatusPause; - } - } - - break; - } + break; } + } #endif /* if ( ipconfigUSE_CALLBACKS != 0 ) */ } } diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/include/NTPDemo.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/include/NTPDemo.h index 11362e06e..bc5fd9486 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/include/NTPDemo.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/include/NTPDemo.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/include/ntpClient.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/include/ntpClient.h index 753743ae6..c30fa1364 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/include/ntpClient.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/NTP/include/ntpClient.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/Packet32.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/Packet32.h index 32162dd94..1cf4c7bac 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/Packet32.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/Packet32.h @@ -154,8 +154,8 @@ UINT bh_caplen; /*/< Length of captured portion. The captured portion can be different */ /*/< from the original packet, because it is possible (with a proper filter) */ /*/< to instruct the driver to capture only a portion of the packets. */ - UINT bh_datalen; /*/< Original length of packet */ - USHORT bh_hdrlen; /*/< Length of bpf header (this struct plus alignment padding). In some cases, */ + UINT bh_datalen; /*/< Original length of packet */ + USHORT bh_hdrlen; /*/< Length of bpf header (this struct plus alignment padding). In some cases, */ /*/< a padding could be added between the end of this structure and the packet */ /*/< data for performance reasons. This filed can be used to retrieve the actual data */ /*/< of the packet. */ @@ -170,11 +170,11 @@ */ struct dump_bpf_hdr { - struct timeval ts; /*/< Time stamp of the packet */ - UINT caplen; /*/< Length of captured portion. The captured portion can smaller than the */ + struct timeval ts; /*/< Time stamp of the packet */ + UINT caplen; /*/< Length of captured portion. The captured portion can smaller than the */ /*/< the original packet, because it is possible (with a proper filter) to */ /*/< instruct the driver to capture only a portion of the packets. */ - UINT len; /*/< Length of the original packet (off wire). */ + UINT len; /*/< Length of the original packet (off wire). */ }; @@ -237,11 +237,11 @@ /*/< function can be used to define the minimum amount of data in the kernel buffer */ /*/< that will cause the event to be signalled. */ - UINT ReadTimeOut; /*/< \internal The amount of time after which a read on the driver will be released and */ + UINT ReadTimeOut; /*/< \internal The amount of time after which a read on the driver will be released and */ /*/< ReadEvent will be signaled, also if no packets were captured */ CHAR Name[ ADAPTER_NAME_LENGTH ]; PWAN_ADAPTER pWanAdapter; - UINT Flags; /*/< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. */ + UINT Flags; /*/< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. */ #ifdef HAVE_AIRPCAP_API PAirpcapHandle AirpcapAd; @@ -267,14 +267,14 @@ */ typedef struct _PACKET { - HANDLE hEvent; /*/< \deprecated Still present for compatibility with old applications. */ - OVERLAPPED OverLapped; /*/< \deprecated Still present for compatibility with old applications. */ - PVOID Buffer; /*/< Buffer with containing the packets. See the PacketReceivePacket() for */ + HANDLE hEvent; /*/< \deprecated Still present for compatibility with old applications. */ + OVERLAPPED OverLapped; /*/< \deprecated Still present for compatibility with old applications. */ + PVOID Buffer; /*/< Buffer with containing the packets. See the PacketReceivePacket() for */ /*/< details about the organization of the data in this buffer */ - UINT Length; /*/< Length of the buffer */ - DWORD ulBytesReceived; /*/< Number of valid bytes present in the buffer, i.e. amount of data */ + UINT Length; /*/< Length of the buffer */ + DWORD ulBytesReceived; /*/< Number of valid bytes present in the buffer, i.e. amount of data */ /*/< received by the last call to PacketReceivePacket() */ - BOOLEAN bIoComplete; /*/< \deprecated Still present for compatibility with old applications. */ + BOOLEAN bIoComplete; /*/< \deprecated Still present for compatibility with old applications. */ } PACKET, * LPPACKET; /*! @@ -286,16 +286,16 @@ */ struct _PACKET_OID_DATA { - ULONG Oid; /*/< OID code. See the Microsoft DDK documentation or the file ntddndis.h */ + ULONG Oid; /*/< OID code. See the Microsoft DDK documentation or the file ntddndis.h */ /*/< for a complete list of valid codes. */ - ULONG Length; /*/< Length of the data field */ - UCHAR Data[ 1 ]; /*/< variable-lenght field that contains the information passed to or received */ + ULONG Length; /*/< Length of the data field */ + UCHAR Data[ 1 ]; /*/< variable-length field that contains the information passed to or received */ /*/< from the adapter. */ }; typedef struct _PACKET_OID_DATA PACKET_OID_DATA, * PPACKET_OID_DATA; #ifdef __cplusplus - extern "C" { + extern "C" { #endif /** @@ -392,7 +392,7 @@ #define PACKET_START_OEM_NO_NETMON 0x00000001 #ifdef __cplusplus - } +} #endif #endif /*__PACKET32 */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/PacketData.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/PacketData.h index 4b136febf..7cc8b3430 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/PacketData.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/PacketData.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -25,7 +25,8 @@ */ -char pkt1[] = { +char pkt1[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x30, 0x09, 0x9c, 0x40, 0x00, 0x80, 0x06, @@ -36,7 +37,8 @@ char pkt1[] = { 0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 }; -char pkt2[] = { +char pkt2[] = +{ 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, @@ -47,7 +49,8 @@ char pkt2[] = { 0x05, 0x92 }; -char pkt3[] = { +char pkt3[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0x9e, 0x40, 0x00, 0x80, 0x06, @@ -57,7 +60,8 @@ char pkt3[] = { 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; -char pkt4[] = { +char pkt4[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x02, 0x27, 0x09, 0x9f, 0x40, 0x00, 0x80, 0x06, @@ -131,7 +135,8 @@ char pkt4[] = { 0x65, 0x0d, 0x0a, 0x0d, 0x0a }; -char pkt5[] = { +char pkt5[] = +{ 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x40, 0x06, @@ -142,7 +147,8 @@ char pkt5[] = { 0x05, 0x92 }; -char pkt6[] = { +char pkt6[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0xa1, 0x40, 0x00, 0x80, 0x06, @@ -152,7 +158,8 @@ char pkt6[] = { 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; -char pkt7[] = { +char pkt7[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x02, 0x27, 0x09, 0xa2, 0x40, 0x00, 0x80, 0x06, @@ -226,7 +233,8 @@ char pkt7[] = { 0x65, 0x0d, 0x0a, 0x0d, 0x0a }; -char pkt8[] = { +char pkt8[] = +{ 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2c, 0x00, 0x03, 0x00, 0x00, 0x40, 0x06, @@ -237,7 +245,8 @@ char pkt8[] = { 0x05, 0x92 }; -char pkt9[] = { +char pkt9[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0xa3, 0x40, 0x00, 0x80, 0x06, @@ -247,7 +256,8 @@ char pkt9[] = { 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; -char pkt10[] = { +char pkt10[] = +{ 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2c, 0x00, 0x04, 0x00, 0x00, 0x40, 0x06, @@ -258,7 +268,8 @@ char pkt10[] = { 0x05, 0x92 }; -char pkt11[] = { +char pkt11[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0xa6, 0x40, 0x00, 0x80, 0x06, @@ -268,7 +279,8 @@ char pkt11[] = { 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; -char pkt12[] = { +char pkt12[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0xa7, 0x40, 0x00, 0x80, 0x06, diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/Win32-Extensions.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/Win32-Extensions.h index f15f3651f..de0f1944d 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/Win32-Extensions.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/Win32-Extensions.h @@ -36,7 +36,7 @@ #define __WIN32_EXTENSIONS_H__ #ifdef __cplusplus - extern "C" { + extern "C" { #endif /* Definitions */ @@ -121,7 +121,7 @@ PAirpcapHandle pcap_get_airpcap_handle( pcap_t * p ); #ifdef __cplusplus - } +} #endif #endif /*__WIN32_EXTENSIONS_H__ */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/arch.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/arch.c index 3342712aa..cabb922ea 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/arch.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/arch.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -48,7 +48,7 @@ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void ); * Open the network interface. The number of the interface to be opened is set * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h. */ -static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces ); +static void prvOpenSelectedNetworkInterface( pcap_if_t * pxAllNetworkInterfaces ); /* * Configure the capture filter to allow blocking reads, and to filter out @@ -56,105 +56,105 @@ static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces ) */ static void prvConfigureCaptureBehaviour( void ); -pcap_t *pxOpenedInterfaceHandle = NULL; +pcap_t * pxOpenedInterfaceHandle = NULL; LARGE_INTEGER freq, sys_start_time; -#define archNUM_BUFFERS 5 -#define archNUM_BUFFER_POINTERS ( archNUM_BUFFERS - 1 ) +#define archNUM_BUFFERS 5 +#define archNUM_BUFFER_POINTERS ( archNUM_BUFFERS - 1 ) -static void prvInterruptSimulator( void *pvParameters ); +static void prvInterruptSimulator( void * pvParameters ); static unsigned char ucEthernetBuffer[ archNUM_BUFFERS ][ UIP_CONF_BUFFER_SIZE ]; -static unsigned char *pucEthernetBufferPointers[ archNUM_BUFFER_POINTERS ]; +static unsigned char * pucEthernetBufferPointers[ archNUM_BUFFER_POINTERS ]; static long lLengthOfDataInBuffer[ archNUM_BUFFER_POINTERS ] = { 0 }; static unsigned char ucNextBufferToFill = 0U, ucNextBufferToProcess = 0U; -unsigned char *uip_buf = NULL; -char cErrorBuffer[PCAP_ERRBUF_SIZE]; +unsigned char * uip_buf = NULL; +char cErrorBuffer[ PCAP_ERRBUF_SIZE ]; void vNetifTx( void ) { - pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); - pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); + pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); + pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); } /*-----------------------------------------------------------*/ UBaseType_t uxNetifRx( void ) { -UBaseType_t xDataLen; -unsigned char *pucTemp; + UBaseType_t xDataLen; + unsigned char * pucTemp; - /* Check there is really data available. */ - xDataLen = lLengthOfDataInBuffer[ ucNextBufferToProcess ]; - if( xDataLen != 0L ) - { + /* Check there is really data available. */ + xDataLen = lLengthOfDataInBuffer[ ucNextBufferToProcess ]; - /* The buffer pointed to by uip_buf is going to change. Remember which - buffer uip_buf is currently pointing to. */ - pucTemp = uip_buf; + if( xDataLen != 0L ) + { + /* The buffer pointed to by uip_buf is going to change. Remember which + * buffer uip_buf is currently pointing to. */ + pucTemp = uip_buf; - /* Point uip_buf at the next buffer that contains data. */ - uip_buf = pucEthernetBufferPointers[ ucNextBufferToProcess ]; + /* Point uip_buf at the next buffer that contains data. */ + uip_buf = pucEthernetBufferPointers[ ucNextBufferToProcess ]; - /* The buffer pointed to by - pucEthernetBufferPointeres[ ucNextBufferToProcess ] is now in use by - uip_buf, but the buffer uip_buf was pointing to on entry to this - function is free. Set - pucEthernetBufferPointeres[ ucNextBufferToProcess ] to the free - buffer. */ - pucEthernetBufferPointers[ ucNextBufferToProcess ] = pucTemp; - lLengthOfDataInBuffer[ ucNextBufferToProcess ] = 0L; + /* The buffer pointed to by + * pucEthernetBufferPointeres[ ucNextBufferToProcess ] is now in use by + * uip_buf, but the buffer uip_buf was pointing to on entry to this + * function is free. Set + * pucEthernetBufferPointeres[ ucNextBufferToProcess ] to the free + * buffer. */ + pucEthernetBufferPointers[ ucNextBufferToProcess ] = pucTemp; + lLengthOfDataInBuffer[ ucNextBufferToProcess ] = 0L; - ucNextBufferToProcess++; - if( ucNextBufferToProcess >= archNUM_BUFFER_POINTERS ) - { - ucNextBufferToProcess = 0L; - } - } + ucNextBufferToProcess++; - return xDataLen; + if( ucNextBufferToProcess >= archNUM_BUFFER_POINTERS ) + { + ucNextBufferToProcess = 0L; + } + } + + return xDataLen; } /*-----------------------------------------------------------*/ BaseType_t xNetifInit( void ) { -BaseType_t x; -pcap_if_t *pxAllNetworkInterfaces; + BaseType_t x; + pcap_if_t * pxAllNetworkInterfaces; - /* Allocate a free buffer to each buffer pointer. */ - for( x = 0; x < sizeof( pucEthernetBufferPointers ) / sizeof( unsigned char * ); x++ ) - { - pucEthernetBufferPointers[ x ] = &( ucEthernetBuffer[ x ][ 0 ] ); - } + /* Allocate a free buffer to each buffer pointer. */ + for( x = 0; x < sizeof( pucEthernetBufferPointers ) / sizeof( unsigned char * ); x++ ) + { + pucEthernetBufferPointers[ x ] = &( ucEthernetBuffer[ x ][ 0 ] ); + } - /* Start with uip_buf pointing to a buffer that is not referenced from the - pucEthernetBufferPointers[] array. */ - uip_buf = &( ucEthernetBuffer[ archNUM_BUFFERS - 1 ][ 0 ] ); + /* Start with uip_buf pointing to a buffer that is not referenced from the + * pucEthernetBufferPointers[] array. */ + uip_buf = &( ucEthernetBuffer[ archNUM_BUFFERS - 1 ][ 0 ] ); - /* Query the computer the simulation is being executed on to find the - network interfaces it has installed. */ - pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces(); - - /* Open the network interface. The number of the interface to be opened is - set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h. - Calling this function will set the pxOpenedInterfaceHandle variable. If, - after calling this function, pxOpenedInterfaceHandle is equal to NULL, then - the interface could not be opened. */ - if( pxAllNetworkInterfaces != NULL ) - { - prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces ); - } - + /* Query the computer the simulation is being executed on to find the + * network interfaces it has installed. */ + pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces(); - return x; + /* Open the network interface. The number of the interface to be opened is + * set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h. + * Calling this function will set the pxOpenedInterfaceHandle variable. If, + * after calling this function, pxOpenedInterfaceHandle is equal to NULL, then + * the interface could not be opened. */ + if( pxAllNetworkInterfaces != NULL ) + { + prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces ); + } + + return x; } /*-----------------------------------------------------------*/ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void ) -{ -pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface; -long lInterfaceNumber = 1; +{ + pcap_if_t * pxAllNetworkInterfaces = NULL, * xInterface; + long lInterfaceNumber = 1; if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 ) { @@ -162,174 +162,176 @@ long lInterfaceNumber = 1; pxAllNetworkInterfaces = NULL; } - if( pxAllNetworkInterfaces != NULL ) - { - /* Print out the list of network interfaces. The first in the list - is interface '1', not interface '0'. */ - for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next ) - { - printf( "%d. %s", lInterfaceNumber, xInterface->name ); - - if( xInterface->description != NULL ) - { - printf( " (%s)\r\n", xInterface->description ); - } - else - { - printf( " (No description available)\r\n") ; - } - - lInterfaceNumber++; - } - } + if( pxAllNetworkInterfaces != NULL ) + { + /* Print out the list of network interfaces. The first in the list + * is interface '1', not interface '0'. */ + for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next ) + { + printf( "%d. %s", lInterfaceNumber, xInterface->name ); + + if( xInterface->description != NULL ) + { + printf( " (%s)\r\n", xInterface->description ); + } + else + { + printf( " (No description available)\r\n" ); + } + + lInterfaceNumber++; + } + } if( lInterfaceNumber == 1 ) { - /* The interface number was never incremented, so the above for() loop - did not execute meaning no interfaces were found. */ + /* The interface number was never incremented, so the above for() loop + * did not execute meaning no interfaces were found. */ printf( " \r\nNo network interfaces were found.\r\n" ); pxAllNetworkInterfaces = NULL; } - printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" ); - printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE ); - + printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" ); + printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE ); + if( ( configNETWORK_INTERFACE_TO_USE < 1L ) || ( configNETWORK_INTERFACE_TO_USE > lInterfaceNumber ) ) { - printf("\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" ); - - if( pxAllNetworkInterfaces != NULL ) - { - /* Free the device list, as no devices are going to be opened. */ - pcap_freealldevs( pxAllNetworkInterfaces ); - pxAllNetworkInterfaces = NULL; - } + printf( "\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" ); + + if( pxAllNetworkInterfaces != NULL ) + { + /* Free the device list, as no devices are going to be opened. */ + pcap_freealldevs( pxAllNetworkInterfaces ); + pxAllNetworkInterfaces = NULL; + } } - return pxAllNetworkInterfaces; + return pxAllNetworkInterfaces; } /*-----------------------------------------------------------*/ -static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces ) +static void prvOpenSelectedNetworkInterface( pcap_if_t * pxAllNetworkInterfaces ) { -pcap_if_t *xInterface; -long x; + pcap_if_t * xInterface; + long x; /* Walk the list of devices until the selected device is located. */ - xInterface = pxAllNetworkInterfaces; + xInterface = pxAllNetworkInterfaces; + for( x = 0L; x < ( configNETWORK_INTERFACE_TO_USE - 1L ); x++ ) - { - xInterface = xInterface->next; - } + { + xInterface = xInterface->next; + } /* Open the selected interface. */ - pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */ - UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */ - PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscious mode as the MAC and - IP address is going to be "simulated", and - not be the real MAC and IP address. This allows - trafic to the simulated IP address to be routed - to uIP, and trafic to the real IP address to be - routed to the Windows TCP/IP stack. */ - 0xfffffffL, /* The read time out. This is going to block - until data is available. */ - NULL, /* No authentication is required as this is - not a remote capture session. */ - cErrorBuffer - ); - - if ( pxOpenedInterfaceHandle == NULL ) + pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */ + UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */ + PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscuous mode as the MAC and + * IP address is going to be "simulated", and + * not be the real MAC and IP address. This allows + * traffic to the simulated IP address to be routed + * to uIP, and traffic to the real IP address to be + * routed to the Windows TCP/IP stack. */ + 0xfffffffL, /* The read time out. This is going to block + * until data is available. */ + NULL, /* No authentication is required as this is + * not a remote capture session. */ + cErrorBuffer + ); + + if( pxOpenedInterfaceHandle == NULL ) { printf( "\r\n%s is not supported by WinPcap and cannot be opened\r\n", xInterface->name ); } - else - { - /* Configure the capture filter to allow blocking reads, and to filter - out packets that are not of interest to this demo. */ - prvConfigureCaptureBehaviour(); - } + else + { + /* Configure the capture filter to allow blocking reads, and to filter + * out packets that are not of interest to this demo. */ + prvConfigureCaptureBehaviour(); + } - /* The device list is no longer required. */ - pcap_freealldevs( pxAllNetworkInterfaces ); + /* The device list is no longer required. */ + pcap_freealldevs( pxAllNetworkInterfaces ); } /*-----------------------------------------------------------*/ static void prvConfigureCaptureBehaviour( void ) { -struct bpf_program xFilterCode; -const long lMinBytesToCopy = 10L, lBlocking = 0L; -unsigned long ulNetMask; + struct bpf_program xFilterCode; + const long lMinBytesToCopy = 10L, lBlocking = 0L; + unsigned long ulNetMask; - /* Unblock a read as soon as anything is received. */ - pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy ); + /* Unblock a read as soon as anything is received. */ + pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy ); - /* Allow blocking. */ - pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer ); + /* Allow blocking. */ + pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer ); - /* Set up a filter so only the packets of interest are passed to the uIP - stack. cErrorBuffer is used for convenience to create the string. Don't - confuse this with an error message. */ - sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); + /* Set up a filter so only the packets of interest are passed to the uIP + * stack. cErrorBuffer is used for convenience to create the string. Don't + * confuse this with an error message. */ + sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); - ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0; + ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0; - if( pcap_compile(pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 ) + if( pcap_compile( pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 ) { - printf("\r\nThe packet filter string is invalid\r\n" ); + printf( "\r\nThe packet filter string is invalid\r\n" ); + } + else + { + if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 ) + { + printf( "\r\nAn error occurred setting the packet filter.\r\n" ); + } } - else - { - if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 ) - { - printf( "\r\nAn error occurred setting the packet filter.\r\n" ); - } - } - /* Create a task that simulates an interrupt in a real system. This will - block waiting for packets, then send a message to the uIP task when data - is available. */ - xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( configuIP_TASK_PRIORITY - 1 ), NULL ); + /* Create a task that simulates an interrupt in a real system. This will + * block waiting for packets, then send a message to the uIP task when data + * is available. */ + xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( ipconfigIP_TASK_PRIORITY - 1 ), NULL ); } /*-----------------------------------------------------------*/ -static void prvInterruptSimulator( void *pvParameters ) +static void prvInterruptSimulator( void * pvParameters ) { -static struct pcap_pkthdr *pxHeader; -const unsigned char *pucPacketData; -extern QueueHandle_t xEMACEventQueue; -const unsigned long ulRxEvent = uipETHERNET_RX_EVENT; -long lResult; + static struct pcap_pkthdr * pxHeader; + const unsigned char * pucPacketData; + extern QueueHandle_t xEMACEventQueue; + const unsigned long ulRxEvent = uipETHERNET_RX_EVENT; + long lResult; - /* Just to kill the compiler warning. */ - ( void ) pvParameters; + /* Just to kill the compiler warning. */ + ( void ) pvParameters; - for( ;; ) - { - /* Get the next packet. */ - lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData ); - if( lResult ) - { - /* Is the next buffer into which data should be placed free? */ - if( lLengthOfDataInBuffer[ ucNextBufferToFill ] == 0L ) - { - /* Copy the data from the captured packet into the buffer. */ - memcpy( pucEthernetBufferPointers[ ucNextBufferToFill ], pucPacketData, pxHeader->len ); + for( ; ; ) + { + /* Get the next packet. */ + lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData ); - /* Note the amount of data that was copied. */ - lLengthOfDataInBuffer[ ucNextBufferToFill ] = pxHeader->len; + if( lResult ) + { + /* Is the next buffer into which data should be placed free? */ + if( lLengthOfDataInBuffer[ ucNextBufferToFill ] == 0L ) + { + /* Copy the data from the captured packet into the buffer. */ + memcpy( pucEthernetBufferPointers[ ucNextBufferToFill ], pucPacketData, pxHeader->len ); - /* Move onto the next buffer, wrapping around if necessary. */ - ucNextBufferToFill++; - if( ucNextBufferToFill >= archNUM_BUFFER_POINTERS ) - { - ucNextBufferToFill = 0U; - } + /* Note the amount of data that was copied. */ + lLengthOfDataInBuffer[ ucNextBufferToFill ] = pxHeader->len; - /* Data was received and stored. Send a message to the uIP task - to let it know. */ - xQueueSendToBack( xEMACEventQueue, &ulRxEvent, portMAX_DELAY ); - } - } - } + /* Move onto the next buffer, wrapping around if necessary. */ + ucNextBufferToFill++; + + if( ucNextBufferToFill >= archNUM_BUFFER_POINTERS ) + { + ucNextBufferToFill = 0U; + } + + /* Data was received and stored. Send a message to the uIP task + * to let it know. */ + xQueueSendToBack( xEMACEventQueue, &ulRxEvent, portMAX_DELAY ); + } + } + } } - diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/ip6_misc.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/ip6_misc.h index 96724e43f..b74662176 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/ip6_misc.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/ip6_misc.h @@ -35,7 +35,7 @@ #endif #endif -#define IN_EXPERIMENTAL( a ) ( ( ( ( u_int32_t ) ( a ) ) & 0xf0000000 ) == 0xf0000000 ) +#define IN_EXPERIMENTAL( a ) ( ( ( ( u_int32_t ) ( a ) ) & 0xf0000000 ) == 0xf0000000 ) #define IN_LOOPBACKNET 127 diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/netif.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/netif.h index b017d930c..c06c0a9bf 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/netif.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/netif.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/bluetooth.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/bluetooth.h index 1216963e6..05332a3a5 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/bluetooth.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/bluetooth.h @@ -32,7 +32,7 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/bluetooth.h,v 1.1 2007/09/22 02:10:17 guy Exp $ */ - + #ifndef _PCAP_BLUETOOTH_STRUCTS_H__ #define _PCAP_BLUETOOTH_STRUCTS_H__ @@ -40,8 +40,9 @@ * Header prepended libpcap to each bluetooth h:4 frame. * fields are in network byte order */ -typedef struct _pcap_bluetooth_h4_header { - u_int32_t direction; /* if first bit is set direction is incoming */ +typedef struct _pcap_bluetooth_h4_header +{ + u_int32_t direction; /* if first bit is set direction is incoming */ } pcap_bluetooth_h4_header; diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/bpf.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/bpf.h index 96ff9e888..d53a87b2f 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/bpf.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/bpf.h @@ -53,45 +53,46 @@ #ifndef BPF_MAJOR_VERSION -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* BSD style release date */ -#define BPF_RELEASE 199606 + #define BPF_RELEASE 199606 -#ifdef MSDOS /* must be 32-bit */ -typedef long bpf_int32; -typedef unsigned long bpf_u_int32; -#else -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #ifdef MSDOS /* must be 32-bit */ + typedef long bpf_int32; + typedef unsigned long bpf_u_int32; + #else + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif /* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + #ifndef __NetBSD__ + #define BPF_ALIGNMENT sizeof( bpf_int32 ) + #else + #define BPF_ALIGNMENT sizeof( long ) + #endif + #define BPF_WORDALIGN( x ) ( ( ( x ) + ( BPF_ALIGNMENT - 1 ) ) & ~( BPF_ALIGNMENT - 1 ) ) -#define BPF_MAXBUFSIZE 0x8000 -#define BPF_MINBUFSIZE 32 + #define BPF_MAXBUFSIZE 0x8000 + #define BPF_MINBUFSIZE 32 /* * Structure for "pcap_compile()", "pcap_setfilter()", etc.. */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - + struct bpf_program + { + u_int bf_len; + struct bpf_insn * bf_insns; + }; + /* - * Struct return by BIOCVERSION. This represents the version number of + * Struct return by BIOCVERSION. This represents the version number of * the filter language described by the instruction encodings below. * bpf understands a program iff kernel_major == filter_major && * kernel_minor >= filter_minor, that is, if the value returned by the @@ -101,13 +102,14 @@ struct bpf_program { * may be accepted haphazardly. * It has nothing to do with the source code version. */ -struct bpf_version { - u_short bv_major; - u_short bv_minor; -}; + struct bpf_version + { + u_short bv_major; + u_short bv_minor; + }; /* Current version number of filter architecture. */ -#define BPF_MAJOR_VERSION 1 -#define BPF_MINOR_VERSION 1 + #define BPF_MAJOR_VERSION 1 + #define BPF_MINOR_VERSION 1 /* * Data-link level type codes. @@ -125,17 +127,17 @@ struct bpf_version { * These are the types that are the same on all platforms, and that * have been defined by for ages. */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* 802.5 Token Ring */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ + #define DLT_NULL 0 /* BSD loopback encapsulation */ + #define DLT_EN10MB 1 /* Ethernet (10Mb) */ + #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ + #define DLT_AX25 3 /* Amateur Radio AX.25 */ + #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ + #define DLT_CHAOS 5 /* Chaos */ + #define DLT_IEEE802 6 /* 802.5 Token Ring */ + #define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ + #define DLT_SLIP 8 /* Serial Line IP */ + #define DLT_PPP 9 /* Point-to-point Protocol */ + #define DLT_FDDI 10 /* FDDI */ /* * These are types that are different on some platforms, and that @@ -146,13 +148,13 @@ struct bpf_version { * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, * but I don't know what the right #define is for BSD/OS. */ -#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + #define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif + #ifdef __OpenBSD__ + #define DLT_RAW 14 /* raw IP */ + #else + #define DLT_RAW 12 /* raw IP */ + #endif /* * Given that the only OS that currently generates BSD/OS SLIP or PPP @@ -160,15 +162,15 @@ struct bpf_version { * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they * didn't. So it goes. */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif + #if defined( __NetBSD__ ) || defined( __FreeBSD__ ) + #ifndef DLT_SLIP_BSDOS + #define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ + #endif + #else + #define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ + #endif /* * 17 is used for DLT_OLD_PFLOG in OpenBSD; @@ -176,21 +178,21 @@ struct bpf_version { * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. */ -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + #define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ /* * Apparently Redback uses this for its SmartEdge 400/800. I hope * nobody else decided to use it, too. */ -#define DLT_REDBACK_SMARTEDGE 32 + #define DLT_REDBACK_SMARTEDGE 32 /* * These values are defined by NetBSD; other platforms should refrain from * using them for other purposes, so that NetBSD savefiles with link * types of 50 or 51 can be read as this type on all platforms. */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + #define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ + #define DLT_PPP_ETHER 51 /* PPP over Ethernet */ /* * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses @@ -199,7 +201,7 @@ struct bpf_version { * Ethernet type, and 36 bytes that appear to be 0 in at least one capture * I've seen. */ -#define DLT_SYMANTEC_FIREWALL 99 + #define DLT_SYMANTEC_FIREWALL 99 /* * Values between 100 and 103 are used in capture file headers as @@ -221,10 +223,10 @@ struct bpf_version { * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, * for source compatibility with programs written for libpcap 0.5. */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC + #define DLT_C_HDLC 104 /* Cisco HDLC */ + #define DLT_CHDLC DLT_C_HDLC -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + #define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ /* * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, @@ -239,7 +241,7 @@ struct bpf_version { * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header * (DLCI, etc.). */ -#define DLT_FRELAY 107 + #define DLT_FRELAY 107 /* * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except @@ -248,22 +250,22 @@ struct bpf_version { * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so * we don't use 12 for it in OSes other than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_LOOP 12 -#else -#define DLT_LOOP 108 -#endif + #ifdef __OpenBSD__ + #define DLT_LOOP 12 + #else + #define DLT_LOOP 108 + #endif /* * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other * than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_ENC 13 -#else -#define DLT_ENC 109 -#endif + #ifdef __OpenBSD__ + #define DLT_ENC 13 + #else + #define DLT_ENC 109 + #endif /* * Values between 110 and 112 are reserved for use in capture file headers @@ -275,22 +277,22 @@ struct bpf_version { /* * This is for Linux cooked sockets. */ -#define DLT_LINUX_SLL 113 + #define DLT_LINUX_SLL 113 /* * Apple LocalTalk hardware. */ -#define DLT_LTALK 114 + #define DLT_LTALK 114 /* * Acorn Econet. */ -#define DLT_ECONET 115 + #define DLT_ECONET 115 /* * Reserved for use with OpenBSD ipfilter. */ -#define DLT_IPFILTER 116 + #define DLT_IPFILTER 116 /* * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 @@ -298,34 +300,34 @@ struct bpf_version { * * XXX: is there a conflict with DLT_PFSYNC 18 as well? */ -#ifdef __OpenBSD__ -#define DLT_OLD_PFLOG 17 -#define DLT_PFSYNC 18 -#endif -#define DLT_PFLOG 117 + #ifdef __OpenBSD__ + #define DLT_OLD_PFLOG 17 + #define DLT_PFSYNC 18 + #endif + #define DLT_PFLOG 117 /* * Registered for Cisco-internal use. */ -#define DLT_CISCO_IOS 118 + #define DLT_CISCO_IOS 118 /* * For 802.11 cards using the Prism II chips, with a link-layer * header including Prism monitor mode information plus an 802.11 * header. */ -#define DLT_PRISM_HEADER 119 + #define DLT_PRISM_HEADER 119 /* * Reserved for Aironet 802.11 cards, with an Aironet link-layer header * (see Doug Ambrisko's FreeBSD patches). */ -#define DLT_AIRONET_HEADER 120 + #define DLT_AIRONET_HEADER 120 /* * Reserved for Siemens HiPath HDLC. */ -#define DLT_HHDLC 121 + #define DLT_HHDLC 121 /* * This is for RFC 2625 IP-over-Fibre Channel. @@ -335,7 +337,7 @@ struct bpf_version { * where the link-layer header starts with an RFC 2625 Network_Header * field. */ -#define DLT_IP_OVER_FC 122 + #define DLT_IP_OVER_FC 122 /* * This is for Full Frontal ATM on Solaris with SunATM, with a @@ -351,22 +353,22 @@ struct bpf_version { * and the like don't have to infer the presence or absence of a * pseudo-header and the form of the pseudo-header. */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ + #define DLT_SUNATM 123 /* Solaris+SunATM */ -/* +/* * Reserved as per request from Kent Dahlgren * for private use. */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + #define DLT_RIO 124 /* RapidIO */ + #define DLT_PCI_EXP 125 /* PCI Express */ + #define DLT_AURORA 126 /* Xilinx Aurora link layer */ /* * Header for 802.11 plus a number of bits of link-layer information * including radio information, used by some recent BSD drivers as * well as the madwifi Atheros driver for Linux. */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + #define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ /* * Reserved for the TZSP encapsulation, as per request from @@ -376,7 +378,7 @@ struct bpf_version { * with the packet, e.g. signal strength and channel * for 802.11 packets. */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + #define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ /* * BSD's ARCNET headers have the source host, destination host, @@ -389,7 +391,7 @@ struct bpf_version { * * We therefore have to have separate DLT_ values for them. */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ + #define DLT_ARCNET_LINUX 129 /* ARCNET */ /* * Juniper-private data link types, as per request from @@ -397,14 +399,14 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 + #define DLT_JUNIPER_MLPPP 130 + #define DLT_JUNIPER_MLFR 131 + #define DLT_JUNIPER_ES 132 + #define DLT_JUNIPER_GGSN 133 + #define DLT_JUNIPER_MFR 134 + #define DLT_JUNIPER_ATM2 135 + #define DLT_JUNIPER_SERVICES 136 + #define DLT_JUNIPER_ATM1 137 /* * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund @@ -421,21 +423,21 @@ struct bpf_version { * with "firewire_type" being an Ethernet type value, rather than, * for example, raw GASP frames being handed up. */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 + #define DLT_APPLE_IP_OVER_IEEE1394 138 /* * Various SS7 encapsulations, as per a request from Jeff Morriss * and subsequent discussions. */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + #define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ + #define DLT_MTP2 140 /* MTP2, without pseudo-header */ + #define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ + #define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ /* * DOCSIS MAC frames. */ -#define DLT_DOCSIS 143 + #define DLT_DOCSIS 143 /* * Linux-IrDA packets. Protocol defined at http://www.irda.org. @@ -446,19 +448,19 @@ struct bpf_version { * interface (irdaX), but not on a raw serial port. * Note the capture is done in "Linux-cooked" mode, so each packet include * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or + * decoding is dependant on the direction of the packet (incoming or * outgoing). * When/if other platform implement IrDA capture, we may revisit the * issue and define a real DLT_IRDA... * Jean II */ -#define DLT_LINUX_IRDA 144 + #define DLT_LINUX_IRDA 144 /* * Reserved for IBM SP switch and IBM Next Federation switch. */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 + #define DLT_IBM_SP 145 + #define DLT_IBM_SN 146 /* * Reserved for private use. If you have some link-layer header type @@ -485,22 +487,22 @@ struct bpf_version { * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, * as per the comment above, and use the type you're given. */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 + #define DLT_USER0 147 + #define DLT_USER1 148 + #define DLT_USER2 149 + #define DLT_USER3 150 + #define DLT_USER4 151 + #define DLT_USER5 152 + #define DLT_USER6 153 + #define DLT_USER7 154 + #define DLT_USER8 155 + #define DLT_USER9 156 + #define DLT_USER10 157 + #define DLT_USER11 158 + #define DLT_USER12 159 + #define DLT_USER13 160 + #define DLT_USER14 161 + #define DLT_USER15 162 /* * For future use with 802.11 captures - defined by AbsoluteValue @@ -512,7 +514,7 @@ struct bpf_version { * but it might be used by some non-AVS drivers now or in the * future. */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + #define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ /* * Juniper-private data link type, as per request from @@ -520,12 +522,12 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MONITOR 164 + #define DLT_JUNIPER_MONITOR 164 /* * Reserved for BACnet MS/TP. */ -#define DLT_BACNET_MS_TP 165 + #define DLT_BACNET_MS_TP 165 /* * Another PPP variant as per request from Karsten Keil . @@ -538,17 +540,17 @@ struct bpf_version { * input packets such as port scans, packets from old lost connections, * etc. to force the connection to stay up). * - * The first byte of the PPP header (0xff03) is modified to accomodate + * The first byte of the PPP header (0xff03) is modified to accommodate * the direction - 0x00 = IN, 0x01 = OUT. */ -#define DLT_PPP_PPPD 166 + #define DLT_PPP_PPPD 166 /* * Names for backwards compatibility with older versions of some PPP * software; new software should use DLT_PPP_PPPD. */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + #define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD + #define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD /* * Juniper-private data link type, as per request from @@ -556,26 +558,26 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, cookies, etc.. */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 + #define DLT_JUNIPER_PPPOE 167 + #define DLT_JUNIPER_PPPOE_ATM 168 -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + #define DLT_GPRS_LLC 169 /* GPRS LLC */ + #define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ + #define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ /* * Requested by Oolan Zimmer for use in Gcom's T1/E1 line * monitoring equipment. */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 + #define DLT_GCOM_T1E1 172 + #define DLT_GCOM_SERIAL 173 /* * Juniper-private data link type, as per request from * Hannes Gredler . The DLT_ is used * for internal communication to Physical Interface Cards (PIC) */ -#define DLT_JUNIPER_PIC_PEER 174 + #define DLT_JUNIPER_PIC_PEER 174 /* * Link types requested by Gregor Maier of Endace @@ -583,8 +585,8 @@ struct bpf_version { * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of * the link-layer header. */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ + #define DLT_ERF_ETH 175 /* Ethernet */ + #define DLT_ERF_POS 176 /* Packet-over-SONET */ /* * Requested by Daniele Orlandi for raw LAPD @@ -592,32 +594,32 @@ struct bpf_version { * includes additional information before the LAPD header, so it's * not necessarily a generic LAPD header. */ -#define DLT_LINUX_LAPD 177 + #define DLT_LINUX_LAPD 177 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ are used for prepending meta-information * like interface index, interface name * before standard Ethernet, PPP, Frelay & C-HDLC Frames */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 + #define DLT_JUNIPER_ETHER 178 + #define DLT_JUNIPER_PPP 179 + #define DLT_JUNIPER_FRELAY 180 + #define DLT_JUNIPER_CHDLC 181 /* * Multi Link Frame Relay (FRF.16) */ -#define DLT_MFR 182 + #define DLT_MFR 182 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * voice Adapter Card (PIC) */ -#define DLT_JUNIPER_VP 183 + #define DLT_JUNIPER_VP 183 /* * Arinc 429 frames. @@ -626,38 +628,38 @@ struct bpf_version { * More documentation on Arinc 429 can be found at * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf */ -#define DLT_A429 184 + #define DLT_A429 184 /* * Arinc 653 Interpartition Communication messages. * DLT_ requested by Gianluca Varenni . * Please refer to the A653-1 standard for more information. */ -#define DLT_A653_ICM 185 + #define DLT_A653_ICM 185 /* * USB packets, beginning with a USB setup header; requested by * Paolo Abeni . */ -#define DLT_USB 186 + #define DLT_USB 186 /* * Bluetooth HCI UART transport layer (part H:4); requested by * Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4 187 + #define DLT_BLUETOOTH_HCI_H4 187 /* * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz * . */ -#define DLT_IEEE802_16_MAC_CPS 188 + #define DLT_IEEE802_16_MAC_CPS 188 /* * USB packets, beginning with a Linux USB header; requested by * Paolo Abeni . */ -#define DLT_USB_LINUX 189 + #define DLT_USB_LINUX 189 /* * Controller Area Network (CAN) v. 2.0B packets. @@ -666,79 +668,79 @@ struct bpf_version { * More documentation on the CAN v2.0B frames can be found at * http://www.can-cia.org/downloads/?269 */ -#define DLT_CAN20B 190 + #define DLT_CAN20B 190 /* * IEEE 802.15.4, with address fields padded, as is done by Linux * drivers; requested by Juergen Schimmer. */ -#define DLT_IEEE802_15_4_LINUX 191 + #define DLT_IEEE802_15_4_LINUX 191 /* * Per Packet Information encapsulated packets. * DLT_ requested by Gianluca Varenni . */ -#define DLT_PPI 192 + #define DLT_PPI 192 /* * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; * requested by Charles Clancy. */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + #define DLT_IEEE802_16_MAC_CPS_RADIO 193 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * integrated service module (ISM). */ -#define DLT_JUNIPER_ISM 194 + #define DLT_JUNIPER_ISM 194 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no * nothing); requested by Mikko Saarnivala . */ -#define DLT_IEEE802_15_4 195 + #define DLT_IEEE802_15_4 195 /* * Various link-layer types, with a pseudo-header, for SITA * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). */ -#define DLT_SITA 196 + #define DLT_SITA 196 /* * Various link-layer types, with a pseudo-header, for Endace DAG cards; * encapsulates Endace ERF records. Requested by Stephen Donnelly * . */ -#define DLT_ERF 197 + #define DLT_ERF 197 /* * Special header prepended to Ethernet packets when capturing from a * u10 Networks board. Requested by Phil Mulholland * . */ -#define DLT_RAIF1 198 + #define DLT_RAIF1 198 /* * IPMB packet for IPMI, beginning with the I2C slave address, followed * by the netFn and LUN, etc.. Requested by Chanthy Toeung * . */ -#define DLT_IPMB 199 + #define DLT_IPMB 199 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for capturing data on a secure tunnel interface. */ -#define DLT_JUNIPER_ST 200 + #define DLT_JUNIPER_ST 200 /* * Bluetooth HCI UART transport layer (part H:4), with pseudo-header * that includes direction information; requested by Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + #define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 /* * AX.25 packet with a 1-byte KISS header; see @@ -747,14 +749,14 @@ struct bpf_version { * * as per Richard Stearn . */ -#define DLT_AX25_KISS 202 + #define DLT_AX25_KISS 202 /* * LAPD packets from an ISDN channel, starting with the address field, * with no pseudo-header. * Requested by Varuna De Silva . */ -#define DLT_LAPD 203 + #define DLT_LAPD 203 /* * Variants of various link-layer headers, with a one-byte direction @@ -762,10 +764,10 @@ struct bpf_version { * non-zero (any non-zero value) means "sent by this host" - as per * Will Barker . */ -#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ -#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ -#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ -#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + #define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ + #define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ + #define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ + #define DLT_LAPB_WITH_DIR 207 /* LAPB */ /* * 208 is reserved for an as-yet-unspecified proprietary link-layer @@ -776,39 +778,39 @@ struct bpf_version { * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman * . */ -#define DLT_IPMB_LINUX 209 + #define DLT_IPMB_LINUX 209 /* * FlexRay automotive bus - http://www.flexray.com/ - as requested * by Hannes Kaelber . */ -#define DLT_FLEXRAY 210 + #define DLT_FLEXRAY 210 /* * Media Oriented Systems Transport (MOST) bus for multimedia * transport - http://www.mostcooperation.com/ - as requested * by Hannes Kaelber . */ -#define DLT_MOST 211 + #define DLT_MOST 211 /* * Local Interconnect Network (LIN) bus for vehicle networks - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber * . */ -#define DLT_LIN 212 + #define DLT_LIN 212 /* * X2E-private data link type used for serial line capture, * as requested by Hannes Kaelber . */ -#define DLT_X2E_SERIAL 213 + #define DLT_X2E_SERIAL 213 /* * X2E-private data link type used for the Xoraya data logger * family, as requested by Hannes Kaelber . */ -#define DLT_X2E_XORAYA 214 + #define DLT_X2E_XORAYA 214 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no @@ -819,7 +821,7 @@ struct bpf_version { * * Requested by Max Filippov . */ -#define DLT_IEEE802_15_4_NONASK_PHY 215 + #define DLT_IEEE802_15_4_NONASK_PHY 215 /* @@ -827,7 +829,7 @@ struct bpf_version { * a member of that class. A class value of 0 indicates a regular * DLT_/LINKTYPE_ value. */ -#define DLT_CLASS(x) ((x) & 0x03ff0000) + #define DLT_CLASS( x ) ( ( x ) & 0x03ff0000 ) /* * NetBSD-specific generic "raw" link type. The class value indicates @@ -836,99 +838,104 @@ struct bpf_version { * do not assume that they correspond to AF_ values for your operating * system. */ -#define DLT_CLASS_NETBSD_RAWAF 0x02240000 -#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) -#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) -#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + #define DLT_CLASS_NETBSD_RAWAF 0x02240000 + #define DLT_NETBSD_RAWAF( af ) ( DLT_CLASS_NETBSD_RAWAF | ( af ) ) + #define DLT_NETBSD_RAWAF_AF( x ) ( ( x ) & 0x0000ffff ) + #define DLT_IS_NETBSD_RAWAF( x ) ( DLT_CLASS( x ) == DLT_CLASS_NETBSD_RAWAF ) /* * The instruction encodings. */ /* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 + #define BPF_CLASS( code ) ( ( code ) & 0x07 ) + #define BPF_LD 0x00 + #define BPF_LDX 0x01 + #define BPF_ST 0x02 + #define BPF_STX 0x03 + #define BPF_ALU 0x04 + #define BPF_JMP 0x05 + #define BPF_RET 0x06 + #define BPF_MISC 0x07 /* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 + #define BPF_SIZE( code ) ( ( code ) & 0x18 ) + #define BPF_W 0x00 + #define BPF_H 0x08 + #define BPF_B 0x10 + #define BPF_MODE( code ) ( ( code ) & 0xe0 ) + #define BPF_IMM 0x00 + #define BPF_ABS 0x20 + #define BPF_IND 0x40 + #define BPF_MEM 0x60 + #define BPF_LEN 0x80 + #define BPF_MSH 0xa0 /* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 + #define BPF_OP( code ) ( ( code ) & 0xf0 ) + #define BPF_ADD 0x00 + #define BPF_SUB 0x10 + #define BPF_MUL 0x20 + #define BPF_DIV 0x30 + #define BPF_OR 0x40 + #define BPF_AND 0x50 + #define BPF_LSH 0x60 + #define BPF_RSH 0x70 + #define BPF_NEG 0x80 + #define BPF_JA 0x00 + #define BPF_JEQ 0x10 + #define BPF_JGT 0x20 + #define BPF_JGE 0x30 + #define BPF_JSET 0x40 + #define BPF_SRC( code ) ( ( code ) & 0x08 ) + #define BPF_K 0x00 + #define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 + #define BPF_RVAL( code ) ( ( code ) & 0x18 ) + #define BPF_A 0x10 /* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 + #define BPF_MISCOP( code ) ( ( code ) & 0xf8 ) + #define BPF_TAX 0x00 + #define BPF_TXA 0x80 /* * The instruction data structure. */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_u_int32 k; -}; + struct bpf_insn + { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; + }; /* * Macros for insn array initializers. */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + #define BPF_STMT( code, k ) { ( u_short ) ( code ), 0, 0, k } + #define BPF_JUMP( code, k, jt, jf ) { ( u_short ) ( code ), jt, jf, k } -#if __STDC__ || defined(__cplusplus) -extern int bpf_validate(const struct bpf_insn *, int); -extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -#else -extern int bpf_validate(); -extern u_int bpf_filter(); -#endif + #if __STDC__ || defined( __cplusplus ) + extern int bpf_validate( const struct bpf_insn *, + int ); + extern u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + #else + extern int bpf_validate(); + extern u_int bpf_filter(); + #endif /* * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). */ -#define BPF_MEMWORDS 16 + #define BPF_MEMWORDS 16 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef BPF_MAJOR_VERSION */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/namedb.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/namedb.h index 7f995bef5..c27e0986d 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/namedb.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/namedb.h @@ -34,11 +34,11 @@ */ #ifndef lib_pcap_namedb_h -#define lib_pcap_namedb_h + #define lib_pcap_namedb_h -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* * As returned by the pcap_next_etherent() @@ -47,43 +47,52 @@ extern "C" { * on systems that don't have support for /etc/ethers, we * export these hooks since they'll */ -struct pcap_etherent { - u_char addr[6]; - char name[122]; -}; -#ifndef PCAP_ETHERS_FILE -#define PCAP_ETHERS_FILE "/etc/ethers" -#endif -struct pcap_etherent *pcap_next_etherent(FILE *); -u_char *pcap_ether_hostton(const char*); -u_char *pcap_ether_aton(const char *); + struct pcap_etherent + { + u_char addr[ 6 ]; + char name[ 122 ]; + }; + #ifndef PCAP_ETHERS_FILE + #define PCAP_ETHERS_FILE "/etc/ethers" + #endif + struct pcap_etherent * pcap_next_etherent( FILE * ); + u_char * pcap_ether_hostton( const char * ); + u_char * pcap_ether_aton( const char * ); -bpf_u_int32 **pcap_nametoaddr(const char *); -#ifdef INET6 -struct addrinfo *pcap_nametoaddrinfo(const char *); -#endif -bpf_u_int32 pcap_nametonetaddr(const char *); + bpf_u_int32 ** pcap_nametoaddr( const char * ); + #ifdef INET6 + struct addrinfo * pcap_nametoaddrinfo( const char * ); + #endif + bpf_u_int32 pcap_nametonetaddr( const char * ); + + int pcap_nametoport( const char *, + int *, + int * ); + int pcap_nametoportrange( const char *, + int *, + int *, + int * ); + int pcap_nametoproto( const char * ); + int pcap_nametoeproto( const char * ); + int pcap_nametollc( const char * ); -int pcap_nametoport(const char *, int *, int *); -int pcap_nametoportrange(const char *, int *, int *, int *); -int pcap_nametoproto(const char *); -int pcap_nametoeproto(const char *); -int pcap_nametollc(const char *); /* * If a protocol is unknown, PROTO_UNDEF is returned. * Also, pcap_nametoport() returns the protocol along with the port number. * If there are ambiguous entried in /etc/services (i.e. domain * can be either tcp or udp) PROTO_UNDEF is returned. */ -#define PROTO_UNDEF -1 + #define PROTO_UNDEF -1 /* XXX move these to pcap-int.h? */ -int __pcap_atodn(const char *, bpf_u_int32 *); -int __pcap_atoin(const char *, bpf_u_int32 *); -u_short __pcap_nametodnaddr(const char *); + int __pcap_atodn( const char *, + bpf_u_int32 * ); + int __pcap_atoin( const char *, + bpf_u_int32 * ); + u_short __pcap_nametodnaddr( const char * ); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_namedb_h */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/pcap.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/pcap.h index ad8fc40ac..20113a9e7 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/pcap.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/pcap.h @@ -1,4 +1,5 @@ /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ + /* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. @@ -35,59 +36,59 @@ */ #ifndef lib_pcap_pcap_h -#define lib_pcap_pcap_h + #define lib_pcap_pcap_h -#if defined(WIN32) - #include -#elif defined(MSDOS) - #include - #include /* u_int, u_char etc. */ -#else /* UN*X */ - #include - #include -#endif /* WIN32/MSDOS/UN*X */ + #if defined( WIN32 ) + #include + #elif defined( MSDOS ) + #include + #include /* u_int, u_char etc. */ + #else /* UN*X */ + #include + #include + #endif /* WIN32/MSDOS/UN*X */ -#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include -#endif + #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H + #include + #endif -#include + #include -#ifdef HAVE_REMOTE - // We have to define the SOCKET here, although it has been defined in sockutils.h - // This is to avoid the distribution of the 'sockutils.h' file around - // (for example in the WinPcap developer's pack) - #ifndef SOCKET - #ifdef WIN32 - #define SOCKET unsigned int - #else - #define SOCKET int - #endif - #endif -#endif + #ifdef HAVE_REMOTE + /* We have to define the SOCKET here, although it has been defined in sockutils.h */ + /* This is to avoid the distribution of the 'sockutils.h' file around */ + /* (for example in the WinPcap developer's pack) */ + #ifndef SOCKET + #ifdef WIN32 + #define SOCKET unsigned int + #else + #define SOCKET int + #endif + #endif + #endif /* ifdef HAVE_REMOTE */ -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 + #define PCAP_VERSION_MAJOR 2 + #define PCAP_VERSION_MINOR 4 -#define PCAP_ERRBUF_SIZE 256 + #define PCAP_ERRBUF_SIZE 256 /* * Compatibility for systems that have a bpf.h that * predates the bpf typedefs for 64-bit support. */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #if BPF_RELEASE - 0 < 199406 + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; + typedef struct pcap pcap_t; + typedef struct pcap_dumper pcap_dumper_t; + typedef struct pcap_if pcap_if_t; + typedef struct pcap_addr pcap_addr_t; /* * The first record in the file contains saved values for some @@ -126,31 +127,33 @@ typedef struct pcap_addr pcap_addr_t; * so that future versions of libpcap and programs that use it (such as * tcpdump) will be able to read your new capture file format. */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; + struct pcap_file_header + { + bpf_u_int32 magic; + u_short version_major; + u_short version_minor; + bpf_int32 thiszone; /* gmt to local correction */ + bpf_u_int32 sigfigs; /* accuracy of timestamps */ + bpf_u_int32 snaplen; /* max length saved portion of each pkt */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ + }; /* * Macros for the value returned by pcap_datalink_ext(). - * + * * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro * gives the FCS length of packets in the capture. */ -#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) -#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) -#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) + #define LT_FCS_LENGTH_PRESENT( x ) ( ( x ) & 0x04000000 ) + #define LT_FCS_LENGTH( x ) ( ( ( x ) & 0xF0000000 ) >> 28 ) + #define LT_FCS_DATALINK_EXT( x ) ( ( ( ( x ) & 0xF ) << 28 ) | 0x04000000 ) -typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT -} pcap_direction_t; + typedef enum + { + PCAP_D_INOUT = 0, + PCAP_D_IN, + PCAP_D_OUT + } pcap_direction_t; /* * Generic per-packet information, as supplied by libpcap. @@ -164,85 +167,92 @@ typedef enum { * should supply the appropriate version of "struct timeval", even if * that's not what the underlying packet capture mechanism supplies. */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; + struct pcap_pkthdr + { + struct timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ + }; /* * As returned by the pcap_stats() */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface XXX not yet supported */ -#ifdef HAVE_REMOTE - u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ - u_int ps_sent; /* number of packets sent by the server on the network */ - u_int ps_netdrop; /* number of packets lost on the network */ -#endif /* HAVE_REMOTE */ -}; + struct pcap_stat + { + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface XXX not yet supported */ + #ifdef HAVE_REMOTE + u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ + u_int ps_sent; /* number of packets sent by the server on the network */ + u_int ps_netdrop; /* number of packets lost on the network */ + #endif /* HAVE_REMOTE */ + }; + + #ifdef MSDOS -#ifdef MSDOS /* * As returned by the pcap_stats_ex() */ -struct pcap_stat_ex { - u_long rx_packets; /* total packets received */ - u_long tx_packets; /* total packets transmitted */ - u_long rx_bytes; /* total bytes received */ - u_long tx_bytes; /* total bytes transmitted */ - u_long rx_errors; /* bad packets received */ - u_long tx_errors; /* packet transmit problems */ - u_long rx_dropped; /* no space in Rx buffers */ - u_long tx_dropped; /* no space available for Tx */ - u_long multicast; /* multicast packets received */ - u_long collisions; + struct pcap_stat_ex + { + u_long rx_packets; /* total packets received */ + u_long tx_packets; /* total packets transmitted */ + u_long rx_bytes; /* total bytes received */ + u_long tx_bytes; /* total bytes transmitted */ + u_long rx_errors; /* bad packets received */ + u_long tx_errors; /* packet transmit problems */ + u_long rx_dropped; /* no space in Rx buffers */ + u_long tx_dropped; /* no space available for Tx */ + u_long multicast; /* multicast packets received */ + u_long collisions; - /* detailed rx_errors: */ - u_long rx_length_errors; - u_long rx_over_errors; /* receiver ring buff overflow */ - u_long rx_crc_errors; /* recv'd pkt with crc error */ - u_long rx_frame_errors; /* recv'd frame alignment error */ - u_long rx_fifo_errors; /* recv'r fifo overrun */ - u_long rx_missed_errors; /* recv'r missed packet */ + /* detailed rx_errors: */ + u_long rx_length_errors; + u_long rx_over_errors; /* receiver ring buff overflow */ + u_long rx_crc_errors; /* recv'd pkt with crc error */ + u_long rx_frame_errors; /* recv'd frame alignment error */ + u_long rx_fifo_errors; /* recv'r fifo overrun */ + u_long rx_missed_errors; /* recv'r missed packet */ - /* detailed tx_errors */ - u_long tx_aborted_errors; - u_long tx_carrier_errors; - u_long tx_fifo_errors; - u_long tx_heartbeat_errors; - u_long tx_window_errors; - }; -#endif + /* detailed tx_errors */ + u_long tx_aborted_errors; + u_long tx_carrier_errors; + u_long tx_fifo_errors; + u_long tx_heartbeat_errors; + u_long tx_window_errors; + }; + #endif /* ifdef MSDOS */ /* * Item in a list of interfaces. */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; + struct pcap_if + { + struct pcap_if * next; + char * name; /* name to hand to "pcap_open_live()" */ + char * description; /* textual description of interface, or NULL */ + struct pcap_addr * addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ + }; -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ + #define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ /* * Representation of an interface address. */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; + struct pcap_addr + { + struct pcap_addr * next; + struct sockaddr * addr; /* address */ + struct sockaddr * netmask; /* netmask for that address */ + struct sockaddr * broadaddr; /* broadcast address for that address */ + struct sockaddr * dstaddr; /* P2P destination address for that address */ + }; -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); + typedef void (* pcap_handler)( u_char *, + const struct pcap_pkthdr *, + const u_char * ); /* * Error codes for the pcap API. @@ -250,158 +260,222 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, * failure of a call that returns these codes by checking for a * negative value. */ -#define PCAP_ERROR -1 /* generic error code */ -#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ -#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ -#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ -#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ -#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ -#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ -#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ -#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ + #define PCAP_ERROR -1 /* generic error code */ + #define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ + #define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ + #define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ + #define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ + #define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ + #define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ + #define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ + #define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ /* * Warning codes for the pcap API. * These will all be positive and non-zero, so they won't look like * errors. */ -#define PCAP_WARNING 1 /* generic warning code */ -#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ + #define PCAP_WARNING 1 /* generic warning code */ + #define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ -char *pcap_lookupdev(char *); -int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); + char * pcap_lookupdev( char * ); + int pcap_lookupnet( const char *, + bpf_u_int32 *, + bpf_u_int32 *, + char * ); -pcap_t *pcap_create(const char *, char *); -int pcap_set_snaplen(pcap_t *, int); -int pcap_set_promisc(pcap_t *, int); -int pcap_can_set_rfmon(pcap_t *); -int pcap_set_rfmon(pcap_t *, int); -int pcap_set_timeout(pcap_t *, int); -int pcap_set_buffer_size(pcap_t *, int); -int pcap_activate(pcap_t *); + pcap_t * pcap_create( const char *, + char * ); + int pcap_set_snaplen( pcap_t *, + int ); + int pcap_set_promisc( pcap_t *, + int ); + int pcap_can_set_rfmon( pcap_t * ); + int pcap_set_rfmon( pcap_t *, + int ); + int pcap_set_timeout( pcap_t *, + int ); + int pcap_set_buffer_size( pcap_t *, + int ); + int pcap_activate( pcap_t * ); -pcap_t *pcap_open_live(const char *, int, int, int, char *); -pcap_t *pcap_open_dead(int, int); -pcap_t *pcap_open_offline(const char *, char *); -#if defined(WIN32) -pcap_t *pcap_hopen_offline(intptr_t, char *); -#if !defined(LIBPCAP_EXPORTS) -#define pcap_fopen_offline(f,b) \ - pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) -#else /*LIBPCAP_EXPORTS*/ -static pcap_t *pcap_fopen_offline(FILE *, char *); -#endif -#else /*WIN32*/ -pcap_t *pcap_fopen_offline(FILE *, char *); -#endif /*WIN32*/ + pcap_t * pcap_open_live( const char *, + int, + int, + int, + char * ); + pcap_t * pcap_open_dead( int, + int ); + pcap_t * pcap_open_offline( const char *, + char * ); + #if defined( WIN32 ) + pcap_t * pcap_hopen_offline( intptr_t, + char * ); + #if !defined( LIBPCAP_EXPORTS ) + #define pcap_fopen_offline( f, b ) \ + pcap_hopen_offline( _get_osfhandle( _fileno( f ) ), b ) + #else /*LIBPCAP_EXPORTS*/ + static pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif + #else /*WIN32*/ + pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif /*WIN32*/ -void pcap_close(pcap_t *); -int pcap_loop(pcap_t *, int, pcap_handler, u_char *); -int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); -const u_char* - pcap_next(pcap_t *, struct pcap_pkthdr *); -int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); -void pcap_breakloop(pcap_t *); -int pcap_stats(pcap_t *, struct pcap_stat *); -int pcap_setfilter(pcap_t *, struct bpf_program *); -int pcap_setdirection(pcap_t *, pcap_direction_t); -int pcap_getnonblock(pcap_t *, char *); -int pcap_setnonblock(pcap_t *, int, char *); -int pcap_inject(pcap_t *, const void *, size_t); -int pcap_sendpacket(pcap_t *, const u_char *, int); -const char *pcap_statustostr(int); -const char *pcap_strerror(int); -char *pcap_geterr(pcap_t *); -void pcap_perror(pcap_t *, char *); -int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32); -int pcap_compile_nopcap(int, int, struct bpf_program *, - const char *, int, bpf_u_int32); -void pcap_freecode(struct bpf_program *); -int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *, - const u_char *); -int pcap_datalink(pcap_t *); -int pcap_datalink_ext(pcap_t *); -int pcap_list_datalinks(pcap_t *, int **); -int pcap_set_datalink(pcap_t *, int); -void pcap_free_datalinks(int *); -int pcap_datalink_name_to_val(const char *); -const char *pcap_datalink_val_to_name(int); -const char *pcap_datalink_val_to_description(int); -int pcap_snapshot(pcap_t *); -int pcap_is_swapped(pcap_t *); -int pcap_major_version(pcap_t *); -int pcap_minor_version(pcap_t *); + void pcap_close( pcap_t * ); + int pcap_loop( pcap_t *, + int, + pcap_handler, + u_char * ); + int pcap_dispatch( pcap_t *, + int, + pcap_handler, + u_char * ); + const u_char * pcap_next( pcap_t *, + struct pcap_pkthdr * ); + int pcap_next_ex( pcap_t *, + struct pcap_pkthdr **, + const u_char ** ); + void pcap_breakloop( pcap_t * ); + int pcap_stats( pcap_t *, + struct pcap_stat * ); + int pcap_setfilter( pcap_t *, + struct bpf_program * ); + int pcap_setdirection( pcap_t *, + pcap_direction_t ); + int pcap_getnonblock( pcap_t *, + char * ); + int pcap_setnonblock( pcap_t *, + int, + char * ); + int pcap_inject( pcap_t *, + const void *, + size_t ); + int pcap_sendpacket( pcap_t *, + const u_char *, + int ); + const char * pcap_statustostr( int ); + const char * pcap_strerror( int ); + char * pcap_geterr( pcap_t * ); + void pcap_perror( pcap_t *, + char * ); + int pcap_compile( pcap_t *, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + int pcap_compile_nopcap( int, + int, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + void pcap_freecode( struct bpf_program * ); + int pcap_offline_filter( struct bpf_program *, + const struct pcap_pkthdr *, + const u_char * ); + int pcap_datalink( pcap_t * ); + int pcap_datalink_ext( pcap_t * ); + int pcap_list_datalinks( pcap_t *, + int ** ); + int pcap_set_datalink( pcap_t *, + int ); + void pcap_free_datalinks( int * ); + int pcap_datalink_name_to_val( const char * ); + const char * pcap_datalink_val_to_name( int ); + const char * pcap_datalink_val_to_description( int ); + int pcap_snapshot( pcap_t * ); + int pcap_is_swapped( pcap_t * ); + int pcap_major_version( pcap_t * ); + int pcap_minor_version( pcap_t * ); /* XXX */ -FILE *pcap_file(pcap_t *); -int pcap_fileno(pcap_t *); + FILE * pcap_file( pcap_t * ); + int pcap_fileno( pcap_t * ); -pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); -pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); -FILE *pcap_dump_file(pcap_dumper_t *); -long pcap_dump_ftell(pcap_dumper_t *); -int pcap_dump_flush(pcap_dumper_t *); -void pcap_dump_close(pcap_dumper_t *); -void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); + pcap_dumper_t * pcap_dump_open( pcap_t *, + const char * ); + pcap_dumper_t * pcap_dump_fopen( pcap_t *, + FILE * fp ); + FILE * pcap_dump_file( pcap_dumper_t * ); + long pcap_dump_ftell( pcap_dumper_t * ); + int pcap_dump_flush( pcap_dumper_t * ); + void pcap_dump_close( pcap_dumper_t * ); + void pcap_dump( u_char *, + const struct pcap_pkthdr *, + const u_char * ); -int pcap_findalldevs(pcap_if_t **, char *); -void pcap_freealldevs(pcap_if_t *); + int pcap_findalldevs( pcap_if_t **, + char * ); + void pcap_freealldevs( pcap_if_t * ); -const char *pcap_lib_version(void); + const char * pcap_lib_version( void ); /* XXX this guy lives in the bpf tree */ -u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -int bpf_validate(const struct bpf_insn *f, int len); -char *bpf_image(const struct bpf_insn *, int); -void bpf_dump(const struct bpf_program *, int); + u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + int bpf_validate( const struct bpf_insn * f, + int len ); + char * bpf_image( const struct bpf_insn *, + int ); + void bpf_dump( const struct bpf_program *, + int ); -#if defined(WIN32) + #if defined( WIN32 ) /* * Win32 definitions */ -int pcap_setbuff(pcap_t *p, int dim); -int pcap_setmode(pcap_t *p, int mode); -int pcap_setmintocopy(pcap_t *p, int size); + int pcap_setbuff( pcap_t * p, + int dim ); + int pcap_setmode( pcap_t * p, + int mode ); + int pcap_setmintocopy( pcap_t * p, + int size ); -#ifdef WPCAP + #ifdef WPCAP /* Include file with the wpcap-specific extensions */ -#include -#endif /* WPCAP */ + #include + #endif /* WPCAP */ -#define MODE_CAPT 0 -#define MODE_STAT 1 -#define MODE_MON 2 + #define MODE_CAPT 0 + #define MODE_STAT 1 + #define MODE_MON 2 -#elif defined(MSDOS) + #elif defined( MSDOS ) /* * MS-DOS definitions */ -int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); -void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); -u_long pcap_mac_packets (void); + int pcap_stats_ex( pcap_t *, + struct pcap_stat_ex * ); + void pcap_set_wait( pcap_t * p, + void ( * yield )( void ), + int wait ); + u_long pcap_mac_packets( void ); -#else /* UN*X */ + #else /* UN*X */ /* * UN*X definitions */ -int pcap_get_selectable_fd(pcap_t *); + int pcap_get_selectable_fd( pcap_t * ); -#endif /* WIN32/MSDOS/UN*X */ + #endif /* WIN32/MSDOS/UN*X */ -#ifdef HAVE_REMOTE + #ifdef HAVE_REMOTE /* Includes most of the public stuff that is needed for the remote capture */ -#include -#endif /* HAVE_REMOTE */ + #include + #endif /* HAVE_REMOTE */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_pcap_h */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/sll.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/sll.h index e9d5452af..e5052236a 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/sll.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/sll.h @@ -79,15 +79,16 @@ /* * A DLT_LINUX_SLL fake link-layer header. */ -#define SLL_HDR_LEN 16 /* total header length */ -#define SLL_ADDRLEN 8 /* length of address field */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ -struct sll_header { - u_int16_t sll_pkttype; /* packet type */ - u_int16_t sll_hatype; /* link-layer address type */ - u_int16_t sll_halen; /* link-layer address length */ - u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ - u_int16_t sll_protocol; /* protocol */ +struct sll_header +{ + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[ SLL_ADDRLEN ]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ }; /* @@ -96,11 +97,11 @@ struct sll_header { * available even on systems other than Linux, and so that they * don't change even if the PACKET_ values change. */ -#define LINUX_SLL_HOST 0 -#define LINUX_SLL_BROADCAST 1 -#define LINUX_SLL_MULTICAST 2 -#define LINUX_SLL_OTHERHOST 3 -#define LINUX_SLL_OUTGOING 4 +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 /* * The LINUX_SLL_ values for "sll_protocol"; these correspond to the @@ -123,7 +124,7 @@ struct sll_header { * in the Linux "if_ether.h" will, I suspect, actually show up in * captures.) */ -#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ -#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ -#endif +#endif /* ifndef lib_pcap_sll_h */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/usb.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/usb.h index b1e3f5e56..44a3c9557 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/usb.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/usb.h @@ -32,36 +32,37 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $ */ - + #ifndef _PCAP_USB_STRUCTS_H__ #define _PCAP_USB_STRUCTS_H__ -/* +/* * possible transfer mode */ -#define URB_TRANSFER_IN 0x80 -#define URB_ISOCHRONOUS 0x0 -#define URB_INTERRUPT 0x1 -#define URB_CONTROL 0x2 -#define URB_BULK 0x3 +#define URB_TRANSFER_IN 0x80 +#define URB_ISOCHRONOUS 0x0 +#define URB_INTERRUPT 0x1 +#define URB_CONTROL 0x2 +#define URB_BULK 0x3 /* * possible event type */ -#define URB_SUBMIT 'S' -#define URB_COMPLETE 'C' -#define URB_ERROR 'E' +#define URB_SUBMIT 'S' +#define URB_COMPLETE 'C' +#define URB_ERROR 'E' /* * USB setup header as defined in USB specification. * Appears at the front of each packet in DLT_USB captures. */ -typedef struct _usb_setup { - u_int8_t bmRequestType; - u_int8_t bRequest; - u_int16_t wValue; - u_int16_t wIndex; - u_int16_t wLength; +typedef struct _usb_setup +{ + u_int8_t bmRequestType; + u_int8_t bRequest; + u_int16_t wValue; + u_int16_t wIndex; + u_int16_t wLength; } pcap_usb_setup; @@ -69,22 +70,23 @@ typedef struct _usb_setup { * Header prepended by linux kernel to each event. * Appears at the front of each packet in DLT_USB_LINUX captures. */ -typedef struct _usb_header { - u_int64_t id; - u_int8_t event_type; - u_int8_t transfer_type; - u_int8_t endpoint_number; - u_int8_t device_address; - u_int16_t bus_id; - char setup_flag;/*if !=0 the urb setup header is not present*/ - char data_flag; /*if !=0 no urb data is present*/ - int64_t ts_sec; - int32_t ts_usec; - int32_t status; - u_int32_t urb_len; - u_int32_t data_len; /* amount of urb data really present in this event*/ - pcap_usb_setup setup; +typedef struct _usb_header +{ + u_int64_t id; + u_int8_t event_type; + u_int8_t transfer_type; + u_int8_t endpoint_number; + u_int8_t device_address; + u_int16_t bus_id; + char setup_flag; /*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + u_int32_t urb_len; + u_int32_t data_len; /* amount of urb data really present in this event*/ + pcap_usb_setup setup; } pcap_usb_header; -#endif +#endif /* ifndef _PCAP_USB_STRUCTS_H__ */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/vlan.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/vlan.h index b0cb7949b..e9be8bd16 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/vlan.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/pcap/vlan.h @@ -36,11 +36,12 @@ #ifndef lib_pcap_vlan_h #define lib_pcap_vlan_h -struct vlan_tag { - u_int16_t vlan_tpid; /* ETH_P_8021Q */ - u_int16_t vlan_tci; /* VLAN TCI */ +struct vlan_tag +{ + u_int16_t vlan_tpid; /* ETH_P_8021Q */ + u_int16_t vlan_tci; /* VLAN TCI */ }; -#define VLAN_TAG_LEN 4 +#define VLAN_TAG_LEN 4 -#endif +#endif /* ifndef lib_pcap_vlan_h */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/remote-ext.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/remote-ext.h index e14198ca9..e6a3d3f84 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/remote-ext.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/remote-ext.h @@ -4,7 +4,7 @@ * All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions + * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright @@ -15,7 +15,7 @@ * 3. Neither the name of the Politecnico di Torino nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -45,7 +45,7 @@ #endif #ifdef __cplusplus - extern "C" { + extern "C" { #endif /*! @@ -204,7 +204,7 @@ #define PCAP_OPENFLAG_PROMISCUOUS 1 /*! - * \brief Defines if the data trasfer (in case of a remote + * \brief Defines if the data transfer (in case of a remote * capture) has to be done with UDP protocol. * * If it is '1' if you want a UDP data connection, '0' if you want @@ -232,7 +232,7 @@ * \brief Defines if the local adapter will capture its own generated traffic. * * This flag tells the underlying capture driver to drop the packets that were sent by itself. - * This is usefult when building applications like bridges, that should ignore the traffic + * This is useful when building applications like bridges, that should ignore the traffic * they just sent. */ #define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 @@ -324,7 +324,7 @@ /*! * - * \brief This structure keeps the information needed to autheticate + * \brief This structure keeps the information needed to authenticate * the user on a remote machine. * * The remote machine can either grant or refuse the access according @@ -397,7 +397,7 @@ -/*! Maximum lenght of an host name (needed for the RPCAP active mode) */ +/*! Maximum length of an host name (needed for the RPCAP active mode) */ #define RPCAP_HOSTLIST_SIZE 1024 @@ -465,7 +465,7 @@ /* End of remote capture functions */ #ifdef __cplusplus - } +} #endif diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleTCPEchoServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleTCPEchoServer.c index f0d1fd7de..0fcd28cfa 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleTCPEchoServer.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleTCPEchoServer.c @@ -1,246 +1,247 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * FreeRTOS tasks are used with FreeRTOS+TCP to create a TCP echo server on the - * standard echo port number (7). - * - * See the following web page for essential demo usage and configuration - * details: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Server.html - */ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "semphr.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" - -/* Remove the whole file if FreeRTOSIPConfig.h is set to exclude TCP. */ -#if( ipconfigUSE_TCP == 1 ) - -/* The maximum time to wait for a closing socket to close. */ -#define tcpechoSHUTDOWN_DELAY ( pdMS_TO_TICKS( 5000 ) ) - -/* The standard echo port number. */ -#define tcpechoPORT_NUMBER 7 - -/* If ipconfigUSE_TCP_WIN is 1 then the Tx sockets will use a buffer size set by -ipconfigTCP_TX_BUFFER_LENGTH, and the Tx window size will be -configECHO_SERVER_TX_WINDOW_SIZE times the buffer size. Note -ipconfigTCP_TX_BUFFER_LENGTH is set in FreeRTOSIPConfig.h as it is a standard TCP/IP -stack constant, whereas configECHO_SERVER_TX_WINDOW_SIZE is set in -FreeRTOSConfig.h as it is a demo application constant. */ -#ifndef configECHO_SERVER_TX_WINDOW_SIZE - #define configECHO_SERVER_TX_WINDOW_SIZE 2 -#endif - -/* If ipconfigUSE_TCP_WIN is 1 then the Rx sockets will use a buffer size set by -ipconfigTCP_RX_BUFFER_LENGTH, and the Rx window size will be -configECHO_SERVER_RX_WINDOW_SIZE times the buffer size. Note -ipconfigTCP_RX_BUFFER_LENGTH is set in FreeRTOSIPConfig.h as it is a standard TCP/IP -stack constant, whereas configECHO_SERVER_RX_WINDOW_SIZE is set in -FreeRTOSConfig.h as it is a demo application constant. */ -#ifndef configECHO_SERVER_RX_WINDOW_SIZE - #define configECHO_SERVER_RX_WINDOW_SIZE 2 -#endif - -/*-----------------------------------------------------------*/ - -/* - * Uses FreeRTOS+TCP to listen for incoming echo connections, creating a task - * to handle each connection. - */ -static void prvConnectionListeningTask( void *pvParameters ); - -/* - * Created by the connection listening task to handle a single connection. - */ -static void prvServerConnectionInstance( void *pvParameters ); - -/*-----------------------------------------------------------*/ - -/* Stores the stack size passed into vStartSimpleTCPServerTasks() so it can be -reused when the server listening task creates tasks to handle connections. */ -static uint16_t usUsedStackSize = 0; - -/*-----------------------------------------------------------*/ - -void vStartSimpleTCPServerTasks( uint16_t usStackSize, UBaseType_t uxPriority ) -{ - /* Create the TCP echo server. */ - xTaskCreate( prvConnectionListeningTask, "ServerListener", usStackSize, NULL, uxPriority + 1, NULL ); - - /* Remember the requested stack size so it can be re-used by the server - listening task when it creates tasks to handle connections. */ - usUsedStackSize = usStackSize; -} -/*-----------------------------------------------------------*/ - -static void prvConnectionListeningTask( void *pvParameters ) -{ -struct freertos_sockaddr xClient, xBindAddress; -Socket_t xListeningSocket, xConnectedSocket; -socklen_t xSize = sizeof( xClient ); -static const TickType_t xReceiveTimeOut = portMAX_DELAY; -const BaseType_t xBacklog = 20; - -#if( ipconfigUSE_TCP_WIN == 1 ) - WinProperties_t xWinProps; - - /* Fill in the buffer and window sizes that will be used by the socket. */ - xWinProps.lTxBufSize = ipconfigTCP_TX_BUFFER_LENGTH; - xWinProps.lTxWinSize = configECHO_SERVER_TX_WINDOW_SIZE; - xWinProps.lRxBufSize = ipconfigTCP_RX_BUFFER_LENGTH; - xWinProps.lRxWinSize = configECHO_SERVER_RX_WINDOW_SIZE; -#endif /* ipconfigUSE_TCP_WIN */ - - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; - - /* Attempt to open the socket. */ - xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); - configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); - - /* Set a time out so accept() will just wait for a connection. */ - FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); - - /* Set the window and buffer sizes. */ - #if( ipconfigUSE_TCP_WIN == 1 ) - { - FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); - } - #endif /* ipconfigUSE_TCP_WIN */ - - /* Bind the socket to the port that the client task will send to, then - listen for incoming connections. */ - xBindAddress.sin_port = tcpechoPORT_NUMBER; - xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); - xBindAddress.sin_family = FREERTOS_AF_INET; - FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); - FreeRTOS_listen( xListeningSocket, xBacklog ); - - for( ;; ) - { - /* Wait for a client to connect. */ - xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize ); - configASSERT( xConnectedSocket != FREERTOS_INVALID_SOCKET ); - - /* Spawn a task to handle the connection. */ - xTaskCreate( prvServerConnectionInstance, "EchoServer", usUsedStackSize, ( void * ) xConnectedSocket, tskIDLE_PRIORITY, NULL ); - } -} -/*-----------------------------------------------------------*/ - -static void prvServerConnectionInstance( void *pvParameters ) -{ -int32_t lBytes, lSent, lTotalSent; -Socket_t xConnectedSocket; -static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 ); -static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 5000 ); -TickType_t xTimeOnShutdown; -uint8_t *pucRxBuffer; - - xConnectedSocket = ( Socket_t ) pvParameters; - - /* Attempt to create the buffer used to receive the string to be echoed - back. This could be avoided using a zero copy interface that just returned - the same buffer. */ - pucRxBuffer = ( uint8_t * ) pvPortMalloc( ipconfigTCP_MSS ); - - if( pucRxBuffer != NULL ) - { - FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); - FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xReceiveTimeOut ) ); - - for( ;; ) - { - /* Zero out the receive array so there is NULL at the end of the string - when it is printed out. */ - memset( pucRxBuffer, 0x00, ipconfigTCP_MSS ); - - /* Receive data on the socket. */ - lBytes = FreeRTOS_recv( xConnectedSocket, pucRxBuffer, ipconfigTCP_MSS, 0 ); - - /* If data was received, echo it back. */ - if( lBytes >= 0 ) - { - lSent = 0; - lTotalSent = 0; - - /* Call send() until all the data has been sent. */ - while( ( lSent >= 0 ) && ( lTotalSent < lBytes ) ) - { - lSent = FreeRTOS_send( xConnectedSocket, pucRxBuffer, lBytes - lTotalSent, 0 ); - lTotalSent += lSent; - } - - if( lSent < 0 ) - { - /* Socket closed? */ - break; - } - } - else - { - /* Socket closed? */ - break; - } - } - } - - /* Initiate a shutdown in case it has not already been initiated. */ - FreeRTOS_shutdown( xConnectedSocket, FREERTOS_SHUT_RDWR ); - - /* Wait for the shutdown to take effect, indicated by FreeRTOS_recv() - returning an error. */ - xTimeOnShutdown = xTaskGetTickCount(); - do - { - if( FreeRTOS_recv( xConnectedSocket, pucRxBuffer, ipconfigTCP_MSS, 0 ) < 0 ) - { - break; - } - } while( ( xTaskGetTickCount() - xTimeOnShutdown ) < tcpechoSHUTDOWN_DELAY ); - - /* Finished with the socket, buffer, the task. */ - vPortFree( pucRxBuffer ); - FreeRTOS_closesocket( xConnectedSocket ); - - vTaskDelete( NULL ); -} -/*-----------------------------------------------------------*/ - -/* The whole file is excluded if TCP is not compiled in. */ -#endif /* ipconfigUSE_TCP */ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * FreeRTOS tasks are used with FreeRTOS+TCP to create a TCP echo server on the + * standard echo port number (7). + * + * See the following web page for essential demo usage and configuration + * details: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Server.html + */ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" + +/* Remove the whole file if FreeRTOSIPConfig.h is set to exclude TCP. */ +#if ( ipconfigUSE_TCP == 1 ) + +/* The maximum time to wait for a closing socket to close. */ + #define tcpechoSHUTDOWN_DELAY ( pdMS_TO_TICKS( 5000 ) ) + +/* The standard echo port number. */ + #define tcpechoPORT_NUMBER 7 + +/* If ipconfigUSE_TCP_WIN is 1 then the Tx sockets will use a buffer size set by + * ipconfigTCP_TX_BUFFER_LENGTH, and the Tx window size will be + * configECHO_SERVER_TX_WINDOW_SIZE times the buffer size. Note + * ipconfigTCP_TX_BUFFER_LENGTH is set in FreeRTOSIPConfig.h as it is a standard TCP/IP + * stack constant, whereas configECHO_SERVER_TX_WINDOW_SIZE is set in + * FreeRTOSConfig.h as it is a demo application constant. */ + #ifndef configECHO_SERVER_TX_WINDOW_SIZE + #define configECHO_SERVER_TX_WINDOW_SIZE 2 + #endif + +/* If ipconfigUSE_TCP_WIN is 1 then the Rx sockets will use a buffer size set by + * ipconfigTCP_RX_BUFFER_LENGTH, and the Rx window size will be + * configECHO_SERVER_RX_WINDOW_SIZE times the buffer size. Note + * ipconfigTCP_RX_BUFFER_LENGTH is set in FreeRTOSIPConfig.h as it is a standard TCP/IP + * stack constant, whereas configECHO_SERVER_RX_WINDOW_SIZE is set in + * FreeRTOSConfig.h as it is a demo application constant. */ + #ifndef configECHO_SERVER_RX_WINDOW_SIZE + #define configECHO_SERVER_RX_WINDOW_SIZE 2 + #endif + +/*-----------------------------------------------------------*/ + +/* + * Uses FreeRTOS+TCP to listen for incoming echo connections, creating a task + * to handle each connection. + */ + static void prvConnectionListeningTask( void * pvParameters ); + +/* + * Created by the connection listening task to handle a single connection. + */ + static void prvServerConnectionInstance( void * pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Stores the stack size passed into vStartSimpleTCPServerTasks() so it can be + * reused when the server listening task creates tasks to handle connections. */ + static uint16_t usUsedStackSize = 0; + +/*-----------------------------------------------------------*/ + + void vStartSimpleTCPServerTasks( uint16_t usStackSize, + UBaseType_t uxPriority ) + { + /* Create the TCP echo server. */ + xTaskCreate( prvConnectionListeningTask, "ServerListener", usStackSize, NULL, uxPriority + 1, NULL ); + + /* Remember the requested stack size so it can be re-used by the server + * listening task when it creates tasks to handle connections. */ + usUsedStackSize = usStackSize; + } +/*-----------------------------------------------------------*/ + + static void prvConnectionListeningTask( void * pvParameters ) + { + struct freertos_sockaddr xClient, xBindAddress; + Socket_t xListeningSocket, xConnectedSocket; + socklen_t xSize = sizeof( xClient ); + static const TickType_t xReceiveTimeOut = portMAX_DELAY; + const BaseType_t xBacklog = 20; + + #if ( ipconfigUSE_TCP_WIN == 1 ) + WinProperties_t xWinProps; + + /* Fill in the buffer and window sizes that will be used by the socket. */ + xWinProps.lTxBufSize = ipconfigTCP_TX_BUFFER_LENGTH; + xWinProps.lTxWinSize = configECHO_SERVER_TX_WINDOW_SIZE; + xWinProps.lRxBufSize = ipconfigTCP_RX_BUFFER_LENGTH; + xWinProps.lRxWinSize = configECHO_SERVER_RX_WINDOW_SIZE; + #endif /* ipconfigUSE_TCP_WIN */ + + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; + + /* Attempt to open the socket. */ + xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); + configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); + + /* Set a time out so accept() will just wait for a connection. */ + FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); + + /* Set the window and buffer sizes. */ + #if ( ipconfigUSE_TCP_WIN == 1 ) + { + FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); + } + #endif /* ipconfigUSE_TCP_WIN */ + + /* Bind the socket to the port that the client task will send to, then + * listen for incoming connections. */ + xBindAddress.sin_port = tcpechoPORT_NUMBER; + xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); + xBindAddress.sin_family = FREERTOS_AF_INET; + FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); + FreeRTOS_listen( xListeningSocket, xBacklog ); + + for( ; ; ) + { + /* Wait for a client to connect. */ + xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize ); + configASSERT( xConnectedSocket != FREERTOS_INVALID_SOCKET ); + + /* Spawn a task to handle the connection. */ + xTaskCreate( prvServerConnectionInstance, "EchoServer", usUsedStackSize, ( void * ) xConnectedSocket, tskIDLE_PRIORITY, NULL ); + } + } +/*-----------------------------------------------------------*/ + + static void prvServerConnectionInstance( void * pvParameters ) + { + int32_t lBytes, lSent, lTotalSent; + Socket_t xConnectedSocket; + static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 ); + static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 5000 ); + TickType_t xTimeOnShutdown; + uint8_t * pucRxBuffer; + + xConnectedSocket = ( Socket_t ) pvParameters; + + /* Attempt to create the buffer used to receive the string to be echoed + * back. This could be avoided using a zero copy interface that just returned + * the same buffer. */ + pucRxBuffer = ( uint8_t * ) pvPortMalloc( ipconfigTCP_MSS ); + + if( pucRxBuffer != NULL ) + { + FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); + FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xReceiveTimeOut ) ); + + for( ; ; ) + { + /* Zero out the receive array so there is NULL at the end of the string + * when it is printed out. */ + memset( pucRxBuffer, 0x00, ipconfigTCP_MSS ); + + /* Receive data on the socket. */ + lBytes = FreeRTOS_recv( xConnectedSocket, pucRxBuffer, ipconfigTCP_MSS, 0 ); + + /* If data was received, echo it back. */ + if( lBytes >= 0 ) + { + lSent = 0; + lTotalSent = 0; + + /* Call send() until all the data has been sent. */ + while( ( lSent >= 0 ) && ( lTotalSent < lBytes ) ) + { + lSent = FreeRTOS_send( xConnectedSocket, pucRxBuffer, lBytes - lTotalSent, 0 ); + lTotalSent += lSent; + } + + if( lSent < 0 ) + { + /* Socket closed? */ + break; + } + } + else + { + /* Socket closed? */ + break; + } + } + } + + /* Initiate a shutdown in case it has not already been initiated. */ + FreeRTOS_shutdown( xConnectedSocket, FREERTOS_SHUT_RDWR ); + + /* Wait for the shutdown to take effect, indicated by FreeRTOS_recv() + * returning an error. */ + xTimeOnShutdown = xTaskGetTickCount(); + + do + { + if( FreeRTOS_recv( xConnectedSocket, pucRxBuffer, ipconfigTCP_MSS, 0 ) < 0 ) + { + break; + } + } while( ( xTaskGetTickCount() - xTimeOnShutdown ) < tcpechoSHUTDOWN_DELAY ); + + /* Finished with the socket, buffer, the task. */ + vPortFree( pucRxBuffer ); + FreeRTOS_closesocket( xConnectedSocket ); + + vTaskDelete( NULL ); + } +/*-----------------------------------------------------------*/ + +/* The whole file is excluded if TCP is not compiled in. */ +#endif /* ipconfigUSE_TCP */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleUDPClientAndServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleUDPClientAndServer.c index 5ed5a060c..71433f914 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleUDPClientAndServer.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleUDPClientAndServer.c @@ -1,389 +1,391 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * Creates two transmitting tasks and two receiving tasks. The transmitting - * tasks send values that are received by the receiving tasks. One set of tasks - * uses the standard API. The other set of tasks uses the zero copy API. - * - * See the following web page for essential demo usage and configuration - * details: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html - */ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" - -#define simpTINY_DELAY ( ( TickType_t ) 2 ) - -/* - * Uses a socket to send data without using the zero copy option. - * prvSimpleServerTask() will receive the data. - */ -static void prvSimpleClientTask( void *pvParameters ); - -/* - * Uses a socket to receive the data sent by the prvSimpleClientTask() task. - * Does not use the zero copy option. - */ -static void prvSimpleServerTask( void *pvParameters ); - -/* - * Uses a socket to send data using the zero copy option. - * prvSimpleZeroCopyServerTask() will receive the data. - */ -static void prvSimpleZeroCopyUDPClientTask( void *pvParameters ); - -/* - * Uses a socket to receive the data sent by the prvSimpleZeroCopyUDPClientTask() - * task. Uses the zero copy option. - */ -static void prvSimpleZeroCopyServerTask( void *pvParameters ); - -/*-----------------------------------------------------------*/ - -void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, uint32_t ulPort, UBaseType_t uxPriority ) -{ - /* Create the client and server tasks that do not use the zero copy - interface. */ - xTaskCreate( prvSimpleClientTask, "SimpCpyClnt", usStackSize, ( void * ) ulPort, uxPriority, NULL ); - xTaskCreate( prvSimpleServerTask, "SimpCpySrv", usStackSize, ( void * ) ulPort, uxPriority + 1, NULL ); - - /* Create the client and server tasks that do use the zero copy interface. */ - xTaskCreate( prvSimpleZeroCopyUDPClientTask, "SimpZCpyClnt", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority, NULL ); - xTaskCreate( prvSimpleZeroCopyServerTask, "SimpZCpySrv", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority + 1, NULL ); -} -/*-----------------------------------------------------------*/ - -static void prvSimpleClientTask( void *pvParameters ) -{ -Socket_t xClientSocket; -struct freertos_sockaddr xDestinationAddress; -uint8_t cString[ 65 ]; -BaseType_t lReturned; -uint32_t ulCount = 0UL, ulIPAddress; -const uint32_t ulLoopsPerSocket = 10UL; -const TickType_t x150ms = 150UL / portTICK_PERIOD_MS; - - /* Remove compiler warning about unused parameters. */ - ( void ) pvParameters; - - /* It is assumed that this task is not created until the network is up, - so the IP address can be obtained immediately. store the IP address being - used in ulIPAddress. This is done so the socket can send to a different - port on the same IP address. */ -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); -#else - FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - /* This test sends to itself, so data sent from here is received by a server - socket on the same IP address. Setup the freertos_sockaddr structure with - this nodes IP address, and the port number being sent to. The strange - casting is to try and remove compiler warnings on 32 bit machines. */ - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xDestinationAddress.sin_address.ulIP_IPv4 = ulIPAddress; - } - #else - { - xDestinationAddress.sin_addr = ulIPAddress; - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; - xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port ); - xDestinationAddress.sin_family = FREERTOS_AF_INET; - - for( ;; ) - { - /* Create the socket. */ - xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); - - /* The count is used to differentiate between different messages sent to - the server, and to break out of the do while loop below. */ - ulCount = 0UL; - - do - { - /* Create the string that is sent to the server. */ - sprintf( ( char * ) cString, "Server received (not zero copy): Message number %lu\r\n", ulCount ); - - /* Send the string to the socket. ulFlags is set to 0, so the zero - copy option is not selected. That means the data from cString[] is - copied into a network buffer inside FreeRTOS_sendto(), and cString[] - can be reused as soon as FreeRTOS_sendto() has returned. */ - lReturned = FreeRTOS_sendto( xClientSocket, ( void * ) cString, strlen( ( const char * ) cString ), 0, &xDestinationAddress, sizeof( xDestinationAddress ) ); - - ulCount++; - - } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) ); - - FreeRTOS_closesocket( xClientSocket ); - - /* A short delay to prevent the messages printed by the server task - scrolling off the screen too quickly, and to prevent reduce the network - loading. */ - vTaskDelay( x150ms ); - } -} -/*-----------------------------------------------------------*/ - -static void prvSimpleServerTask( void *pvParameters ) -{ -int32_t lBytes; -uint8_t cReceivedString[ 60 ]; -struct freertos_sockaddr xClient, xBindAddress; -uint32_t xClientLength = sizeof( xClient ); -Socket_t xListeningSocket; - - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; - - /* Attempt to open the socket. */ - xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); - - /* This test receives data sent from a different port on the same IP - address. Configure the freertos_sockaddr structure with the address being - bound to. The strange casting is to try and remove compiler warnings on 32 - bit machines. Note that this task is only created after the network is up, - so the IP address is valid here. */ - xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; - xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); - xBindAddress.sin_family = FREERTOS_AF_INET; - - /* Bind the socket to the port that the client task will send to. */ - FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); - - for( ;; ) - { - /* Zero out the receive array so there is NULL at the end of the string - when it is printed out. */ - memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); - - /* Receive data on the socket. ulFlags is zero, so the zero copy option - is not set and the received data is copied into the buffer pointed to by - cReceivedString. By default the block time is portMAX_DELAY. - xClientLength is not actually used by FreeRTOS_recvfrom(), but is set - appropriately in case future versions do use it. */ - lBytes = FreeRTOS_recvfrom( xListeningSocket, cReceivedString, sizeof( cReceivedString ), 0, &xClient, &xClientLength ); - - /* Error check. */ - configASSERT( lBytes == ( BaseType_t ) strlen( ( const char * ) cReceivedString ) ); - } -} -/*-----------------------------------------------------------*/ - -static void prvSimpleZeroCopyUDPClientTask( void *pvParameters ) -{ -Socket_t xClientSocket; -uint8_t *pucUDPPayloadBuffer; -struct freertos_sockaddr xDestinationAddress; -BaseType_t lReturned; -uint32_t ulCount = 0UL, ulIPAddress; -const uint32_t ulLoopsPerSocket = 10UL; -const char *pcStringToSend = "Server received (using zero copy): Message number "; -const TickType_t x150ms = 150UL / portTICK_PERIOD_MS; -/* 15 is added to ensure the number, \r\n and terminating zero fit. */ -const size_t xStringLength = strlen( pcStringToSend ) + 15; - - /* Remove compiler warning about unused parameters. */ - ( void ) pvParameters; - - /* It is assumed that this task is not created until the network is up, - so the IP address can be obtained immediately. store the IP address being - used in ulIPAddress. This is done so the socket can send to a different - port on the same IP address. */ -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - /* This test sends to itself, so data sent from here is received by a server - socket on the same IP address. Setup the freertos_sockaddr structure with - this nodes IP address, and the port number being sent to. The strange - casting is to try and remove compiler warnings on 32 bit machines. */ - xDestinationAddress.sin_address.ulIP_IPv4 = ulIPAddress; -#else - FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); - /* This test sends to itself, so data sent from here is received by a server - socket on the same IP address. Setup the freertos_sockaddr structure with - this nodes IP address, and the port number being sent to. The strange - casting is to try and remove compiler warnings on 32 bit machines. */ - xDestinationAddress.sin_addr = ulIPAddress; -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; - xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port ); - xDestinationAddress.sin_family = FREERTOS_AF_INET; - - for( ;; ) - { - /* Create the socket. */ - xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); - - /* The count is used to differentiate between different messages sent to - the server, and to break out of the do while loop below. */ - ulCount = 0UL; - - do - { - /* This task is going to send using the zero copy interface. The - data being sent is therefore written directly into a buffer that is - passed into, rather than copied into, the FreeRTOS_sendto() - function. - - First obtain a buffer of adequate length from the IP stack into which - the string will be written. Although a max delay is used, the actual - delay will be capped to ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence - the do while loop is used to ensure a buffer is obtained. */ - do - { - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer_Multi( xStringLength, portMAX_DELAY, ipTYPE_IPv4 ) ) == NULL ); - #else - } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xStringLength, portMAX_DELAY ) ) == NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - /* A buffer was successfully obtained. Create the string that is - sent to the server. First the string is filled with zeros as this will - effectively be the null terminator when the string is received at the other - end. Note that the string is being written directly into the buffer - obtained from the IP stack above. */ - memset( ( void * ) pucUDPPayloadBuffer, 0x00, xStringLength ); - sprintf( ( char * ) pucUDPPayloadBuffer, "%s%lu\r\n", pcStringToSend, ulCount ); - - /* Pass the buffer into the send function. ulFlags has the - FREERTOS_ZERO_COPY bit set so the IP stack will take control of the - buffer rather than copy data out of the buffer. */ - lReturned = FreeRTOS_sendto( xClientSocket, /* The socket being sent to. */ - ( void * ) pucUDPPayloadBuffer, /* A pointer to the the data being sent. */ - strlen( ( const char * ) pucUDPPayloadBuffer ) + 1, /* The length of the data being sent - including the string's null terminator. */ - FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */ - &xDestinationAddress, /* Where the data is being sent. */ - sizeof( xDestinationAddress ) ); - - if( lReturned == 0 ) - { - /* The send operation failed, so this task is still responsible - for the buffer obtained from the IP stack. To ensure the buffer - is not lost it must either be used again, or, as in this case, - returned to the IP stack using FreeRTOS_ReleaseUDPPayloadBuffer(). - pucUDPPayloadBuffer can be safely re-used after this call. */ - FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer ); - } - else - { - /* The send was successful so the IP stack is now managing the - buffer pointed to by pucUDPPayloadBuffer, and the IP stack will - return the buffer once it has been sent. pucUDPPayloadBuffer can - be safely re-used. */ - } - - ulCount++; - - } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) ); - - FreeRTOS_closesocket( xClientSocket ); - - /* A short delay to prevent the messages scrolling off the screen too - quickly. */ - vTaskDelay( x150ms ); - } -} -/*-----------------------------------------------------------*/ - -static void prvSimpleZeroCopyServerTask( void *pvParameters ) -{ -int32_t lBytes; -uint8_t *pucUDPPayloadBuffer; -struct freertos_sockaddr xClient, xBindAddress; -uint32_t xClientLength = sizeof( xClient ), ulIPAddress; -Socket_t xListeningSocket; - - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; - - /* Attempt to open the socket. */ - xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); - - /* This test receives data sent from a different port on the same IP address. - Obtain the nodes IP address. Configure the freertos_sockaddr structure with - the address being bound to. The strange casting is to try and remove - compiler warnings on 32 bit machines. Note that this task is only created - after the network is up, so the IP address is valid here. */ -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - xBindAddress.sin_address.ulIP_IPv4 = ulIPAddress; -#else - FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); - xBindAddress.sin_addr = ulIPAddress; -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; - xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); - xBindAddress.sin_family = FREERTOS_AF_INET; - - /* Bind the socket to the port that the client task will send to. */ - FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); - - for( ;; ) - { - /* Receive data on the socket. ulFlags has the zero copy bit set - (FREERTOS_ZERO_COPY) indicating to the stack that a reference to the - received data should be passed out to this task using the second - parameter to the FreeRTOS_recvfrom() call. When this is done the - IP stack is no longer responsible for releasing the buffer, and - the task *must* return the buffer to the stack when it is no longer - needed. By default the block time is portMAX_DELAY. */ - lBytes = FreeRTOS_recvfrom( xListeningSocket, ( void * ) &pucUDPPayloadBuffer, 0, FREERTOS_ZERO_COPY, &xClient, &xClientLength ); - - /* Print the received characters. */ - if( lBytes > 0 ) - { - /* It is expected to receive one more byte than the string length as - the NULL terminator is also transmitted. */ - configASSERT( lBytes == ( ( BaseType_t ) strlen( ( const char * ) pucUDPPayloadBuffer ) + 1 ) ); - } - - if( lBytes >= 0 ) - { - /* The buffer *must* be freed once it is no longer needed. */ - FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer ); - } - } -} - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Creates two transmitting tasks and two receiving tasks. The transmitting + * tasks send values that are received by the receiving tasks. One set of tasks + * uses the standard API. The other set of tasks uses the zero copy API. + * + * See the following web page for essential demo usage and configuration + * details: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html + */ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" + +#define simpTINY_DELAY ( ( TickType_t ) 2 ) + +/* + * Uses a socket to send data without using the zero copy option. + * prvSimpleServerTask() will receive the data. + */ +static void prvSimpleClientTask( void * pvParameters ); + +/* + * Uses a socket to receive the data sent by the prvSimpleClientTask() task. + * Does not use the zero copy option. + */ +static void prvSimpleServerTask( void * pvParameters ); + +/* + * Uses a socket to send data using the zero copy option. + * prvSimpleZeroCopyServerTask() will receive the data. + */ +static void prvSimpleZeroCopyUDPClientTask( void * pvParameters ); + +/* + * Uses a socket to receive the data sent by the prvSimpleZeroCopyUDPClientTask() + * task. Uses the zero copy option. + */ +static void prvSimpleZeroCopyServerTask( void * pvParameters ); + +/*-----------------------------------------------------------*/ + +void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, + uint32_t ulPort, + UBaseType_t uxPriority ) +{ + /* Create the client and server tasks that do not use the zero copy + * interface. */ + xTaskCreate( prvSimpleClientTask, "SimpCpyClnt", usStackSize, ( void * ) ulPort, uxPriority, NULL ); + xTaskCreate( prvSimpleServerTask, "SimpCpySrv", usStackSize, ( void * ) ulPort, uxPriority + 1, NULL ); + + /* Create the client and server tasks that do use the zero copy interface. */ + xTaskCreate( prvSimpleZeroCopyUDPClientTask, "SimpZCpyClnt", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority, NULL ); + xTaskCreate( prvSimpleZeroCopyServerTask, "SimpZCpySrv", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority + 1, NULL ); +} +/*-----------------------------------------------------------*/ + +static void prvSimpleClientTask( void * pvParameters ) +{ + Socket_t xClientSocket; + struct freertos_sockaddr xDestinationAddress; + uint8_t cString[ 65 ]; + BaseType_t lReturned; + uint32_t ulCount = 0UL, ulIPAddress; + const uint32_t ulLoopsPerSocket = 10UL; + const TickType_t x150ms = 150UL / portTICK_PERIOD_MS; + + /* Remove compiler warning about unused parameters. */ + ( void ) pvParameters; + + /* It is assumed that this task is not created until the network is up, + * so the IP address can be obtained immediately. store the IP address being + * used in ulIPAddress. This is done so the socket can send to a different + * port on the same IP address. */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + /* This test sends to itself, so data sent from here is received by a server + * socket on the same IP address. Setup the freertos_sockaddr structure with + * this nodes IP address, and the port number being sent to. The strange + * casting is to try and remove compiler warnings on 32 bit machines. */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xDestinationAddress.sin_address.ulIP_IPv4 = ulIPAddress; + } + #else + { + xDestinationAddress.sin_addr = ulIPAddress; + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; + xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port ); + xDestinationAddress.sin_family = FREERTOS_AF_INET; + + for( ; ; ) + { + /* Create the socket. */ + xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); + + /* The count is used to differentiate between different messages sent to + * the server, and to break out of the do while loop below. */ + ulCount = 0UL; + + do + { + /* Create the string that is sent to the server. */ + sprintf( ( char * ) cString, "Server received (not zero copy): Message number %lu\r\n", ulCount ); + + /* Send the string to the socket. ulFlags is set to 0, so the zero + * copy option is not selected. That means the data from cString[] is + * copied into a network buffer inside FreeRTOS_sendto(), and cString[] + * can be reused as soon as FreeRTOS_sendto() has returned. */ + lReturned = FreeRTOS_sendto( xClientSocket, ( void * ) cString, strlen( ( const char * ) cString ), 0, &xDestinationAddress, sizeof( xDestinationAddress ) ); + + ulCount++; + } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) ); + + FreeRTOS_closesocket( xClientSocket ); + + /* A short delay to prevent the messages printed by the server task + * scrolling off the screen too quickly, and to prevent reduce the network + * loading. */ + vTaskDelay( x150ms ); + } +} +/*-----------------------------------------------------------*/ + +static void prvSimpleServerTask( void * pvParameters ) +{ + int32_t lBytes; + uint8_t cReceivedString[ 60 ]; + struct freertos_sockaddr xClient, xBindAddress; + uint32_t xClientLength = sizeof( xClient ); + Socket_t xListeningSocket; + + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; + + /* Attempt to open the socket. */ + xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); + + /* This test receives data sent from a different port on the same IP + * address. Configure the freertos_sockaddr structure with the address being + * bound to. The strange casting is to try and remove compiler warnings on 32 + * bit machines. Note that this task is only created after the network is up, + * so the IP address is valid here. */ + xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; + xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); + xBindAddress.sin_family = FREERTOS_AF_INET; + + /* Bind the socket to the port that the client task will send to. */ + FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); + + for( ; ; ) + { + /* Zero out the receive array so there is NULL at the end of the string + * when it is printed out. */ + memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); + + /* Receive data on the socket. ulFlags is zero, so the zero copy option + * is not set and the received data is copied into the buffer pointed to by + * cReceivedString. By default the block time is portMAX_DELAY. + * xClientLength is not actually used by FreeRTOS_recvfrom(), but is set + * appropriately in case future versions do use it. */ + lBytes = FreeRTOS_recvfrom( xListeningSocket, cReceivedString, sizeof( cReceivedString ), 0, &xClient, &xClientLength ); + + /* Error check. */ + configASSERT( lBytes == ( BaseType_t ) strlen( ( const char * ) cReceivedString ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvSimpleZeroCopyUDPClientTask( void * pvParameters ) +{ + Socket_t xClientSocket; + uint8_t * pucUDPPayloadBuffer; + struct freertos_sockaddr xDestinationAddress; + BaseType_t lReturned; + uint32_t ulCount = 0UL, ulIPAddress; + const uint32_t ulLoopsPerSocket = 10UL; + const char * pcStringToSend = "Server received (using zero copy): Message number "; + const TickType_t x150ms = 150UL / portTICK_PERIOD_MS; +/* 15 is added to ensure the number, \r\n and terminating zero fit. */ + const size_t xStringLength = strlen( pcStringToSend ) + 15; + + /* Remove compiler warning about unused parameters. */ + ( void ) pvParameters; + + /* It is assumed that this task is not created until the network is up, + * so the IP address can be obtained immediately. store the IP address being + * used in ulIPAddress. This is done so the socket can send to a different + * port on the same IP address. */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); + + /* This test sends to itself, so data sent from here is received by a server + * socket on the same IP address. Setup the freertos_sockaddr structure with + * this nodes IP address, and the port number being sent to. The strange + * casting is to try and remove compiler warnings on 32 bit machines. */ + xDestinationAddress.sin_address.ulIP_IPv4 = ulIPAddress; + #else + FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); + + /* This test sends to itself, so data sent from here is received by a server + * socket on the same IP address. Setup the freertos_sockaddr structure with + * this nodes IP address, and the port number being sent to. The strange + * casting is to try and remove compiler warnings on 32 bit machines. */ + xDestinationAddress.sin_addr = ulIPAddress; + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; + xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port ); + xDestinationAddress.sin_family = FREERTOS_AF_INET; + + for( ; ; ) + { + /* Create the socket. */ + xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); + + /* The count is used to differentiate between different messages sent to + * the server, and to break out of the do while loop below. */ + ulCount = 0UL; + + do + { + /* This task is going to send using the zero copy interface. The + * data being sent is therefore written directly into a buffer that is + * passed into, rather than copied into, the FreeRTOS_sendto() + * function. + * + * First obtain a buffer of adequate length from the IP stack into which + * the string will be written. Although a max delay is used, the actual + * delay will be capped to ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence + * the do while loop is used to ensure a buffer is obtained. */ + do + { + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer_Multi( xStringLength, portMAX_DELAY, ipTYPE_IPv4 ) ) == NULL ); + #else + } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xStringLength, portMAX_DELAY ) ) == NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + /* A buffer was successfully obtained. Create the string that is + * sent to the server. First the string is filled with zeros as this will + * effectively be the null terminator when the string is received at the other + * end. Note that the string is being written directly into the buffer + * obtained from the IP stack above. */ + memset( ( void * ) pucUDPPayloadBuffer, 0x00, xStringLength ); + sprintf( ( char * ) pucUDPPayloadBuffer, "%s%lu\r\n", pcStringToSend, ulCount ); + + /* Pass the buffer into the send function. ulFlags has the + * FREERTOS_ZERO_COPY bit set so the IP stack will take control of the + * buffer rather than copy data out of the buffer. */ + lReturned = FreeRTOS_sendto( xClientSocket, /* The socket being sent to. */ + ( void * ) pucUDPPayloadBuffer, /* A pointer to the the data being sent. */ + strlen( ( const char * ) pucUDPPayloadBuffer ) + 1, /* The length of the data being sent - including the string's null terminator. */ + FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */ + &xDestinationAddress, /* Where the data is being sent. */ + sizeof( xDestinationAddress ) ); + + if( lReturned == 0 ) + { + /* The send operation failed, so this task is still responsible + * for the buffer obtained from the IP stack. To ensure the buffer + * is not lost it must either be used again, or, as in this case, + * returned to the IP stack using FreeRTOS_ReleaseUDPPayloadBuffer(). + * pucUDPPayloadBuffer can be safely re-used after this call. */ + FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer ); + } + else + { + /* The send was successful so the IP stack is now managing the + * buffer pointed to by pucUDPPayloadBuffer, and the IP stack will + * return the buffer once it has been sent. pucUDPPayloadBuffer can + * be safely re-used. */ + } + + ulCount++; + } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) ); + + FreeRTOS_closesocket( xClientSocket ); + + /* A short delay to prevent the messages scrolling off the screen too + * quickly. */ + vTaskDelay( x150ms ); + } +} +/*-----------------------------------------------------------*/ + +static void prvSimpleZeroCopyServerTask( void * pvParameters ) +{ + int32_t lBytes; + uint8_t * pucUDPPayloadBuffer; + struct freertos_sockaddr xClient, xBindAddress; + uint32_t xClientLength = sizeof( xClient ), ulIPAddress; + Socket_t xListeningSocket; + + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; + + /* Attempt to open the socket. */ + xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); + + /* This test receives data sent from a different port on the same IP address. + * Obtain the nodes IP address. Configure the freertos_sockaddr structure with + * the address being bound to. The strange casting is to try and remove + * compiler warnings on 32 bit machines. Note that this task is only created + * after the network is up, so the IP address is valid here. */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); + xBindAddress.sin_address.ulIP_IPv4 = ulIPAddress; + #else + FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); + xBindAddress.sin_addr = ulIPAddress; + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; + xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); + xBindAddress.sin_family = FREERTOS_AF_INET; + + /* Bind the socket to the port that the client task will send to. */ + FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); + + for( ; ; ) + { + /* Receive data on the socket. ulFlags has the zero copy bit set + * (FREERTOS_ZERO_COPY) indicating to the stack that a reference to the + * received data should be passed out to this task using the second + * parameter to the FreeRTOS_recvfrom() call. When this is done the + * IP stack is no longer responsible for releasing the buffer, and + * the task *must* return the buffer to the stack when it is no longer + * needed. By default the block time is portMAX_DELAY. */ + lBytes = FreeRTOS_recvfrom( xListeningSocket, ( void * ) &pucUDPPayloadBuffer, 0, FREERTOS_ZERO_COPY, &xClient, &xClientLength ); + + /* Print the received characters. */ + if( lBytes > 0 ) + { + /* It is expected to receive one more byte than the string length as + * the NULL terminator is also transmitted. */ + configASSERT( lBytes == ( ( BaseType_t ) strlen( ( const char * ) pucUDPPayloadBuffer ) + 1 ) ); + } + + if( lBytes >= 0 ) + { + /* The buffer *must* be freed once it is no longer needed. */ + FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer ); + } + } +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/TCPEchoClient_SingleTasks.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/TCPEchoClient_SingleTasks.c index a5c1e60b3..a30909c36 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/TCPEchoClient_SingleTasks.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/TCPEchoClient_SingleTasks.c @@ -1,382 +1,385 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * A set of tasks are created that send TCP echo requests to the standard echo - * port (port 7) on the IP address set by the configECHO_SERVER_ADDR0 to - * configECHO_SERVER_ADDR3 constants, then wait for and verify the reply - * (another demo is available that demonstrates the reception being performed in - * a task other than that from with the request was made). - * - * See the following web page for essential demo usage and configuration - * details: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html - */ - -/* Standard includes. */ -#include -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" - -/* FreeRTOS+TCP includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" - -#include "tcp_echo_config.h" - -/* Exclude the whole file if FreeRTOSIPConfig.h is configured to use UDP only. */ -#if( ipconfigUSE_TCP == 1 ) - -/* The echo tasks create a socket, send out a number of echo requests, listen -for the echo reply, then close the socket again before starting over. This -delay is used between each iteration to ensure the network does not get too -congested. */ -#define echoLOOP_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS ) - -/* The echo server is assumed to be on port 7, which is the standard echo -protocol port. */ -#define echoECHO_PORT ( 7 ) - -/* The size of the buffers is a multiple of the MSS - the length of the data -sent is a pseudo random size between 20 and echoBUFFER_SIZES. */ -#define echoBUFFER_SIZE_MULTIPLIER ( 3 ) -#define echoBUFFER_SIZES ( ipconfigTCP_MSS * echoBUFFER_SIZE_MULTIPLIER ) - -/* The number of instances of the echo client task to create. */ -#define echoNUM_ECHO_CLIENTS ( 5 ) - -/*-----------------------------------------------------------*/ - -/* - * Uses a socket to send data to, then receive data from, the standard echo - * port number 7. - */ -static void prvEchoClientTask( void *pvParameters ); - -/* - * Creates a pseudo random sized buffer of data to send to the echo server. - */ -static BaseType_t prvCreateTxData( char *ucBuffer, uint32_t ulBufferLength ); - -/*-----------------------------------------------------------*/ - -/* Rx and Tx time outs are used to ensure the sockets do not wait too long for -missing data. */ -static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 4000 ); -static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 2000 ); - -/* Counters for each created task - for inspection only. */ -static uint32_t ulTxRxCycles[ echoNUM_ECHO_CLIENTS ] = { 0 }, - ulTxRxFailures[ echoNUM_ECHO_CLIENTS ] = { 0 }, - ulConnections[ echoNUM_ECHO_CLIENTS ] = { 0 }; - -/* Rx and Tx buffers for each created task. */ -static char cTxBuffers[ echoNUM_ECHO_CLIENTS ][ echoBUFFER_SIZES ], - cRxBuffers[ echoNUM_ECHO_CLIENTS ][ echoBUFFER_SIZES ]; - -/*-----------------------------------------------------------*/ - -void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority ) -{ -BaseType_t x; - - /* Create the echo client tasks. */ - for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) - { - xTaskCreate( prvEchoClientTask, /* The function that implements the task. */ - "Echo0", /* Just a text name for the task to aid debugging. */ - usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ - ( void * ) x, /* The task parameter, not used in this case. */ - uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ - NULL ); /* The task handle is not used. */ - } -} -/*-----------------------------------------------------------*/ - -static void prvEchoClientTask( void *pvParameters ) -{ -Socket_t xSocket; -struct freertos_sockaddr xEchoServerAddress; -int32_t lLoopCount = 0UL; -const int32_t lMaxLoopCount = 1; -volatile uint32_t ulTxCount = 0UL; -BaseType_t xReceivedBytes, xReturned, xInstance; -BaseType_t lTransmitted, lStringLength; -char *pcTransmittedString, *pcReceivedString; -WinProperties_t xWinProps; -TickType_t xTimeOnEntering; - - /* Fill in the buffer and window sizes that will be used by the socket. */ - xWinProps.lTxBufSize = 6 * ipconfigTCP_MSS; - xWinProps.lTxWinSize = 3; - xWinProps.lRxBufSize = 6 * ipconfigTCP_MSS; - xWinProps.lRxWinSize = 3; - - /* This task can be created a number of times. Each instance is numbered - to enable each instance to use a different Rx and Tx buffer. The number is - passed in as the task's parameter. */ - xInstance = ( BaseType_t ) pvParameters; - - /* Point to the buffers to be used by this instance of this task. */ - pcTransmittedString = &( cTxBuffers[ xInstance ][ 0 ] ); - pcReceivedString = &( cRxBuffers[ xInstance ][ 0 ] ); - - /* Echo requests are sent to the echo server. The address of the echo - server is configured by the constants configECHO_SERVER_ADDR0 to - configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ - xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr( configECHO_SERVER_ADDR ); - } - #else - { - xEchoServerAddress.sin_addr = FreeRTOS_inet_addr( configECHO_SERVER_ADDR ); - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xEchoServerAddress.sin_family = FREERTOS_AF_INET; - - for( ;; ) - { - /* Create a TCP socket. */ - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); - configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); - - /* Set a time out so a missing reply does not cause the task to block - indefinitely. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); - - /* Set the window and buffer sizes. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); - - /* Connect to the echo server. */ - if( FreeRTOS_connect( xSocket, &xEchoServerAddress, sizeof( xEchoServerAddress ) ) == 0 ) - { - ulConnections[ xInstance ]++; - - /* Send a number of echo requests. */ - for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) - { - /* Create the string that is sent to the echo server. */ - lStringLength = prvCreateTxData( pcTransmittedString, echoBUFFER_SIZES ); - - /* Add in some unique text at the front of the string. */ - sprintf( pcTransmittedString, "TxRx message number %u", ulTxCount ); - - /* Replace '\0' with '-' for string length and comparison functions */ - pcTransmittedString[ strlen( pcTransmittedString ) ] = '-'; - - printf( "\n\tSending %d bytes of data to the echo server\n", lStringLength ); - ulTxCount++; - - /* Send the string to the socket. */ - lTransmitted = FreeRTOS_send( xSocket, /* The socket being sent to. */ - ( void * ) pcTransmittedString, /* The data being sent. */ - lStringLength, /* The length of the data being sent. */ - 0 ); /* No flags. */ - - if( lTransmitted < 0 ) - { - /* Error? */ - break; - } - - /* Clear the buffer into which the echoed string will be - placed. */ - memset( ( void * ) pcReceivedString, 0x00, echoBUFFER_SIZES ); - xReceivedBytes = 0; - - /* Receive data echoed back to the socket. */ - while( xReceivedBytes < lTransmitted ) - { - xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ - &( pcReceivedString[ xReceivedBytes ] ),/* The buffer into which the received data will be written. */ - lStringLength - xReceivedBytes, /* The size of the buffer provided to receive the data. */ - 0 ); /* No flags. */ - - if( xReturned < 0 ) - { - /* Error occurred. Latch it so it can be detected - below. */ - xReceivedBytes = xReturned; - break; - } - else if( xReturned == 0 ) - { - /* Timed out. */ - break; - } - else - { - /* Keep a count of the bytes received so far. */ - xReceivedBytes += xReturned; - } - } - - /* If an error occurred it will be latched in xReceivedBytes, - otherwise xReceived bytes will be just that - the number of - bytes received from the echo server. */ - if( xReceivedBytes > 0 ) - { - /* Compare the transmitted string to the received string. */ - configASSERT( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ); - if( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ) - { - /* The echo reply was received without error. */ - ulTxRxCycles[ xInstance ]++; - - /* The "Received correct data" line is used to determine if - * this demo runs successfully on a GitHub workflow. */ - printf( "\tReceived correct data %d times.\n", ulTxRxCycles[ xInstance ] ); - } - else - { - /* The received string did not match the transmitted - string. */ - ulTxRxFailures[ xInstance ]++; - printf( "\tReceived incorrect data %d times.\n", ulTxRxFailures[ xInstance ] ); - break; - } - } - else if( xReceivedBytes < 0 ) - { - /* FreeRTOS_recv() returned an error. */ - break; - } - else - { - /* Timed out without receiving anything? */ - break; - } - } - - /* Finished using the connected socket, initiate a graceful close: - FIN, FIN+ACK, ACK. */ - FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR ); - - /* Expect FreeRTOS_recv() to return an error once the shutdown is - complete. */ - xTimeOnEntering = xTaskGetTickCount(); - do - { - xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ - &( pcReceivedString[ 0 ] ), /* The buffer into which the received data will be written. */ - echoBUFFER_SIZES, /* The size of the buffer provided to receive the data. */ - 0 ); - - if( xReturned < 0 ) - { - break; - } - - } while( ( xTaskGetTickCount() - xTimeOnEntering ) < xReceiveTimeOut ); - } - - /* Close this socket before looping back to create another. */ - FreeRTOS_closesocket( xSocket ); - - /* Pause for a short while to ensure the network is not too - congested. */ - vTaskDelay( echoLOOP_DELAY ); - } -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvCreateTxData( char *cBuffer, uint32_t ulBufferLength ) -{ -BaseType_t lCharactersToAdd, lCharacter; -char cChar = 'A'; -const BaseType_t lMinimumLength = 60; -uint32_t ulRandomNumber; - - /* Randomise the number of characters that will be sent in the echo - request. */ - do - { - ( void ) xApplicationGetRandomNumber( &ulRandomNumber ); - lCharactersToAdd = ulRandomNumber % ( ulBufferLength - 20UL ); - } while ( ( lCharactersToAdd == 0 ) || ( lCharactersToAdd < lMinimumLength ) ); /* Must be at least enough to add the unique text to the start of the string later. */ - - /* Fill the buffer. */ - for( lCharacter = 0; lCharacter < lCharactersToAdd; lCharacter++ ) - { - cBuffer[ lCharacter ] = cChar; - cChar++; - - if( cChar > 'Z' ) - { - cChar = 'A'; - } - } - - cBuffer[ lCharacter - 1 ] = '\n'; - cBuffer[ lCharacter ] = '\0'; - - return lCharactersToAdd; -} -/*-----------------------------------------------------------*/ - -BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ) -{ -static uint32_t ulLastEchoSocketCount[ echoNUM_ECHO_CLIENTS ] = { 0 }, ulLastConnections[ echoNUM_ECHO_CLIENTS ] = { 0 }; -BaseType_t xReturn = pdPASS, x; - - /* Return fail is the number of cycles does not increment between - consecutive calls. */ - for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) - { - if( ulTxRxCycles[ x ] == ulLastEchoSocketCount[ x ] ) - { - xReturn = pdFAIL; - } - else - { - ulLastEchoSocketCount[ x ] = ulTxRxCycles[ x ]; - } - - if( ulConnections[ x ] == ulLastConnections[ x ] ) - { - xReturn = pdFAIL; - } - else - { - ulConnections[ x ] = ulLastConnections[ x ]; - } - } - - return xReturn; -} - -#endif /* ipconfigUSE_TCP */ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * A set of tasks are created that send TCP echo requests to the standard echo + * port (port 7) on the IP address set by the configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR3 constants, then wait for and verify the reply + * (another demo is available that demonstrates the reception being performed in + * a task other than that from with the request was made). + * + * See the following web page for essential demo usage and configuration + * details: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html + */ + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* FreeRTOS+TCP includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" + +#include "tcp_echo_config.h" + +/* Exclude the whole file if FreeRTOSIPConfig.h is configured to use UDP only. */ +#if ( ipconfigUSE_TCP == 1 ) + +/* The echo tasks create a socket, send out a number of echo requests, listen + * for the echo reply, then close the socket again before starting over. This + * delay is used between each iteration to ensure the network does not get too + * congested. */ + #define echoLOOP_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS ) + +/* The echo server is assumed to be on port 7, which is the standard echo + * protocol port. */ + #define echoECHO_PORT ( 7 ) + +/* The size of the buffers is a multiple of the MSS - the length of the data + * sent is a pseudo random size between 20 and echoBUFFER_SIZES. */ + #define echoBUFFER_SIZE_MULTIPLIER ( 3 ) + #define echoBUFFER_SIZES ( ipconfigTCP_MSS * echoBUFFER_SIZE_MULTIPLIER ) + +/* The number of instances of the echo client task to create. */ + #define echoNUM_ECHO_CLIENTS ( 5 ) + +/*-----------------------------------------------------------*/ + +/* + * Uses a socket to send data to, then receive data from, the standard echo + * port number 7. + */ + static void prvEchoClientTask( void * pvParameters ); + +/* + * Creates a pseudo random sized buffer of data to send to the echo server. + */ + static BaseType_t prvCreateTxData( char * ucBuffer, + uint32_t ulBufferLength ); + +/*-----------------------------------------------------------*/ + +/* Rx and Tx time outs are used to ensure the sockets do not wait too long for + * missing data. */ + static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 4000 ); + static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 2000 ); + +/* Counters for each created task - for inspection only. */ + static uint32_t ulTxRxCycles[ echoNUM_ECHO_CLIENTS ] = { 0 }, + ulTxRxFailures[ echoNUM_ECHO_CLIENTS ] = { 0 }, + ulConnections[ echoNUM_ECHO_CLIENTS ] = { 0 }; + +/* Rx and Tx buffers for each created task. */ + static char cTxBuffers[ echoNUM_ECHO_CLIENTS ][ echoBUFFER_SIZES ], + cRxBuffers[ echoNUM_ECHO_CLIENTS ][ echoBUFFER_SIZES ]; + +/*-----------------------------------------------------------*/ + + void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ) + { + BaseType_t x; + + /* Create the echo client tasks. */ + for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) + { + xTaskCreate( prvEchoClientTask, /* The function that implements the task. */ + "Echo0", /* Just a text name for the task to aid debugging. */ + usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ + ( void * ) x, /* The task parameter, not used in this case. */ + uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ + NULL ); /* The task handle is not used. */ + } + } +/*-----------------------------------------------------------*/ + + static void prvEchoClientTask( void * pvParameters ) + { + Socket_t xSocket; + struct freertos_sockaddr xEchoServerAddress; + int32_t lLoopCount = 0UL; + const int32_t lMaxLoopCount = 1; + volatile uint32_t ulTxCount = 0UL; + BaseType_t xReceivedBytes, xReturned, xInstance; + BaseType_t lTransmitted, lStringLength; + char * pcTransmittedString, * pcReceivedString; + WinProperties_t xWinProps; + TickType_t xTimeOnEntering; + + /* Fill in the buffer and window sizes that will be used by the socket. */ + xWinProps.lTxBufSize = 6 * ipconfigTCP_MSS; + xWinProps.lTxWinSize = 3; + xWinProps.lRxBufSize = 6 * ipconfigTCP_MSS; + xWinProps.lRxWinSize = 3; + + /* This task can be created a number of times. Each instance is numbered + * to enable each instance to use a different Rx and Tx buffer. The number is + * passed in as the task's parameter. */ + xInstance = ( BaseType_t ) pvParameters; + + /* Point to the buffers to be used by this instance of this task. */ + pcTransmittedString = &( cTxBuffers[ xInstance ][ 0 ] ); + pcReceivedString = &( cRxBuffers[ xInstance ][ 0 ] ); + + /* Echo requests are sent to the echo server. The address of the echo + * server is configured by the constants configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ + xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr( configECHO_SERVER_ADDR ); + } + #else + { + xEchoServerAddress.sin_addr = FreeRTOS_inet_addr( configECHO_SERVER_ADDR ); + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + xEchoServerAddress.sin_family = FREERTOS_AF_INET; + + for( ; ; ) + { + /* Create a TCP socket. */ + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); + configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); + + /* Set a time out so a missing reply does not cause the task to block + * indefinitely. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); + + /* Set the window and buffer sizes. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) ); + + /* Connect to the echo server. */ + if( FreeRTOS_connect( xSocket, &xEchoServerAddress, sizeof( xEchoServerAddress ) ) == 0 ) + { + ulConnections[ xInstance ]++; + + /* Send a number of echo requests. */ + for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) + { + /* Create the string that is sent to the echo server. */ + lStringLength = prvCreateTxData( pcTransmittedString, echoBUFFER_SIZES ); + + /* Add in some unique text at the front of the string. */ + sprintf( pcTransmittedString, "TxRx message number %u", ulTxCount ); + + /* Replace '\0' with '-' for string length and comparison functions */ + pcTransmittedString[ strlen( pcTransmittedString ) ] = '-'; + + printf( "\n\tSending %d bytes of data to the echo server\n", lStringLength ); + ulTxCount++; + + /* Send the string to the socket. */ + lTransmitted = FreeRTOS_send( xSocket, /* The socket being sent to. */ + ( void * ) pcTransmittedString, /* The data being sent. */ + lStringLength, /* The length of the data being sent. */ + 0 ); /* No flags. */ + + if( lTransmitted < 0 ) + { + /* Error? */ + break; + } + + /* Clear the buffer into which the echoed string will be + * placed. */ + memset( ( void * ) pcReceivedString, 0x00, echoBUFFER_SIZES ); + xReceivedBytes = 0; + + /* Receive data echoed back to the socket. */ + while( xReceivedBytes < lTransmitted ) + { + xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ + &( pcReceivedString[ xReceivedBytes ] ), /* The buffer into which the received data will be written. */ + lStringLength - xReceivedBytes, /* The size of the buffer provided to receive the data. */ + 0 ); /* No flags. */ + + if( xReturned < 0 ) + { + /* Error occurred. Latch it so it can be detected + * below. */ + xReceivedBytes = xReturned; + break; + } + else if( xReturned == 0 ) + { + /* Timed out. */ + break; + } + else + { + /* Keep a count of the bytes received so far. */ + xReceivedBytes += xReturned; + } + } + + /* If an error occurred it will be latched in xReceivedBytes, + * otherwise xReceived bytes will be just that - the number of + * bytes received from the echo server. */ + if( xReceivedBytes > 0 ) + { + /* Compare the transmitted string to the received string. */ + configASSERT( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ); + + if( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 ) + { + /* The echo reply was received without error. */ + ulTxRxCycles[ xInstance ]++; + + /* The "Received correct data" line is used to determine if + * this demo runs successfully on a GitHub workflow. */ + printf( "\tReceived correct data %d times.\n", ulTxRxCycles[ xInstance ] ); + } + else + { + /* The received string did not match the transmitted + * string. */ + ulTxRxFailures[ xInstance ]++; + printf( "\tReceived incorrect data %d times.\n", ulTxRxFailures[ xInstance ] ); + break; + } + } + else if( xReceivedBytes < 0 ) + { + /* FreeRTOS_recv() returned an error. */ + break; + } + else + { + /* Timed out without receiving anything? */ + break; + } + } + + /* Finished using the connected socket, initiate a graceful close: + * FIN, FIN+ACK, ACK. */ + FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR ); + + /* Expect FreeRTOS_recv() to return an error once the shutdown is + * complete. */ + xTimeOnEntering = xTaskGetTickCount(); + + do + { + xReturned = FreeRTOS_recv( xSocket, /* The socket being received from. */ + &( pcReceivedString[ 0 ] ), /* The buffer into which the received data will be written. */ + echoBUFFER_SIZES, /* The size of the buffer provided to receive the data. */ + 0 ); + + if( xReturned < 0 ) + { + break; + } + } while( ( xTaskGetTickCount() - xTimeOnEntering ) < xReceiveTimeOut ); + } + + /* Close this socket before looping back to create another. */ + FreeRTOS_closesocket( xSocket ); + + /* Pause for a short while to ensure the network is not too + * congested. */ + vTaskDelay( echoLOOP_DELAY ); + } + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvCreateTxData( char * cBuffer, + uint32_t ulBufferLength ) + { + BaseType_t lCharactersToAdd, lCharacter; + char cChar = 'A'; + const BaseType_t lMinimumLength = 60; + uint32_t ulRandomNumber; + + /* Randomise the number of characters that will be sent in the echo + * request. */ + do + { + ( void ) xApplicationGetRandomNumber( &ulRandomNumber ); + lCharactersToAdd = ulRandomNumber % ( ulBufferLength - 20UL ); + } while( ( lCharactersToAdd == 0 ) || ( lCharactersToAdd < lMinimumLength ) ); /* Must be at least enough to add the unique text to the start of the string later. */ + + /* Fill the buffer. */ + for( lCharacter = 0; lCharacter < lCharactersToAdd; lCharacter++ ) + { + cBuffer[ lCharacter ] = cChar; + cChar++; + + if( cChar > 'Z' ) + { + cChar = 'A'; + } + } + + cBuffer[ lCharacter - 1 ] = '\n'; + cBuffer[ lCharacter ] = '\0'; + + return lCharactersToAdd; + } +/*-----------------------------------------------------------*/ + + BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ) + { + static uint32_t ulLastEchoSocketCount[ echoNUM_ECHO_CLIENTS ] = { 0 }, ulLastConnections[ echoNUM_ECHO_CLIENTS ] = { 0 }; + BaseType_t xReturn = pdPASS, x; + + /* Return fail is the number of cycles does not increment between + * consecutive calls. */ + for( x = 0; x < echoNUM_ECHO_CLIENTS; x++ ) + { + if( ulTxRxCycles[ x ] == ulLastEchoSocketCount[ x ] ) + { + xReturn = pdFAIL; + } + else + { + ulLastEchoSocketCount[ x ] = ulTxRxCycles[ x ]; + } + + if( ulConnections[ x ] == ulLastConnections[ x ] ) + { + xReturn = pdFAIL; + } + else + { + ulConnections[ x ] = ulLastConnections[ x ]; + } + } + + return xReturn; + } + +#endif /* ipconfigUSE_TCP */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleTCPEchoServer.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleTCPEchoServer.h index 7c61caab4..5046f0f5b 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleTCPEchoServer.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleTCPEchoServer.h @@ -1,76 +1,67 @@ -/* - FreeRTOS V202212.00 - 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 SIMPLE_TCP_ECHO_SERVER_H -#define SIMPLE_TCP_ECHO_SERVER_H - -void vStartSimpleTCPServerTasks( uint16_t usStackSize, BaseType_t uxPriority ); -BaseType_t xAreTCPEchoServersStillRunning( void ); - -#endif /* SIMPLE_TCP_ECHO_SERVER_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * + * 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 SIMPLE_TCP_ECHO_SERVER_H +#define SIMPLE_TCP_ECHO_SERVER_H + +void vStartSimpleTCPServerTasks( uint16_t usStackSize, + BaseType_t uxPriority ); +BaseType_t xAreTCPEchoServersStillRunning( void ); + +#endif /* SIMPLE_TCP_ECHO_SERVER_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleUDPClientAndServer.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleUDPClientAndServer.h index 85262cfae..9376ad0f4 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleUDPClientAndServer.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleUDPClientAndServer.h @@ -1,32 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -#ifndef SIMPLE_UDP_CLIENT_AND_SERVER_H -#define SIMPLE_UDPCLIENT_AND_SERVER_H - -void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, uint32_t ulsPort, UBaseType_t uxPriority ); - -#endif /* SIMPLE_UDPCLIENT_AND_SERVER_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef SIMPLE_UDP_CLIENT_AND_SERVER_H +#define SIMPLE_UDPCLIENT_AND_SERVER_H + +void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, + uint32_t ulsPort, + UBaseType_t uxPriority ); + +#endif /* SIMPLE_UDPCLIENT_AND_SERVER_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/TCPEchoClient_SingleTasks.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/TCPEchoClient_SingleTasks.h index f30b7de5d..063821d67 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/TCPEchoClient_SingleTasks.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/TCPEchoClient_SingleTasks.h @@ -1,39 +1,38 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -#ifndef SINGLE_TASK_TCP_ECHO_CLIENTS_H -#define SINGLE_TASK_TCP_ECHO_CLIENTS_H - -/* - * Create the TCP echo client tasks. This is the version where an echo request - * is made from the same task that listens for the echo reply. - */ -void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority ); -BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ); - -#endif /* SINGLE_TASK_TCP_ECHO_CLIENTS_H */ - - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef SINGLE_TASK_TCP_ECHO_CLIENTS_H +#define SINGLE_TASK_TCP_ECHO_CLIENTS_H + +/* + * Create the TCP echo client tasks. This is the version where an echo request + * is made from the same task that listens for the echo reply. + */ +void vStartTCPEchoClientTasks_SingleTasks( uint16_t usTaskStackSize, + UBaseType_t uxTaskPriority ); +BaseType_t xAreSingleTaskTCPEchoClientsStillRunning( void ); + +#endif /* SINGLE_TASK_TCP_ECHO_CLIENTS_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOS_Plus_TCP_Minimal.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOS_Plus_TCP_Minimal.sln index f71e7e3d5..d34259b18 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOS_Plus_TCP_Minimal.sln +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOS_Plus_TCP_Minimal.sln @@ -1,89 +1,89 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.33027.164 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_TCP_Minimal", "FreeRTOS_Plus_TCP_Minimal.vcxproj", "{382DC80F-E278-4BC9-9DB6-59014486DA0F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{190A6643-3DE4-49DC-96AA-7867C5E0A835}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 - Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug|Win32.ActiveCfg = Debug|Win32 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug|Win32.Build.0 = Debug|Win32 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug|x64.ActiveCfg = Debug|x64 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug|x64.Build.0 = Debug|x64 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Release|Win32.ActiveCfg = Release|Win32 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Release|Win32.Build.0 = Release|Win32 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Release|x64.ActiveCfg = Release|x64 - {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {72C209C4-49A4-4942-A201-44706C9D77EC} = {190A6643-3DE4-49DC-96AA-7867C5E0A835} - {C90E6CC5-818B-4C97-8876-0986D989387C} = {190A6643-3DE4-49DC-96AA-7867C5E0A835} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {190A6643-3DE4-49DC-96AA-7867C5E0A835} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {3876F3F5-8086-4F8E-BB5E-D8840E7D926C} - EndGlobalSection - GlobalSection(TestCaseManagementSettings) = postSolution - CategoryFile = FreeRTOS_Plus_TCP_Minimal.vsmdi - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.33027.164 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_TCP_Minimal", "FreeRTOS_Plus_TCP_Minimal.vcxproj", "{382DC80F-E278-4BC9-9DB6-59014486DA0F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{190A6643-3DE4-49DC-96AA-7867C5E0A835}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 + Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug|Win32.ActiveCfg = Debug|Win32 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug|Win32.Build.0 = Debug|Win32 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug|x64.ActiveCfg = Debug|x64 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Debug|x64.Build.0 = Debug|x64 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Release|Win32.ActiveCfg = Release|Win32 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Release|Win32.Build.0 = Release|Win32 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Release|x64.ActiveCfg = Release|x64 + {382DC80F-E278-4BC9-9DB6-59014486DA0F}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {72C209C4-49A4-4942-A201-44706C9D77EC} = {190A6643-3DE4-49DC-96AA-7867C5E0A835} + {C90E6CC5-818B-4C97-8876-0986D989387C} = {190A6643-3DE4-49DC-96AA-7867C5E0A835} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {190A6643-3DE4-49DC-96AA-7867C5E0A835} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3876F3F5-8086-4F8E-BB5E-D8840E7D926C} + EndGlobalSection + GlobalSection(TestCaseManagementSettings) = postSolution + CategoryFile = FreeRTOS_Plus_TCP_Minimal.vsmdi + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOS_Plus_TCP_Minimal.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOS_Plus_TCP_Minimal.vcxproj.filters index deeab7a5a..224821e69 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOS_Plus_TCP_Minimal.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOS_Plus_TCP_Minimal.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/ReadMe.txt b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/ReadMe.txt index 682a18c8d..0eb0f7392 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/ReadMe.txt +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/ReadMe.txt @@ -1,34 +1,34 @@ -The FreeRTOS+TCP source code and example projects are currently provided in -their own .zip file download, but using the directory structure of the official -FreeRTOS .zip file download. This allow the projects to be seamlessly moved -from one download to the other, but can seem strange when the files are viewed -in isolation. - -The minimal FreeRTOS+TCP Visual Studio project file is in the following directory: -FreeRTOS-Plus\Demo\FreeRTOS_Plus_TCP_Minimal_Windows_Simulator - -The minimal project is a cut down version of the full Windows demo that only -includes examples of simple TCP and UDP clients. The instructions for the full -Windows demo are still relevant though as they describe how to set up the -WinPCap development environment, how to set the IP address, and other such -items. Note that, as delivered, configUSE_DHCP is set to 0, so a static IP -address is used. The instructions are provided on the following URL: -http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html - -The UDP client example included in the minimal project is described on the -following URL: -http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_client_server.html - -The TCP client example included in the minimal project is described on the -following URL: -http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html - -A description of the FreeRTOS+TCP source code directory is provided on the -following URL: -http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial_Source_Code_Organisation.html - -A description of the way the main FreeRTOS .zip file download source code is -organised is provided on the following URL: -http://www.freertos.org/a00017.html - - +The FreeRTOS+TCP source code and example projects are currently provided in +their own .zip file download, but using the directory structure of the official +FreeRTOS .zip file download. This allow the projects to be seamlessly moved +from one download to the other, but can seem strange when the files are viewed +in isolation. + +The minimal FreeRTOS+TCP Visual Studio project file is in the following directory: +FreeRTOS-Plus\Demo\FreeRTOS_Plus_TCP_Minimal_Windows_Simulator + +The minimal project is a cut down version of the full Windows demo that only +includes examples of simple TCP and UDP clients. The instructions for the full +Windows demo are still relevant though as they describe how to set up the +WinPCap development environment, how to set the IP address, and other such +items. Note that, as delivered, configUSE_DHCP is set to 0, so a static IP +address is used. The instructions are provided on the following URL: +http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html + +The UDP client example included in the minimal project is described on the +following URL: +http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_client_server.html + +The TCP client example included in the minimal project is described on the +following URL: +http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html + +A description of the FreeRTOS+TCP source code directory is provided on the +following URL: +http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial_Source_Code_Organisation.html + +A description of the way the main FreeRTOS .zip file download source code is +organized is provided on the following URL: +http://www.freertos.org/a00017.html + + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/Read_Me_Build_Instructions.url b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/Read_Me_Build_Instructions.url index 3ceab7642..f01ec1411 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/Read_Me_Build_Instructions.url +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/Read_Me_Build_Instructions.url @@ -1,6 +1,6 @@ -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 -[InternetShortcut] -URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html -IDList= -HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html +IDList= +HotKey=0 diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c index 502877baa..126e74776 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c @@ -1,434 +1,433 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * This project is a cut down version of the project described on the following - * link. Only the simple UDP client and server and the TCP echo clients are - * included in the build: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html - */ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include -#include "task.h" - -#include "FreeRTOSIPConfig.h" - -/* Demo application includes. */ -#include "FreeRTOS_IP.h" -#include "FreeRTOS_Sockets.h" -#include "SimpleUDPClientAndServer.h" -#include "SimpleTCPEchoServer.h" -#include "TCPEchoClient_SingleTasks.h" -#include "logging.h" - -/* Simple UDP client and server task parameters. */ -#define mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY ) -#define mainSIMPLE_UDP_CLIENT_SERVER_PORT ( 5005UL ) - -/* Echo client task parameters - used for both TCP and UDP echo clients. */ -#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */ -#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) - -/* Echo server task parameters. */ -#define mainECHO_SERVER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */ -#define mainECHO_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) - -/* Define a name that will be used for LLMNR and NBNS searches. */ -#define mainHOST_NAME "RTOSDemo" -#define mainDEVICE_NICK_NAME "windows_demo" - -/* Set the following constants to 1 or 0 to define which tasks to include and - * exclude: - * - * mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS: When set to 1 two UDP client tasks - * and two UDP server tasks are created. The clients talk to the servers. One set - * of tasks use the standard sockets interface, and the other the zero copy sockets - * interface. These tasks are self checking and will trigger a configASSERT() if - * they detect a difference in the data that is received from that which was sent. - * As these tasks use UDP, and can therefore loose packets, they will cause - * configASSERT() to be called when they are run in a less than perfect networking - * environment. - * - * mainCREATE_TCP_ECHO_TASKS_SINGLE: When set to 1 a set of tasks are created that - * send TCP echo requests to the standard echo port (port 7), then wait for and - * verify the echo reply, from within the same task (Tx and Rx are performed in the - * same RTOS task). The IP address of the echo server must be configured using the - * configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 constants in - * FreeRTOSConfig.h. - * - * mainCREATE_TCP_ECHO_SERVER_TASK: When set to 1 a task is created that accepts - * connections on the standard echo port (port 7), then echos back any data - * received on that connection. - */ -#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 0 -#define mainCREATE_TCP_ECHO_TASKS_SINGLE 1 -#define mainCREATE_TCP_ECHO_SERVER_TASK 0 -/*-----------------------------------------------------------*/ - -/* - * Just seeds the simple pseudo random number generator. - */ -static void prvSRand( UBaseType_t ulSeed ); - -/* - * Miscellaneous initialisation including preparing the logging and seeding the - * random number generator. - */ -static void prvMiscInitialisation( void ); - -/* The default IP and MAC address used by the demo. The address configuration - * defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is - * 1 but a DHCP server could not be contacted. See the online documentation for - * more information. */ -static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 }; -static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 }; -static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 }; -static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 }; - -/* Set the following constant to pdTRUE to log using the method indicated by the - * name of the constant, or pdFALSE to not log using the method indicated by the - * name of the constant. Options include to standard out (xLogToStdout) and to a - * file on disk (xLogToFile). */ -const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE; - -/* Default MAC address configuration. The demo creates a virtual network - * connection that uses this MAC address by accessing the raw Ethernet data - * to and from a real network connection on the host PC. See the - * configNETWORK_INTERFACE_TO_USE definition for information on how to configure - * the real network connection to use. */ -const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 }; - -/* Use by the pseudo random number generator. */ -static UBaseType_t ulNextRand; -/*-----------------------------------------------------------*/ - -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - /* In case multiple interfaces are used, define them statically. */ - - /* With WinPCap there is only 1 physical interface. */ - static NetworkInterface_t xInterfaces[ 1 ]; - - /* It will have several end-points. */ - static NetworkEndPoint_t xEndPoints[ 4 ]; - -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - -/*-----------------------------------------------------------*/ - -int main( void ) -{ - const uint32_t ulLongTime_ms = pdMS_TO_TICKS( 1000UL ); - - /* - * Instructions for using this project are provided on: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html - */ - - /* Miscellaneous initialisation including preparing the logging and seeding - * the random number generator. */ - prvMiscInitialisation(); - - /* Initialise the network interface. - * - ***NOTE*** Tasks that use the network are created in the network event hook - * when the network is connected and ready for use (see the definition of - * vApplicationIPNetworkEventHook() below). The address values passed in here - * are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1 - * but a DHCP server cannot be contacted. */ - - /* Initialise the network interface.*/ - FreeRTOS_debug_printf( ( "FreeRTOS_IPInit\r\n" ) ); - -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - -#ifdef ipconfigUSE_LIBSLIRP - extern NetworkInterface_t* pxLibslirp_FillInterfaceDescriptor(BaseType_t xEMACIndex, - NetworkInterface_t * pxInterface); - pxLibslirp_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); -#else - pxWinPcap_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); -#endif - - /* === End-point 0 === */ - FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); - #if ( ipconfigUSE_DHCP != 0 ) - { - /* End-point 0 wants to use DHCPv4. */ - xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; - } - #endif /* ( ipconfigUSE_DHCP != 0 ) */ - - memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof( ucMACAddress ) ); - - FreeRTOS_IPInit_Multi(); -#else - /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ - FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - /* Start the RTOS scheduler. */ - FreeRTOS_debug_printf( ( "vTaskStartScheduler\r\n" ) ); - vTaskStartScheduler(); - - /* If all is well, the scheduler will now be running, and the following - * line will never be reached. If the following line does execute, then - * there was insufficient FreeRTOS heap memory available for the idle and/or - * timer tasks to be created. See the memory management section on the - * FreeRTOS web site for more details (this is standard text that is not not - * really applicable to the Win32 simulator port). */ - for( ; ; ) - { - Sleep( ulLongTime_ms ); - } -} -/*-----------------------------------------------------------*/ - -void vApplicationIdleHook( void ) -{ - const uint32_t ulMSToSleep = 1; - - /* This is just a trivial example of an idle hook. It is called on each - * cycle of the idle task if configUSE_IDLE_HOOK is set to 1 in - * FreeRTOSConfig.h. It must *NOT* attempt to block. In this case the - * idle task just sleeps to lower the CPU usage. */ - Sleep( ulMSToSleep ); -} -/*-----------------------------------------------------------*/ - - -/* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect - * events are only received if implemented in the MAC driver. */ -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, - struct xNetworkEndPoint * pxEndPoint ) -#else - void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ -{ - uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress; - char cBuffer[ 16 ]; - static BaseType_t xTasksAlreadyCreated = pdFALSE; - - /* If the network has just come up...*/ - if( eNetworkEvent == eNetworkUp ) - { - /* Create the tasks that use the IP stack if they have not already been - * created. */ - if( xTasksAlreadyCreated == pdFALSE ) - { - /* See the comments above the definitions of these pre-processor - * macros at the top of this file for a description of the individual - * demo tasks. */ - #if ( mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS == 1 ) - { - vStartSimpleUDPClientServerTasks( configMINIMAL_STACK_SIZE, mainSIMPLE_UDP_CLIENT_SERVER_PORT, mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY ); - } - #endif /* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS */ - - #if ( mainCREATE_TCP_ECHO_TASKS_SINGLE == 1 ) - { - vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY ); - } - #endif /* mainCREATE_TCP_ECHO_TASKS_SINGLE */ - - #if ( mainCREATE_TCP_ECHO_SERVER_TASK == 1 ) - { - vStartSimpleTCPServerTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY ); - } - #endif - - xTasksAlreadyCreated = pdTRUE; - } - - /* Print out the network configuration, which may have come from a DHCP - * server. */ - - /* Using ipconfigIPv4_BACKWARD_COMPATIBLE as the substitute of the - * downward compatibility*/ - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - FreeRTOS_inet_ntoa( ulIPAddress, cBuffer ); - FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) ); - - FreeRTOS_inet_ntoa( ulNetMask, cBuffer ); - FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) ); - - FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer ); - FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) ); - - FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer ); - FreeRTOS_printf( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) ); - } -} -/*-----------------------------------------------------------*/ - -void vApplicationMallocFailedHook( void ) -{ - /* Called if a call to pvPortMalloc() fails because there is insufficient - * free memory available in the FreeRTOS heap. pvPortMalloc() is called - * internally by FreeRTOS API functions that create tasks, queues, software - * timers, and semaphores. The size of the FreeRTOS heap is set by the - * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ - vAssertCalled( __FILE__, __LINE__ ); -} -/*-----------------------------------------------------------*/ - - -static void prvSRand( UBaseType_t ulSeed ) -{ - /* Utility function to seed the pseudo random number generator. */ - ulNextRand = ulSeed; -} -/*-----------------------------------------------------------*/ - -static void prvMiscInitialisation( void ) -{ - time_t xTimeNow; - uint32_t ulRandomNumbers[ 4 ]; - - vLoggingInit( xLogToStdout, xLogToFile, pdFALSE, 0, 0 ); - - /* Seed the random number generator. */ - time( &xTimeNow ); - FreeRTOS_debug_printf( ( "Seed for randomiser: %lu\r\n", xTimeNow ) ); - prvSRand( ( uint32_t ) xTimeNow ); - - ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 0 ] ); - ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 1 ] ); - ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 2 ] ); - ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 3 ] ); - FreeRTOS_debug_printf( ( "Random numbers: %08X %08X %08X %08X\r\n", - ulRandomNumbers[ 0 ], - ulRandomNumbers[ 1 ], - ulRandomNumbers[ 2 ], - ulRandomNumbers[ 3 ] ) ); -} -/*-----------------------------------------------------------*/ - -#if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 ) - - const char * pcApplicationHostnameHook( void ) - { - /* Assign the name "FreeRTOS" to this network node. This function will - * be called during the DHCP: the machine will be registered with an IP - * address plus this name. */ - return mainHOST_NAME; - } - -#endif -/*-----------------------------------------------------------*/ - -#if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) - - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, - const char * pcName ) - #else - BaseType_t xApplicationDNSQueryHook( const char * pcName ) - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - { - BaseType_t xReturn; - - /* Determine if a name lookup is for this node. Two names are given - * to this node: that returned by pcApplicationHostnameHook() and that set - * by mainDEVICE_NICK_NAME. */ - if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 ) - { - xReturn = pdPASS; - } - else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 ) - { - xReturn = pdPASS; - } - else - { - xReturn = pdFAIL; - } - - return xReturn; - } - -#endif /* if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) */ -/*-----------------------------------------------------------*/ - -/* - * Callback that provides the inputs necessary to generate a randomized TCP - * Initial Sequence Number per RFC 6528. THIS IS ONLY A DUMMY IMPLEMENTATION - * THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION - * SYSTEMS. - */ -extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress, - uint16_t usSourcePort, - uint32_t ulDestinationAddress, - uint16_t usDestinationPort ) -{ - ( void ) ulSourceAddress; - ( void ) usSourcePort; - ( void ) ulDestinationAddress; - ( void ) usDestinationPort; - - return uxRand(); -} -/*-----------------------------------------------------------*/ - -/* - * Supply a random number to FreeRTOS+TCP stack. - * THIS IS ONLY A DUMMY IMPLEMENTATION THAT RETURNS A PSEUDO RANDOM NUMBER - * SO IS NOT INTENDED FOR USE IN PRODUCTION SYSTEMS. - */ -BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber ) -{ - *( pulNumber ) = uxRand(); - return pdTRUE; -} -/*-----------------------------------------------------------*/ - -#if ( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_DHCP_HOOK != 0 ) ) - - #if ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 ) - eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, - uint32_t ulIPAddress ) - #else /* ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 ) */ - eDHCPCallbackAnswer_t xApplicationDHCPHook_Multi( eDHCPCallbackPhase_t eDHCPPhase, - struct xNetworkEndPoint * pxEndPoint, - IP_Address_t * pxIPAddress ) - #endif /* ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 ) */ -{ - /* Provide a stub for this function. */ - return eDHCPContinue; -} - -#endif -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * This project is a cut down version of the project described on the following + * link. Only the simple UDP client and server and the TCP echo clients are + * included in the build: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html + */ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include +#include "task.h" + +#include "FreeRTOSIPConfig.h" + +/* Demo application includes. */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" +#include "SimpleUDPClientAndServer.h" +#include "SimpleTCPEchoServer.h" +#include "TCPEchoClient_SingleTasks.h" +#include "logging.h" + +/* Simple UDP client and server task parameters. */ +#define mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define mainSIMPLE_UDP_CLIENT_SERVER_PORT ( 5005UL ) + +/* Echo client task parameters - used for both TCP and UDP echo clients. */ +#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */ +#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* Echo server task parameters. */ +#define mainECHO_SERVER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) /* Not used in the Windows port. */ +#define mainECHO_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* Define a name that will be used for LLMNR and NBNS searches. */ +#define mainHOST_NAME "RTOSDemo" +#define mainDEVICE_NICK_NAME "windows_demo" + +/* Set the following constants to 1 or 0 to define which tasks to include and + * exclude: + * + * mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS: When set to 1 two UDP client tasks + * and two UDP server tasks are created. The clients talk to the servers. One set + * of tasks use the standard sockets interface, and the other the zero copy sockets + * interface. These tasks are self checking and will trigger a configASSERT() if + * they detect a difference in the data that is received from that which was sent. + * As these tasks use UDP, and can therefore loose packets, they will cause + * configASSERT() to be called when they are run in a less than perfect networking + * environment. + * + * mainCREATE_TCP_ECHO_TASKS_SINGLE: When set to 1 a set of tasks are created that + * send TCP echo requests to the standard echo port (port 7), then wait for and + * verify the echo reply, from within the same task (Tx and Rx are performed in the + * same RTOS task). The IP address of the echo server must be configured using the + * configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 constants in + * FreeRTOSConfig.h. + * + * mainCREATE_TCP_ECHO_SERVER_TASK: When set to 1 a task is created that accepts + * connections on the standard echo port (port 7), then echos back any data + * received on that connection. + */ +#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 0 +#define mainCREATE_TCP_ECHO_TASKS_SINGLE 1 +#define mainCREATE_TCP_ECHO_SERVER_TASK 0 +/*-----------------------------------------------------------*/ + +/* + * Just seeds the simple pseudo random number generator. + */ +static void prvSRand( UBaseType_t ulSeed ); + +/* + * Miscellaneous initialisation including preparing the logging and seeding the + * random number generator. + */ +static void prvMiscInitialisation( void ); + +/* The default IP and MAC address used by the demo. The address configuration + * defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is + * 1 but a DHCP server could not be contacted. See the online documentation for + * more information. */ +static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 }; +static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 }; +static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 }; +static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 }; + +/* Set the following constant to pdTRUE to log using the method indicated by the + * name of the constant, or pdFALSE to not log using the method indicated by the + * name of the constant. Options include to standard out (xLogToStdout) and to a + * file on disk (xLogToFile). */ +const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE; + +/* Default MAC address configuration. The demo creates a virtual network + * connection that uses this MAC address by accessing the raw Ethernet data + * to and from a real network connection on the host PC. See the + * configNETWORK_INTERFACE_TO_USE definition for information on how to configure + * the real network connection to use. */ +const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 }; + +/* Use by the pseudo random number generator. */ +static UBaseType_t ulNextRand; +/*-----------------------------------------------------------*/ + +#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + /* In case multiple interfaces are used, define them statically. */ + +/* With WinPCap there is only 1 physical interface. */ + static NetworkInterface_t xInterfaces[ 1 ]; + +/* It will have several end-points. */ + static NetworkEndPoint_t xEndPoints[ 4 ]; + +#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + const uint32_t ulLongTime_ms = pdMS_TO_TICKS( 1000UL ); + + /* + * Instructions for using this project are provided on: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html + */ + + /* Miscellaneous initialisation including preparing the logging and seeding + * the random number generator. */ + prvMiscInitialisation(); + + /* Initialise the network interface. + * + ***NOTE*** Tasks that use the network are created in the network event hook + * when the network is connected and ready for use (see the definition of + * vApplicationIPNetworkEventHook() below). The address values passed in here + * are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1 + * but a DHCP server cannot be contacted. */ + + /* Initialise the network interface.*/ + FreeRTOS_debug_printf( ( "FreeRTOS_IPInit\r\n" ) ); + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + #ifdef ipconfigUSE_LIBSLIRP + extern NetworkInterface_t * pxLibslirp_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ); + pxLibslirp_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); + #else + pxWinPcap_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); + #endif + + /* === End-point 0 === */ + FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + #if ( ipconfigUSE_DHCP != 0 ) + { + /* End-point 0 wants to use DHCPv4. */ + xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; + } + #endif /* ( ipconfigUSE_DHCP != 0 ) */ + + memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof( ucMACAddress ) ); + + FreeRTOS_IPInit_Multi(); + #else /* if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ + FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + + /* Start the RTOS scheduler. */ + FreeRTOS_debug_printf( ( "vTaskStartScheduler\r\n" ) ); + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + * line will never be reached. If the following line does execute, then + * there was insufficient FreeRTOS heap memory available for the idle and/or + * timer tasks to be created. See the memory management section on the + * FreeRTOS web site for more details (this is standard text that is not not + * really applicable to the Win32 simulator port). */ + for( ; ; ) + { + Sleep( ulLongTime_ms ); + } +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + const uint32_t ulMSToSleep = 1; + + /* This is just a trivial example of an idle hook. It is called on each + * cycle of the idle task if configUSE_IDLE_HOOK is set to 1 in + * FreeRTOSConfig.h. It must *NOT* attempt to block. In this case the + * idle task just sleeps to lower the CPU usage. */ + Sleep( ulMSToSleep ); +} +/*-----------------------------------------------------------*/ + + +/* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect + * events are only received if implemented in the MAC driver. */ +#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, + struct xNetworkEndPoint * pxEndPoint ) +#else + void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) +#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ +{ + uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress; + char cBuffer[ 16 ]; + static BaseType_t xTasksAlreadyCreated = pdFALSE; + + /* If the network has just come up...*/ + if( eNetworkEvent == eNetworkUp ) + { + /* Create the tasks that use the IP stack if they have not already been + * created. */ + if( xTasksAlreadyCreated == pdFALSE ) + { + /* See the comments above the definitions of these pre-processor + * macros at the top of this file for a description of the individual + * demo tasks. */ + #if ( mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS == 1 ) + { + vStartSimpleUDPClientServerTasks( configMINIMAL_STACK_SIZE, mainSIMPLE_UDP_CLIENT_SERVER_PORT, mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY ); + } + #endif /* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS */ + + #if ( mainCREATE_TCP_ECHO_TASKS_SINGLE == 1 ) + { + vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY ); + } + #endif /* mainCREATE_TCP_ECHO_TASKS_SINGLE */ + + #if ( mainCREATE_TCP_ECHO_SERVER_TASK == 1 ) + { + vStartSimpleTCPServerTasks( mainECHO_SERVER_TASK_STACK_SIZE, mainECHO_SERVER_TASK_PRIORITY ); + } + #endif + + xTasksAlreadyCreated = pdTRUE; + } + + /* Print out the network configuration, which may have come from a DHCP + * server. */ + + /* Using ipconfigIPv4_BACKWARD_COMPATIBLE as the substitute of the + * downward compatibility*/ + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + FreeRTOS_inet_ntoa( ulIPAddress, cBuffer ); + FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) ); + + FreeRTOS_inet_ntoa( ulNetMask, cBuffer ); + FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) ); + + FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer ); + FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) ); + + FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer ); + FreeRTOS_printf( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) ); + } +} +/*-----------------------------------------------------------*/ + +void vApplicationMallocFailedHook( void ) +{ + /* Called if a call to pvPortMalloc() fails because there is insufficient + * free memory available in the FreeRTOS heap. pvPortMalloc() is called + * internally by FreeRTOS API functions that create tasks, queues, software + * timers, and semaphores. The size of the FreeRTOS heap is set by the + * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ + vAssertCalled( __FILE__, __LINE__ ); +} +/*-----------------------------------------------------------*/ + + +static void prvSRand( UBaseType_t ulSeed ) +{ + /* Utility function to seed the pseudo random number generator. */ + ulNextRand = ulSeed; +} +/*-----------------------------------------------------------*/ + +static void prvMiscInitialisation( void ) +{ + time_t xTimeNow; + uint32_t ulRandomNumbers[ 4 ]; + + vLoggingInit( xLogToStdout, xLogToFile, pdFALSE, 0, 0 ); + + /* Seed the random number generator. */ + time( &xTimeNow ); + FreeRTOS_debug_printf( ( "Seed for randomiser: %lu\r\n", xTimeNow ) ); + prvSRand( ( uint32_t ) xTimeNow ); + + ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 0 ] ); + ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 1 ] ); + ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 2 ] ); + ( void ) xApplicationGetRandomNumber( &ulRandomNumbers[ 3 ] ); + FreeRTOS_debug_printf( ( "Random numbers: %08X %08X %08X %08X\r\n", + ulRandomNumbers[ 0 ], + ulRandomNumbers[ 1 ], + ulRandomNumbers[ 2 ], + ulRandomNumbers[ 3 ] ) ); +} +/*-----------------------------------------------------------*/ + +#if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 ) + + const char * pcApplicationHostnameHook( void ) + { + /* Assign the name "FreeRTOS" to this network node. This function will + * be called during the DHCP: the machine will be registered with an IP + * address plus this name. */ + return mainHOST_NAME; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) + + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, + const char * pcName ) + #else + BaseType_t xApplicationDNSQueryHook( const char * pcName ) + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + { + BaseType_t xReturn; + + /* Determine if a name lookup is for this node. Two names are given + * to this node: that returned by pcApplicationHostnameHook() and that set + * by mainDEVICE_NICK_NAME. */ + if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 ) + { + xReturn = pdPASS; + } + else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 ) + { + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) */ +/*-----------------------------------------------------------*/ + +/* + * Callback that provides the inputs necessary to generate a randomized TCP + * Initial Sequence Number per RFC 6528. THIS IS ONLY A DUMMY IMPLEMENTATION + * THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION + * SYSTEMS. + */ +extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress, + uint16_t usSourcePort, + uint32_t ulDestinationAddress, + uint16_t usDestinationPort ) +{ + ( void ) ulSourceAddress; + ( void ) usSourcePort; + ( void ) ulDestinationAddress; + ( void ) usDestinationPort; + + return uxRand(); +} +/*-----------------------------------------------------------*/ + +/* + * Supply a random number to FreeRTOS+TCP stack. + * THIS IS ONLY A DUMMY IMPLEMENTATION THAT RETURNS A PSEUDO RANDOM NUMBER + * SO IS NOT INTENDED FOR USE IN PRODUCTION SYSTEMS. + */ +BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber ) +{ + *( pulNumber ) = uxRand(); + return pdTRUE; +} +/*-----------------------------------------------------------*/ + +#if ( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_DHCP_HOOK != 0 ) ) + + #if ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 ) + eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, + uint32_t ulIPAddress ) + #else /* ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 ) */ + eDHCPCallbackAnswer_t xApplicationDHCPHook_Multi( eDHCPCallbackPhase_t eDHCPPhase, + struct xNetworkEndPoint * pxEndPoint, + IP_Address_t * pxIPAddress ) + #endif /* ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 ) */ + { + /* Provide a stub for this function. */ + return eDHCPContinue; + } + +#endif /* if ( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_DHCP_HOOK != 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/tcp_echo_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/tcp_echo_config.h index cab889c1a..422275783 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/tcp_echo_config.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/tcp_echo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/CLI-commands.c index 36f5c894c..f3f7139e7 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/CLI-commands.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/CLI-commands.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -24,12 +24,12 @@ * */ - /****************************************************************************** - * - * See the following URL for information on the commands defined in this file: - * http://localhost/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml - * - ******************************************************************************/ +/****************************************************************************** +* +* See the following URL for information on the commands defined in this file: +* http://localhost/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml +* +******************************************************************************/ /* FreeRTOS includes. */ @@ -45,602 +45,635 @@ #include "FreeRTOS_CLI.h" /* FreeRTOS+UDP includes, just to make the stats available to the CLI -commands. */ + * commands. */ #include "FreeRTOS_UDP_IP.h" #include "FreeRTOS_Sockets.h" #ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS - #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0 + #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0 #endif /* * Implements the run-time-stats command. */ -static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); +static portBASE_TYPE prvTaskStatsCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ); /* * Implements the task-stats command. */ -static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); +static portBASE_TYPE prvRunTimeStatsCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ); /* * Implements the echo-three-parameters command. */ -static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); +static portBASE_TYPE prvThreeParameterEchoCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ); /* * Implements the echo-parameters command. */ -static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); +static portBASE_TYPE prvParameterEchoCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ); /* * Defines a command that prints out IP address information. */ -static portBASE_TYPE prvDisplayIPConfig( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); +static portBASE_TYPE prvDisplayIPConfig( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ); /* * Defines a command that prints out the gathered demo debug stats. */ -static portBASE_TYPE prvDisplayIPDebugStats( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); +static portBASE_TYPE prvDisplayIPDebugStats( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ); /* * Defines a command that sends an ICMP ping request to an IP address. */ -static portBASE_TYPE prvPingCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); +static portBASE_TYPE prvPingCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ); /* * Implements the "trace start" and "trace stop" commands; */ #if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + static portBASE_TYPE prvStartStopTraceCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ); #endif /* Structure that defines the "ip-config" command line command. */ static const CLI_Command_Definition_t xIPConfig = { - ( const int8_t * const ) "ip-config", - ( const int8_t * const ) "ip-config:\r\n Displays IP address configuration\r\n\r\n", - prvDisplayIPConfig, - 0 + ( const int8_t * const ) "ip-config", + ( const int8_t * const ) "ip-config:\r\n Displays IP address configuration\r\n\r\n", + prvDisplayIPConfig, + 0 }; #if configINCLUDE_DEMO_DEBUG_STATS != 0 - /* Structure that defines the "ip-debug-stats" command line command. */ - static const CLI_Command_Definition_t xIPDebugStats = - { - ( const int8_t * const ) "ip-debug-stats", /* The command string to type. */ - ( const int8_t * const ) "ip-debug-stats:\r\n Shows some IP stack stats useful for debug - an example only.\r\n\r\n", - prvDisplayIPDebugStats, /* The function to run. */ - 0 /* No parameters are expected. */ - }; + /* Structure that defines the "ip-debug-stats" command line command. */ + static const CLI_Command_Definition_t xIPDebugStats = + { + ( const int8_t * const ) "ip-debug-stats", /* The command string to type. */ + ( const int8_t * const ) "ip-debug-stats:\r\n Shows some IP stack stats useful for debug - an example only.\r\n\r\n", + prvDisplayIPDebugStats, /* The function to run. */ + 0 /* No parameters are expected. */ + }; #endif /* configINCLUDE_DEMO_DEBUG_STATS */ /* Structure that defines the "run-time-stats" command line command. This -generates a table that shows how much run time each task has */ + * generates a table that shows how much run time each task has */ static const CLI_Command_Definition_t xRunTimeStats = { - ( const int8_t * const ) "run-time-stats", /* The command string to type. */ - ( const int8_t * const ) "run-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n", - prvRunTimeStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ + ( const int8_t * const ) "run-time-stats", /* The command string to type. */ + ( const int8_t * const ) "run-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n", + prvRunTimeStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ }; /* Structure that defines the "task-stats" command line command. This generates -a table that gives information on each task in the system. */ + * a table that gives information on each task in the system. */ static const CLI_Command_Definition_t xTaskStats = { - ( const int8_t * const ) "task-stats", /* The command string to type. */ - ( const int8_t * const ) "task-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n\r\n", - prvTaskStatsCommand, /* The function to run. */ - 0 /* No parameters are expected. */ + ( const int8_t * const ) "task-stats", /* The command string to type. */ + ( const int8_t * const ) "task-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n\r\n", + prvTaskStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ }; /* Structure that defines the "echo_3_parameters" command line command. This -takes exactly three parameters that the command simply echos back one at a -time. */ + * takes exactly three parameters that the command simply echos back one at a + * time. */ static const CLI_Command_Definition_t xThreeParameterEcho = { - ( const int8_t * const ) "echo-3-parameters", - ( const int8_t * const ) "echo-3-parameters :\r\n Expects three parameters, echos each in turn\r\n\r\n", - prvThreeParameterEchoCommand, /* The function to run. */ - 3 /* Three parameters are expected, which can take any value. */ + ( const int8_t * const ) "echo-3-parameters", + ( const int8_t * const ) "echo-3-parameters :\r\n Expects three parameters, echos each in turn\r\n\r\n", + prvThreeParameterEchoCommand, /* The function to run. */ + 3 /* Three parameters are expected, which can take any value. */ }; /* Structure that defines the "echo_parameters" command line command. This -takes a variable number of parameters that the command simply echos back one at -a time. */ + * takes a variable number of parameters that the command simply echos back one at + * a time. */ static const CLI_Command_Definition_t xParameterEcho = { - ( const int8_t * const ) "echo-parameters", - ( const int8_t * const ) "echo-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n\r\n", - prvParameterEchoCommand, /* The function to run. */ - -1 /* The user can enter any number of commands. */ + ( const int8_t * const ) "echo-parameters", + ( const int8_t * const ) "echo-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n\r\n", + prvParameterEchoCommand, /* The function to run. */ + -1 /* The user can enter any number of commands. */ }; #if ipconfigSUPPORT_OUTGOING_PINGS == 1 - /* Structure that defines the "ping" command line command. This takes an IP - address or host name and (optionally) the number of bytes to ping as - parameters. */ - static const CLI_Command_Definition_t xPing = - { - ( const int8_t * const ) "ping", - ( const int8_t * const ) "ping :\r\n for example, ping 192.168.0.3 8, or ping www.example.com\r\n\r\n", - prvPingCommand, /* The function to run. */ - -1 /* Ping can take either one or two parameter, so the number of parameters has to be determined by the ping command implementation. */ - }; +/* Structure that defines the "ping" command line command. This takes an IP + * address or host name and (optionally) the number of bytes to ping as + * parameters. */ + static const CLI_Command_Definition_t xPing = + { + ( const int8_t * const ) "ping", + ( const int8_t * const ) "ping :\r\n for example, ping 192.168.0.3 8, or ping www.example.com\r\n\r\n", + prvPingCommand, /* The function to run. */ + -1 /* Ping can take either one or two parameter, so the number of parameters has to be determined by the ping command implementation. */ + }; #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ #if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - /* Structure that defines the "trace" command line command. This takes a single - parameter, which can be either "start" or "stop". */ - static const CLI_Command_Definition_t xStartStopTrace = - { - ( const int8_t * const ) "trace", - ( const int8_t * const ) "trace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n\r\n", - prvStartStopTraceCommand, /* The function to run. */ - 1 /* One parameter is expected. Valid values are "start" and "stop". */ - }; + +/* Structure that defines the "trace" command line command. This takes a single + * parameter, which can be either "start" or "stop". */ + static const CLI_Command_Definition_t xStartStopTrace = + { + ( const int8_t * const ) "trace", + ( const int8_t * const ) "trace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n\r\n", + prvStartStopTraceCommand, /* The function to run. */ + 1 /* One parameter is expected. Valid values are "start" and "stop". */ + }; #endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ /*-----------------------------------------------------------*/ void vRegisterCLICommands( void ) { - /* Register all the command line commands defined immediately above. */ - FreeRTOS_CLIRegisterCommand( &xTaskStats ); - FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); - FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); - FreeRTOS_CLIRegisterCommand( &xParameterEcho ); - FreeRTOS_CLIRegisterCommand( &xIPConfig ); + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xTaskStats ); + FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); + FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); + FreeRTOS_CLIRegisterCommand( &xParameterEcho ); + FreeRTOS_CLIRegisterCommand( &xIPConfig ); - #if ipconfigSUPPORT_OUTGOING_PINGS == 1 - { - FreeRTOS_CLIRegisterCommand( &xPing ); - } - #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ + #if ipconfigSUPPORT_OUTGOING_PINGS == 1 + { + FreeRTOS_CLIRegisterCommand( &xPing ); + } + #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ - #if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - FreeRTOS_CLIRegisterCommand( & xStartStopTrace ); - #endif + #if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + FreeRTOS_CLIRegisterCommand( &xStartStopTrace ); + #endif } /*-----------------------------------------------------------*/ -static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +static portBASE_TYPE prvTaskStatsCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ) { -const int8_t *const pcHeader = ( int8_t * ) "Task State Priority Stack #\r\n************************************************\r\n"; + const int8_t * const pcHeader = ( int8_t * ) "Task State Priority Stack #\r\n************************************************\r\n"; - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); - /* Generate a table of task stats. */ - strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader ); - vTaskList( pcWriteBuffer + strlen( ( char * ) pcHeader ) ); + /* Generate a table of task stats. */ + strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader ); + vTaskList( pcWriteBuffer + strlen( ( char * ) pcHeader ) ); - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; } /*-----------------------------------------------------------*/ -static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +static portBASE_TYPE prvRunTimeStatsCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ) { -const int8_t * const pcHeader = ( int8_t * ) "Task Abs Time % Time\r\n****************************************\r\n"; + const int8_t * const pcHeader = ( int8_t * ) "Task Abs Time % Time\r\n****************************************\r\n"; - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); - /* Generate a table of task stats. */ - strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader ); + /* Generate a table of task stats. */ + strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader ); #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - vTaskGetRunTimeStats( pcWriteBuffer + strlen( ( char * ) pcHeader ) ); + vTaskGetRunTimeStats( pcWriteBuffer + strlen( ( char * ) pcHeader ) ); #endif - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; } /*-----------------------------------------------------------*/ -static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +static portBASE_TYPE prvThreeParameterEchoCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ) { -int8_t *pcParameter; -portBASE_TYPE xParameterStringLength, xReturn; -static portBASE_TYPE lParameterNumber = 0; + int8_t * pcParameter; + portBASE_TYPE xParameterStringLength, xReturn; + static portBASE_TYPE lParameterNumber = 0; - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); - if( lParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( ( char * ) pcWriteBuffer, "The three parameters were:\r\n" ); + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( ( char * ) pcWriteBuffer, "The three parameters were:\r\n" ); - /* Next time the function is called the first parameter will be echoed - back. */ - lParameterNumber = 1L; + /* Next time the function is called the first parameter will be echoed + * back. */ + lParameterNumber = 1L; - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - lParameterNumber, /* Return the next parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); - /* Sanity check something was returned. */ - configASSERT( pcParameter ); + /* Sanity check something was returned. */ + configASSERT( pcParameter ); - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); - strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength ); - strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); + strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength ); + strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - if( lParameterNumber == 3L ) - { - /* If this is the last of the three parameters then there are no more - strings to return after this one. */ - xReturn = pdFALSE; - lParameterNumber = 0L; - } - else - { - /* There are more parameters to return after this one. */ - xReturn = pdTRUE; - lParameterNumber++; - } - } + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + if( lParameterNumber == 3L ) + { + /* If this is the last of the three parameters then there are no more + * strings to return after this one. */ + xReturn = pdFALSE; + lParameterNumber = 0L; + } + else + { + /* There are more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + } - return xReturn; + return xReturn; } /*-----------------------------------------------------------*/ -static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +static portBASE_TYPE prvParameterEchoCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ) { -int8_t *pcParameter; -portBASE_TYPE xParameterStringLength, xReturn; -static portBASE_TYPE lParameterNumber = 0; + int8_t * pcParameter; + portBASE_TYPE xParameterStringLength, xReturn; + static portBASE_TYPE lParameterNumber = 0; - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); - if( lParameterNumber == 0 ) - { - /* The first time the function is called after the command has been - entered just a header string is returned. */ - sprintf( ( char * ) pcWriteBuffer, "The parameters were:\r\n" ); + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + * entered just a header string is returned. */ + sprintf( ( char * ) pcWriteBuffer, "The parameters were:\r\n" ); - /* Next time the function is called the first parameter will be echoed - back. */ - lParameterNumber = 1L; + /* Next time the function is called the first parameter will be echoed + * back. */ + lParameterNumber = 1L; - /* There is more data to be returned as no parameters have been echoed - back yet. */ - xReturn = pdPASS; - } - else - { - /* Obtain the parameter string. */ - pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - lParameterNumber, /* Return the next parameter. */ - &xParameterStringLength /* Store the parameter string length. */ - ); + /* There is more data to be returned as no parameters have been echoed + * back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); - if( pcParameter != NULL ) - { - /* Return the parameter string. */ - memset( pcWriteBuffer, 0x00, xWriteBufferLen ); - sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); - strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength ); - strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + if( pcParameter != NULL ) + { + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); + strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength ); + strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); - /* There might be more parameters to return after this one. */ - xReturn = pdTRUE; - lParameterNumber++; - } - else - { - /* No more parameters were found. Make sure the write buffer does - not contain a valid string. */ - pcWriteBuffer[ 0 ] = 0x00; + /* There might be more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + else + { + /* No more parameters were found. Make sure the write buffer does + * not contain a valid string. */ + pcWriteBuffer[ 0 ] = 0x00; - /* No more data to return. */ - xReturn = pdFALSE; + /* No more data to return. */ + xReturn = pdFALSE; - /* Start over the next time this command is executed. */ - lParameterNumber = 0; - } - } + /* Start over the next time this command is executed. */ + lParameterNumber = 0; + } + } - return xReturn; + return xReturn; } /*-----------------------------------------------------------*/ #if ipconfigSUPPORT_OUTGOING_PINGS == 1 - static portBASE_TYPE prvPingCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) - { - int8_t * pcParameter; - portBASE_TYPE lParameterStringLength, xReturn; - uint32_t ulIPAddress, ulBytesToPing; - const uint32_t ulDefaultBytesToPing = 8UL; - int8_t cBuffer[ 16 ]; + static portBASE_TYPE prvPingCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ) + { + int8_t * pcParameter; + portBASE_TYPE lParameterStringLength, xReturn; + uint32_t ulIPAddress, ulBytesToPing; + const uint32_t ulDefaultBytesToPing = 8UL; + int8_t cBuffer[ 16 ]; - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); - /* Start with an empty string. */ - pcWriteBuffer[ 0 ] = 0x00; + /* Start with an empty string. */ + pcWriteBuffer[ 0 ] = 0x00; - /* Obtain the number of bytes to ping. */ - pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 2, /* Return the second parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); + /* Obtain the number of bytes to ping. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 2, /* Return the second parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); - if( pcParameter == NULL ) - { - /* The number of bytes was not specified, so default it. */ - ulBytesToPing = ulDefaultBytesToPing; - } - else - { - ulBytesToPing = atol( ( const char * ) pcParameter ); - } + if( pcParameter == NULL ) + { + /* The number of bytes was not specified, so default it. */ + ulBytesToPing = ulDefaultBytesToPing; + } + else + { + ulBytesToPing = atol( ( const char * ) pcParameter ); + } - /* Obtain the IP address string. */ - pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); + /* Obtain the IP address string. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); - /* Sanity check something was returned. */ - configASSERT( pcParameter ); + /* Sanity check something was returned. */ + configASSERT( pcParameter ); - /* Attempt to obtain the IP address. If the first character is not a - digit, assume the host name has been passed in. */ - if( ( *pcParameter >= '0' ) && ( *pcParameter <= '9' ) ) - { - ulIPAddress = FreeRTOS_inet_addr( ( const uint8_t * ) pcParameter ); - } - else - { - /* Terminate the host name. */ - pcParameter[ lParameterStringLength ] = 0x00; + /* Attempt to obtain the IP address. If the first character is not a + * digit, assume the host name has been passed in. */ + if( ( *pcParameter >= '0' ) && ( *pcParameter <= '9' ) ) + { + ulIPAddress = FreeRTOS_inet_addr( ( const uint8_t * ) pcParameter ); + } + else + { + /* Terminate the host name. */ + pcParameter[ lParameterStringLength ] = 0x00; - /* Attempt to resolve host. */ - ulIPAddress = FreeRTOS_gethostbyname( ( uint8_t * ) pcParameter ); - } + /* Attempt to resolve host. */ + ulIPAddress = FreeRTOS_gethostbyname( ( uint8_t * ) pcParameter ); + } - /* Convert IP address, which may have come from a DNS lookup, to string. */ - FreeRTOS_inet_ntoa( ulIPAddress, ( char * ) cBuffer ); + /* Convert IP address, which may have come from a DNS lookup, to string. */ + FreeRTOS_inet_ntoa( ulIPAddress, ( char * ) cBuffer ); - if( ulIPAddress != 0 ) - { - xReturn = FreeRTOS_SendPingRequest( ulIPAddress, ( uint16_t ) ulBytesToPing, portMAX_DELAY ); - } - else - { - xReturn = pdFALSE; - } + if( ulIPAddress != 0 ) + { + xReturn = FreeRTOS_SendPingRequest( ulIPAddress, ( uint16_t ) ulBytesToPing, portMAX_DELAY ); + } + else + { + xReturn = pdFALSE; + } - if( xReturn == pdFALSE ) - { - sprintf( ( char * ) pcWriteBuffer, "%s", "Could not send ping request\r\n" ); - } - else - { - sprintf( ( char * ) pcWriteBuffer, "Ping sent to %s with identifier %d\r\n", cBuffer, xReturn ); - } + if( xReturn == pdFALSE ) + { + sprintf( ( char * ) pcWriteBuffer, "%s", "Could not send ping request\r\n" ); + } + else + { + sprintf( ( char * ) pcWriteBuffer, "Ping sent to %s with identifier %d\r\n", cBuffer, xReturn ); + } - return pdFALSE; - } - /*-----------------------------------------------------------*/ + return pdFALSE; + } + /*-----------------------------------------------------------*/ #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ #if configINCLUDE_DEMO_DEBUG_STATS != 0 - static portBASE_TYPE prvDisplayIPDebugStats( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) - { - static portBASE_TYPE xIndex = -1; - extern xExampleDebugStatEntry_t xIPTraceValues[]; - portBASE_TYPE xReturn; + static portBASE_TYPE prvDisplayIPDebugStats( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ) + { + static portBASE_TYPE xIndex = -1; + extern xExampleDebugStatEntry_t xIPTraceValues[]; + portBASE_TYPE xReturn; - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); - xIndex++; + xIndex++; - if( xIndex < xExampleDebugStatEntries() ) - { - sprintf( ( char * ) pcWriteBuffer, "%s %d\r\n", ( char * ) xIPTraceValues[ xIndex ].pucDescription, ( int ) xIPTraceValues[ xIndex ].ulData ); - xReturn = pdPASS; - } - else - { - /* Reset the index for the next time it is called. */ - xIndex = -1; + if( xIndex < xExampleDebugStatEntries() ) + { + sprintf( ( char * ) pcWriteBuffer, "%s %d\r\n", ( char * ) xIPTraceValues[ xIndex ].pucDescription, ( int ) xIPTraceValues[ xIndex ].ulData ); + xReturn = pdPASS; + } + else + { + /* Reset the index for the next time it is called. */ + xIndex = -1; - /* Ensure nothing remains in the write buffer. */ - pcWriteBuffer[ 0 ] = 0x00; - xReturn = pdFALSE; - } + /* Ensure nothing remains in the write buffer. */ + pcWriteBuffer[ 0 ] = 0x00; + xReturn = pdFALSE; + } - return xReturn; - } - /*-----------------------------------------------------------*/ + return xReturn; + } + /*-----------------------------------------------------------*/ #endif /* configINCLUDE_DEMO_DEBUG_STATS */ -static portBASE_TYPE prvDisplayIPConfig( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +static portBASE_TYPE prvDisplayIPConfig( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ) { -static portBASE_TYPE xIndex = 0; -portBASE_TYPE xReturn; -uint32_t ulAddress; + static portBASE_TYPE xIndex = 0; + portBASE_TYPE xReturn; + uint32_t ulAddress; - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); - switch( xIndex ) - { - case 0 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( &ulAddress, NULL, NULL, NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( ( char * ) pcWriteBuffer, "\r\nIP address " ); - xReturn = pdTRUE; - xIndex++; - break; + switch( xIndex ) + { + case 0: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulAddress, NULL, NULL, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( &ulAddress, NULL, NULL, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( ( char * ) pcWriteBuffer, "\r\nIP address " ); + xReturn = pdTRUE; + xIndex++; + break; - case 1 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( NULL, &ulAddress, NULL, NULL, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( NULL, &ulAddress, NULL, NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( ( char * ) pcWriteBuffer, "\r\nNet mask " ); - xReturn = pdTRUE; - xIndex++; - break; + case 1: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( NULL, &ulAddress, NULL, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( NULL, &ulAddress, NULL, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( ( char * ) pcWriteBuffer, "\r\nNet mask " ); + xReturn = pdTRUE; + xIndex++; + break; - case 2 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( NULL, NULL, &ulAddress, NULL, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( NULL, NULL, &ulAddress, NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( ( char * ) pcWriteBuffer, "\r\nGateway address " ); - xReturn = pdTRUE; - xIndex++; - break; + case 2: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( NULL, NULL, &ulAddress, NULL, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( NULL, NULL, &ulAddress, NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( ( char * ) pcWriteBuffer, "\r\nGateway address " ); + xReturn = pdTRUE; + xIndex++; + break; - case 3 : - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( NULL, NULL, NULL, &ulAddress, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulAddress ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - sprintf( ( char * ) pcWriteBuffer, "\r\nDNS server address " ); - xReturn = pdTRUE; - xIndex++; - break; + case 3: + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( NULL, NULL, NULL, &ulAddress, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulAddress ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + sprintf( ( char * ) pcWriteBuffer, "\r\nDNS server address " ); + xReturn = pdTRUE; + xIndex++; + break; - default : - ulAddress = 0; - sprintf( ( char * ) pcWriteBuffer, "\r\n\r\n" ); - xReturn = pdFALSE; - xIndex = 0; - break; - } + default: + ulAddress = 0; + sprintf( ( char * ) pcWriteBuffer, "\r\n\r\n" ); + xReturn = pdFALSE; + xIndex = 0; + break; + } - if( ulAddress != 0 ) - { - FreeRTOS_inet_ntoa( ulAddress, ( ( char * ) &( pcWriteBuffer[ strlen( ( char * ) pcWriteBuffer ) ] ) ) ); - } + if( ulAddress != 0 ) + { + FreeRTOS_inet_ntoa( ulAddress, ( ( char * ) &( pcWriteBuffer[ strlen( ( char * ) pcWriteBuffer ) ] ) ) ); + } - return xReturn; + return xReturn; } /*-----------------------------------------------------------*/ #if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 - static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) - { - int8_t *pcParameter; - portBASE_TYPE lParameterStringLength; + static portBASE_TYPE prvStartStopTraceCommand( int8_t * pcWriteBuffer, + size_t xWriteBufferLen, + const int8_t * pcCommandString ) + { + int8_t * pcParameter; + portBASE_TYPE lParameterStringLength; - /* Remove compile time warnings about unused parameters, and check the - write buffer is not NULL. NOTE - for simplicity, this example assumes the - write buffer length is adequate, so does not check for buffer overflows. */ - ( void ) pcCommandString; - ( void ) xWriteBufferLen; - configASSERT( pcWriteBuffer ); + /* Remove compile time warnings about unused parameters, and check the + * write buffer is not NULL. NOTE - for simplicity, this example assumes the + * write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); - /* Obtain the parameter string. */ - pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter - ( - pcCommandString, /* The command string itself. */ - 1, /* Return the first parameter. */ - &lParameterStringLength /* Store the parameter string length. */ - ); + /* Obtain the parameter string. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); - /* Sanity check something was returned. */ - configASSERT( pcParameter ); + /* Sanity check something was returned. */ + configASSERT( pcParameter ); - /* There are only two valid parameter values. */ - if( strncmp( ( const char * ) pcParameter, "start", strlen( "start" ) ) == 0 ) - { - /* Start or restart the trace. */ - vTraceStop(); - vTraceClear(); - vTraceStart(); + /* There are only two valid parameter values. */ + if( strncmp( ( const char * ) pcParameter, "start", strlen( "start" ) ) == 0 ) + { + /* Start or restart the trace. */ + vTraceStop(); + vTraceClear(); + vTraceStart(); - sprintf( ( char * ) pcWriteBuffer, "Trace recording (re)started.\r\n" ); - } - else if( strncmp( ( const char * ) pcParameter, "stop", strlen( "stop" ) ) == 0 ) - { - /* End the trace, if one is running. */ - vTraceStop(); - sprintf( ( char * ) pcWriteBuffer, "Stopping trace recording.\r\n" ); - } - else - { - sprintf( ( char * ) pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); - } + sprintf( ( char * ) pcWriteBuffer, "Trace recording (re)started.\r\n" ); + } + else if( strncmp( ( const char * ) pcParameter, "stop", strlen( "stop" ) ) == 0 ) + { + /* End the trace, if one is running. */ + vTraceStop(); + sprintf( ( char * ) pcWriteBuffer, "Stopping trace recording.\r\n" ); + } + else + { + sprintf( ( char * ) pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); + } - /* There is no more data to return after this single string, so return - pdFALSE. */ - return pdFALSE; - } + /* There is no more data to return after this single string, so return + * pdFALSE. */ + return pdFALSE; + } #endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/SimpleClientAndServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/SimpleClientAndServer.c index 183853ea0..6251682c4 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/SimpleClientAndServer.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/SimpleClientAndServer.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -36,349 +36,352 @@ #include "FreeRTOS_IP.h" #include "FreeRTOS_Sockets.h" -#define simpTINY_DELAY ( ( portTickType ) 2 ) +#define simpTINY_DELAY ( ( portTickType ) 2 ) /* * Uses a socket to send data without using the zero copy option. * prvSimpleServerTask() will receive the data. */ -static void prvSimpleClientTask( void *pvParameters ); +static void prvSimpleClientTask( void * pvParameters ); /* * Uses a socket to receive the data sent by the prvSimpleClientTask() task. * Does not use the zero copy option. */ -static void prvSimpleServerTask( void *pvParameters ); +static void prvSimpleServerTask( void * pvParameters ); /* * Uses a socket to send data using the zero copy option. * prvSimpleZeroCopyServerTask() will receive the data. */ -static void prvSimpleZeroCopyUDPClientTask( void *pvParameters ); +static void prvSimpleZeroCopyUDPClientTask( void * pvParameters ); /* * Uses a socket to receive the data sent by the prvSimpleZeroCopyUDPClientTask() * task. Uses the zero copy option. */ -static void prvSimpleZeroCopyServerTask( void *pvParameters ); +static void prvSimpleZeroCopyServerTask( void * pvParameters ); /*-----------------------------------------------------------*/ -void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, uint32_t ulPort, unsigned portBASE_TYPE uxPriority ) +void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, + uint32_t ulPort, + unsigned portBASE_TYPE uxPriority ) { - /* Create the client and server tasks that do not use the zero copy - interface. */ - xTaskCreate( prvSimpleClientTask, "SimpCpyClnt", usStackSize, ( void * ) ulPort, uxPriority, NULL ); - xTaskCreate( prvSimpleServerTask, "SimpCpySrv", usStackSize, ( void * ) ulPort, uxPriority + 1, NULL ); + /* Create the client and server tasks that do not use the zero copy + * interface. */ + xTaskCreate( prvSimpleClientTask, "SimpCpyClnt", usStackSize, ( void * ) ulPort, uxPriority, NULL ); + xTaskCreate( prvSimpleServerTask, "SimpCpySrv", usStackSize, ( void * ) ulPort, uxPriority + 1, NULL ); - /* Create the client and server tasks that do use the zero copy interface. */ - xTaskCreate( prvSimpleZeroCopyUDPClientTask, "SimpZCpyClnt", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority, NULL ); - xTaskCreate( prvSimpleZeroCopyServerTask, "SimpZCpySrv", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority + 1, NULL ); + /* Create the client and server tasks that do use the zero copy interface. */ + xTaskCreate( prvSimpleZeroCopyUDPClientTask, "SimpZCpyClnt", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority, NULL ); + xTaskCreate( prvSimpleZeroCopyServerTask, "SimpZCpySrv", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority + 1, NULL ); } /*-----------------------------------------------------------*/ -static void prvSimpleClientTask( void *pvParameters ) +static void prvSimpleClientTask( void * pvParameters ) { -Socket_t xClientSocket; -struct freertos_sockaddr xDestinationAddress; -uint8_t cString[ 50 ]; -portBASE_TYPE lReturned; -uint32_t ulCount = 0UL, ulIPAddress; -const uint32_t ulLoopsPerSocket = 10UL; -const portTickType x150ms = 150UL / portTICK_RATE_MS; + Socket_t xClientSocket; + struct freertos_sockaddr xDestinationAddress; + uint8_t cString[ 50 ]; + portBASE_TYPE lReturned; + uint32_t ulCount = 0UL, ulIPAddress; + const uint32_t ulLoopsPerSocket = 10UL; + const portTickType x150ms = 150UL / portTICK_RATE_MS; - /* Remove compiler warning about unused parameters. */ - ( void ) pvParameters; + /* Remove compiler warning about unused parameters. */ + ( void ) pvParameters; - /* It is assumed that this task is not created until the network is up, - so the IP address can be obtained immediately. store the IP address being - used in ulIPAddress. This is done so the socket can send to a different - port on the same IP address. */ -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - /* This test sends to itself, so data sent from here is received by a server - socket on the same IP address. Setup the freertos_sockaddr structure with - this nodes IP address, and the port number being sent to. The strange - casting is to try and remove compiler warnings on 32 bit machines. */ - xDestinationAddress.sin_address.ulIP_IPv4 = ulIPAddress; -#else - FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); - /* This test sends to itself, so data sent from here is received by a server - socket on the same IP address. Setup the freertos_sockaddr structure with - this nodes IP address, and the port number being sent to. The strange - casting is to try and remove compiler warnings on 32 bit machines. */ - xDestinationAddress.sin_addr = ulIPAddress; -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; - xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port ); - xDestinationAddress.sin_family = FREERTOS_AF_INET; + /* It is assumed that this task is not created until the network is up, + * so the IP address can be obtained immediately. store the IP address being + * used in ulIPAddress. This is done so the socket can send to a different + * port on the same IP address. */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - for( ;; ) - { - /* Create the socket. */ - xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); + /* This test sends to itself, so data sent from here is received by a server + * socket on the same IP address. Setup the freertos_sockaddr structure with + * this nodes IP address, and the port number being sent to. The strange + * casting is to try and remove compiler warnings on 32 bit machines. */ + xDestinationAddress.sin_address.ulIP_IPv4 = ulIPAddress; + #else + FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); - /* The count is used to differentiate between different messages sent to - the server, and to break out of the do while loop below. */ - ulCount = 0UL; + /* This test sends to itself, so data sent from here is received by a server + * socket on the same IP address. Setup the freertos_sockaddr structure with + * this nodes IP address, and the port number being sent to. The strange + * casting is to try and remove compiler warnings on 32 bit machines. */ + xDestinationAddress.sin_addr = ulIPAddress; + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - do - { - /* Create the string that is sent to the server. */ - sprintf( ( char * ) cString, "Server received (not zero copy): Message number %lu\r\n", ulCount ); + xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; + xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port ); + xDestinationAddress.sin_family = FREERTOS_AF_INET; - /* Send the string to the socket. ulFlags is set to 0, so the zero - copy option is not selected. That means the data from cString[] is - copied into a network buffer inside FreeRTOS_sendto(), and cString[] - can be reused as soon as FreeRTOS_sendto() has returned. */ - lReturned = FreeRTOS_sendto( xClientSocket, ( void * ) cString, strlen( ( const char * ) cString ), 0, &xDestinationAddress, sizeof( xDestinationAddress ) ); + for( ; ; ) + { + /* Create the socket. */ + xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); - ulCount++; + /* The count is used to differentiate between different messages sent to + * the server, and to break out of the do while loop below. */ + ulCount = 0UL; - } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) ); + do + { + /* Create the string that is sent to the server. */ + sprintf( ( char * ) cString, "Server received (not zero copy): Message number %lu\r\n", ulCount ); - FreeRTOS_closesocket( xClientSocket ); + /* Send the string to the socket. ulFlags is set to 0, so the zero + * copy option is not selected. That means the data from cString[] is + * copied into a network buffer inside FreeRTOS_sendto(), and cString[] + * can be reused as soon as FreeRTOS_sendto() has returned. */ + lReturned = FreeRTOS_sendto( xClientSocket, ( void * ) cString, strlen( ( const char * ) cString ), 0, &xDestinationAddress, sizeof( xDestinationAddress ) ); - /* A short delay to prevent the messages printed by the server task - scrolling off the screen too quickly, and to prevent reduce the network - loading. */ - vTaskDelay( x150ms ); - } + ulCount++; + } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) ); + + FreeRTOS_closesocket( xClientSocket ); + + /* A short delay to prevent the messages printed by the server task + * scrolling off the screen too quickly, and to prevent reduce the network + * loading. */ + vTaskDelay( x150ms ); + } } /*-----------------------------------------------------------*/ -static void prvSimpleServerTask( void *pvParameters ) +static void prvSimpleServerTask( void * pvParameters ) { -long lBytes; -uint8_t cReceivedString[ 60 ]; -struct freertos_sockaddr xClient, xBindAddress; -uint32_t xClientLength = sizeof( xClient ); -Socket_t xListeningSocket; + long lBytes; + uint8_t cReceivedString[ 60 ]; + struct freertos_sockaddr xClient, xBindAddress; + uint32_t xClientLength = sizeof( xClient ); + Socket_t xListeningSocket; - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; - /* Attempt to open the socket. */ - xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); + /* Attempt to open the socket. */ + xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); - /* This test receives data sent from a different port on the same IP - address. Configure the freertos_sockaddr structure with the address being - bound to. The strange casting is to try and remove compiler warnings on 32 - bit machines. Note that this task is only created after the network is up, - so the IP address is valid here. */ - xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; - xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); - xBindAddress.sin_family = FREERTOS_AF_INET; + /* This test receives data sent from a different port on the same IP + * address. Configure the freertos_sockaddr structure with the address being + * bound to. The strange casting is to try and remove compiler warnings on 32 + * bit machines. Note that this task is only created after the network is up, + * so the IP address is valid here. */ + xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; + xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); + xBindAddress.sin_family = FREERTOS_AF_INET; - /* Bind the socket to the port that the client task will send to. */ - FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); + /* Bind the socket to the port that the client task will send to. */ + FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); - for( ;; ) - { - /* Zero out the receive array so there is NULL at the end of the string - when it is printed out. */ - memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); + for( ; ; ) + { + /* Zero out the receive array so there is NULL at the end of the string + * when it is printed out. */ + memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); - /* Receive data on the socket. ulFlags is zero, so the zero copy option - is not set and the received data is copied into the buffer pointed to by - cReceivedString. By default the block time is portMAX_DELAY. - xClientLength is not actually used by FreeRTOS_recvfrom(), but is set - appropriately in case future versions do use it. */ - lBytes = FreeRTOS_recvfrom( xListeningSocket, cReceivedString, sizeof( cReceivedString ), 0, &xClient, &xClientLength ); + /* Receive data on the socket. ulFlags is zero, so the zero copy option + * is not set and the received data is copied into the buffer pointed to by + * cReceivedString. By default the block time is portMAX_DELAY. + * xClientLength is not actually used by FreeRTOS_recvfrom(), but is set + * appropriately in case future versions do use it. */ + lBytes = FreeRTOS_recvfrom( xListeningSocket, cReceivedString, sizeof( cReceivedString ), 0, &xClient, &xClientLength ); - /* Print the received characters. */ - if( lBytes > 0 ) - { - FreeRTOS_debug_printf( ( ( char * ) cReceivedString ) ); - } + /* Print the received characters. */ + if( lBytes > 0 ) + { + FreeRTOS_debug_printf( ( ( char * ) cReceivedString ) ); + } - /* Error check. */ - configASSERT( lBytes == ( portBASE_TYPE ) strlen( ( const char * ) cReceivedString ) ); - } + /* Error check. */ + configASSERT( lBytes == ( portBASE_TYPE ) strlen( ( const char * ) cReceivedString ) ); + } } /*-----------------------------------------------------------*/ -static void prvSimpleZeroCopyUDPClientTask( void *pvParameters ) +static void prvSimpleZeroCopyUDPClientTask( void * pvParameters ) { -Socket_t xClientSocket; -uint8_t *pucUDPPayloadBuffer; -struct freertos_sockaddr xDestinationAddress; -portBASE_TYPE lReturned; -uint32_t ulCount = 0UL, ulIPAddress; -const uint32_t ulLoopsPerSocket = 10UL; -const uint8_t *pucStringToSend = ( const uint8_t * ) "Server received (using zero copy): Message number "; -const portTickType x150ms = 150UL / portTICK_RATE_MS; + Socket_t xClientSocket; + uint8_t * pucUDPPayloadBuffer; + struct freertos_sockaddr xDestinationAddress; + portBASE_TYPE lReturned; + uint32_t ulCount = 0UL, ulIPAddress; + const uint32_t ulLoopsPerSocket = 10UL; + const uint8_t * pucStringToSend = ( const uint8_t * ) "Server received (using zero copy): Message number "; + const portTickType x150ms = 150UL / portTICK_RATE_MS; /* 15 is added to ensure the number, \r\n and terminating zero fit. */ -const size_t xStringLength = strlen( ( char * ) pucStringToSend ) + 15; + const size_t xStringLength = strlen( ( char * ) pucStringToSend ) + 15; - /* Remove compiler warning about unused parameters. */ - ( void ) pvParameters; + /* Remove compiler warning about unused parameters. */ + ( void ) pvParameters; - /* It is assumed that this task is not created until the network is up, - so the IP address can be obtained immediately. store the IP address being - used in ulIPAddress. This is done so the socket can send to a different - port on the same IP address. */ -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - /* This test sends to itself, so data sent from here is received by a server - socket on the same IP address. Setup the freertos_sockaddr structure with - this nodes IP address, and the port number being sent to. The strange - casting is to try and remove compiler warnings on 32 bit machines. */ - xDestinationAddress.sin_address.ulIP_IPv4 = ulIPAddress; -#else - FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); - /* This test sends to itself, so data sent from here is received by a server - socket on the same IP address. Setup the freertos_sockaddr structure with - this nodes IP address, and the port number being sent to. The strange - casting is to try and remove compiler warnings on 32 bit machines. */ - xDestinationAddress.sin_addr = ulIPAddress; -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + /* It is assumed that this task is not created until the network is up, + * so the IP address can be obtained immediately. store the IP address being + * used in ulIPAddress. This is done so the socket can send to a different + * port on the same IP address. */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; - xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port ); - xDestinationAddress.sin_family = FREERTOS_AF_INET; + /* This test sends to itself, so data sent from here is received by a server + * socket on the same IP address. Setup the freertos_sockaddr structure with + * this nodes IP address, and the port number being sent to. The strange + * casting is to try and remove compiler warnings on 32 bit machines. */ + xDestinationAddress.sin_address.ulIP_IPv4 = ulIPAddress; + #else + FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); - for( ;; ) - { - /* Create the socket. */ - xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); + /* This test sends to itself, so data sent from here is received by a server + * socket on the same IP address. Setup the freertos_sockaddr structure with + * this nodes IP address, and the port number being sent to. The strange + * casting is to try and remove compiler warnings on 32 bit machines. */ + xDestinationAddress.sin_addr = ulIPAddress; + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - /* The count is used to differentiate between different messages sent to - the server, and to break out of the do while loop below. */ - ulCount = 0UL; + xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; + xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port ); + xDestinationAddress.sin_family = FREERTOS_AF_INET; - do - { - /* This task is going to send using the zero copy interface. The - data being sent is therefore written directly into a buffer that is - passed into, rather than copied into, the FreeRTOS_sendto() - function. + for( ; ; ) + { + /* Create the socket. */ + xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET ); - First obtain a buffer of adequate length from the IP stack into which - the string will be written. Although a max delay is used, the actual - delay will be capped to ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence - the do while loop is used to ensure a buffer is obtained. */ - do - { - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer_Multi( xStringLength, portMAX_DELAY, ipTYPE_IPv4 ) ) == NULL ); - #else - } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xStringLength, portMAX_DELAY ) ) == NULL ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + /* The count is used to differentiate between different messages sent to + * the server, and to break out of the do while loop below. */ + ulCount = 0UL; - /* A buffer was successfully obtained. Create the string that is - sent to the server. First the string is filled with zeros as this will - effectively be the null terminator when the string is received at the other - end. Note that the string is being written directly into the buffer - obtained from the IP stack above. */ - memset( ( void * ) pucUDPPayloadBuffer, 0x00, xStringLength ); - sprintf( ( char * ) pucUDPPayloadBuffer, "%s%lu\r\n", ( char * ) pucStringToSend, ulCount ); + do + { + /* This task is going to send using the zero copy interface. The + * data being sent is therefore written directly into a buffer that is + * passed into, rather than copied into, the FreeRTOS_sendto() + * function. + * + * First obtain a buffer of adequate length from the IP stack into which + * the string will be written. Although a max delay is used, the actual + * delay will be capped to ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence + * the do while loop is used to ensure a buffer is obtained. */ + do + { + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer_Multi( xStringLength, portMAX_DELAY, ipTYPE_IPv4 ) ) == NULL ); + #else + } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xStringLength, portMAX_DELAY ) ) == NULL ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - /* Pass the buffer into the send function. ulFlags has the - FREERTOS_ZERO_COPY bit set so the IP stack will take control of the - buffer rather than copy data out of the buffer. */ - lReturned = FreeRTOS_sendto( xClientSocket, /* The socket being sent to. */ - ( void * ) pucUDPPayloadBuffer, /* A pointer to the the data being sent. */ - strlen( ( const char * ) pucUDPPayloadBuffer ) + 1, /* The length of the data being sent - including the string's null terminator. */ - FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */ - &xDestinationAddress, /* Where the data is being sent. */ - sizeof( xDestinationAddress ) ); + /* A buffer was successfully obtained. Create the string that is + * sent to the server. First the string is filled with zeros as this will + * effectively be the null terminator when the string is received at the other + * end. Note that the string is being written directly into the buffer + * obtained from the IP stack above. */ + memset( ( void * ) pucUDPPayloadBuffer, 0x00, xStringLength ); + sprintf( ( char * ) pucUDPPayloadBuffer, "%s%lu\r\n", ( char * ) pucStringToSend, ulCount ); - if( lReturned == 0 ) - { - /* The send operation failed, so this task is still responsible - for the buffer obtained from the IP stack. To ensure the buffer - is not lost it must either be used again, or, as in this case, - returned to the IP stack using FreeRTOS_ReleaseUDPPayloadBuffer(). - pucUDPPayloadBuffer can be safely re-used after this call. */ - FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer ); - } - else - { - /* The send was successful so the IP stack is now managing the - buffer pointed to by pucUDPPayloadBuffer, and the IP stack will - return the buffer once it has been sent. pucUDPPayloadBuffer can - be safely re-used. */ - } + /* Pass the buffer into the send function. ulFlags has the + * FREERTOS_ZERO_COPY bit set so the IP stack will take control of the + * buffer rather than copy data out of the buffer. */ + lReturned = FreeRTOS_sendto( xClientSocket, /* The socket being sent to. */ + ( void * ) pucUDPPayloadBuffer, /* A pointer to the the data being sent. */ + strlen( ( const char * ) pucUDPPayloadBuffer ) + 1, /* The length of the data being sent - including the string's null terminator. */ + FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */ + &xDestinationAddress, /* Where the data is being sent. */ + sizeof( xDestinationAddress ) ); - ulCount++; + if( lReturned == 0 ) + { + /* The send operation failed, so this task is still responsible + * for the buffer obtained from the IP stack. To ensure the buffer + * is not lost it must either be used again, or, as in this case, + * returned to the IP stack using FreeRTOS_ReleaseUDPPayloadBuffer(). + * pucUDPPayloadBuffer can be safely re-used after this call. */ + FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer ); + } + else + { + /* The send was successful so the IP stack is now managing the + * buffer pointed to by pucUDPPayloadBuffer, and the IP stack will + * return the buffer once it has been sent. pucUDPPayloadBuffer can + * be safely re-used. */ + } - } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) ); + ulCount++; + } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) ); - FreeRTOS_closesocket( xClientSocket ); + FreeRTOS_closesocket( xClientSocket ); - /* A short delay to prevent the messages scrolling off the screen too - quickly. */ - vTaskDelay( x150ms ); - } + /* A short delay to prevent the messages scrolling off the screen too + * quickly. */ + vTaskDelay( x150ms ); + } } /*-----------------------------------------------------------*/ -static void prvSimpleZeroCopyServerTask( void *pvParameters ) +static void prvSimpleZeroCopyServerTask( void * pvParameters ) { -int32_t lBytes; -uint8_t *pucUDPPayloadBuffer; -struct freertos_sockaddr xClient, xBindAddress; -uint32_t xClientLength = sizeof( xClient ), ulIPAddress; -Socket_t xListeningSocket; + int32_t lBytes; + uint8_t * pucUDPPayloadBuffer; + struct freertos_sockaddr xClient, xBindAddress; + uint32_t xClientLength = sizeof( xClient ), ulIPAddress; + Socket_t xListeningSocket; - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; - /* Attempt to open the socket. */ - xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); + /* Attempt to open the socket. */ + xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); - /* This test receives data sent from a different port on the same IP address. - Obtain the nodes IP address. Configure the freertos_sockaddr structure with - the address being bound to. The strange casting is to try and remove - compiler warnings on 32 bit machines. Note that this task is only created - after the network is up, so the IP address is valid here. */ -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); - xBindAddress.sin_address.ulIP_IPv4 = ulIPAddress; -#else - FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); - xBindAddress.sin_addr = ulIPAddress; -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - - xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; - xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); - xBindAddress.sin_family = FREERTOS_AF_INET; + /* This test receives data sent from a different port on the same IP address. + * Obtain the nodes IP address. Configure the freertos_sockaddr structure with + * the address being bound to. The strange casting is to try and remove + * compiler warnings on 32 bit machines. Note that this task is only created + * after the network is up, so the IP address is valid here. */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulIPAddress, NULL, NULL, NULL, pxNetworkEndPoints ); + xBindAddress.sin_address.ulIP_IPv4 = ulIPAddress; + #else + FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); + xBindAddress.sin_addr = ulIPAddress; + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - /* Bind the socket to the port that the client task will send to. */ - FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); + xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; + xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); + xBindAddress.sin_family = FREERTOS_AF_INET; - for( ;; ) - { - /* Receive data on the socket. ulFlags has the zero copy bit set - (FREERTOS_ZERO_COPY) indicating to the stack that a reference to the - received data should be passed out to this task using the second - parameter to the FreeRTOS_recvfrom() call. When this is done the - IP stack is no longer responsible for releasing the buffer, and - the task *must* return the buffer to the stack when it is no longer - needed. By default the block time is portMAX_DELAY. */ - lBytes = FreeRTOS_recvfrom( xListeningSocket, ( void * ) &pucUDPPayloadBuffer, 0, FREERTOS_ZERO_COPY, &xClient, &xClientLength ); + /* Bind the socket to the port that the client task will send to. */ + FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); - /* It is expected to receive one more byte than the string length as - the NULL terminator is also transmitted. */ - configASSERT( lBytes == ( ( portBASE_TYPE ) strlen( ( const char * ) pucUDPPayloadBuffer ) + 1 ) ); + for( ; ; ) + { + /* Receive data on the socket. ulFlags has the zero copy bit set + * (FREERTOS_ZERO_COPY) indicating to the stack that a reference to the + * received data should be passed out to this task using the second + * parameter to the FreeRTOS_recvfrom() call. When this is done the + * IP stack is no longer responsible for releasing the buffer, and + * the task *must* return the buffer to the stack when it is no longer + * needed. By default the block time is portMAX_DELAY. */ + lBytes = FreeRTOS_recvfrom( xListeningSocket, ( void * ) &pucUDPPayloadBuffer, 0, FREERTOS_ZERO_COPY, &xClient, &xClientLength ); - /* Print the received characters. */ - if( lBytes > 0 ) - { - FreeRTOS_debug_printf( ( ( char * ) pucUDPPayloadBuffer ) ); - } + /* It is expected to receive one more byte than the string length as + * the NULL terminator is also transmitted. */ + configASSERT( lBytes == ( ( portBASE_TYPE ) strlen( ( const char * ) pucUDPPayloadBuffer ) + 1 ) ); - if( lBytes >= 0 ) - { - /* The buffer *must* be freed once it is no longer needed. */ - FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer ); - } - } + /* Print the received characters. */ + if( lBytes > 0 ) + { + FreeRTOS_debug_printf( ( ( char * ) pucUDPPayloadBuffer ) ); + } + + if( lBytes >= 0 ) + { + /* The buffer *must* be freed once it is no longer needed. */ + FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer ); + } + } } - diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/TwoEchoClients.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/TwoEchoClients.c index 0d8b7403d..f7277a636 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/TwoEchoClients.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/TwoEchoClients.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -26,12 +26,12 @@ /****************************************************************************** - * - * See the following web page for essential TwoEchoClient.c usage and - * configuration details: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Common_Echo_Clients.shtml - * - ******************************************************************************/ +* +* See the following web page for essential TwoEchoClient.c usage and +* configuration details: +* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Common_Echo_Clients.shtml +* +******************************************************************************/ /* Standard includes. */ @@ -51,383 +51,385 @@ #include "user_settings.h" /* Small delay used between attempts to obtain a zero copy buffer. */ -#define echoTINY_DELAY ( ( portTickType ) 2 ) +#define echoTINY_DELAY ( ( portTickType ) 2 ) /* The echo tasks create a socket, send out a number of echo requests -(listening for each echo reply), then close the socket again before -starting over. This delay is used between each iteration to ensure the -network does not get too congested. The delay is shorter when the Windows -simulator is used because simulated time is slower than real time. */ + * (listening for each echo reply), then close the socket again before + * starting over. This delay is used between each iteration to ensure the + * network does not get too congested. The delay is shorter when the Windows + * simulator is used because simulated time is slower than real time. */ #ifdef _WINDOWS_ - #define echoLOOP_DELAY ( ( portTickType ) 10 / portTICK_RATE_MS ) + #define echoLOOP_DELAY ( ( portTickType ) 10 / portTICK_RATE_MS ) #else - #define echoLOOP_DELAY ( ( portTickType ) 150 / portTICK_RATE_MS ) + #define echoLOOP_DELAY ( ( portTickType ) 150 / portTICK_RATE_MS ) #endif /* _WINDOWS_ */ #if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 - /* When the trace recorder code is included user events are generated to - mark the sending and receiving of the echoed data (only in the zero copy - task. */ - #define echoMARK_SEND_IN_TRACE_BUFFER( x ) vTraceUserEvent( x ) - traceLabel xZeroCopySendEvent, xZeroCopyReceiveEvent; + +/* When the trace recorder code is included user events are generated to + * mark the sending and receiving of the echoed data (only in the zero copy + * task. */ + #define echoMARK_SEND_IN_TRACE_BUFFER( x ) vTraceUserEvent( x ) + traceLabel xZeroCopySendEvent, xZeroCopyReceiveEvent; #else - /* When the trace recorder code is not included just #define away the call - to post the user event. */ - #define echoMARK_SEND_IN_TRACE_BUFFER( x ) - #define xZeroCopySendEvent 0 - #define xZeroCopyReceiveEvent 0 + +/* When the trace recorder code is not included just #define away the call + * to post the user event. */ + #define echoMARK_SEND_IN_TRACE_BUFFER( x ) + #define xZeroCopySendEvent 0 + #define xZeroCopyReceiveEvent 0 #endif /* The echo server is assumed to be on port 7, which is the standard echo -protocol port. */ -#define echoECHO_PORT ( 8080 ) + * protocol port. */ +#define echoECHO_PORT ( 8080 ) /* * Uses a socket to send data to, then receive data from, the standard echo * port number 7. prvEchoClientTask() uses the standard interface. * prvZeroCopyEchoClientTask() uses the zero copy interface. */ -static void prvEchoClientTask( void *pvParameters ); -static void prvZeroCopyEchoClientTask( void *pvParameters ); +static void prvEchoClientTask( void * pvParameters ); +static void prvZeroCopyEchoClientTask( void * pvParameters ); /* The receive timeout is set shorter when the windows simulator is used -because simulated time is slower than real time. */ + * because simulated time is slower than real time. */ #ifdef _WINDOWS_ - const portTickType xReceiveTimeOut = 500 / portTICK_RATE_MS; + const portTickType xReceiveTimeOut = 500 / portTICK_RATE_MS; #else - const portTickType xReceiveTimeOut = 1000 / portTICK_RATE_MS; + const portTickType xReceiveTimeOut = 1000 / portTICK_RATE_MS; #endif /*-----------------------------------------------------------*/ -void vStartEchoClientTasks( uint16_t usTaskStackSize, unsigned portBASE_TYPE uxTaskPriority ) +void vStartEchoClientTasks( uint16_t usTaskStackSize, + unsigned portBASE_TYPE uxTaskPriority ) { - /* Create the echo client task that does not use the zero copy interface. */ - xTaskCreate( prvEchoClientTask, /* The function that implements the task. */ - ( const signed char * const ) "Echo0", /* Just a text name for the task to aid debugging. */ - usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ - NULL, /* The task parameter, not used in this case. */ - uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ - NULL ); /* The task handle is not used. */ + /* Create the echo client task that does not use the zero copy interface. */ + xTaskCreate( prvEchoClientTask, /* The function that implements the task. */ + ( const signed char * const ) "Echo0", /* Just a text name for the task to aid debugging. */ + usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ + NULL, /* The task parameter, not used in this case. */ + uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ + NULL ); /* The task handle is not used. */ - /* Create the echo client task that does use the zero copy interface. */ - xTaskCreate( prvZeroCopyEchoClientTask, /* The function that implements the task. */ - ( const signed char * const ) "Echo1", /* Just a text name for the task to aid debugging. */ - usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ - NULL, /* The task parameter, not used in this case. */ - uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ - NULL ); /* The task handle is not used. */ + /* Create the echo client task that does use the zero copy interface. */ + xTaskCreate( prvZeroCopyEchoClientTask, /* The function that implements the task. */ + ( const signed char * const ) "Echo1", /* Just a text name for the task to aid debugging. */ + usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ + NULL, /* The task parameter, not used in this case. */ + uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ + NULL ); /* The task handle is not used. */ } /*-----------------------------------------------------------*/ -static void prvEchoClientTask( void *pvParameters ) +static void prvEchoClientTask( void * pvParameters ) { -Socket_t xSocket; -struct freertos_sockaddr xEchoServerAddress; -int8_t cTxString[ 25 ], cRxString[ 25 ]; /* Make sure the stack is large enough to hold these. Turn on stack overflow checking during debug to be sure. */ -int32_t lLoopCount = 0UL; -int32_t lReturned; -const int32_t lMaxLoopCount = 50; -volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL; -uint32_t xAddressLength = sizeof( xEchoServerAddress ); + Socket_t xSocket; + struct freertos_sockaddr xEchoServerAddress; + int8_t cTxString[ 25 ], cRxString[ 25 ]; /* Make sure the stack is large enough to hold these. Turn on stack overflow checking during debug to be sure. */ + int32_t lLoopCount = 0UL; + int32_t lReturned; + const int32_t lMaxLoopCount = 50; + volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL; + uint32_t xAddressLength = sizeof( xEchoServerAddress ); - /* Remove compiler warning about unused parameters. */ - ( void ) pvParameters; + /* Remove compiler warning about unused parameters. */ + ( void ) pvParameters; - /* Echo requests are sent to the echo server. The address of the echo - server is configured by the constants configECHO_SERVER_ADDR0 to - configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ - xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); + /* Echo requests are sent to the echo server. The address of the echo + * server is configured by the constants configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ + xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); - } - #else - { - xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); + } + #else + { + xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - xEchoServerAddress.sin_family = FREERTOS_AF_INET; + xEchoServerAddress.sin_family = FREERTOS_AF_INET; - for( ;; ) - { - /* Create a socket. */ - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); + for( ; ; ) + { + /* Create a socket. */ + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); - /* Set a time out so a missing reply does not cause the task to block - indefinitely. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); + /* Set a time out so a missing reply does not cause the task to block + * indefinitely. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); - /* Send a number of echo requests. */ - for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) - { - /* Create the string that is sent to the echo server. */ - sprintf( ( char * ) cTxString, "Message number %u\r\n", ulTxCount ); + /* Send a number of echo requests. */ + for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) + { + /* Create the string that is sent to the echo server. */ + sprintf( ( char * ) cTxString, "Message number %u\r\n", ulTxCount ); - /* Send the string to the socket. ulFlags is set to 0, so the zero - copy interface is not used. That means the data from cTxString is - copied into a network buffer inside FreeRTOS_sendto(), and cTxString - can be reused as soon as FreeRTOS_sendto() has returned. 1 is added - to ensure the NULL string terminator is sent as part of the message. */ - lReturned = FreeRTOS_sendto( xSocket, /* The socket being sent to. */ - ( void * ) cTxString, /* The data being sent. */ - strlen( ( const char * ) cTxString ) + 1, /* The length of the data being sent. */ - 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ - &xEchoServerAddress, /* The destination address. */ - sizeof( xEchoServerAddress ) ); + /* Send the string to the socket. ulFlags is set to 0, so the zero + * copy interface is not used. That means the data from cTxString is + * copied into a network buffer inside FreeRTOS_sendto(), and cTxString + * can be reused as soon as FreeRTOS_sendto() has returned. 1 is added + * to ensure the NULL string terminator is sent as part of the message. */ + lReturned = FreeRTOS_sendto( xSocket, /* The socket being sent to. */ + ( void * ) cTxString, /* The data being sent. */ + strlen( ( const char * ) cTxString ) + 1, /* The length of the data being sent. */ + 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ + &xEchoServerAddress, /* The destination address. */ + sizeof( xEchoServerAddress ) ); - if( lReturned == 0 ) - { - /* The send operation failed. */ - } - else - { - /* The send was successful. */ - FreeRTOS_debug_printf( ( "[Echo Client] Data sent... \r\n" ) ); - } + if( lReturned == 0 ) + { + /* The send operation failed. */ + } + else + { + /* The send was successful. */ + FreeRTOS_debug_printf( ( "[Echo Client] Data sent... \r\n" ) ); + } - /* Keep a count of how many echo requests have been transmitted so - it can be compared to the number of echo replies received. It would - be expected to loose at least one to an ARP message the first time - the connection is created. */ - ulTxCount++; + /* Keep a count of how many echo requests have been transmitted so + * it can be compared to the number of echo replies received. It would + * be expected to loose at least one to an ARP message the first time + * the connection is created. */ + ulTxCount++; - /* Receive data echoed back to the socket. ulFlags is zero, so the - zero copy option is not being used and the received data will be - copied into the buffer pointed to by cRxString. xAddressLength is - not actually used (at the time of writing this comment, anyway) by - FreeRTOS_recvfrom(), but is set appropriately in case future - versions do use it. */ + /* Receive data echoed back to the socket. ulFlags is zero, so the + * zero copy option is not being used and the received data will be + * copied into the buffer pointed to by cRxString. xAddressLength is + * not actually used (at the time of writing this comment, anyway) by + * FreeRTOS_recvfrom(), but is set appropriately in case future + * versions do use it. */ - memset( ( void * ) cRxString, 0x00, sizeof( cRxString ) ); - lReturned = FreeRTOS_recvfrom( xSocket, /* The socket being received from. */ - cRxString, /* The buffer into which the received data will be written. */ - sizeof( cRxString ), /* The size of the buffer provided to receive the data. */ - 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ - &xEchoServerAddress, /* The address from where the data was sent (the source address). */ - &xAddressLength ); + memset( ( void * ) cRxString, 0x00, sizeof( cRxString ) ); + lReturned = FreeRTOS_recvfrom( xSocket, /* The socket being received from. */ + cRxString, /* The buffer into which the received data will be written. */ + sizeof( cRxString ), /* The size of the buffer provided to receive the data. */ + 0, /* ulFlags with the FREERTOS_ZERO_COPY bit clear. */ + &xEchoServerAddress, /* The address from where the data was sent (the source address). */ + &xAddressLength ); - if( lReturned > 0 ) - { - /* Compare the transmitted string to the received string. */ - if( strcmp( ( char * ) cRxString, ( char * ) cTxString ) == 0 ) - { - /* The echo reply was received without error. */ - ulRxCount++; - FreeRTOS_debug_printf( ( "[Echo Client] Data was received correctly.\r\n" ) ); - } - else - { - FreeRTOS_debug_printf( ( "[Echo Client] Data received was erreneous.\r\n" ) ); - } - } - else - { - FreeRTOS_debug_printf( ( "[Echo Client] Data was not received\r\n" ) ); - } - } + if( lReturned > 0 ) + { + /* Compare the transmitted string to the received string. */ + if( strcmp( ( char * ) cRxString, ( char * ) cTxString ) == 0 ) + { + /* The echo reply was received without error. */ + ulRxCount++; + FreeRTOS_debug_printf( ( "[Echo Client] Data was received correctly.\r\n" ) ); + } + else + { + FreeRTOS_debug_printf( ( "[Echo Client] Data received was erroneous.\r\n" ) ); + } + } + else + { + FreeRTOS_debug_printf( ( "[Echo Client] Data was not received\r\n" ) ); + } + } - /* Pause for a short while to ensure the network is not too - congested. */ - vTaskDelay( echoLOOP_DELAY ); + /* Pause for a short while to ensure the network is not too + * congested. */ + vTaskDelay( echoLOOP_DELAY ); - /* Close this socket before looping back to create another. */ - FreeRTOS_closesocket( xSocket ); - } + /* Close this socket before looping back to create another. */ + FreeRTOS_closesocket( xSocket ); + } } /*-----------------------------------------------------------*/ -static void prvZeroCopyEchoClientTask( void *pvParameters ) +static void prvZeroCopyEchoClientTask( void * pvParameters ) { -Socket_t xSocket; -struct freertos_sockaddr xEchoServerAddress; -static int8_t cTxString[ 40 ]; -int32_t lLoopCount = 0UL; -volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL; -uint32_t xAddressLength = sizeof( xEchoServerAddress ); -int32_t lReturned; -uint8_t *pucUDPPayloadBuffer; + Socket_t xSocket; + struct freertos_sockaddr xEchoServerAddress; + static int8_t cTxString[ 40 ]; + int32_t lLoopCount = 0UL; + volatile uint32_t ulRxCount = 0UL, ulTxCount = 0UL; + uint32_t xAddressLength = sizeof( xEchoServerAddress ); + int32_t lReturned; + uint8_t * pucUDPPayloadBuffer; -const int32_t lMaxLoopCount = 50; -const uint8_t * const pucStringToSend = ( const uint8_t * const ) "Zero copy message number"; + const int32_t lMaxLoopCount = 50; + const uint8_t * const pucStringToSend = ( const uint8_t * const ) "Zero copy message number"; /* The buffer is large enough to hold the string, a number, and the string terminator. */ -const size_t xBufferLength = strlen( ( char * ) pucStringToSend ) + 15; + const size_t xBufferLength = strlen( ( char * ) pucStringToSend ) + 15; - #if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 - { - /* When the trace recorder code is included user events are generated to - mark the sending and receiving of the echoed data (only in the zero copy - task). */ - xZeroCopySendEvent = xTraceOpenLabel( "ZeroCopyTx" ); - xZeroCopyReceiveEvent = xTraceOpenLabel( "ZeroCopyRx" ); - } - #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS */ + #if ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 + { + /* When the trace recorder code is included user events are generated to + * mark the sending and receiving of the echoed data (only in the zero copy + * task). */ + xZeroCopySendEvent = xTraceOpenLabel( "ZeroCopyTx" ); + xZeroCopyReceiveEvent = xTraceOpenLabel( "ZeroCopyRx" ); + } + #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS */ - /* Remove compiler warning about unused parameters. */ - ( void ) pvParameters; + /* Remove compiler warning about unused parameters. */ + ( void ) pvParameters; - /* Delay for a little while to ensure the task is out of synch with the - other echo task implemented above. */ - vTaskDelay( echoLOOP_DELAY >> 1 ); + /* Delay for a little while to ensure the task is out of synch with the + * other echo task implemented above. */ + vTaskDelay( echoLOOP_DELAY >> 1 ); - /* Echo requests are sent to the echo server. The address of the echo - server is configured by the constants configECHO_SERVER_ADDR0 to - configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ - xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); + /* Echo requests are sent to the echo server. The address of the echo + * server is configured by the constants configECHO_SERVER_ADDR0 to + * configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */ + xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT ); - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - { - xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); - } - #else - { - xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, - configECHO_SERVER_ADDR1, - configECHO_SERVER_ADDR2, - configECHO_SERVER_ADDR3 ); - } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + { + xEchoServerAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); + } + #else + { + xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, + configECHO_SERVER_ADDR1, + configECHO_SERVER_ADDR2, + configECHO_SERVER_ADDR3 ); + } + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - xEchoServerAddress.sin_family = FREERTOS_AF_INET; + xEchoServerAddress.sin_family = FREERTOS_AF_INET; - for( ;; ) - { - /* Create a socket. */ - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); + for( ; ; ) + { + /* Create a socket. */ + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); + configASSERT( xSocket != FREERTOS_INVALID_SOCKET ); - /* Set a time out so a missing reply does not cause the task to block - indefinitely. */ - FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); + /* Set a time out so a missing reply does not cause the task to block + * indefinitely. */ + FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); - /* Send a number of echo requests. */ - for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) - { - /* This task is going to send using the zero copy interface. The - data being sent is therefore written directly into a buffer that is - passed by reference into the FreeRTOS_sendto() function. First - obtain a buffer of adequate size from the IP stack. Although a max - delay is used, the actual delay will be capped to - ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence the test to ensure a buffer - was actually obtained. */ + /* Send a number of echo requests. */ + for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ ) + { + /* This task is going to send using the zero copy interface. The + * data being sent is therefore written directly into a buffer that is + * passed by reference into the FreeRTOS_sendto() function. First + * obtain a buffer of adequate size from the IP stack. Although a max + * delay is used, the actual delay will be capped to + * ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence the test to ensure a buffer + * was actually obtained. */ - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer_Multi( xBufferLength, portMAX_DELAY, ipTYPE_IPv4 ); - #else - pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xBufferLength, portMAX_DELAY ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer_Multi( xBufferLength, portMAX_DELAY, ipTYPE_IPv4 ); + #else + pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xBufferLength, portMAX_DELAY ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - if( pucUDPPayloadBuffer != NULL ) - { - /* A buffer was successfully obtained. Create the string that is - sent to the echo server. Note the string is written directly - into the buffer obtained from the IP stack. */ - sprintf( ( char * ) pucUDPPayloadBuffer, "%s %u\r\n", ( const char * ) "Zero copy message number", ulTxCount ); + if( pucUDPPayloadBuffer != NULL ) + { + /* A buffer was successfully obtained. Create the string that is + * sent to the echo server. Note the string is written directly + * into the buffer obtained from the IP stack. */ + sprintf( ( char * ) pucUDPPayloadBuffer, "%s %u\r\n", ( const char * ) "Zero copy message number", ulTxCount ); - /* Also copy the string into a local buffer so it can be compared - with the string that is later received back from the echo server. */ - strcpy( ( char * ) cTxString, ( char * ) pucUDPPayloadBuffer ); + /* Also copy the string into a local buffer so it can be compared + * with the string that is later received back from the echo server. */ + strcpy( ( char * ) cTxString, ( char * ) pucUDPPayloadBuffer ); - /* Pass the buffer into the send function. ulFlags has the - FREERTOS_ZERO_COPY bit set so the IP stack will take control of - the buffer, rather than copy data out of the buffer. */ - echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopySendEvent ); - lReturned = FreeRTOS_sendto( xSocket, /* The socket being sent to. */ - ( void * ) pucUDPPayloadBuffer, /* The buffer being passed into the IP stack. */ - strlen( ( const char * ) cTxString ) + 1, /* The length of the data being sent. Plus 1 to ensure the null terminator is part of the data. */ - FREERTOS_ZERO_COPY, /* ulFlags with the zero copy bit is set. */ - &xEchoServerAddress, /* Where the data is being sent. */ - sizeof( xEchoServerAddress ) ); + /* Pass the buffer into the send function. ulFlags has the + * FREERTOS_ZERO_COPY bit set so the IP stack will take control of + * the buffer, rather than copy data out of the buffer. */ + echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopySendEvent ); + lReturned = FreeRTOS_sendto( xSocket, /* The socket being sent to. */ + ( void * ) pucUDPPayloadBuffer, /* The buffer being passed into the IP stack. */ + strlen( ( const char * ) cTxString ) + 1, /* The length of the data being sent. Plus 1 to ensure the null terminator is part of the data. */ + FREERTOS_ZERO_COPY, /* ulFlags with the zero copy bit is set. */ + &xEchoServerAddress, /* Where the data is being sent. */ + sizeof( xEchoServerAddress ) ); - if( lReturned == 0 ) - { - /* The send operation failed, so this task is still - responsible for the buffer obtained from the IP stack. To - ensure the buffer is not lost it must either be used again, - or, as in this case, returned to the IP stack using - FreeRTOS_ReleaseUDPPayloadBuffer(). pucUDPPayloadBuffer can - be safely re-used to receive from the socket below once the - buffer has been returned to the stack. */ - FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer ); - } - else - { - /* The send was successful so the IP stack is now managing - the buffer pointed to by pucUDPPayloadBuffer, and the IP - stack will return the buffer once it has been sent. - pucUDPPayloadBuffer can be safely re-used to receive from - the socket below. */ - FreeRTOS_debug_printf( ( "[Zero Copy] Data sent... \r\n" ) ); - } + if( lReturned == 0 ) + { + /* The send operation failed, so this task is still + * responsible for the buffer obtained from the IP stack. To + * ensure the buffer is not lost it must either be used again, + * or, as in this case, returned to the IP stack using + * FreeRTOS_ReleaseUDPPayloadBuffer(). pucUDPPayloadBuffer can + * be safely re-used to receive from the socket below once the + * buffer has been returned to the stack. */ + FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer ); + } + else + { + /* The send was successful so the IP stack is now managing + * the buffer pointed to by pucUDPPayloadBuffer, and the IP + * stack will return the buffer once it has been sent. + * pucUDPPayloadBuffer can be safely re-used to receive from + * the socket below. */ + FreeRTOS_debug_printf( ( "[Zero Copy] Data sent... \r\n" ) ); + } - /* Keep a count of how many echo requests have been transmitted - so it can be compared to the number of echo replies received. - It would be expected to loose at least one to an ARP message the - first time the connection is created. */ - ulTxCount++; + /* Keep a count of how many echo requests have been transmitted + * so it can be compared to the number of echo replies received. + * It would be expected to loose at least one to an ARP message the + * first time the connection is created. */ + ulTxCount++; - /* Receive data on the socket. ulFlags has the zero copy bit set - (FREERTOS_ZERO_COPY) indicating to the stack that a reference to - the received data should be passed out to this task using the - second parameter to the FreeRTOS_recvfrom() call. When this is - done the IP stack is no longer responsible for releasing the - buffer, and the task *must* return the buffer to the stack when - it is no longer needed. By default the receive block time is - portMAX_DELAY. */ - echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopyReceiveEvent ); - lReturned = FreeRTOS_recvfrom( xSocket, /* The socket to receive from. */ - ( void * ) &pucUDPPayloadBuffer, /* pucUDPPayloadBuffer will be set to point to the buffer that already contains the received data. */ - 0, /* Ignored because the zero copy interface is being used. */ - FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */ - &xEchoServerAddress, /* The address from which the data was sent. */ - &xAddressLength ); + /* Receive data on the socket. ulFlags has the zero copy bit set + * (FREERTOS_ZERO_COPY) indicating to the stack that a reference to + * the received data should be passed out to this task using the + * second parameter to the FreeRTOS_recvfrom() call. When this is + * done the IP stack is no longer responsible for releasing the + * buffer, and the task *must* return the buffer to the stack when + * it is no longer needed. By default the receive block time is + * portMAX_DELAY. */ + echoMARK_SEND_IN_TRACE_BUFFER( xZeroCopyReceiveEvent ); + lReturned = FreeRTOS_recvfrom( xSocket, /* The socket to receive from. */ + ( void * ) &pucUDPPayloadBuffer, /* pucUDPPayloadBuffer will be set to point to the buffer that already contains the received data. */ + 0, /* Ignored because the zero copy interface is being used. */ + FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */ + &xEchoServerAddress, /* The address from which the data was sent. */ + &xAddressLength ); - if( lReturned > 0 ) - { - /* Compare the string sent to the echo server with the string - received back from the echo server. */ - if( strcmp( ( char * ) pucUDPPayloadBuffer, ( char * ) cTxString ) == 0 ) - { - /* The strings matched. */ - ulRxCount++; - FreeRTOS_debug_printf( ( "[Zero Copy] Data was received correctly.\r\n" ) ); - } - else - { - FreeRTOS_debug_printf( ( "[Zero Copy] Data received was erreneous.\r\n" ) ); - } + if( lReturned > 0 ) + { + /* Compare the string sent to the echo server with the string + * received back from the echo server. */ + if( strcmp( ( char * ) pucUDPPayloadBuffer, ( char * ) cTxString ) == 0 ) + { + /* The strings matched. */ + ulRxCount++; + FreeRTOS_debug_printf( ( "[Zero Copy] Data was received correctly.\r\n" ) ); + } + else + { + FreeRTOS_debug_printf( ( "[Zero Copy] Data received was erroneous.\r\n" ) ); + } - /* The buffer that contains the data passed out of the stack - *must* be returned to the stack. */ - FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer ); - } - else - { - FreeRTOS_debug_printf( ( "[Zero Copy] Data was not received\r\n" ) ); - } - } - } + /* The buffer that contains the data passed out of the stack + * must* be returned to the stack. */ + FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer ); + } + else + { + FreeRTOS_debug_printf( ( "[Zero Copy] Data was not received\r\n" ) ); + } + } + } - /* Pause for a short while to ensure the network is not too - congested. */ - vTaskDelay( echoLOOP_DELAY ); + /* Pause for a short while to ensure the network is not too + * congested. */ + vTaskDelay( echoLOOP_DELAY ); - /* Close this socket before looping back to create another. */ - FreeRTOS_closesocket( xSocket ); - } + /* Close this socket before looping back to create another. */ + FreeRTOS_closesocket( xSocket ); + } } /*-----------------------------------------------------------*/ - diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/UDPCommandServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/UDPCommandServer.c index ecbf51dcf..37d2b5510 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/UDPCommandServer.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/UDPCommandServer.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -43,18 +43,18 @@ #include "UDPCommandInterpreter.h" /* Dimensions the buffer into which input characters are placed. */ -#define cmdMAX_INPUT_SIZE 60 +#define cmdMAX_INPUT_SIZE 60 /* Dimensions the buffer into which string outputs can be placed. */ -#define cmdMAX_OUTPUT_SIZE 1024 +#define cmdMAX_OUTPUT_SIZE 1024 /* Dimensions the buffer passed to the recvfrom() call. */ -#define cmdSOCKET_INPUT_BUFFER_SIZE 60 +#define cmdSOCKET_INPUT_BUFFER_SIZE 60 /* * The task that runs FreeRTOS+CLI. */ -void vUDPCommandInterpreterTask( void *pvParameters ); +void vUDPCommandInterpreterTask( void * pvParameters ); /* * Open and configure the UDP socket. @@ -63,146 +63,147 @@ static Socket_t prvOpenUDPServerSocket( uint16_t usPort ); /*-----------------------------------------------------------*/ -void vStartUDPCommandInterpreterTask( uint16_t usStackSize, uint32_t ulPort, unsigned portBASE_TYPE uxPriority ) +void vStartUDPCommandInterpreterTask( uint16_t usStackSize, + uint32_t ulPort, + unsigned portBASE_TYPE uxPriority ) { - xTaskCreate( vUDPCommandInterpreterTask, ( signed char * ) "CLI", usStackSize, ( void * ) ulPort, uxPriority, NULL ); + xTaskCreate( vUDPCommandInterpreterTask, ( signed char * ) "CLI", usStackSize, ( void * ) ulPort, uxPriority, NULL ); } /*-----------------------------------------------------------*/ -/* +/* * Task that provides the input and output for the FreeRTOS+CLI command * interpreter. In this case a UDP port is used. See the URL in the comments * within main.c for the location of the online documentation. */ -void vUDPCommandInterpreterTask( void *pvParameters ) +void vUDPCommandInterpreterTask( void * pvParameters ) { -long lBytes, lByte; -signed char cInChar, cInputIndex = 0; -static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ]; -portBASE_TYPE xMoreDataToFollow; -struct freertos_sockaddr xClient; -socklen_t xClientAddressLength = 0; /* This is required as a parameter to maintain the sendto() Berkeley sockets API - but it is not actually used so can take any value. */ -Socket_t xSocket; -extern const uint8_t ucIPAddress[ 4 ]; -extern const uint8_t ucMACAddress[ 6 ]; + long lBytes, lByte; + signed char cInChar, cInputIndex = 0; + static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ]; + portBASE_TYPE xMoreDataToFollow; + struct freertos_sockaddr xClient; + socklen_t xClientAddressLength = 0; /* This is required as a parameter to maintain the sendto() Berkeley sockets API - but it is not actually used so can take any value. */ + Socket_t xSocket; + extern const uint8_t ucIPAddress[ 4 ]; + extern const uint8_t ucMACAddress[ 6 ]; - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; - /* Attempt to open the socket. The port number is passed in the task - parameter. The strange casting is to remove compiler warnings on 32-bit - machines. */ - xSocket = prvOpenUDPServerSocket( ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL ); + /* Attempt to open the socket. The port number is passed in the task + * parameter. The strange casting is to remove compiler warnings on 32-bit + * machines. */ + xSocket = prvOpenUDPServerSocket( ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL ); - if( xSocket != FREERTOS_INVALID_SOCKET ) - { - for( ;; ) - { - /* Wait for incoming data on the opened socket. */ - lBytes = FreeRTOS_recvfrom( xSocket, ( void * ) cLocalBuffer, sizeof( cLocalBuffer ), 0, &xClient, &xClientAddressLength ); + if( xSocket != FREERTOS_INVALID_SOCKET ) + { + for( ; ; ) + { + /* Wait for incoming data on the opened socket. */ + lBytes = FreeRTOS_recvfrom( xSocket, ( void * ) cLocalBuffer, sizeof( cLocalBuffer ), 0, &xClient, &xClientAddressLength ); - if( lBytes != FREERTOS_SOCKET_ERROR ) - { - /* Process each received byte in turn. */ - lByte = 0; - while( lByte < lBytes ) - { - /* The next character in the input buffer. */ - cInChar = cLocalBuffer[ lByte ]; - lByte++; + if( lBytes != FREERTOS_SOCKET_ERROR ) + { + /* Process each received byte in turn. */ + lByte = 0; - /* Newline characters are taken as the end of the command - string. */ - if( cInChar == '\n' ) - { - /* Process the input string received prior to the - newline. */ - do - { - /* Pass the string to FreeRTOS+CLI. */ - xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE ); - - /* Send the output generated by the command's - implementation. */ - FreeRTOS_sendto( xSocket, cOutputString, strlen( ( const char * ) cOutputString ), 0, &xClient, xClientAddressLength ); + while( lByte < lBytes ) + { + /* The next character in the input buffer. */ + cInChar = cLocalBuffer[ lByte ]; + lByte++; - } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */ + /* Newline characters are taken as the end of the command + * string. */ + if( cInChar == '\n' ) + { + /* Process the input string received prior to the + * newline. */ + do + { + /* Pass the string to FreeRTOS+CLI. */ + xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE ); - /* All the strings generated by the command processing - have been sent. Clear the input string ready to receive - the next command. */ - cInputIndex = 0; - memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); - - /* Transmit a spacer, just to make the command console - easier to read. */ - FreeRTOS_sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, &xClient, xClientAddressLength ); - } - else - { - if( cInChar == '\r' ) - { - /* Ignore the character. Newlines are used to - detect the end of the input string. */ - } - else if( cInChar == '\b' ) - { - /* Backspace was pressed. Erase the last character - in the string - if any. */ - if( cInputIndex > 0 ) - { - cInputIndex--; - cInputString[ cInputIndex ] = '\0'; - } - } - else - { - /* A character was entered. Add it to the string - entered so far. When a \n is entered the complete - string will be passed to the command interpreter. */ - if( cInputIndex < cmdMAX_INPUT_SIZE ) - { - cInputString[ cInputIndex ] = cInChar; - cInputIndex++; - } - } - } - } - } - } - } - else - { - /* The socket could not be opened. */ - vTaskDelete( NULL ); - } + /* Send the output generated by the command's + * implementation. */ + FreeRTOS_sendto( xSocket, cOutputString, strlen( ( const char * ) cOutputString ), 0, &xClient, xClientAddressLength ); + } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */ + + /* All the strings generated by the command processing + * have been sent. Clear the input string ready to receive + * the next command. */ + cInputIndex = 0; + memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); + + /* Transmit a spacer, just to make the command console + * easier to read. */ + FreeRTOS_sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, &xClient, xClientAddressLength ); + } + else + { + if( cInChar == '\r' ) + { + /* Ignore the character. Newlines are used to + * detect the end of the input string. */ + } + else if( cInChar == '\b' ) + { + /* Backspace was pressed. Erase the last character + * in the string - if any. */ + if( cInputIndex > 0 ) + { + cInputIndex--; + cInputString[ cInputIndex ] = '\0'; + } + } + else + { + /* A character was entered. Add it to the string + * entered so far. When a \n is entered the complete + * string will be passed to the command interpreter. */ + if( cInputIndex < cmdMAX_INPUT_SIZE ) + { + cInputString[ cInputIndex ] = cInChar; + cInputIndex++; + } + } + } + } + } + } + } + else + { + /* The socket could not be opened. */ + vTaskDelete( NULL ); + } } /*-----------------------------------------------------------*/ static Socket_t prvOpenUDPServerSocket( uint16_t usPort ) { -struct freertos_sockaddr xServer; -Socket_t xSocket = FREERTOS_INVALID_SOCKET; + struct freertos_sockaddr xServer; + Socket_t xSocket = FREERTOS_INVALID_SOCKET; - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - if( xSocket != FREERTOS_INVALID_SOCKET) - { - /* Zero out the server structure. */ - memset( ( void * ) &xServer, 0x00, sizeof( xServer ) ); + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); - /* Set family and port. */ - xServer.sin_port = FreeRTOS_htons( usPort ); - xServer.sin_family = FREERTOS_AF_INET; + if( xSocket != FREERTOS_INVALID_SOCKET ) + { + /* Zero out the server structure. */ + memset( ( void * ) &xServer, 0x00, sizeof( xServer ) ); - /* Bind the address to the socket. */ - if( FreeRTOS_bind( xSocket, &xServer, sizeof( xServer ) ) == -1 ) - { - FreeRTOS_closesocket( xSocket ); - xSocket = FREERTOS_INVALID_SOCKET; - } - } + /* Set family and port. */ + xServer.sin_port = FreeRTOS_htons( usPort ); + xServer.sin_family = FREERTOS_AF_INET; - return xSocket; + /* Bind the address to the socket. */ + if( FreeRTOS_bind( xSocket, &xServer, sizeof( xServer ) ) == -1 ) + { + FreeRTOS_closesocket( xSocket ); + xSocket = FREERTOS_INVALID_SOCKET; + } + } + + return xSocket; } - - diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/SimpleClientAndServer.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/SimpleClientAndServer.h index 48b69c1aa..b3b85278b 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/SimpleClientAndServer.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/SimpleClientAndServer.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -27,6 +27,8 @@ #ifndef SIMPLE_CLIENT_AND_SERVER_H #define SIMPLE_CLIENT_AND_SERVER_H -void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, uint32_t ulsPort, unsigned portBASE_TYPE uxPriority ); +void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, + uint32_t ulsPort, + unsigned portBASE_TYPE uxPriority ); #endif /* SIMPLE_CLIENT_AND_SERVER_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/TwoEchoClients.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/TwoEchoClients.h index d8de80d4f..141e7106e 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/TwoEchoClients.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/TwoEchoClients.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -32,6 +32,7 @@ * to send to and receive from an echo server. The other task uses the zero * copy interface to send to and receive from an echo server. */ -void vStartEchoClientTasks( uint16_t usTaskStackSize, unsigned portBASE_TYPE uxTaskPriority ); +void vStartEchoClientTasks( uint16_t usTaskStackSize, + unsigned portBASE_TYPE uxTaskPriority ); #endif /* TWO_ECHO_CLIENTS_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/UDPCommandInterpreter.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/UDPCommandInterpreter.h index d2cc936f7..bdc740cb4 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/UDPCommandInterpreter.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/UDPCommandInterpreter.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -27,6 +27,8 @@ #ifndef UDP_COMMAND_INTERPRETER_H #define UDP_COMMAND_INTERPRETER_H -void vStartUDPCommandInterpreterTask( uint16_t usStackSize, uint32_t ulPort, unsigned portBASE_TYPE uxPriority ); +void vStartUDPCommandInterpreterTask( uint16_t usStackSize, + uint32_t ulPort, + unsigned portBASE_TYPE uxPriority ); #endif /* UDP_COMMAND_INTERPRETER_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/user_settings.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/user_settings.h index 7dea93133..be76e8cb8 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/user_settings.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/DemoTasks/include/user_settings.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -29,14 +29,14 @@ - /* The address of an echo server that will be used by the two demo echo client - tasks. - http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html - http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html */ +/* The address of an echo server that will be used by the two demo echo client + * tasks. + * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html + * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html */ -#define configECHO_SERVER_ADDR0 172 -#define configECHO_SERVER_ADDR1 19 -#define configECHO_SERVER_ADDR2 195 -#define configECHO_SERVER_ADDR3 36 +#define configECHO_SERVER_ADDR0 172 +#define configECHO_SERVER_ADDR1 19 +#define configECHO_SERVER_ADDR2 195 +#define configECHO_SERVER_ADDR3 36 -#endif /* ifndef USER_SETTINGS_H_ */ \ No newline at end of file +#endif /* ifndef USER_SETTINGS_H_ */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.sln index c822868cd..25ad69485 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.sln +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.sln @@ -1,86 +1,86 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_UDP_with_CLI", "FreeRTOS_Plus_UDP_with_CLI.vcxproj", "{66422066-D458-449A-AE2A-0A44D4BDE94B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{19F0A285-8705-4308-AAD2-7E2108B05F0D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|Win32.ActiveCfg = Debug|Win32 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|Win32.Build.0 = Debug|Win32 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|x64.ActiveCfg = Debug|x64 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|x64.Build.0 = Debug|x64 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|x86.ActiveCfg = Debug|Win32 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|x86.Build.0 = Debug|Win32 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|Win32.ActiveCfg = Release|Win32 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|Win32.Build.0 = Release|Win32 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|x64.ActiveCfg = Release|x64 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|x64.Build.0 = Release|x64 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|x86.ActiveCfg = Release|Win32 - {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {19F0A285-8705-4308-AAD2-7E2108B05F0D} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {19F0A285-8705-4308-AAD2-7E2108B05F0D} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {19F0A285-8705-4308-AAD2-7E2108B05F0D} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {C258A7A3-BDFD-4E7F-87B4-760A5DC5F447} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_UDP_with_CLI", "FreeRTOS_Plus_UDP_with_CLI.vcxproj", "{66422066-D458-449A-AE2A-0A44D4BDE94B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{19F0A285-8705-4308-AAD2-7E2108B05F0D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|Win32.ActiveCfg = Debug|Win32 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|Win32.Build.0 = Debug|Win32 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|x64.ActiveCfg = Debug|x64 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|x64.Build.0 = Debug|x64 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|x86.ActiveCfg = Debug|Win32 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Debug|x86.Build.0 = Debug|Win32 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|Win32.ActiveCfg = Release|Win32 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|Win32.Build.0 = Release|Win32 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|x64.ActiveCfg = Release|x64 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|x64.Build.0 = Release|x64 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|x86.ActiveCfg = Release|Win32 + {66422066-D458-449A-AE2A-0A44D4BDE94B}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {19F0A285-8705-4308-AAD2-7E2108B05F0D} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {19F0A285-8705-4308-AAD2-7E2108B05F0D} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {19F0A285-8705-4308-AAD2-7E2108B05F0D} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C258A7A3-BDFD-4E7F-87B4-760A5DC5F447} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.vcxproj index fd9146a50..a7d666b0d 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.vcxproj @@ -1,175 +1,175 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {66422066-d458-449a-ae2a-0a44d4bde94b} - FreeRTOSPlusUDPwithCLI - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\DemoTasks\include;..\Common\WinPCap;..\..\Source\FreeRTOS-Plus-CLI;.;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\DemoTasks\include;..\Common\WinPCap;..\..\Source\FreeRTOS-Plus-CLI;.;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\DemoTasks\include;..\Common\WinPCap;..\..\Source\FreeRTOS-Plus-CLI;.;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - .\DemoTasks\include;..\Common\WinPCap;..\..\Source\FreeRTOS-Plus-CLI;.;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {66422066-d458-449a-ae2a-0a44d4bde94b} + FreeRTOSPlusUDPwithCLI + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\DemoTasks\include;..\Common\WinPCap;..\..\Source\FreeRTOS-Plus-CLI;.;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\DemoTasks\include;..\Common\WinPCap;..\..\Source\FreeRTOS-Plus-CLI;.;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\DemoTasks\include;..\Common\WinPCap;..\..\Source\FreeRTOS-Plus-CLI;.;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + .\DemoTasks\include;..\Common\WinPCap;..\..\Source\FreeRTOS-Plus-CLI;.;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.vcxproj.filters index 3a75f2eb4..91ea043de 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/FreeRTOS_Plus_UDP_with_CLI.vcxproj.filters @@ -1,60 +1,60 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {ccb4f243-ddf3-4801-b9ad-120ec89ce7d5} - - - - - FreeRTOS+CLI - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - FreeRTOS+CLI - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {ccb4f243-ddf3-4801-b9ad-120ec89ce7d5} + + + + + FreeRTOS+CLI + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + FreeRTOS+CLI + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/README_FIRST.txt b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/README_FIRST.txt index b6688685b..c184f495b 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/README_FIRST.txt +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/README_FIRST.txt @@ -4,8 +4,8 @@ http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Exampl The FreeRTOS+UDP API is documented on the following web page: http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/FreeRTOS_UDP_API_Functions.shtml -Other information, including a FreeRTOS+UDP primer, a description of the -directory structure, and a glossary of networking terminology, can be found in +Other information, including a FreeRTOS+UDP primer, a description of the +directory structure, and a glossary of networking terminology, can be found in the FreeRTOS+UDP portal: http://www.FreeRTOS.org/udp diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/Run-time-stats-utils.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/Run-time-stats-utils.c index 3ea7d036b..79fef9b05 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/Run-time-stats-utils.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/Run-time-stats-utils.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -34,56 +34,56 @@ * * Also note that it is assumed this demo is going to be used for short periods * of time only, and therefore timer overflows are not handled. -*/ + */ /* FreeRTOS includes. */ #include /* Variables used in the creation of the run time stats time base. Run time -stats record how much time each task spends in the Running state. */ -static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL; + * stats record how much time each task spends in the Running state. */ +static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundredthMillisecond = 0LL; /*-----------------------------------------------------------*/ void vConfigureTimerForRunTimeStats( void ) { -LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue; + LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue; - /* Initialise the variables used to create the run time stats time base. - Run time stats record how much time each task spends in the Running - state. */ + /* Initialise the variables used to create the run time stats time base. + * Run time stats record how much time each task spends in the Running + * state. */ - if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 ) - { - llTicksPerHundedthMillisecond = 1; - } - else - { - /* How many times does the performance counter increment in 1/100th - millisecond. */ - llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL; + if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 ) + { + llTicksPerHundredthMillisecond = 1; + } + else + { + /* How many times does the performance counter increment in 1/100th + * millisecond. */ + llTicksPerHundredthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL; - /* What is the performance counter value now, this will be subtracted - from readings taken at run time. */ - QueryPerformanceCounter( &liInitialRunTimeValue ); - llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart; - } + /* What is the performance counter value now, this will be subtracted + * from readings taken at run time. */ + QueryPerformanceCounter( &liInitialRunTimeValue ); + llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart; + } } /*-----------------------------------------------------------*/ unsigned long ulGetRunTimeCounterValue( void ) { -LARGE_INTEGER liCurrentCount; -unsigned long ulReturn; + LARGE_INTEGER liCurrentCount; + unsigned long ulReturn; - /* What is the performance counter value now? */ - QueryPerformanceCounter( &liCurrentCount ); + /* What is the performance counter value now? */ + QueryPerformanceCounter( &liCurrentCount ); - /* Subtract the performance counter value reading taken when the - application started to get a count from that reference point, then - scale to (simulated) 1/100ths of a millisecond. */ - ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundedthMillisecond ); + /* Subtract the performance counter value reading taken when the + * application started to get a count from that reference point, then + * scale to (simulated) 1/100ths of a millisecond. */ + ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundredthMillisecond ); - return ulReturn; + return ulReturn; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/main.c index eea3e0d92..1f7ff80b9 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_UDP_Mode_CLI_Windows_Simulator/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -44,24 +44,24 @@ #include "user_settings.h" /* UDP command server task parameters. */ -#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY ) -#define mainUDP_CLI_PORT_NUMBER ( 5001UL ) -#define mainUDP_CLI_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE ) +#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define mainUDP_CLI_PORT_NUMBER ( 5001UL ) +#define mainUDP_CLI_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE ) /* Simple UDP client and server task parameters. */ -#define mainSIMPLE_CLIENT_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY ) -#define mainSIMPLE_CLIENT_SERVER_PORT ( 5005UL ) -#define mainSIMPLE_CLIENT_SERVER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE ) +#define mainSIMPLE_CLIENT_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define mainSIMPLE_CLIENT_SERVER_PORT ( 5005UL ) +#define mainSIMPLE_CLIENT_SERVER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE ) /* Echo client task parameters. */ -#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) -#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainECHO_CLIENT_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) +#define mainECHO_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) /* Set the following constants to 1 or 0 to define which tasks to include and -exclude. */ -#define mainCREATE_UDP_CLI_TASKS 1 -#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 0 -#define mainCREATE_UDP_ECHO_TASKS 1 + * exclude. */ +#define mainCREATE_UDP_CLI_TASKS 1 +#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 0 +#define mainCREATE_UDP_ECHO_TASKS 1 /*-----------------------------------------------------------*/ @@ -72,19 +72,19 @@ exclude. */ extern void vRegisterCLICommands( void ); /* The default IP and MAC address used by the demo. The address configuration -defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is -1 but a DHCP server could not be contacted. See the online documentation for -more information. */ + * defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is + * 1 but a DHCP server could not be contacted. See the online documentation for + * more information. */ static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 }; static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 }; static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 }; static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 }; /* Default MAC address configuration. The demo creates a virtual network -connection that uses this MAC address by accessing the raw Ethernet data -to and from a real network connection on the host PC. See the -configNETWORK_INTERFACE_TO_USE definition for information on how to configure -the real network connection to use. */ + * connection that uses this MAC address by accessing the raw Ethernet data + * to and from a real network connection on the host PC. See the + * configNETWORK_INTERFACE_TO_USE definition for information on how to configure + * the real network connection to use. */ const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 }; /* Used to guard prints to the console. */ @@ -102,35 +102,35 @@ const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE, xLogToUDP = pdFALS /*-----------------------------------------------------------*/ /* Define a name that will be used for LLMNR and NBNS searches. */ -#define mainHOST_NAME "RTOSDemo" -#define mainDEVICE_NICK_NAME "windows_demo" +#define mainHOST_NAME "RTOSDemo" +#define mainDEVICE_NICK_NAME "windows_demo" /* Used by the pseudo random number generator. */ static UBaseType_t ulNextRand; #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - /* In case multiple interfaces are used, define them statically. */ +/* In case multiple interfaces are used, define them statically. */ - /* There is only 1 physical interface. */ +/* There is only 1 physical interface. */ static NetworkInterface_t xInterfaces[ 1 ]; - /* It will have several end-points. */ +/* It will have several end-points. */ static NetworkEndPoint_t xEndPoints[ 4 ]; #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ /****************************************************************************** - * - * See the following web page for information on using this demo. - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/RTOS_UDP_CLI_Windows_Simulator.shtml - * - ******************************************************************************/ +* +* See the following web page for information on using this demo. +* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/RTOS_UDP_CLI_Windows_Simulator.shtml +* +******************************************************************************/ int main( void ) { -const uint32_t ulLongTime_ms = 250UL; + const uint32_t ulLongTime_ms = 250UL; /* Create a mutex that is used to guard against the console being accessed * by more than one task simultaneously. */ @@ -145,24 +145,24 @@ const uint32_t ulLongTime_ms = 250UL; /* Initialise the network interface.*/ FreeRTOS_debug_printf( ( "FreeRTOS_IPInit\r\n" ) ); -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - /* Initialise the interface descriptor for WinPCap. */ - pxWinPcap_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + /* Initialise the interface descriptor for WinPCap. */ + pxWinPcap_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); - /* === End-point 0 === */ - FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + /* === End-point 0 === */ + FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); #if ( ipconfigUSE_DHCP != 0 ) - { - /* End-point 0 wants to use DHCPv4. */ - xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; - } - #endif /* ( ipconfigUSE_DHCP != 0 ) */ - memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof( ucMACAddress ) ); - FreeRTOS_IPInit_Multi(); -#else - /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ - FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + { + /* End-point 0 wants to use DHCPv4. */ + xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; + } + #endif /* ( ipconfigUSE_DHCP != 0 ) */ + memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof( ucMACAddress ) ); + FreeRTOS_IPInit_Multi(); + #else /* if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ + FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ /* Initialise the logging. */ uint32_t ulLoggingIPAddress; @@ -186,7 +186,7 @@ const uint32_t ulLongTime_ms = 250UL; * timer tasks to be created. See the memory management section on the * FreeRTOS web site for more details (this is standard text that is not not * really applicable to the Win32 simulator port). */ - for( ;; ) + for( ; ; ) { Sleep( ulLongTime_ms ); } @@ -195,7 +195,7 @@ const uint32_t ulLongTime_ms = 250UL; void vApplicationIdleHook( void ) { -const unsigned long ulMSToSleep = 5; + const unsigned long ulMSToSleep = 5; /* This function is called on each cycle of the idle task if * configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU @@ -205,12 +205,13 @@ const unsigned long ulMSToSleep = 5; /*-----------------------------------------------------------*/ /* Called automatically when a reply to an outgoing ping is received. */ -void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier ) +void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, + uint16_t usIdentifier ) { -static const uint8_t *pcSuccess = ( uint8_t * ) "Ping reply received - "; -static const uint8_t *pcInvalidChecksum = ( uint8_t * ) "Ping reply received with invalid checksum - "; -static const uint8_t *pcInvalidData = ( uint8_t * ) "Ping reply received with invalid data - "; -static uint8_t cMessage[ 50 ]; + static const uint8_t * pcSuccess = ( uint8_t * ) "Ping reply received - "; + static const uint8_t * pcInvalidChecksum = ( uint8_t * ) "Ping reply received with invalid checksum - "; + static const uint8_t * pcInvalidData = ( uint8_t * ) "Ping reply received with invalid data - "; + static uint8_t cMessage[ 50 ]; switch( eStatus ) @@ -227,7 +228,8 @@ static uint8_t cMessage[ 50 ]; FreeRTOS_debug_printf( ( ( char * ) pcInvalidData ) ); break; - default : + default: + /* It is not possible to get here as all enums have their own * case. */ break; @@ -252,7 +254,10 @@ void vApplicationMallocFailedHook( void ) * (although it does not provide information on how the remaining heap might * be fragmented). */ taskDISABLE_INTERRUPTS(); - for( ;; ); + + for( ; ; ) + { + } } /*-----------------------------------------------------------*/ @@ -273,7 +278,7 @@ void vApplicationMallocFailedHook( void ) #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, - const char * pcName ) + const char * pcName ) #else BaseType_t xApplicationDNSQueryHook( const char * pcName ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/ReadMe.txt b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/ReadMe.txt index 24bb5461e..bc35bc3a0 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/ReadMe.txt +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/ReadMe.txt @@ -1,4 +1,4 @@ -FreeRTOS+UDP was removed in FreeRTOS V10.1.0 as it was replaced by FreeRTOS+TCP, -which was brought into the main download in FreeRTOS V10.0.0. FreeRTOS+TCP can -be configured as a UDP only stack, and FreeRTOS+UDP does not contain the patches +FreeRTOS+UDP was removed in FreeRTOS V10.1.0 as it was replaced by FreeRTOS+TCP, +which was brought into the main download in FreeRTOS V10.0.0. FreeRTOS+TCP can +be configured as a UDP only stack, and FreeRTOS+UDP does not contain the patches applied to FreeRTOS+TCP. \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/See also FreeRTOS+TCP.url b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/See also FreeRTOS+TCP.url index 2da199cac..6617b6062 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/See also FreeRTOS+TCP.url +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/See also FreeRTOS+TCP.url @@ -1,5 +1,5 @@ -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 -[InternetShortcut] -URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html -IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html +IDList= diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL.sln index ba59754e1..3b53adff6 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL.sln +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL.sln @@ -1,113 +1,113 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_WolfSSL_Windows_Simulator", "FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj", "{C8144D60-5005-4111-841E-FA3529F84A8B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{859BA71E-DC13-41CE-A405-0F83CC78F7BF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 - Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 - Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|Win32.ActiveCfg = Debug|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|Win32.Build.0 = Debug|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|x64.ActiveCfg = Debug|x64 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|x64.Build.0 = Debug|x64 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|x86.ActiveCfg = Debug|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|x86.Build.0 = Debug|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|Win32.ActiveCfg = Release|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|Win32.Build.0 = Release|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|x64.ActiveCfg = Release|x64 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|x64.Build.0 = Release|x64 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|x86.ActiveCfg = Release|Win32 - {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {859BA71E-DC13-41CE-A405-0F83CC78F7BF} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {859BA71E-DC13-41CE-A405-0F83CC78F7BF} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {859BA71E-DC13-41CE-A405-0F83CC78F7BF} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {77AB32C6-C9AC-4247-A3E4-D11153F3B741} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS_Plus_WolfSSL_Windows_Simulator", "FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj", "{C8144D60-5005-4111-841E-FA3529F84A8B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{859BA71E-DC13-41CE-A405-0F83CC78F7BF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 + Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 + Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|Win32.ActiveCfg = Debug|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|Win32.Build.0 = Debug|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|x64.ActiveCfg = Debug|x64 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|x64.Build.0 = Debug|x64 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|x86.ActiveCfg = Debug|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Debug|x86.Build.0 = Debug|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|Win32.ActiveCfg = Release|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|Win32.Build.0 = Release|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|x64.ActiveCfg = Release|x64 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|x64.Build.0 = Release|x64 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|x86.ActiveCfg = Release|Win32 + {C8144D60-5005-4111-841E-FA3529F84A8B}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {859BA71E-DC13-41CE-A405-0F83CC78F7BF} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {859BA71E-DC13-41CE-A405-0F83CC78F7BF} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {859BA71E-DC13-41CE-A405-0F83CC78F7BF} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {77AB32C6-C9AC-4247-A3E4-D11153F3B741} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj index dfea90f72..30167b9a7 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj @@ -1,356 +1,356 @@ - - - - - Debug_with_Libslirp - Win32 - - - Debug_with_Libslirp - x64 - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {c8144d60-5005-4111-841e-fa3529f84a8b} - FreeRTOSPlusWolfSSLVisualStudio_StaticProjects - 10.0 - - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - true - - - true - - - false - - - - Level3 - true - WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN - true - ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) - - - Console - true - Bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - true - WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN - true - ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) - - - Console - true - Bcrypt.lib;Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN - true - ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - true - WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN - true - ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN - true - ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) - - - Console - true - Bcrypt.lib;Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN - true - ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - - - - - - + + + + + Debug_with_Libslirp + Win32 + + + Debug_with_Libslirp + x64 + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {c8144d60-5005-4111-841e-fa3529f84a8b} + FreeRTOSPlusWolfSSLVisualStudio_StaticProjects + 10.0 + + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + true + + + true + + + false + + + + Level3 + true + WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN + true + ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) + + + Console + true + Bcrypt.lib;%(AdditionalDependencies) + + + + + Level3 + true + WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN + true + ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) + + + Console + true + Bcrypt.lib;Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN + true + ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN + true + ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN + true + ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) + + + Console + true + Bcrypt.lib;Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + WOLFSSL_USER_SETTINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WOLFSSL_IGNORE_FILE_WARN + true + ..\..\ThirdParty\WolfSSL;.;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj.filters index c8d1884bd..151f3999c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOS_Plus_WolfSSL_Windows_Simulator.vcxproj.filters @@ -1,389 +1,389 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {0f203ff4-373b-4655-952c-8c02392c935b} - - - {a5051803-872c-41c6-ac09-0672c69946a1} - - - - - Source Files - - - Header Files - - - Header Files - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - - - Source Files - - - Source Files - - - Source Files - - - wolfSSL - - - wolfSSL - - - wolfSSL - - - wolfSSL - - - wolfSSL - - - wolfSSL - - - wolfSSL - - - wolfSSL - - - wolfSSL - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - wolfSSL\wolfcrypt - - - - - Header Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {0f203ff4-373b-4655-952c-8c02392c935b} + + + {a5051803-872c-41c6-ac09-0672c69946a1} + + + + + Source Files + + + Header Files + + + Header Files + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + + + Source Files + + + Source Files + + + Source Files + + + wolfSSL + + + wolfSSL + + + wolfSSL + + + wolfSSL + + + wolfSSL + + + wolfSSL + + + wolfSSL + + + wolfSSL + + + wolfSSL + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + wolfSSL\wolfcrypt + + + + + Header Files + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/READ_ME.url b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/READ_ME.url index 4b773e348..967308be8 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/READ_ME.url +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/READ_ME.url @@ -1,5 +1,5 @@ -[InternetShortcut] -URL=http://www.freertos.org/FreeRTOS-Plus/WolfSSL/FreeRTOS_WolfSSL_Example.shtml -IDList= -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/FreeRTOS-Plus/WolfSSL/FreeRTOS_WolfSSL_Example.shtml +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPClientTask.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPClientTask.c index 1485b3de7..a38e8c7aa 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPClientTask.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPClientTask.c @@ -1,135 +1,133 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -#pragma comment( lib, "ws2_32.lib" ) - -/* Win32 includes. */ -#include - -/* wolfSSL includes. */ -#include "wolfssl/ssl.h" - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/*-----------------------------------------------------------*/ - -/* The wolfSSL context for the client. */ -static WOLFSSL_CTX* xWolfSSL_ClientContext = NULL; - -/*-----------------------------------------------------------*/ - -/* See the comments at the top of main.c. */ -void vSecureTCPClientTask( void *pvParameters ) -{ -SOCKET xClientSocket; -struct sockaddr_in xConnection; -WOLFSSL* xWolfSSL_Object; -WORD wVersionRequested; -WSADATA xWSAData; -char cString[ 50 ]; -BaseType_t lReturned; -uint32_t ulCount = 0UL; - - /* Remove compiler warning about unused parameters. */ - ( void ) pvParameters; - - /* Prepare to use WinSock. */ - wVersionRequested = MAKEWORD( 2, 2 ); - configASSERT( WSAStartup( wVersionRequested, &xWSAData ) == 0 ); - - /* Set family and port for client socket. */ - memset( ( void * ) &xConnection, 0x00, sizeof( struct sockaddr_in ) ); - xConnection.sin_family = AF_INET; - xConnection.sin_addr.s_addr = inet_addr("127.0.0.1"); - xConnection.sin_port = htons( configTCP_PORT_NUMBER ); - - /* Attempt to create a context that uses the TLS 1.3 server protocol. */ - xWolfSSL_ClientContext = wolfSSL_CTX_new( wolfTLSv1_3_client_method() ); - configASSERT( xWolfSSL_ClientContext ); - - /* Load the CA certificate. */ - lReturned = wolfSSL_CTX_load_verify_locations( xWolfSSL_ClientContext, "ca-cert.pem", 0 ); - configASSERT( lReturned == SSL_SUCCESS ); - - for( ;; ) - { - /* Create the socket. */ - xClientSocket = socket( AF_INET, SOCK_STREAM, 0 ); - configASSERT( xClientSocket != INVALID_SOCKET ); - - /* Connect to the secure server. */ - if( connect( xClientSocket, ( SOCKADDR * ) &xConnection, sizeof( xConnection ) ) == 0 ) - { - /* The connect was successful. Create a wolfSSL object to associate - with this connection. */ - xWolfSSL_Object = wolfSSL_new( xWolfSSL_ClientContext ); - - if( xWolfSSL_Object != NULL ) - { - /* Associate the created wolfSSL object with the connected - socket. */ - lReturned = wolfSSL_set_fd( xWolfSSL_Object, xClientSocket ); - configASSERT( lReturned == SSL_SUCCESS ); - - /* The count is used to differentiate between messages sent to - the server, and to break out of the do while loop below. */ - ulCount = 0UL; - - do - { - /* Create the string that is sent to the secure server. */ - sprintf( cString, "Message number %lu\r\n", ulCount ); - - /* The next line is the secure equivalent of the standard - sockets call: - lReturned = send( xClientSocket, cString, strlen( cString ) + 1, 0 ); */ - lReturned = wolfSSL_write( xWolfSSL_Object, cString, strlen( cString ) + 1 ); - - - /* Short delay to prevent the messages streaming up the - console too quickly. */ - vTaskDelay( 50 ); - ulCount++; - - } while( ( lReturned != SOCKET_ERROR ) && ( ulCount < 10UL ) ); - } - - wolfSSL_free( xWolfSSL_Object ); - closesocket( xClientSocket ); - - /* Delay for a short time before starting over. */ - vTaskDelay( 250 ); - } - } -} -/*-----------------------------------------------------------*/ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#pragma comment( lib, "ws2_32.lib" ) + +/* Win32 includes. */ +#include + +/* wolfSSL includes. */ +#include "wolfssl/ssl.h" + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/*-----------------------------------------------------------*/ + +/* The wolfSSL context for the client. */ +static WOLFSSL_CTX * xWolfSSL_ClientContext = NULL; + +/*-----------------------------------------------------------*/ + +/* See the comments at the top of main.c. */ +void vSecureTCPClientTask( void * pvParameters ) +{ + SOCKET xClientSocket; + struct sockaddr_in xConnection; + WOLFSSL * xWolfSSL_Object; + WORD wVersionRequested; + WSADATA xWSAData; + char cString[ 50 ]; + BaseType_t lReturned; + uint32_t ulCount = 0UL; + + /* Remove compiler warning about unused parameters. */ + ( void ) pvParameters; + + /* Prepare to use WinSock. */ + wVersionRequested = MAKEWORD( 2, 2 ); + configASSERT( WSAStartup( wVersionRequested, &xWSAData ) == 0 ); + + /* Set family and port for client socket. */ + memset( ( void * ) &xConnection, 0x00, sizeof( struct sockaddr_in ) ); + xConnection.sin_family = AF_INET; + xConnection.sin_addr.s_addr = inet_addr( "127.0.0.1" ); + xConnection.sin_port = htons( configTCP_PORT_NUMBER ); + + /* Attempt to create a context that uses the TLS 1.3 server protocol. */ + xWolfSSL_ClientContext = wolfSSL_CTX_new( wolfTLSv1_3_client_method() ); + configASSERT( xWolfSSL_ClientContext ); + + /* Load the CA certificate. */ + lReturned = wolfSSL_CTX_load_verify_locations( xWolfSSL_ClientContext, "ca-cert.pem", 0 ); + configASSERT( lReturned == SSL_SUCCESS ); + + for( ; ; ) + { + /* Create the socket. */ + xClientSocket = socket( AF_INET, SOCK_STREAM, 0 ); + configASSERT( xClientSocket != INVALID_SOCKET ); + + /* Connect to the secure server. */ + if( connect( xClientSocket, ( SOCKADDR * ) &xConnection, sizeof( xConnection ) ) == 0 ) + { + /* The connect was successful. Create a wolfSSL object to associate + * with this connection. */ + xWolfSSL_Object = wolfSSL_new( xWolfSSL_ClientContext ); + + if( xWolfSSL_Object != NULL ) + { + /* Associate the created wolfSSL object with the connected + * socket. */ + lReturned = wolfSSL_set_fd( xWolfSSL_Object, xClientSocket ); + configASSERT( lReturned == SSL_SUCCESS ); + + /* The count is used to differentiate between messages sent to + * the server, and to break out of the do while loop below. */ + ulCount = 0UL; + + do + { + /* Create the string that is sent to the secure server. */ + sprintf( cString, "Message number %lu\r\n", ulCount ); + + /* The next line is the secure equivalent of the standard + * sockets call: + * lReturned = send( xClientSocket, cString, strlen( cString ) + 1, 0 ); */ + lReturned = wolfSSL_write( xWolfSSL_Object, cString, strlen( cString ) + 1 ); + + + /* Short delay to prevent the messages streaming up the + * console too quickly. */ + vTaskDelay( 50 ); + ulCount++; + } while( ( lReturned != SOCKET_ERROR ) && ( ulCount < 10UL ) ); + } + + wolfSSL_free( xWolfSSL_Object ); + closesocket( xClientSocket ); + + /* Delay for a short time before starting over. */ + vTaskDelay( 250 ); + } + } +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPServerTask.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPServerTask.c index 0feb346cc..47b7c608f 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPServerTask.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPServerTask.c @@ -1,244 +1,243 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos - * - */ - -#pragma comment( lib, "ws2_32.lib" ) - -/* Win32 includes. */ -#include - -/* wolfSSL includes. */ -#include "wolfssl/ssl.h" - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* This application is using the FreeRTOS Windows simulator, which uses the -FreeRTOS scheduler to schedule FreeRTOS task within the Windows environment. -The Windows envrionment must not be allowed to block any Windows threads that -are running FreeRTOS tasks, unless the FreeRTOS task is running at the FreeRTOS -idle priority. For simplicity, this demo uses the Windows TCP/IP stack, the -API for which can cause Windows threads to block. Therefore, any FreeRTOS task -that makes calls to the Windows TCP/IP stack must be assigned the idle prioity. -Note this is only a restriction of the simulated Windows environment - real -FreeRTOS ports do not have this restriction. */ -#define sstSECURE_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY ) - -/*-----------------------------------------------------------*/ - -/* - * Open, configures and binds the server's TCP socket. - */ -static SOCKET prvOpenServerSocket( void ); - -/* - * Prepare the wolfSSL library for use. - */ -static void prvInitialiseWolfSSL( void ); - -/* - * The task that implements the client side of the connection. - */ -extern void vSecureTCPClientTask( void *pvParameters ); - -/*-----------------------------------------------------------*/ - -/* The wolfSSL context for the server. */ -static WOLFSSL_CTX* xWolfSSL_ServerContext = NULL; - -/*-----------------------------------------------------------*/ - -/* See the comments at the top of main.c. */ -void vSecureTCPServerTask( void *pvParameters ) -{ -BaseType_t xReturned; -long lBytes; -uint8_t cReceivedString[ 60 ]; -struct sockaddr_in xClient; -int xClientAddressLength = sizeof( struct sockaddr_in ); -SOCKET xListeningSocket, xConnectedSocket; -WOLFSSL* xWolfSSL_Object; /* Only one connection is accepted at a time, so only one object is needed at a time. */ - - /* Just to prevent compiler warnings. */ - ( void ) pvParameters; - - /* Perform the initialisation necessary before wolfSSL can be used. */ - prvInitialiseWolfSSL(); - configASSERT( xWolfSSL_ServerContext ); - - /* Attempt to open the socket. */ - xListeningSocket = prvOpenServerSocket(); - - /* Now the server socket has been created and the wolfSSL library has been - initialised, the task that implements the client side can be created. */ - xTaskCreate( vSecureTCPClientTask, "Client", configMINIMAL_STACK_SIZE, NULL, sstSECURE_CLIENT_TASK_PRIORITY, NULL ); - - if( xListeningSocket != INVALID_SOCKET ) - { - for( ;; ) - { - /* Wait until the client connects. */ - printf( "Waiting for new connection\r\n" ); - xConnectedSocket = accept( xListeningSocket, ( struct sockaddr * ) &xClient, &xClientAddressLength ); - - if( xConnectedSocket != INVALID_SOCKET ) - { - printf( "Connection established\r\n" ); - - /* A connection has been accepted by the server. Create a - wolfSSL object for use with the newly connected socket. */ - xWolfSSL_Object = NULL; - xWolfSSL_Object = wolfSSL_new( xWolfSSL_ServerContext ); - - if( xWolfSSL_Object != NULL ) - { - /* Associate the created wolfSSL object with the connected - socket. */ - xReturned = wolfSSL_set_fd( xWolfSSL_Object, xConnectedSocket ); - configASSERT( xReturned == SSL_SUCCESS ); - - do - { - /* The next line is the secure equivalent to the - standard sockets call: - lBytes = recv( xConnectedSocket, cReceivedString, 50, 0 ); */ - lBytes = wolfSSL_read( xWolfSSL_Object, cReceivedString, sizeof( cReceivedString ) ); - - /* Print the received characters. */ - if( lBytes > 0 ) - { - printf( "Received by the secure server: %s\r\n", cReceivedString ); - } - - } while ( lBytes > 0 ); - - /* The connection was closed, close the socket and free the - wolfSSL object. */ - closesocket( xConnectedSocket ); - wolfSSL_free( xWolfSSL_Object ); - printf( "Connection closed, back to start\r\n\r\n" ); - } - } - } - } - else - { - /* The socket could not be opened. */ - vTaskDelete( NULL ); - } -} -/*-----------------------------------------------------------*/ - -static SOCKET prvOpenServerSocket( void ) -{ -WSADATA xWSAData; -WORD wVersionRequested; -struct sockaddr_in xConnection; -SOCKET xSocket = INVALID_SOCKET; - - wVersionRequested = MAKEWORD( 2, 2 ); - - /* Prepare to use WinSock. */ - if( WSAStartup( wVersionRequested, &xWSAData ) != 0 ) - { - fprintf( stderr, "Could not open Windows connection.\n" ); - } - else - { - xSocket = socket( AF_INET, SOCK_STREAM, 0 ); - if( xSocket == INVALID_SOCKET) - { - fprintf( stderr, "Could not create socket.\n" ); - WSACleanup(); - } - else - { - /* Zero out the server structure. */ - memset( ( void * ) &xConnection, 0x00, sizeof( struct sockaddr_in ) ); - - xConnection.sin_family = AF_INET; - xConnection.sin_addr.s_addr = inet_addr("127.0.0.1"); - xConnection.sin_port = htons( configTCP_PORT_NUMBER ); - - /* Bind the address to the socket. */ - if( bind( xSocket, ( struct sockaddr * ) &xConnection, sizeof( struct sockaddr_in ) ) == -1 ) - { - fprintf( stderr, "Could not socket to port %d.\n", configTCP_PORT_NUMBER ); - closesocket( xSocket ); - xSocket = INVALID_SOCKET; - WSACleanup(); - } - - if( listen( xSocket, 20 ) != 0 ) - { - closesocket( xSocket ); - xSocket = INVALID_SOCKET; - WSACleanup(); - } - } - } - - return xSocket; -} -/*-----------------------------------------------------------*/ - -static void prvInitialiseWolfSSL( void ) -{ -int32_t iReturn; - - #ifdef DEBUG_WOLFSSL - { - wolfSSL_Debugging_ON(); - } - #endif - - /* Initialise wolfSSL. This must be done before any other wolfSSL functions - are called. */ - wolfSSL_Init(); - - /* Attempt to create a context that uses the TLS 1.3 server protocol. */ - xWolfSSL_ServerContext = wolfSSL_CTX_new( wolfTLSv1_3_server_method() ); - - if( xWolfSSL_ServerContext != NULL ) - { - /* Load the CA certificate. Real applications should ensure that - wolfSSL_CTX_load_verify_locations() returns SSL_SUCCESS before - proceeding. */ - iReturn = wolfSSL_CTX_load_verify_locations( xWolfSSL_ServerContext, "ca-cert.pem", 0 ); - configASSERT( iReturn == SSL_SUCCESS ); - - iReturn = wolfSSL_CTX_use_certificate_file( xWolfSSL_ServerContext, "server-cert.pem", SSL_FILETYPE_PEM ); - configASSERT( iReturn == SSL_SUCCESS ); - - iReturn = wolfSSL_CTX_use_PrivateKey_file( xWolfSSL_ServerContext, "server-key.pem", SSL_FILETYPE_PEM ); - configASSERT( iReturn == SSL_SUCCESS ); - } -} - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#pragma comment( lib, "ws2_32.lib" ) + +/* Win32 includes. */ +#include + +/* wolfSSL includes. */ +#include "wolfssl/ssl.h" + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* This application is using the FreeRTOS Windows simulator, which uses the + * FreeRTOS scheduler to schedule FreeRTOS task within the Windows environment. + * The Windows envrionment must not be allowed to block any Windows threads that + * are running FreeRTOS tasks, unless the FreeRTOS task is running at the FreeRTOS + * idle priority. For simplicity, this demo uses the Windows TCP/IP stack, the + * API for which can cause Windows threads to block. Therefore, any FreeRTOS task + * that makes calls to the Windows TCP/IP stack must be assigned the idle priority. + * Note this is only a restriction of the simulated Windows environment - real + * FreeRTOS ports do not have this restriction. */ +#define sstSECURE_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY ) + +/*-----------------------------------------------------------*/ + +/* + * Open, configures and binds the server's TCP socket. + */ +static SOCKET prvOpenServerSocket( void ); + +/* + * Prepare the wolfSSL library for use. + */ +static void prvInitialiseWolfSSL( void ); + +/* + * The task that implements the client side of the connection. + */ +extern void vSecureTCPClientTask( void * pvParameters ); + +/*-----------------------------------------------------------*/ + +/* The wolfSSL context for the server. */ +static WOLFSSL_CTX * xWolfSSL_ServerContext = NULL; + +/*-----------------------------------------------------------*/ + +/* See the comments at the top of main.c. */ +void vSecureTCPServerTask( void * pvParameters ) +{ + BaseType_t xReturned; + long lBytes; + uint8_t cReceivedString[ 60 ]; + struct sockaddr_in xClient; + int xClientAddressLength = sizeof( struct sockaddr_in ); + SOCKET xListeningSocket, xConnectedSocket; + WOLFSSL * xWolfSSL_Object; /* Only one connection is accepted at a time, so only one object is needed at a time. */ + + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; + + /* Perform the initialisation necessary before wolfSSL can be used. */ + prvInitialiseWolfSSL(); + configASSERT( xWolfSSL_ServerContext ); + + /* Attempt to open the socket. */ + xListeningSocket = prvOpenServerSocket(); + + /* Now the server socket has been created and the wolfSSL library has been + * initialised, the task that implements the client side can be created. */ + xTaskCreate( vSecureTCPClientTask, "Client", configMINIMAL_STACK_SIZE, NULL, sstSECURE_CLIENT_TASK_PRIORITY, NULL ); + + if( xListeningSocket != INVALID_SOCKET ) + { + for( ; ; ) + { + /* Wait until the client connects. */ + printf( "Waiting for new connection\r\n" ); + xConnectedSocket = accept( xListeningSocket, ( struct sockaddr * ) &xClient, &xClientAddressLength ); + + if( xConnectedSocket != INVALID_SOCKET ) + { + printf( "Connection established\r\n" ); + + /* A connection has been accepted by the server. Create a + * wolfSSL object for use with the newly connected socket. */ + xWolfSSL_Object = NULL; + xWolfSSL_Object = wolfSSL_new( xWolfSSL_ServerContext ); + + if( xWolfSSL_Object != NULL ) + { + /* Associate the created wolfSSL object with the connected + * socket. */ + xReturned = wolfSSL_set_fd( xWolfSSL_Object, xConnectedSocket ); + configASSERT( xReturned == SSL_SUCCESS ); + + do + { + /* The next line is the secure equivalent to the + * standard sockets call: + * lBytes = recv( xConnectedSocket, cReceivedString, 50, 0 ); */ + lBytes = wolfSSL_read( xWolfSSL_Object, cReceivedString, sizeof( cReceivedString ) ); + + /* Print the received characters. */ + if( lBytes > 0 ) + { + printf( "Received by the secure server: %s\r\n", cReceivedString ); + } + } while( lBytes > 0 ); + + /* The connection was closed, close the socket and free the + * wolfSSL object. */ + closesocket( xConnectedSocket ); + wolfSSL_free( xWolfSSL_Object ); + printf( "Connection closed, back to start\r\n\r\n" ); + } + } + } + } + else + { + /* The socket could not be opened. */ + vTaskDelete( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static SOCKET prvOpenServerSocket( void ) +{ + WSADATA xWSAData; + WORD wVersionRequested; + struct sockaddr_in xConnection; + SOCKET xSocket = INVALID_SOCKET; + + wVersionRequested = MAKEWORD( 2, 2 ); + + /* Prepare to use WinSock. */ + if( WSAStartup( wVersionRequested, &xWSAData ) != 0 ) + { + fprintf( stderr, "Could not open Windows connection.\n" ); + } + else + { + xSocket = socket( AF_INET, SOCK_STREAM, 0 ); + + if( xSocket == INVALID_SOCKET ) + { + fprintf( stderr, "Could not create socket.\n" ); + WSACleanup(); + } + else + { + /* Zero out the server structure. */ + memset( ( void * ) &xConnection, 0x00, sizeof( struct sockaddr_in ) ); + + xConnection.sin_family = AF_INET; + xConnection.sin_addr.s_addr = inet_addr( "127.0.0.1" ); + xConnection.sin_port = htons( configTCP_PORT_NUMBER ); + + /* Bind the address to the socket. */ + if( bind( xSocket, ( struct sockaddr * ) &xConnection, sizeof( struct sockaddr_in ) ) == -1 ) + { + fprintf( stderr, "Could not socket to port %d.\n", configTCP_PORT_NUMBER ); + closesocket( xSocket ); + xSocket = INVALID_SOCKET; + WSACleanup(); + } + + if( listen( xSocket, 20 ) != 0 ) + { + closesocket( xSocket ); + xSocket = INVALID_SOCKET; + WSACleanup(); + } + } + } + + return xSocket; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseWolfSSL( void ) +{ + int32_t iReturn; + + #ifdef DEBUG_WOLFSSL + { + wolfSSL_Debugging_ON(); + } + #endif + + /* Initialise wolfSSL. This must be done before any other wolfSSL functions + * are called. */ + wolfSSL_Init(); + + /* Attempt to create a context that uses the TLS 1.3 server protocol. */ + xWolfSSL_ServerContext = wolfSSL_CTX_new( wolfTLSv1_3_server_method() ); + + if( xWolfSSL_ServerContext != NULL ) + { + /* Load the CA certificate. Real applications should ensure that + * wolfSSL_CTX_load_verify_locations() returns SSL_SUCCESS before + * proceeding. */ + iReturn = wolfSSL_CTX_load_verify_locations( xWolfSSL_ServerContext, "ca-cert.pem", 0 ); + configASSERT( iReturn == SSL_SUCCESS ); + + iReturn = wolfSSL_CTX_use_certificate_file( xWolfSSL_ServerContext, "server-cert.pem", SSL_FILETYPE_PEM ); + configASSERT( iReturn == SSL_SUCCESS ); + + iReturn = wolfSSL_CTX_use_PrivateKey_file( xWolfSSL_ServerContext, "server-key.pem", SSL_FILETYPE_PEM ); + configASSERT( iReturn == SSL_SUCCESS ); + } +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/main.c index 5845a02c9..8856c6e73 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/main.c @@ -1,90 +1,89 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include -#include "task.h" - -/* This application is using the FreeRTOS Windows simulator, which uses the -FreeRTOS scheduler to schedule FreeRTOS task within the Windows environment. -The Windows environment must not be allowed to block any Windows threads that -are running FreeRTOS tasks, unless the FreeRTOS task is running at the FreeRTOS -idle priority. For simplicity, this demo uses the Windows TCP/IP stack, the -API for which can cause Windows threads to block. Therefore, any FreeRTOS task -that makes calls to the Windows TCP/IP stack must be assigned the idle priority. -Note this is only a restriction of the simulated Windows environment - real -FreeRTOS ports do not have this restriction. */ -#define mainSECURE_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY ) - - -/*-----------------------------------------------------------*/ - -/* - * The task that implements the server side. - */ -extern void vSecureTCPServerTask( void *pvParameters ); - -/*-----------------------------------------------------------*/ - -int main( void ) -{ -const uint32_t ulLongTime_ms = 250UL; - - /* Create the TCP server task. This will itself create the client task - once it has completed the wolfSSL initialisation. */ - xTaskCreate( vSecureTCPServerTask, "Server", configMINIMAL_STACK_SIZE, NULL, mainSECURE_SERVER_TASK_PRIORITY, NULL ); - - /* Start the task running. */ - vTaskStartScheduler(); - - /* If all is well, the scheduler will now be running, and the following - line will never be reached. If the following line does execute, then - there was insufficient FreeRTOS heap memory available for the idle and/or - timer tasks to be created. See the memory management section on the - FreeRTOS web site for more details (this is standard text that is not - really applicable to the Win32 simulator port). */ - for( ;; ) - { - Sleep( ulLongTime_ms ); - } -} -/*-----------------------------------------------------------*/ - -void vApplicationIdleHook( void ) -{ -const unsigned long ulMSToSleep = 5; - - /* This function is called on each cycle of the idle task if - configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU - load. */ - Sleep( ulMSToSleep ); -} -/*-----------------------------------------------------------*/ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include +#include "task.h" + +/* This application is using the FreeRTOS Windows simulator, which uses the + * FreeRTOS scheduler to schedule FreeRTOS task within the Windows environment. + * The Windows environment must not be allowed to block any Windows threads that + * are running FreeRTOS tasks, unless the FreeRTOS task is running at the FreeRTOS + * idle priority. For simplicity, this demo uses the Windows TCP/IP stack, the + * API for which can cause Windows threads to block. Therefore, any FreeRTOS task + * that makes calls to the Windows TCP/IP stack must be assigned the idle priority. + * Note this is only a restriction of the simulated Windows environment - real + * FreeRTOS ports do not have this restriction. */ +#define mainSECURE_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY ) + + +/*-----------------------------------------------------------*/ + +/* + * The task that implements the server side. + */ +extern void vSecureTCPServerTask( void * pvParameters ); + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + const uint32_t ulLongTime_ms = 250UL; + + /* Create the TCP server task. This will itself create the client task + * once it has completed the wolfSSL initialisation. */ + xTaskCreate( vSecureTCPServerTask, "Server", configMINIMAL_STACK_SIZE, NULL, mainSECURE_SERVER_TASK_PRIORITY, NULL ); + + /* Start the task running. */ + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + * line will never be reached. If the following line does execute, then + * there was insufficient FreeRTOS heap memory available for the idle and/or + * timer tasks to be created. See the memory management section on the + * FreeRTOS web site for more details (this is standard text that is not + * really applicable to the Win32 simulator port). */ + for( ; ; ) + { + Sleep( ulLongTime_ms ); + } +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + const unsigned long ulMSToSleep = 5; + + /* This function is called on each cycle of the idle task if + * configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU + * load. */ + Sleep( ulMSToSleep ); +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/user_settings.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/user_settings.h index 9d01c35a4..5806b040d 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/user_settings.h +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/user_settings.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -33,27 +33,27 @@ * * *----------------------------------------------------------------------------*/ - #define WOLFSSL_TLS13 - #define HAVE_FFDHE_2048 - #define WC_RSA_PSS - #define HAVE_HKDF +#define WOLFSSL_TLS13 +#define HAVE_FFDHE_2048 +#define WC_RSA_PSS +#define HAVE_HKDF - - #define HAVE_AESGCM - #define WOLFSSL_AES_128 - #define HAVE_AES_CBC - #define WOLFSSL_SHA512 - #define HAVE_TLS_EXTENSIONS - #define HAVE_SUPPORTED_CURVES - #define HAVE_ECC - #define HAVE_CURVE25519 - #define CURVE25519_SMALL - #define HAVE_ED25519 +#define HAVE_AESGCM +#define WOLFSSL_AES_128 +#define HAVE_AES_CBC +#define WOLFSSL_SHA512 - #define WC_RSA_BLINDING - #define ECC_TIMING_RESISTANT - #define TFM_TIMING_RESISTANT +#define HAVE_TLS_EXTENSIONS +#define HAVE_SUPPORTED_CURVES +#define HAVE_ECC +#define HAVE_CURVE25519 +#define CURVE25519_SMALL +#define HAVE_ED25519 + +#define WC_RSA_BLINDING +#define ECC_TIMING_RESISTANT +#define TFM_TIMING_RESISTANT /*-- Debugging options ------------------------------------------------------ @@ -65,6 +65,6 @@ /*#define DEBUG_WOLFSSL*/ /* The TCP port used by both the secure client and the secure server. */ -#define configTCP_PORT_NUMBER 5001 +#define configTCP_PORT_NUMBER 5001 -#endif /* ifndef USER_SETTINGS_H_ */ \ No newline at end of file +#endif /* ifndef USER_SETTINGS_H_ */ diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/http_demo_utils.c b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/http_demo_utils.c index df0f61933..61d7eb548 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/http_demo_utils.c +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/http_demo_utils.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -63,8 +63,8 @@ /*-----------------------------------------------------------*/ -/** - * @brief Each compilation unit that consumes the NetworkContext must define it. +/** + * @brief Each compilation unit that consumes the NetworkContext must define it. * It should contain a single pointer to the type of your desired transport. * This utility is used by both TLS and plaintext HTTP demos, so define this pointer as void *. * diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/http_demo_utils.h b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/http_demo_utils.h index 350177457..175f2899d 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/http_demo_utils.h +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/http_demo_utils.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/main.c b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/main.c index 7d22e8aca..8c25c819b 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/main.c +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -81,4 +81,3 @@ int main( void ) } /*-----------------------------------------------------------*/ - diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/README.md b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/README.md index db5fe1a81..90b1d84ee 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/README.md +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/README.md @@ -1,55 +1,55 @@ -# Presigned S3 URLs Generator +# Presigned S3 URLs Generator -`presigned_url_gen.py` generates pre-signed URLs for S3 HTTP GET and PUT request access. +`presigned_url_gen.py` generates pre-signed URLs for S3 HTTP GET and PUT request access. -### Dependencies +### Dependencies -* Python 3+ -* boto3 -* argparse +* Python 3+ +* boto3 +* argparse -### Prerequisites +### Prerequisites -1. Install the dependencies. - ```sh - pip install boto3 argparse - ``` +1. Install the dependencies. + ```sh + pip install boto3 argparse + ``` -1. You will need an AWS Account with S3 access before beginning. You must install and configure the AWS CLI in order to - use this script. - For information on AWS S3 please see: https://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html - For AWS CLI installation information please see: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html - For AWS CLI configuration information please see: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html +1. You will need an AWS Account with S3 access before beginning. You must install and configure the AWS CLI in order to + use this script. + For information on AWS S3 please see: https://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html + For AWS CLI installation information please see: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html + For AWS CLI configuration information please see: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html - ```sh - aws configure - ``` + ```sh + aws configure + ``` -### Usage +### Usage -1. Run `presigned_url_gen.py` with your s3 bucket name and s3 object key. - ```sh - ./presigned_urls_gen.py --bucket --key - ``` - An example expected output: - ``` - #define democonfigS3_PRESIGNED_GET_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlABcdEFgfIjK" - #define democonfigS3_PRESIGNED_PUT_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlLMnmOPqrStUvW" - ``` -1. Copy and paste the output to `demo_config.h` for macros `democonfigS3_PRESIGNED_GET_URL` and `democonfigS3_PRESIGNED_PUT_URL`. - ```c - #define democonfigS3_PRESIGNED_GET_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlABcdEFgfIjK" - #define democonfigS3_PRESIGNED_PUT_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlLMnmOPqrStUvW" - ``` +1. Run `presigned_url_gen.py` with your s3 bucket name and s3 object key. + ```sh + ./presigned_urls_gen.py --bucket --key + ``` + An example expected output: + ``` + #define democonfigS3_PRESIGNED_GET_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlABcdEFgfIjK" + #define democonfigS3_PRESIGNED_PUT_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlLMnmOPqrStUvW" + ``` +1. Copy and paste the output to `demo_config.h` for macros `democonfigS3_PRESIGNED_GET_URL` and `democonfigS3_PRESIGNED_PUT_URL`. + ```c + #define democonfigS3_PRESIGNED_GET_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlABcdEFgfIjK" + #define democonfigS3_PRESIGNED_PUT_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlLMnmOPqrStUvW" + ``` -### Parameters +### Parameters -#### --bucket -The name of the S3 bucket from which the demo will download or upload. +#### --bucket +The name of the S3 bucket from which the demo will download or upload. -#### --key -The name of the existing object you wish to download (GET), -or the name of the object you wish to upload (PUT). +#### --key +The name of the existing object you wish to download (GET), +or the name of the object you wish to upload (PUT). -#### --region -Optional parameter for the AWS region in which the bucket is located. \ No newline at end of file +#### --region +Optional parameter for the AWS region in which the bucket is located. \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/CoreHTTP_Mutual_Auth.vcxproj.filters b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/CoreHTTP_Mutual_Auth.vcxproj.filters index 9d9a2cfb2..e6b7fe358 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/CoreHTTP_Mutual_Auth.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/CoreHTTP_Mutual_Auth.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/DemoTasks/MutualAuthHTTPExample.c b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/DemoTasks/MutualAuthHTTPExample.c index b94cd672b..eb652c3b9 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/DemoTasks/MutualAuthHTTPExample.c +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/DemoTasks/MutualAuthHTTPExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/demo_config.h b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/demo_config.h index 4a1f2edfd..5252108e7 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/http_mutual_auth_demo.sln b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/http_mutual_auth_demo.sln index e2470bcca..1245a8b48 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/http_mutual_auth_demo.sln +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Mutual_Auth/http_mutual_auth_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/CoreHTTP_Plaintext.vcxproj.filters b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/CoreHTTP_Plaintext.vcxproj.filters index 3da434f0e..9a32e8798 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/CoreHTTP_Plaintext.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/CoreHTTP_Plaintext.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/DemoTasks/PlainTextHTTPExample.c b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/DemoTasks/PlainTextHTTPExample.c index 11a1c4f07..52914bcd6 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/DemoTasks/PlainTextHTTPExample.c +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/DemoTasks/PlainTextHTTPExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/demo_config.h b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/demo_config.h index 11b850a7a..83996d46c 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/http_plain_text_demo.sln b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/http_plain_text_demo.sln index 2f51325d7..be872d883 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/http_plain_text_demo.sln +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_Plaintext/http_plain_text_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/CoreHTTP_S3_Download.vcxproj.filters b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/CoreHTTP_S3_Download.vcxproj.filters index 1c929bbf8..9576ada82 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/CoreHTTP_S3_Download.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/CoreHTTP_S3_Download.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/DemoTasks/S3DownloadHTTPExample.c b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/DemoTasks/S3DownloadHTTPExample.c index c5af7b44b..ac78ccd29 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/DemoTasks/S3DownloadHTTPExample.c +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/DemoTasks/S3DownloadHTTPExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -1492,7 +1492,7 @@ static void prvSha256Encode( const char * pcInputStr, mbedtls_sha256( pcInputStr, xInputStrLen, ucSha256, 0 ); #endif - for(size_t i = 0; i < SHA256_HASH_DIGEST_LENGTH; i++ ) + for( size_t i = 0; i < SHA256_HASH_DIGEST_LENGTH; i++ ) { *pcOutputChar = cHexChars[ ( ucSha256[ i ] & 0xF0 ) >> 4 ]; pcOutputChar++; diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/README.md b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/README.md index cbd1d9645..4cbc2c1a3 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/README.md +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/README.md @@ -4,9 +4,9 @@ Following steps needs to be followed to configure HTTP S3 Download Demo to use S ### Prerequisites -1. You will need an AWS Account with S3 access before beginning. You must be familiar with AWS IoT and IAM to perform steps using the AWS CLI. You must install and configure the AWS CLI in order to follow the steps. - For information on AWS S3 please see: https://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html - For AWS CLI installation information please see: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html +1. You will need an AWS Account with S3 access before beginning. You must be familiar with AWS IoT and IAM to perform steps using the AWS CLI. You must install and configure the AWS CLI in order to follow the steps. + For information on AWS S3 please see: https://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html + For AWS CLI installation information please see: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html For AWS CLI configuration information please see: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html ```sh @@ -15,7 +15,7 @@ Following steps needs to be followed to configure HTTP S3 Download Demo to use S ### Detailed Steps -#### 1. Create an AWS IoT thing: +#### 1. Create an AWS IoT thing: You may utilize an already existing AWS IoT Thing or create a new one in the IoT Core section of the AWS Management Console UI. @@ -37,8 +37,8 @@ Run the following command in the AWS CLI to attach the device certificate to you ```sh aws iot attach-thing-principal --thing-name device_thing_name --principal ``` - -#### 3. Configure an IAM role: + +#### 3. Configure an IAM role: Next, configure an IAM role in your AWS account that will be assumed by the credentials provider on behalf of your device. You are required to associate two policies with the role: a trust policy that controls who can assume the role, and an access policy that controls which actions can be performed on which resources by assuming the role. @@ -108,8 +108,8 @@ Now, run the following command to attach the policy to the IAM user. aws iam attach-user-policy --policy-arn arn:aws:iam:::policy/passrolepermission --user-name ``` -#### 4. Create a role alias: - +#### 4. Create a role alias: + Now that you have configured the IAM role, you will create a role alias with AWS IoT. You must provide the following pieces of information when creating a role alias: RoleAlias: This is the primary key of the role alias data model and hence a mandatory attribute. It is a string; the minimum length is 1 character, and the maximum length is 128 characters. @@ -123,7 +123,7 @@ Run the following command in the AWS CLI to create a role alias. Use the credent aws iot create-role-alias --role-alias name-s3-access-role-alias --role-arn arn:aws:iam:::role/s3-access-role --credential-duration-seconds 3600 ``` -#### 5. Attach a policy: +#### 5. Attach a policy: You created and registered a certificate with AWS IoT earlier for successful authentication of your device. Now, you need to create and attach a policy to the certificate to authorize the request for the security token. ``` { @@ -146,8 +146,8 @@ Use the following command to attach the policy with the certificate you register aws iot attach-policy --policy-name Thing_Policy_Name --target ``` -#### 6. Request a security token: - +#### 6. Request a security token: + Make an HTTPS request to the credentials provider to fetch a security token. You have to supply the following information: Certificate and key pair: Because this is an HTTP request over TLS mutual authentication, you have to provide the certificate and the corresponding key pair to your client while making the request. Use the same certificate and key pair that you used during certificate registration with AWS IoT. @@ -179,13 +179,13 @@ The following is sample output of the describe-endpoint command. It contains the #### 8. After the following the above steps, configure the below macros in `demo_config.h`. ```c -#define democonfigIOT_THING_NAME "Name of IOT Thing that you provided in STEP 1" +#define democonfigIOT_THING_NAME "Name of IOT Thing that you provided in STEP 1" #define democonfigIOT_CREDENTIAL_PROVIDER_ROLE "Name of ROLE ALIAS that you provided in STEP 4" #define democonfigS3_BUCKET_NAME "Name of Bucket that contains the object that needs to be downloaded" #define democonfigS3_BUCKET_REGION "Region where Bucket is located" #define democonfigS3_OBJECT_NAME "Name of object that needs to be downloaded from AWS S3" ``` - + ### Parameters #### device_thing_name diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/demo_config.h b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/demo_config.h index 2201800e4..f5695422a 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -94,7 +94,7 @@ extern void vLoggingPrintf( const char * pcFormatString, * "...base64 data...\n"\ * "-----END CERTIFICATE-----\n" * - * #define democonfigS3_ROOT_CA_PEM "...insert here..." + * #define democonfigS3_ROOT_CA_PEM "...insert here..." */ /** @@ -109,7 +109,7 @@ extern void vLoggingPrintf( const char * pcFormatString, * "-----BEGIN CERTIFICATE-----\n"\ * "...base64 data...\n"\ * "-----END CERTIFICATE-----\n" - * #define democonfigIOT_CRED_PROVIDER_ROOT_CA_PEM "...insert here..." + * #define democonfigIOT_CRED_PROVIDER_ROOT_CA_PEM "...insert here..." */ @@ -120,9 +120,9 @@ extern void vLoggingPrintf( const char * pcFormatString, * * Must include the PEM header and footer: * "-----BEGIN CERTIFICATE----- -" * "...base64 data... -" * "-----END CERTIFICATE----- -" + * " * "...base64 data... + * " * "-----END CERTIFICATE----- + * " * * #define democonfigCLIENT_CERTIFICATE_PEM "...insert here..." */ @@ -166,7 +166,7 @@ extern void vLoggingPrintf( const char * pcFormatString, * while setting up AWS resources before running the demo. * Refer to the demo setup instructions in the README.md file * within the same directory as this file in the repository. - + * * #define democonfigIOT_CREDENTIAL_PROVIDER_ROLE "...insert here..." */ diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/http_s3_download_demo.sln b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/http_s3_download_demo.sln index a02e3656c..40e731dc0 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/http_s3_download_demo.sln +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/http_s3_download_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/sigv4_config.h b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/sigv4_config.h index 8582869ff..ee7903972 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/sigv4_config.h +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download/sigv4_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/CoreHTTP_S3_Download_Multithreaded.vcxproj.filters b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/CoreHTTP_S3_Download_Multithreaded.vcxproj.filters index 6be0b57eb..5dc3852d6 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/CoreHTTP_S3_Download_Multithreaded.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/CoreHTTP_S3_Download_Multithreaded.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c index 68a6f0662..cd8359627 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/demo_config.h b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/demo_config.h index 9bf3d374f..0013f75c7 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/http_s3_download_multithreaded_demo.sln b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/http_s3_download_multithreaded_demo.sln index 51e940f57..4a677fcfc 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/http_s3_download_multithreaded_demo.sln +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/http_s3_download_multithreaded_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/CoreHTTP_S3_Upload.vcxproj.filters b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/CoreHTTP_S3_Upload.vcxproj.filters index c1006c528..d7b78706b 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/CoreHTTP_S3_Upload.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/CoreHTTP_S3_Upload.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/DemoTasks/S3UploadHTTPExample.c b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/DemoTasks/S3UploadHTTPExample.c index 575c33a07..e4a50471f 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/DemoTasks/S3UploadHTTPExample.c +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/DemoTasks/S3UploadHTTPExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/demo_config.h b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/demo_config.h index bf7383ede..a2d034fc1 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/http_s3_upload_demo.sln b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/http_s3_upload_demo.sln index 7f0cd7ed2..7959e593d 100644 --- a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/http_s3_upload_demo.sln +++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Upload/http_s3_upload_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/Common/core_mqtt_config.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/Common/core_mqtt_config.h index b5522041c..ae6b66fba 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/Common/core_mqtt_config.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/Common/core_mqtt_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -74,7 +74,7 @@ extern void vLoggingPrintf( const char * pcFormatString, * macro sets the limit on how many simultaneous PUBLISH states an MQTT * context maintains. */ -#define MQTT_STATE_ARRAY_MAX_COUNT 20U +#define MQTT_STATE_ARRAY_MAX_COUNT 20U /** * @brief The maximum duration between non-empty network reads while @@ -94,6 +94,7 @@ extern void vLoggingPrintf( const char * pcFormatString, #define MQTT_RECV_POLLING_TIMEOUT_MS 0U /*********************** coreMQTT Agent Configurations **********************/ + /** * @brief The maximum number of pending acknowledgments to track for a single * connection. diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/Common/main.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/Common/main.c index 0777ebd4c..7c8accbba 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/Common/main.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/Common/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/DemoTasks/BasicTLSMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/DemoTasks/BasicTLSMQTTExample.c index e6dd53770..06470c3f2 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/DemoTasks/BasicTLSMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/DemoTasks/BasicTLSMQTTExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -749,7 +749,7 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) usSubscribePacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); /* Populate subscription list. */ - for(ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { xMQTTSubscription[ ulTopicCount ].qos = MQTTQoS2; xMQTTSubscription[ ulTopicCount ].pTopicFilter = xTopicFilterContext[ ulTopicCount ].pcTopicFilter; @@ -777,7 +777,7 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) usSubscribePacketIdentifier ); configASSERT( xResult == MQTTSuccess ); - for(ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { LogInfo( ( "SUBSCRIBE sent for topic %s to broker.\n\n", xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) ); @@ -880,7 +880,7 @@ static void prvMQTTUnsubscribeFromTopics( MQTTContext_t * pxMQTTContext ) memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); /* Populate subscription list. */ - for(ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { xMQTTSubscription[ ulTopicCount ].qos = MQTTQoS2; xMQTTSubscription[ ulTopicCount ].pTopicFilter = xTopicFilterContext[ ulTopicCount ].pcTopicFilter; @@ -994,7 +994,7 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ) LogInfo( ( "Incoming QoS : %d\n", pxPublishInfo->qos ) ); /* Verify the received publish is for one of the topics that's been subscribed to. */ - for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { if( ( pxPublishInfo->topicNameLength == strlen( xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) ) && ( strncmp( xTopicFilterContext[ ulTopicCount ].pcTopicFilter, pxPublishInfo->pTopicName, pxPublishInfo->topicNameLength ) == 0 ) ) @@ -1105,7 +1105,7 @@ static void prvInitializeTopicBuffers( void ) int xCharactersWritten; - for(ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { /* Write topic strings into buffers. */ xCharactersWritten = snprintf( xTopicFilterContext[ ulTopicCount ].pcTopicFilter, diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj index 86816d11c..3c5e4cdf6 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj @@ -1,255 +1,255 @@ - - - - - Debug_with_Libslirp - Win32 - - - Debug_with_Libslirp - x64 - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {0b57f66e-ffdb-430f-a28d-0d9f8062faeb} - MQTTBasicTLS - 10.0 - - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - true - - - true - - - false - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug_with_Libslirp + Win32 + + + Debug_with_Libslirp + x64 + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {0b57f66e-ffdb-430f-a28d-0d9f8062faeb} + MQTTBasicTLS + 10.0 + + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + true + + + true + + + false + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj.filters index 553b9a879..1770ea04f 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/MQTT_Basic_TLS.vcxproj.filters @@ -1,117 +1,117 @@ - - - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {0da51220-8bed-4caf-b2aa-873bfea093e6} - - - {0859f27c-e810-4c5d-b58c-20781298e5bc} - - - {c0ae9251-11ab-4be8-b8cb-49862d0ee3bb} - - - {419b9d40-6a57-44bb-9108-313f44457d08} - - - {ab569f57-b030-426e-af8a-4311acbddfd2} - - - {b3505093-7ddd-4e53-b273-fd7a79c338b9} - - - {ebb2e3e4-1878-412f-83f2-f4345bcb1142} - - - {db3fbd19-b65e-4783-bcc7-96e50960613e} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {515fa98c-9051-4c5b-84c2-6fddd7d9d496} - - - {ac434eb3-8879-48dc-91f7-02233b416f01} - - - {20a28667-7df8-450e-a195-b32360664cdb} - - - {b70eeb00-b1db-48e4-b2fd-b82f0decd003} - - - {b0596e1f-bc18-4977-ae07-2fed4fdd217d} - - - - - Headers - - - Additional Libraries\Backoff Algorithm\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\interface - - - Config - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - - - Source - - - Source - - - Additional Libraries\Backoff Algorithm - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Network Transport Files\TCP Sockets Wrapper\ports - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {0da51220-8bed-4caf-b2aa-873bfea093e6} + + + {0859f27c-e810-4c5d-b58c-20781298e5bc} + + + {c0ae9251-11ab-4be8-b8cb-49862d0ee3bb} + + + {419b9d40-6a57-44bb-9108-313f44457d08} + + + {ab569f57-b030-426e-af8a-4311acbddfd2} + + + {b3505093-7ddd-4e53-b273-fd7a79c338b9} + + + {ebb2e3e4-1878-412f-83f2-f4345bcb1142} + + + {db3fbd19-b65e-4783-bcc7-96e50960613e} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {515fa98c-9051-4c5b-84c2-6fddd7d9d496} + + + {ac434eb3-8879-48dc-91f7-02233b416f01} + + + {20a28667-7df8-450e-a195-b32360664cdb} + + + {b70eeb00-b1db-48e4-b2fd-b82f0decd003} + + + {b0596e1f-bc18-4977-ae07-2fed4fdd217d} + + + + + Headers + + + Additional Libraries\Backoff Algorithm\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\interface + + + Config + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + + + Source + + + Source + + + Additional Libraries\Backoff Algorithm + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Network Transport Files\TCP Sockets Wrapper\ports + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/demo_config.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/demo_config.h index 9cde08587..cdcbfbd31 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,7 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/mqtt_basic_tls_demo.sln b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/mqtt_basic_tls_demo.sln index e112a0368..bc5aea730 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/mqtt_basic_tls_demo.sln +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/mqtt_basic_tls_demo.sln @@ -1,134 +1,134 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Basic_TLS", "MQTT_Basic_TLS.vcxproj", "{0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{F1C6C407-5829-47E8-97C8-45C1BDAD10DD}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 - Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 - Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|Win32.ActiveCfg = Debug|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|Win32.Build.0 = Debug|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|x64.ActiveCfg = Debug|x64 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|x64.Build.0 = Debug|x64 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|x86.ActiveCfg = Debug|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|x86.Build.0 = Debug|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|Win32.ActiveCfg = Release|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|Win32.Build.0 = Release|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|x64.ActiveCfg = Release|x64 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|x64.Build.0 = Release|x64 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|x86.ActiveCfg = Release|Win32 - {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {F1C6C407-5829-47E8-97C8-45C1BDAD10DD} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {F1C6C407-5829-47E8-97C8-45C1BDAD10DD} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {F1C6C407-5829-47E8-97C8-45C1BDAD10DD} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {F1C6C407-5829-47E8-97C8-45C1BDAD10DD} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {06311655-E6E0-4E7B-8804-F3A0F70D94EC} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Basic_TLS", "MQTT_Basic_TLS.vcxproj", "{0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{F1C6C407-5829-47E8-97C8-45C1BDAD10DD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 + Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 + Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|Win32.ActiveCfg = Debug|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|Win32.Build.0 = Debug|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|x64.ActiveCfg = Debug|x64 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|x64.Build.0 = Debug|x64 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|x86.ActiveCfg = Debug|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Debug|x86.Build.0 = Debug|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|Win32.ActiveCfg = Release|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|Win32.Build.0 = Release|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|x64.ActiveCfg = Release|x64 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|x64.Build.0 = Release|x64 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|x86.ActiveCfg = Release|Win32 + {0B57F66E-FFDB-430F-A28D-0D9F8062FAEB}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {F1C6C407-5829-47E8-97C8-45C1BDAD10DD} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {F1C6C407-5829-47E8-97C8-45C1BDAD10DD} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {F1C6C407-5829-47E8-97C8-45C1BDAD10DD} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {F1C6C407-5829-47E8-97C8-45C1BDAD10DD} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {06311655-E6E0-4E7B-8804-F3A0F70D94EC} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/mqtt_broker_setup.txt b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/mqtt_broker_setup.txt index b029a9bce..b869ede34 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/mqtt_broker_setup.txt +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/mqtt_broker_setup.txt @@ -51,7 +51,7 @@ TLS server-only authentication for use with this MQTT demo. "-----BEGIN CERTIFICATE-----\n" \ "...base64 data...\n" \ "-----END CERTIFICATE-----\n" -11. Update the config `democonfigdisableSNI` to `( pdTRUE )`. It needs to be +11. Update the config `democonfigdisableSNI` to `( pdTRUE )`. It needs to be configured this way because the local MQTT broker will only have an IP address but not a hostname. However, SNI (Server name indication) should be enabled whenever possible. diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/DemoTasks/KeepAliveMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/DemoTasks/KeepAliveMQTTExample.c index 0d1940c33..b89bb644d 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/DemoTasks/KeepAliveMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/DemoTasks/KeepAliveMQTTExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj index b5bef438a..31a743134 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj @@ -1,223 +1,223 @@ - - - - - Debug_with_Libslirp - Win32 - - - Debug_with_Libslirp - x64 - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {7260cb0d-0bbf-4dac-91d9-d091022c1f9a} - MQTTKeepAlive - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - v142 - - - v142 - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - - - - - - - - - - - - - - - - - - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug_with_Libslirp + Win32 + + + Debug_with_Libslirp + x64 + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {7260cb0d-0bbf-4dac-91d9-d091022c1f9a} + MQTTKeepAlive + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + v142 + + + v142 + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + + + + + + + + + + + + + + + + + + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj.filters index acda18137..d784f4feb 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/MQTT_Keep_Alive.vcxproj.filters @@ -1,104 +1,104 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {ca85e3b4-48b5-41e3-b78e-0969dcbb4014} - - - {ee581e1d-f4c8-4ccf-8e5a-123c2e5e9547} - - - {2430635d-0b61-42ee-b526-a3f96fdffacd} - - - {ca386497-b254-469a-968a-7a6a64aaddb5} - - - {63d48723-fc3b-4f3d-9717-8d7f6ac8e592} - - - {628e3184-4ee7-4597-a6f3-406e6fb32fd0} - - - {1e47e29c-64f2-485d-843c-bf6cebd04529} - - - {be34c1eb-2b93-4475-90e9-fe1681790d11} - - - {f22601ed-22e4-4f63-b692-f40725d45806} - - - {31fc5121-9909-40e4-8ffc-959188291c48} - - - {dea14617-4fab-45e0-a2fa-3fa11d95d388} - - - {7c4a1006-eb8b-43a6-a876-b0bafaf2e380} - - - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\backoff_algorithm\include - - - Header - - - Config - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\backoff_algorithm - - - Source - - - Source - - - Additional Network Transport Files\TCP Sockets Wrapper\ports - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {ca85e3b4-48b5-41e3-b78e-0969dcbb4014} + + + {ee581e1d-f4c8-4ccf-8e5a-123c2e5e9547} + + + {2430635d-0b61-42ee-b526-a3f96fdffacd} + + + {ca386497-b254-469a-968a-7a6a64aaddb5} + + + {63d48723-fc3b-4f3d-9717-8d7f6ac8e592} + + + {628e3184-4ee7-4597-a6f3-406e6fb32fd0} + + + {1e47e29c-64f2-485d-843c-bf6cebd04529} + + + {be34c1eb-2b93-4475-90e9-fe1681790d11} + + + {f22601ed-22e4-4f63-b692-f40725d45806} + + + {31fc5121-9909-40e4-8ffc-959188291c48} + + + {dea14617-4fab-45e0-a2fa-3fa11d95d388} + + + {7c4a1006-eb8b-43a6-a876-b0bafaf2e380} + + + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\backoff_algorithm\include + + + Header + + + Config + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\backoff_algorithm + + + Source + + + Source + + + Additional Network Transport Files\TCP Sockets Wrapper\ports + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/demo_config.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/demo_config.h index 24a5cab41..298ee6de1 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,7 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/mqtt_keep_alive_demo.sln b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/mqtt_keep_alive_demo.sln index 29ad6a9a8..de868fe30 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/mqtt_keep_alive_demo.sln +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Keep_Alive/mqtt_keep_alive_demo.sln @@ -1,134 +1,134 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Keep_Alive", "MQTT_Keep_Alive.vcxproj", "{7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{75B2B370-3E3C-46AE-98F2-66BC80A8175A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 - Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 - Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|Win32.ActiveCfg = Debug|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|Win32.Build.0 = Debug|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|x64.ActiveCfg = Debug|x64 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|x64.Build.0 = Debug|x64 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|x86.ActiveCfg = Debug|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|x86.Build.0 = Debug|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|Win32.ActiveCfg = Release|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|Win32.Build.0 = Release|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|x64.ActiveCfg = Release|x64 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|x64.Build.0 = Release|x64 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|x86.ActiveCfg = Release|Win32 - {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {75B2B370-3E3C-46AE-98F2-66BC80A8175A} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {75B2B370-3E3C-46AE-98F2-66BC80A8175A} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {75B2B370-3E3C-46AE-98F2-66BC80A8175A} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {75B2B370-3E3C-46AE-98F2-66BC80A8175A} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {D0EA1B18-3B19-44D7-AE7D-FA4FB739DF96} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Keep_Alive", "MQTT_Keep_Alive.vcxproj", "{7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{75B2B370-3E3C-46AE-98F2-66BC80A8175A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 + Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 + Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|Win32.ActiveCfg = Debug|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|Win32.Build.0 = Debug|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|x64.ActiveCfg = Debug|x64 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|x64.Build.0 = Debug|x64 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|x86.ActiveCfg = Debug|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Debug|x86.Build.0 = Debug|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|Win32.ActiveCfg = Release|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|Win32.Build.0 = Release|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|x64.ActiveCfg = Release|x64 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|x64.Build.0 = Release|x64 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|x86.ActiveCfg = Release|Win32 + {7260CB0D-0BBF-4DAC-91D9-D091022C1F9A}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {75B2B370-3E3C-46AE-98F2-66BC80A8175A} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {75B2B370-3E3C-46AE-98F2-66BC80A8175A} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {75B2B370-3E3C-46AE-98F2-66BC80A8175A} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {75B2B370-3E3C-46AE-98F2-66BC80A8175A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D0EA1B18-3B19-44D7-AE7D-FA4FB739DF96} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/mqtt-agent-task.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/mqtt-agent-task.c index a3cf2ee15..2d88c9fa5 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/mqtt-agent-task.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/mqtt-agent-task.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -111,13 +111,13 @@ #ifndef democonfigCLIENT_IDENTIFIER - /** - * @brief The MQTT client identifier used in this example. Each client identifier - * must be unique so edit as required to ensure no two clients connecting to the - * same broker use the same client identifier. Using a #define is for convenience - * of demonstration only - production devices should use something unique to the - * device that can be read from software - such as a production serial number. - */ +/** + * @brief The MQTT client identifier used in this example. Each client identifier + * must be unique so edit as required to ensure no two clients connecting to the + * same broker use the same client identifier. Using a #define is for convenience + * of demonstration only - production devices should use something unique to the + * device that can be read from software - such as a production serial number. + */ #error "Please define democonfigCLIENT_IDENTIFIER in demo_config.h to something unique for this device." #endif @@ -127,7 +127,7 @@ #error "Please define Root CA certificate of the MQTT broker(democonfigROOT_CA_PEM) in demo_config.h." #endif - /* If no username is defined, then a client certificate/key is required. */ +/* If no username is defined, then a client certificate/key is required. */ #ifndef democonfigCLIENT_USERNAME /* @@ -150,8 +150,8 @@ #error "Please define client password(democonfigCLIENT_PASSWORD) in demo_config.h for client authentication based on username/password." #endif - /* AWS IoT MQTT broker port needs to be 443 for client authentication based on - * username/password. */ +/* AWS IoT MQTT broker port needs to be 443 for client authentication based on + * username/password. */ #if defined( democonfigUSE_AWS_IOT_CORE_BROKER ) && democonfigMQTT_BROKER_PORT != 443 #error "Broker port(democonfigMQTT_BROKER_PORT) should be defined as 443 in demo_config.h for client authentication based on username/password in AWS IoT Core." #endif @@ -720,55 +720,57 @@ static BaseType_t prvSocketConnect( NetworkContext_t * pxNetworkContext ) NetworkCredentials_t xNetworkCredentials = { 0 }; #if defined( democonfigUSE_AWS_IOT_CORE_BROKER ) - #if defined( democonfigCLIENT_USERNAME ) - /* - * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect - * to AWS IoT Core with Custom Authentication on port 443. - * - * Custom Authentication uses the contents of the username and password - * fields of the MQTT CONNECT packet to authenticate the client. - * - * For more information, refer to the documentation at: - * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html - */ - static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; - #if democonfigMQTT_BROKER_PORT != 443U - #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." - #endif /* democonfigMQTT_BROKER_PORT != 443U */ - #else /* if !defined( democonfigCLIENT_USERNAME ) */ - /* - * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using - * x509 Certificate Authentication. - */ - static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; - #endif /* !defined( democonfigCLIENT_USERNAME ) */ + #if defined( democonfigCLIENT_USERNAME ) /* - * An ALPN identifier is only required when connecting to AWS IoT core on port 443. - * https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html + * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect + * to AWS IoT Core with Custom Authentication on port 443. + * + * Custom Authentication uses the contents of the username and password + * fields of the MQTT CONNECT packet to authenticate the client. + * + * For more information, refer to the documentation at: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html */ - #if democonfigMQTT_BROKER_PORT == 443U - xNetworkCredentials.pAlpnProtos = ppcAlpnProtocols; - #elif democonfigMQTT_BROKER_PORT == 8883U - xNetworkCredentials.pAlpnProtos = NULL; - #else /* democonfigMQTT_BROKER_PORT != 8883U */ - xNetworkCredentials.pAlpnProtos = NULL; - #error "MQTT connections to AWS IoT Core are only allowed on ports 443 and 8883." + static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; + #if democonfigMQTT_BROKER_PORT != 443U + #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." #endif /* democonfigMQTT_BROKER_PORT != 443U */ + #else /* if !defined( democonfigCLIENT_USERNAME ) */ + + /* + * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using + * x509 Certificate Authentication. + */ + static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; + #endif /* !defined( democonfigCLIENT_USERNAME ) */ + + /* + * An ALPN identifier is only required when connecting to AWS IoT core on port 443. + * https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html + */ + #if democonfigMQTT_BROKER_PORT == 443U + xNetworkCredentials.pAlpnProtos = ppcAlpnProtocols; + #elif democonfigMQTT_BROKER_PORT == 8883U + xNetworkCredentials.pAlpnProtos = NULL; + #else /* democonfigMQTT_BROKER_PORT != 8883U */ + xNetworkCredentials.pAlpnProtos = NULL; + #error "MQTT connections to AWS IoT Core are only allowed on ports 443 and 8883." + #endif /* democonfigMQTT_BROKER_PORT != 443U */ #else /* !defined( democonfigUSE_AWS_IOT_CORE_BROKER ) */ xNetworkCredentials.pAlpnProtos = NULL; - #endif /* !defined( democonfigUSE_AWS_IOT_CORE_BROKER ) */ + #endif /* !defined( democonfigUSE_AWS_IOT_CORE_BROKER ) */ - /* Set the credentials for establishing a TLS connection. */ - xNetworkCredentials.pRootCa = ( const unsigned char * ) democonfigROOT_CA_PEM; - xNetworkCredentials.rootCaSize = sizeof( democonfigROOT_CA_PEM ); - #ifdef democonfigCLIENT_CERTIFICATE_PEM - xNetworkCredentials.pClientCert = ( const unsigned char * ) democonfigCLIENT_CERTIFICATE_PEM; - xNetworkCredentials.clientCertSize = sizeof( democonfigCLIENT_CERTIFICATE_PEM ); - xNetworkCredentials.pPrivateKey = ( const unsigned char * ) democonfigCLIENT_PRIVATE_KEY_PEM; - xNetworkCredentials.privateKeySize = sizeof( democonfigCLIENT_PRIVATE_KEY_PEM ); - #endif - xNetworkCredentials.disableSni = democonfigDISABLE_SNI; + /* Set the credentials for establishing a TLS connection. */ + xNetworkCredentials.pRootCa = ( const unsigned char * ) democonfigROOT_CA_PEM; + xNetworkCredentials.rootCaSize = sizeof( democonfigROOT_CA_PEM ); + #ifdef democonfigCLIENT_CERTIFICATE_PEM + xNetworkCredentials.pClientCert = ( const unsigned char * ) democonfigCLIENT_CERTIFICATE_PEM; + xNetworkCredentials.clientCertSize = sizeof( democonfigCLIENT_CERTIFICATE_PEM ); + xNetworkCredentials.pPrivateKey = ( const unsigned char * ) democonfigCLIENT_PRIVATE_KEY_PEM; + xNetworkCredentials.privateKeySize = sizeof( democonfigCLIENT_PRIVATE_KEY_PEM ); + #endif + xNetworkCredentials.disableSni = democonfigDISABLE_SNI; #else /* if defined( democonfigUSE_TLS ) && ( democonfigUSE_TLS == 1 ) */ PlaintextTransportStatus_t xNetworkStatus = PLAINTEXT_TRANSPORT_CONNECT_FAILURE; #endif /* if defined( democonfigUSE_TLS ) && ( democonfigUSE_TLS == 1 ) */ @@ -1036,11 +1038,11 @@ static void prvConnectAndCreateDemoTasks( void * pvParameters ) /* Selectively create demo tasks as per the compile time constant settings. */ #if ( democonfigNUM_SIMPLE_SUB_PUB_TASKS_TO_CREATE > 0 ) - { - vStartSimpleSubscribePublishTask( democonfigNUM_SIMPLE_SUB_PUB_TASKS_TO_CREATE, - democonfigSIMPLE_SUB_PUB_TASK_STACK_SIZE, - tskIDLE_PRIORITY ); - } + { + vStartSimpleSubscribePublishTask( democonfigNUM_SIMPLE_SUB_PUB_TASKS_TO_CREATE, + democonfigSIMPLE_SUB_PUB_TASK_STACK_SIZE, + tskIDLE_PRIORITY ); + } #endif diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/simple_sub_pub_demo.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/simple_sub_pub_demo.c index c2822f203..5eb6ff2d9 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/simple_sub_pub_demo.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/DemoTasks/simple_sub_pub_demo.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj index 461eb200d..bb04d0058 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj @@ -1,199 +1,199 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {c35a89ca-0a40-49ff-a7f8-6e6830809b26} - MQTTMultitask - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\Demo\Common\coreMQTT_Agent_Interface\include;.\subscription-manager;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\Demo\Common\coreMQTT_Agent_Interface\include;.\subscription-manager;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - true - MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\Demo\Common\coreMQTT_Agent_Interface\include;.\subscription-manager;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\Demo\Common\coreMQTT_Agent_Interface\include;.\subscription-manager;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {c35a89ca-0a40-49ff-a7f8-6e6830809b26} + MQTTMultitask + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\Demo\Common\coreMQTT_Agent_Interface\include;.\subscription-manager;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\Demo\Common\coreMQTT_Agent_Interface\include;.\subscription-manager;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\Demo\Common\coreMQTT_Agent_Interface\include;.\subscription-manager;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + MQTT_AGENT_DO_NOT_USE_CUSTOM_CONFIG;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Application-Protocols\coreMQTT-Agent\source\include;..\..\..\Demo\Common\coreMQTT_Agent_Interface\include;.\subscription-manager;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj.filters index 6194ea413..1dcc31d1b 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/MQTT_Multitask.vcxproj.filters @@ -1,161 +1,161 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {e28cc02c-0b9d-45da-8c3e-b47d1fe1efaa} - - - {a287c69d-43f4-4df6-9a13-f59eb70cd4a9} - - - {a536fa15-908b-4702-b7d9-d104bdddf43f} - - - {77d5b871-432c-4302-85ec-248ced5a5240} - - - {c26f536c-96d0-4d97-90c2-eecbba863ee4} - - - {2f73859a-4f36-4e0f-8c47-f960b35a3489} - - - {b00537c2-88cc-4f13-bdef-09b5f7b77a37} - - - {2cbd459d-09be-4169-9880-5eeec1539a82} - - - {eba01140-0f72-4f5d-a8c2-431c6c426c6b} - - - {21c3aeda-e0b6-41cd-9017-e21d1c34d696} - - - {3fccb3e5-6ba5-4c3f-bc83-5026714db790} - - - {a88db31a-aa38-42b0-bf70-fdc9f16791cc} - - - {44686a65-b104-4af3-8855-28bbbaf9772e} - - - {1e2c2c93-0989-45f3-aa58-a05a2ebc9e40} - - - {4202753e-a139-4b7b-a7d3-00d97c2fd4f6} - - - - - Headers - - - Headers - - - Additional Libraries\coreMQTT-Agent\include - - - Additional Libraries\coreMQTT-Agent\include - - - Additional Libraries\coreMQTT-Agent\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\backoff_algorithm\include - - - Additional Libraries\coreMQTT-Agent\interface - - - Additional Libraries\coreMQTT-Agent\interface - - - Config - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - - - Source - - - Source - - - Source - - - Source - - - Additional Libraries\coreMQTT-Agent - - - Additional Libraries\coreMQTT-Agent - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\backoff_algorithm - - - Additional Libraries\coreMQTT-Agent - - - Additional Libraries\coreMQTT-Agent - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper\ports - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {e28cc02c-0b9d-45da-8c3e-b47d1fe1efaa} + + + {a287c69d-43f4-4df6-9a13-f59eb70cd4a9} + + + {a536fa15-908b-4702-b7d9-d104bdddf43f} + + + {77d5b871-432c-4302-85ec-248ced5a5240} + + + {c26f536c-96d0-4d97-90c2-eecbba863ee4} + + + {2f73859a-4f36-4e0f-8c47-f960b35a3489} + + + {b00537c2-88cc-4f13-bdef-09b5f7b77a37} + + + {2cbd459d-09be-4169-9880-5eeec1539a82} + + + {eba01140-0f72-4f5d-a8c2-431c6c426c6b} + + + {21c3aeda-e0b6-41cd-9017-e21d1c34d696} + + + {3fccb3e5-6ba5-4c3f-bc83-5026714db790} + + + {a88db31a-aa38-42b0-bf70-fdc9f16791cc} + + + {44686a65-b104-4af3-8855-28bbbaf9772e} + + + {1e2c2c93-0989-45f3-aa58-a05a2ebc9e40} + + + {4202753e-a139-4b7b-a7d3-00d97c2fd4f6} + + + + + Headers + + + Headers + + + Additional Libraries\coreMQTT-Agent\include + + + Additional Libraries\coreMQTT-Agent\include + + + Additional Libraries\coreMQTT-Agent\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\backoff_algorithm\include + + + Additional Libraries\coreMQTT-Agent\interface + + + Additional Libraries\coreMQTT-Agent\interface + + + Config + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + + + Source + + + Source + + + Source + + + Source + + + Additional Libraries\coreMQTT-Agent + + + Additional Libraries\coreMQTT-Agent + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\backoff_algorithm + + + Additional Libraries\coreMQTT-Agent + + + Additional Libraries\coreMQTT-Agent + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper\ports + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/demo_config.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/demo_config.h index 18f765f13..5debbd328 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/mqtt_multitask_demo.sln b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/mqtt_multitask_demo.sln index 939e67e35..96f752d3f 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/mqtt_multitask_demo.sln +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/mqtt_multitask_demo.sln @@ -1,101 +1,101 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Multitask", "MQTT_Multitask.vcxproj", "{C35A89CA-0A40-49FF-A7F8-6E6830809B26}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{4EB64985-ED1A-481B-98EA-E8CF26FA32E5}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|Win32.ActiveCfg = Debug|Win32 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|Win32.Build.0 = Debug|Win32 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|x64.ActiveCfg = Debug|x64 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|x64.Build.0 = Debug|x64 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|x86.ActiveCfg = Debug|Win32 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|x86.Build.0 = Debug|Win32 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|Win32.ActiveCfg = Release|Win32 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|Win32.Build.0 = Release|Win32 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|x64.ActiveCfg = Release|x64 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|x64.Build.0 = Release|x64 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|x86.ActiveCfg = Release|Win32 - {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {4EB64985-ED1A-481B-98EA-E8CF26FA32E5} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {4EB64985-ED1A-481B-98EA-E8CF26FA32E5} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {4EB64985-ED1A-481B-98EA-E8CF26FA32E5} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {4EB64985-ED1A-481B-98EA-E8CF26FA32E5} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {BB2A157E-F3C3-4F17-BD43-49F15AD91A13} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Multitask", "MQTT_Multitask.vcxproj", "{C35A89CA-0A40-49FF-A7F8-6E6830809B26}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{4EB64985-ED1A-481B-98EA-E8CF26FA32E5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|Win32.ActiveCfg = Debug|Win32 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|Win32.Build.0 = Debug|Win32 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|x64.ActiveCfg = Debug|x64 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|x64.Build.0 = Debug|x64 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|x86.ActiveCfg = Debug|Win32 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Debug|x86.Build.0 = Debug|Win32 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|Win32.ActiveCfg = Release|Win32 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|Win32.Build.0 = Release|Win32 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|x64.ActiveCfg = Release|x64 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|x64.Build.0 = Release|x64 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|x86.ActiveCfg = Release|Win32 + {C35A89CA-0A40-49FF-A7F8-6E6830809B26}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {4EB64985-ED1A-481B-98EA-E8CF26FA32E5} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {4EB64985-ED1A-481B-98EA-E8CF26FA32E5} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {4EB64985-ED1A-481B-98EA-E8CF26FA32E5} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {4EB64985-ED1A-481B-98EA-E8CF26FA32E5} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BB2A157E-F3C3-4F17-BD43-49F15AD91A13} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/subscription-manager/subscription_manager.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/subscription-manager/subscription_manager.c index f9c69a02a..0ab787aa0 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/subscription-manager/subscription_manager.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/subscription-manager/subscription_manager.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/subscription-manager/subscription_manager.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/subscription-manager/subscription_manager.h index d95dcfd25..30ffa591a 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/subscription-manager/subscription_manager.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Multitask/subscription-manager/subscription_manager.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/DemoTasks/MutualAuthMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/DemoTasks/MutualAuthMQTTExample.c index eb2b01a77..625b793f4 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/DemoTasks/MutualAuthMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/DemoTasks/MutualAuthMQTTExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -673,26 +673,28 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkCredent uint16_t usNextRetryBackOff = 0U; #if defined( democonfigCLIENT_USERNAME ) - /* - * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect - * to AWS IoT Core with Custom Authentication on port 443. - * - * Custom Authentication uses the contents of the username and password - * fields of the MQTT CONNECT packet to authenticate the client. - * - * For more information, refer to the documentation at: - * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html - */ - static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; - #if democonfigMQTT_BROKER_PORT != 443U - #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." - #endif /* democonfigMQTT_BROKER_PORT != 443U */ + + /* + * When democonfigCLIENT_USERNAME is defined, use the "mqtt" alpn to connect + * to AWS IoT Core with Custom Authentication on port 443. + * + * Custom Authentication uses the contents of the username and password + * fields of the MQTT CONNECT packet to authenticate the client. + * + * For more information, refer to the documentation at: + * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html + */ + static const char * ppcAlpnProtocols[] = { "mqtt", NULL }; + #if democonfigMQTT_BROKER_PORT != 443U + #error "Connections to AWS IoT Core with custom authentication must connect to TCP port 443 with the \"mqtt\" alpn." + #endif /* democonfigMQTT_BROKER_PORT != 443U */ #else /* if !defined( democonfigCLIENT_USERNAME ) */ - /* - * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using - * x509 Certificate Authentication. - */ - static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; + + /* + * Otherwise, use the "x-amzn-mqtt-ca" alpn to connect to AWS IoT Core using + * x509 Certificate Authentication. + */ + static const char * ppcAlpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; #endif /* !defined( democonfigCLIENT_USERNAME ) */ /* diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj index 357f19f2b..8315c9c7f 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj @@ -1,255 +1,255 @@ - - - - - Debug_with_Libslirp - Win32 - - - Debug_with_Libslirp - x64 - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {dd2281b6-6d9b-4477-ba0a-8842f2e917c7} - MQTTMutualAuth - 10.0 - - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - true - - - true - - - false - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug_with_Libslirp + Win32 + + + Debug_with_Libslirp + x64 + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {dd2281b6-6d9b-4477-ba0a-8842f2e917c7} + MQTTMutualAuth + 10.0 + + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + true + + + true + + + false + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj.filters index dc158fc16..11ec89b6c 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/MQTT_Mutual_Auth.vcxproj.filters @@ -1,114 +1,114 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {5c3de8f6-98f6-428c-99ac-ac37d6c1192b} - - - {e211737e-5af5-42c0-b070-0d866aea1cce} - - - {7ee32915-6737-465a-9b4f-46a97c8832c2} - - - {436a06e1-8dc3-4620-a7bb-55f3479fd51c} - - - {d9b88983-3018-4ce2-b989-bce0d9ed2869} - - - {e96dc04e-c4ea-497d-a8b2-a6d3fe28d2f5} - - - {74d65d77-4301-4a58-9027-f550adf17030} - - - {b99db9c9-e15b-48e7-9a84-c13b2beb1b6b} - - - {cbbb933e-96a0-4e36-9803-cfa84580fd71} - - - {bb1fcecb-0b74-4ba7-bed0-692572d5ffac} - - - {fea74b8f-d16a-4d60-ab54-efdcfcc9d828} - - - {5dd8708c-c8c7-410b-9707-a85e39acaeb8} - - - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\Backoff Algorithm - - - Source Files - - - Source Files - - - Additional Network Transport Files\TCP Sockets Wrapper\ports - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\Backoff Algorithm\include - - - Header Files - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Config - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {5c3de8f6-98f6-428c-99ac-ac37d6c1192b} + + + {e211737e-5af5-42c0-b070-0d866aea1cce} + + + {7ee32915-6737-465a-9b4f-46a97c8832c2} + + + {436a06e1-8dc3-4620-a7bb-55f3479fd51c} + + + {d9b88983-3018-4ce2-b989-bce0d9ed2869} + + + {e96dc04e-c4ea-497d-a8b2-a6d3fe28d2f5} + + + {74d65d77-4301-4a58-9027-f550adf17030} + + + {b99db9c9-e15b-48e7-9a84-c13b2beb1b6b} + + + {cbbb933e-96a0-4e36-9803-cfa84580fd71} + + + {bb1fcecb-0b74-4ba7-bed0-692572d5ffac} + + + {fea74b8f-d16a-4d60-ab54-efdcfcc9d828} + + + {5dd8708c-c8c7-410b-9707-a85e39acaeb8} + + + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\Backoff Algorithm + + + Source Files + + + Source Files + + + Additional Network Transport Files\TCP Sockets Wrapper\ports + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\Backoff Algorithm\include + + + Header Files + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Config + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/demo_config.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/demo_config.h index 07716920d..d3f496be5 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/mqtt_mutual_auth_demo.sln b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/mqtt_mutual_auth_demo.sln index 6587256f5..c1dbf5726 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/mqtt_mutual_auth_demo.sln +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth/mqtt_mutual_auth_demo.sln @@ -1,134 +1,134 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Mutual_Auth", "MQTT_Mutual_Auth.vcxproj", "{DD2281B6-6D9B-4477-BA0A-8842F2E917C7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{D0F63241-9AE5-48D7-AB26-604122594805}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 - Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 - Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|Win32.ActiveCfg = Debug|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|Win32.Build.0 = Debug|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|x64.ActiveCfg = Debug|x64 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|x64.Build.0 = Debug|x64 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|x86.ActiveCfg = Debug|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|x86.Build.0 = Debug|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|Win32.ActiveCfg = Release|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|Win32.Build.0 = Release|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|x64.ActiveCfg = Release|x64 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|x64.Build.0 = Release|x64 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|x86.ActiveCfg = Release|Win32 - {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {D0F63241-9AE5-48D7-AB26-604122594805} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {D0F63241-9AE5-48D7-AB26-604122594805} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {D0F63241-9AE5-48D7-AB26-604122594805} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {D0F63241-9AE5-48D7-AB26-604122594805} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {159FDB3F-FFEE-450A-9618-80588C4710B6} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Mutual_Auth", "MQTT_Mutual_Auth.vcxproj", "{DD2281B6-6D9B-4477-BA0A-8842F2E917C7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{D0F63241-9AE5-48D7-AB26-604122594805}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 + Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 + Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|Win32.ActiveCfg = Debug|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|Win32.Build.0 = Debug|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|x64.ActiveCfg = Debug|x64 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|x64.Build.0 = Debug|x64 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|x86.ActiveCfg = Debug|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Debug|x86.Build.0 = Debug|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|Win32.ActiveCfg = Release|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|Win32.Build.0 = Release|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|x64.ActiveCfg = Release|x64 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|x64.Build.0 = Release|x64 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|x86.ActiveCfg = Release|Win32 + {DD2281B6-6D9B-4477-BA0A-8842F2E917C7}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {D0F63241-9AE5-48D7-AB26-604122594805} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {D0F63241-9AE5-48D7-AB26-604122594805} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {D0F63241-9AE5-48D7-AB26-604122594805} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {D0F63241-9AE5-48D7-AB26-604122594805} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {159FDB3F-FFEE-450A-9618-80588C4710B6} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/DemoTasks/MutualAuthMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/DemoTasks/MutualAuthMQTTExample.c index c2affeda9..f354064e5 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/DemoTasks/MutualAuthMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/DemoTasks/MutualAuthMQTTExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj index 23034ba89..d91c84e56 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj @@ -1,366 +1,366 @@ - - - - - Debug_with_Libslirp - Win32 - - - Debug - Win32 - - - - {C686325E-3261-42F7-AEB1-DDE5280E1CEB} - RTOSDemo - 10.0 - - - - Application - false - MultiByte - v142 - - - Application - false - MultiByte - v142 - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - .\Debug\ - .\Debug\ - .\Debug\ - .\Debug\ - true - true - AllRules.ruleset - AllRules.ruleset - - - - .\Debug/WIN32.tlb - - - - - Disabled - .\;..\Common;..\..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\FreeRTOS-Plus\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\wolfSSL_freertos;..\..\..\ThirdParty\wolfSSL;%(AdditionalIncludeDirectories) - WOLFSSL_USER_SETTINGS;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDLL - .\Debug/WIN32.pch - .\Debug/ - .\Debug/ - .\Debug/ - Level4 - true - false - EditAndContinue - /wd4210 /wd4127 /wd4214 /wd4201 /wd4244 /wd4310 /wd4200 %(AdditionalOptions) - true - NotUsing - false - CompileAsC - 4819;4206;4706 - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c09 - - - .\Debug/RTOSDemo.exe - true - true - .\Debug/WIN32.pdb - Console - MachineX86 - Bcrypt.lib;%(AdditionalDependencies) - ..\..\Common\WinPCap - false - false - - - true - .\Debug/WIN32.bsc - - - - - .\Debug/WIN32.tlb - - - - - Disabled - .\;..\Common;..\..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\FreeRTOS-Plus\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\wolfSSL_freertos;..\..\..\ThirdParty\wolfSSL;%(AdditionalIncludeDirectories) - WOLFSSL_USER_SETTINGS;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDLL - .\Debug/WIN32.pch - .\Debug/ - .\Debug/ - .\Debug/ - Level4 - true - false - EditAndContinue - /wd4210 /wd4127 /wd4214 /wd4201 /wd4244 /wd4310 /wd4200 %(AdditionalOptions) - true - NotUsing - false - CompileAsC - 4819;4206;4706 - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c09 - - - .\Debug/RTOSDemo.exe - true - true - .\Debug/WIN32.pdb - Console - MachineX86 - Bcrypt.lib;Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - ..\..\Common\WinPCap - false - false - - - true - .\Debug/WIN32.bsc - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug_with_Libslirp + Win32 + + + Debug + Win32 + + + + {C686325E-3261-42F7-AEB1-DDE5280E1CEB} + RTOSDemo + 10.0 + + + + Application + false + MultiByte + v142 + + + Application + false + MultiByte + v142 + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\Debug\ + .\Debug\ + .\Debug\ + .\Debug\ + true + true + AllRules.ruleset + AllRules.ruleset + + + + .\Debug/WIN32.tlb + + + + + Disabled + .\;..\Common;..\..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\FreeRTOS-Plus\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\wolfSSL_freertos;..\..\..\ThirdParty\wolfSSL;%(AdditionalIncludeDirectories) + WOLFSSL_USER_SETTINGS;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDLL + .\Debug/WIN32.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level4 + true + false + EditAndContinue + /wd4210 /wd4127 /wd4214 /wd4201 /wd4244 /wd4310 /wd4200 %(AdditionalOptions) + true + NotUsing + false + CompileAsC + 4819;4206;4706 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + .\Debug/RTOSDemo.exe + true + true + .\Debug/WIN32.pdb + Console + MachineX86 + Bcrypt.lib;%(AdditionalDependencies) + ..\..\Common\WinPCap + false + false + + + true + .\Debug/WIN32.bsc + + + + + .\Debug/WIN32.tlb + + + + + Disabled + .\;..\Common;..\..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\FreeRTOS-Plus\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\wolfSSL_freertos;..\..\..\ThirdParty\wolfSSL;%(AdditionalIncludeDirectories) + WOLFSSL_USER_SETTINGS;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDLL + .\Debug/WIN32.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level4 + true + false + EditAndContinue + /wd4210 /wd4127 /wd4214 /wd4201 /wd4244 /wd4310 /wd4200 %(AdditionalOptions) + true + NotUsing + false + CompileAsC + 4819;4206;4706 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + .\Debug/RTOSDemo.exe + true + true + .\Debug/WIN32.pdb + Console + MachineX86 + Bcrypt.lib;Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + ..\..\Common\WinPCap + false + false + + + true + .\Debug/WIN32.bsc + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj.filters index 02ff32970..1781be7ab 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/MQTT_Mutual_Auth_wolfSSL.vcxproj.filters @@ -1,629 +1,629 @@ - - - - - {e5ad4ec7-23dc-4295-8add-2acaee488f5a} - - - {a3bc0245-a552-43a3-828c-76334f37f837} - - - {b34b7d37-9bff-41ac-b6a9-849bb3da790a} - - - {2d7875b9-6040-413b-be28-ccab70bacf45} - - - {6ad56e6d-c330-4830-8f4b-c75b05dfa866} - - - {90bcf555-1d56-4512-85b0-dafefb542437} - - - {617d7848-f326-4873-8006-bb13604861e6} - - - {c1be3c08-d159-45ef-be6f-eb32bd235015} - - - {93eb4d69-0f79-41a9-8101-68c1ddf755ee} - - - {5599e5a4-2ff0-4ec0-8082-e9dc20d17723} - - - {01240ff7-3a87-4cdd-9adb-b3f44b39f1be} - - - {c5c63fb4-8831-4eab-9612-95d4cc864c15} - - - {2711a83b-f983-4c9e-923b-5e182733c7c3} - - - {371386a6-ca3b-4488-ac67-349984357769} - - - {3c77352a-cb7e-4024-aa37-b2e42f32d84a} - - - {ba7af2f2-2f54-428d-b0f6-c914e5afe295} - - - {04240a1c-18b8-42cc-be16-a4f96a038630} - - - {26da2e92-d2cc-45bf-ab30-8e1171a28578} - - - {1e84e441-f597-4e10-b476-d89c026dd16e} - - - {10614ed2-fe01-463b-b961-1ce443780e8b} - - - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\wolfSSL\wolfcrypt\source - - - Additional Libraries\Backoff Algorithm - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Network Transport Files\TCP Sockets Wrapper\ports - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Source - - - Source - - - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\wolfcrypt\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\wolfSSL\include - - - Additional Libraries\Backoff Algorithm\include - - - Additional Libraries\coreMQTT\include - - - Header - - - Header - - - Config - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - - - Additional Libraries\wolfSSL\wolfcrypt\source - - + + + + + {e5ad4ec7-23dc-4295-8add-2acaee488f5a} + + + {a3bc0245-a552-43a3-828c-76334f37f837} + + + {b34b7d37-9bff-41ac-b6a9-849bb3da790a} + + + {2d7875b9-6040-413b-be28-ccab70bacf45} + + + {6ad56e6d-c330-4830-8f4b-c75b05dfa866} + + + {90bcf555-1d56-4512-85b0-dafefb542437} + + + {617d7848-f326-4873-8006-bb13604861e6} + + + {c1be3c08-d159-45ef-be6f-eb32bd235015} + + + {93eb4d69-0f79-41a9-8101-68c1ddf755ee} + + + {5599e5a4-2ff0-4ec0-8082-e9dc20d17723} + + + {01240ff7-3a87-4cdd-9adb-b3f44b39f1be} + + + {c5c63fb4-8831-4eab-9612-95d4cc864c15} + + + {2711a83b-f983-4c9e-923b-5e182733c7c3} + + + {371386a6-ca3b-4488-ac67-349984357769} + + + {3c77352a-cb7e-4024-aa37-b2e42f32d84a} + + + {ba7af2f2-2f54-428d-b0f6-c914e5afe295} + + + {04240a1c-18b8-42cc-be16-a4f96a038630} + + + {26da2e92-d2cc-45bf-ab30-8e1171a28578} + + + {1e84e441-f597-4e10-b476-d89c026dd16e} + + + {10614ed2-fe01-463b-b961-1ce443780e8b} + + + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\wolfSSL\wolfcrypt\source + + + Additional Libraries\Backoff Algorithm + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Network Transport Files\TCP Sockets Wrapper\ports + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Source + + + Source + + + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\wolfcrypt\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\wolfSSL\include + + + Additional Libraries\Backoff Algorithm\include + + + Additional Libraries\coreMQTT\include + + + Header + + + Header + + + Config + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + + + Additional Libraries\wolfSSL\wolfcrypt\source + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/README_wolfSSL.md b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/README_wolfSSL.md index 8fb05999b..a6af01711 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/README_wolfSSL.md +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/README_wolfSSL.md @@ -1,183 +1,183 @@ -# MQTT Mutual Auth wolfSSL Demo - -# Overview -This demo shows an MQTT subscriber / publisher establishing a TLS connection with an MQTT broker to send and receive topics in encrypted form. wolfSSL acts as a TLS library under the FreeRTOS MQTT library. -A single FreeRTOS task acts as both an MQTT subscriber and an MQTT publisher, sending and receiving topics through the MQTT broker endpoint you specified. The task holds a client certificate and authenticate each other with the MQTT broker. - -# How to build and run the Demo application - -By double-clicking the solution file named "**mqtt_mutual_auth_demo_wolfSSL.sln**" included in this folder, Visual Studio starts and shows you a project in its solution explorer. It is named "RTOSDemo" and provides a console application program which runs on windows. - -All required settings for wolfSSL have been set in the user_settings.h header file included in the RTOSDemo folder in the solution explorer pane. For this demo to work, you need to set the following information: - -1. set broker endpoint -2. set root CA certificate -3. set client certificate -4. set private key -5. choose interface to use - -If even one of the above 1 to 4 is not set, an error will occur at build time. You should open **demo_config.h** to set them. - -
- -# Set Broker endpoint - -A broker endpoint is a url that represents where MQTT subscribers and publishers access. In case your device is going to access AWS IoT device data endpoints, the endpoint would be the following format: ***account-specific-prefix*.iot.*aws-region*. amazonaws.com**. - -To set broker endpoint, find the statement '**#define democonfigMQTT_BROKER_ENDPOINT "...insert here...**' in demo_config.h and activate it by copy & paste to the outside of the commented part. Replace "...insert here..." with your broker endpoint url. -``` -#define democonfigMQTT_BROKER_ENDPOINT "a****.iot.us-***.amazonaws.com" -``` -You may find "democonfigMQTT_BROKER_PORT" just below of the democonfigMQTT_BROKER_ENDPOINT macro. If your MQTT broker port is "8883", no need to specifiy that value here, since the value is defined in MutualAuthMQTTExample.c by default. - -
- -# Set Credentials - -Since this demo handles mutual authentication, you need to provide rootCA certificate, client certificate and client private key. Those credentials should be set by way of following macros in demo_config.h: -1. **democonfigROOT_CA_PEM** -2. **democonfigCLIENT_CERTIFICATE_PEM** -3. **democonfigCLIENT_PRIVATE_KEY_PEM** - -For setting those credentials, you have a option to specify the source of them, using file or using buffer. If you want provide credentials using buffer, -activate **democonfigCREDENTIALS_IN_BUFFER** macro. Otherwise, let the macro commented out. -``` -#define democonfigCREDENTIALS_IN_BUFFER -``` -
- -## Setting credentials using file - -
- -By default, above **democonfigCREDENTIALS_IN_BUFFER** macro definition is commented out, therefore each credential should be provided by PEM encoded file. In this case, each macro definition looks like: - -``` -#define democonfigROOT_CA_PEM "rootCA-PEM-encoded-file-path" -``` -Activate two other macro definitions and set a file path for each. - -
- -## Setting credential using buffer - -
- -First of all, activate **democonfigCREDENTIALS_IN_BUFFER** macro. -``` -#define democonfigCREDENTIALS_IN_BUFFER -``` - -Second, activate following three macros: - -``` -#define democonfigROOT_CA_PEM "...insert here..." -#define democonfigCLIENT_CERTIFICATE_PEM "...insert here..." -#define democonfigCLIENT_PRIVATE_KEY_PEM "...insert here..." -``` -The "...insert here..." portion of each macro should be replaced with corrensponding credential file content data. -For exsample, democonfigROOT_CA_PEM macro would be: - -``` -#define democonfigROOT_CA_PEM \ -"-----BEGIN CERTIFICATE-----\n" -"MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB\n" \ - ...... -"-----END CERTIFICATE-----\n" -``` - -If you completes above settings, re-build demo to continue with the final setup. - -# Choose an interface to use -At this point, assume that you have completed all the necessary settings other than this interface settings and the demo is runnable. Remember you should choose an interface to use to configure the demo. However you may not know how to choose it. The demo will give you good guidance. Run the demo. - -A console that pops up appears with output similar to the following: -``` -The following network interfaces are available: - -Interface 1 - rpcap://\Device\NPF_{F47******-2150-****-89***-*******8C8D8} - (Network adapter 'Qualcomm Atheros Ar81xx series PCI-E Ethernet Controller' on local host) - - -The interface that will be opened is set by "configNETWORK_INTERFACE_TO_USE", which -should be defined in FreeRTOSConfig.h - -ERROR: configNETWORK_INTERFACE_TO_USE is set to 0, which is an invalid value. -Please set configNETWORK_INTERFACE_TO_USE to one of the interface numbers listed above, -then re-compile and re-start the application. Only Ethernet (as opposed to WiFi) -interfaces are supported. - -HALTING -``` -
- -This output provides guidance and a list of interfaces available on the system. Open the **FreeRTOSConfig.h** file in the same folder where this readme file located, and set the selected interface number to ***configNETWORK_INTERFACE_TO_USE*** . -Then rebuild and run the demo. This time you can see that the interface is set up and working. -

- -``` -The following network interfaces are available: - -Interface 1 - rpcap://\Device\NPF_{F47******-2150-****-89***-*******8C8D8} - (Network adapter 'Qualcomm Atheros Ar81xx series PCI-E Ethernet Controller' on local host) - - -The interface that will be opened is set by "configNETWORK_INTERFACE_TO_USE", which -should be defined in FreeRTOSConfig.h -Attempting to open interface number 1. -Successfully opened interface number 1. -0 560 [IP-task] vDHCPProcess: offer 192.168.1.6 -vDHCPProcess: offer 192.168.1.6 -1 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:158] ---------STARTING DEMO--------- -2 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:167] IP Address: 192.168.1.6 -3 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:170] Subnet Mask: 255.255.255.0 -4 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:173] Gateway Address: 192.168.1.1 -5 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:176] DNS Server Address: 192.168.1.1 -6 600 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:356] Creating a TLS connection to ...insert here...:8883. -vAssertCalled( ***\FreeRTOS\FreeRTOS-Plus\Demo\coreMQTT_Windows_Simulator\MQTT_Mutual_Auth_wolfSSL\DemoTasks\MutualAuthMQTTExample.c, 457 -``` - -
- -# Demo output -Below is the output digest when a Aws MQTT IoT endpoint and appropriate credentials are set. You can find "**Hello World!**" message was published and received as a topic repeatedly. - -``` -... -1 8221 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:158] ---------STARTING DEMO--------- -2 8221 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:167] IP Address: 192.168.1.14 -... -6 8222 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:356] Creating a TLS connection to a**************************.amazonaws.com:8883. -... -8 10221 [MQTTDemo] A mutually authenticated TLS connection established with a**************************.amazonaws.com::8883. -... -9 10221 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:361] Creating an MQTT connection to a**************************.amazonaws.com:. -... -14 10381 [MQTTDemo] [INFO] [MQTT] [MQTT_Connect:1798] MQTT connection established with the broker. -15 10381 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvCreateMQTTConnectionWithBroker:514] An MQTT connection is established with a**************************.amazonaws.com:. -16 10381 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:375] Attempt to subscribe to the MQTT topic demoDevice/example/topic. -... -19 11481 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:394] Publish to the MQTT topic demoDevice/example/topic. -20 11481 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:399] Attempt to receive publish message from broker. -... -Incoming Publish Topic Name: demoDevice/example/topic matches subscribed topic. -Incoming Publish Message : Hello World! - -30 12641 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:404] Keeping Connection Idle... -31 14641 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:394] Publish to the MQTT topic demoDevice/example/topic. -32 14641 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:399] Attempt to receive publish message from broker. -... -Incoming Publish Topic Name: demoDevice/example/topic matches subscribed topic. -Incoming Publish Message : Hello World! - -42 15741 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:404] Keeping Connection Idle... -43 17741 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:394] Publish to the MQTT topic demoDevice/example/topic. -44 17741 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:399] Attempt to receive publish message from broker. -... -Incoming Publish Topic Name: demoDevice/example/topic matches subscribed topic. -Incoming Publish Message : Hello World! -... - -``` - - +# MQTT Mutual Auth wolfSSL Demo + +# Overview +This demo shows an MQTT subscriber / publisher establishing a TLS connection with an MQTT broker to send and receive topics in encrypted form. wolfSSL acts as a TLS library under the FreeRTOS MQTT library. +A single FreeRTOS task acts as both an MQTT subscriber and an MQTT publisher, sending and receiving topics through the MQTT broker endpoint you specified. The task holds a client certificate and authenticate each other with the MQTT broker. + +# How to build and run the Demo application + +By double-clicking the solution file named "**mqtt_mutual_auth_demo_wolfSSL.sln**" included in this folder, Visual Studio starts and shows you a project in its solution explorer. It is named "RTOSDemo" and provides a console application program which runs on windows. + +All required settings for wolfSSL have been set in the user_settings.h header file included in the RTOSDemo folder in the solution explorer pane. For this demo to work, you need to set the following information: + +1. set broker endpoint +2. set root CA certificate +3. set client certificate +4. set private key +5. choose interface to use + +If even one of the above 1 to 4 is not set, an error will occur at build time. You should open **demo_config.h** to set them. + +
+ +# Set Broker endpoint + +A broker endpoint is a url that represents where MQTT subscribers and publishers access. In case your device is going to access AWS IoT device data endpoints, the endpoint would be the following format: ***account-specific-prefix*.iot.*aws-region*. amazonaws.com**. + +To set broker endpoint, find the statement '**#define democonfigMQTT_BROKER_ENDPOINT "...insert here...**' in demo_config.h and activate it by copy & paste to the outside of the commented part. Replace "...insert here..." with your broker endpoint url. +``` +#define democonfigMQTT_BROKER_ENDPOINT "a****.iot.us-***.amazonaws.com" +``` +You may find "democonfigMQTT_BROKER_PORT" just below of the democonfigMQTT_BROKER_ENDPOINT macro. If your MQTT broker port is "8883", no need to specify that value here, since the value is defined in MutualAuthMQTTExample.c by default. + +
+ +# Set Credentials + +Since this demo handles mutual authentication, you need to provide rootCA certificate, client certificate and client private key. Those credentials should be set by way of following macros in demo_config.h: +1. **democonfigROOT_CA_PEM** +2. **democonfigCLIENT_CERTIFICATE_PEM** +3. **democonfigCLIENT_PRIVATE_KEY_PEM** + +For setting those credentials, you have a option to specify the source of them, using file or using buffer. If you want provide credentials using buffer, +activate **democonfigCREDENTIALS_IN_BUFFER** macro. Otherwise, let the macro commented out. +``` +#define democonfigCREDENTIALS_IN_BUFFER +``` +
+ +## Setting credentials using file + +
+ +By default, above **democonfigCREDENTIALS_IN_BUFFER** macro definition is commented out, therefore each credential should be provided by PEM encoded file. In this case, each macro definition looks like: + +``` +#define democonfigROOT_CA_PEM "rootCA-PEM-encoded-file-path" +``` +Activate two other macro definitions and set a file path for each. + +
+ +## Setting credential using buffer + +
+ +First of all, activate **democonfigCREDENTIALS_IN_BUFFER** macro. +``` +#define democonfigCREDENTIALS_IN_BUFFER +``` + +Second, activate following three macros: + +``` +#define democonfigROOT_CA_PEM "...insert here..." +#define democonfigCLIENT_CERTIFICATE_PEM "...insert here..." +#define democonfigCLIENT_PRIVATE_KEY_PEM "...insert here..." +``` +The "...insert here..." portion of each macro should be replaced with corrensponding credential file content data. +For example, democonfigROOT_CA_PEM macro would be: + +``` +#define democonfigROOT_CA_PEM \ +"-----BEGIN CERTIFICATE-----\n" +"MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB\n" \ + ...... +"-----END CERTIFICATE-----\n" +``` + +If you completes above settings, re-build demo to continue with the final setup. + +# Choose an interface to use +At this point, assume that you have completed all the necessary settings other than this interface settings and the demo is runnable. Remember you should choose an interface to use to configure the demo. However you may not know how to choose it. The demo will give you good guidance. Run the demo. + +A console that pops up appears with output similar to the following: +``` +The following network interfaces are available: + +Interface 1 - rpcap://\Device\NPF_{F47******-2150-****-89***-*******8C8D8} + (Network adapter 'Qualcomm Atheros Ar81xx series PCI-E Ethernet Controller' on local host) + + +The interface that will be opened is set by "configNETWORK_INTERFACE_TO_USE", which +should be defined in FreeRTOSConfig.h + +ERROR: configNETWORK_INTERFACE_TO_USE is set to 0, which is an invalid value. +Please set configNETWORK_INTERFACE_TO_USE to one of the interface numbers listed above, +then re-compile and re-start the application. Only Ethernet (as opposed to WiFi) +interfaces are supported. + +HALTING +``` +
+ +This output provides guidance and a list of interfaces available on the system. Open the **FreeRTOSConfig.h** file in the same folder where this readme file located, and set the selected interface number to ***configNETWORK_INTERFACE_TO_USE*** . +Then rebuild and run the demo. This time you can see that the interface is set up and working. +

+ +``` +The following network interfaces are available: + +Interface 1 - rpcap://\Device\NPF_{F47******-2150-****-89***-*******8C8D8} + (Network adapter 'Qualcomm Atheros Ar81xx series PCI-E Ethernet Controller' on local host) + + +The interface that will be opened is set by "configNETWORK_INTERFACE_TO_USE", which +should be defined in FreeRTOSConfig.h +Attempting to open interface number 1. +Successfully opened interface number 1. +0 560 [IP-task] vDHCPProcess: offer 192.168.1.6 +vDHCPProcess: offer 192.168.1.6 +1 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:158] ---------STARTING DEMO--------- +2 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:167] IP Address: 192.168.1.6 +3 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:170] Subnet Mask: 255.255.255.0 +4 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:173] Gateway Address: 192.168.1.1 +5 600 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:176] DNS Server Address: 192.168.1.1 +6 600 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:356] Creating a TLS connection to ...insert here...:8883. +vAssertCalled( ***\FreeRTOS\FreeRTOS-Plus\Demo\coreMQTT_Windows_Simulator\MQTT_Mutual_Auth_wolfSSL\DemoTasks\MutualAuthMQTTExample.c, 457 +``` + +
+ +# Demo output +Below is the output digest when a Aws MQTT IoT endpoint and appropriate credentials are set. You can find "**Hello World!**" message was published and received as a topic repeatedly. + +``` +... +1 8221 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:158] ---------STARTING DEMO--------- +2 8221 [IP-task] [INFO] [MQTT-wolfSSL] [vApplicationIPNetworkEventHook:167] IP Address: 192.168.1.14 +... +6 8222 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:356] Creating a TLS connection to a**************************.amazonaws.com:8883. +... +8 10221 [MQTTDemo] A mutually authenticated TLS connection established with a**************************.amazonaws.com::8883. +... +9 10221 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:361] Creating an MQTT connection to a**************************.amazonaws.com:. +... +14 10381 [MQTTDemo] [INFO] [MQTT] [MQTT_Connect:1798] MQTT connection established with the broker. +15 10381 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvCreateMQTTConnectionWithBroker:514] An MQTT connection is established with a**************************.amazonaws.com:. +16 10381 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:375] Attempt to subscribe to the MQTT topic demoDevice/example/topic. +... +19 11481 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:394] Publish to the MQTT topic demoDevice/example/topic. +20 11481 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:399] Attempt to receive publish message from broker. +... +Incoming Publish Topic Name: demoDevice/example/topic matches subscribed topic. +Incoming Publish Message : Hello World! + +30 12641 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:404] Keeping Connection Idle... +31 14641 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:394] Publish to the MQTT topic demoDevice/example/topic. +32 14641 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:399] Attempt to receive publish message from broker. +... +Incoming Publish Topic Name: demoDevice/example/topic matches subscribed topic. +Incoming Publish Message : Hello World! + +42 15741 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:404] Keeping Connection Idle... +43 17741 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:394] Publish to the MQTT topic demoDevice/example/topic. +44 17741 [MQTTDemo] [INFO] [MQTT-wolfSSL] [prvMQTTDemoTask:399] Attempt to receive publish message from broker. +... +Incoming Publish Topic Name: demoDevice/example/topic matches subscribed topic. +Incoming Publish Message : Hello World! +... + +``` + + diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/demo_config.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/demo_config.h index 0980457af..1b77488b0 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -56,13 +56,13 @@ * of FreeRTOS. * The function prints to the console before the network is connected; * then a UDP port after the network has connected. */ -extern void vLoggingPrintf(const char* pcFormatString, - ...); +extern void vLoggingPrintf( const char * pcFormatString, + ... ); /* Map the SdkLog macro to the logging function to enable logging * on Windows simulator. */ #ifndef SdkLog -#define SdkLog( message ) vLoggingPrintf message + #define SdkLog( message ) vLoggingPrintf message #endif #include "logging_stack.h" @@ -122,7 +122,7 @@ extern void vLoggingPrintf(const char* pcFormatString, * #define democonfigCREDENTIALS_IN_BUFFER */ - /** +/** * @brief Server's root CA certificate. * * For AWS IoT MQTT broker, this certificate is used to identify the AWS IoT diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/mqtt_mutual_auth_demo_wolfSSL.sln b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/mqtt_mutual_auth_demo_wolfSSL.sln index b2dcf1b29..51e1d4b14 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/mqtt_mutual_auth_demo_wolfSSL.sln +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/mqtt_mutual_auth_demo_wolfSSL.sln @@ -1,102 +1,102 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29215.179 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "MQTT_Mutual_Auth_wolfSSL.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{18C74643-B0CA-4709-8835-F4E8F4F3005A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 - Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|Win32 - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32 - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32 - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|x64.ActiveCfg = Debug|Win32 - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Debug|Win32 - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Debug|Win32 - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|x64.ActiveCfg = Debug|Win32 - {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|x64.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {18C74643-B0CA-4709-8835-F4E8F4F3005A} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {18C74643-B0CA-4709-8835-F4E8F4F3005A} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {18C74643-B0CA-4709-8835-F4E8F4F3005A} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {18C74643-B0CA-4709-8835-F4E8F4F3005A} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {150F08BF-9D61-4CC2-8DBF-1335172A1EA4} - EndGlobalSection - GlobalSection(TestCaseManagementSettings) = postSolution - CategoryFile = FreeRTOS_Plus_TCP_Minimal.vsmdi - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29215.179 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "MQTT_Mutual_Auth_wolfSSL.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{18C74643-B0CA-4709-8835-F4E8F4F3005A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 + Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|x64.ActiveCfg = Debug|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Debug|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Debug|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|x64.ActiveCfg = Debug|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|x64.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {18C74643-B0CA-4709-8835-F4E8F4F3005A} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {18C74643-B0CA-4709-8835-F4E8F4F3005A} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {18C74643-B0CA-4709-8835-F4E8F4F3005A} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {18C74643-B0CA-4709-8835-F4E8F4F3005A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {150F08BF-9D61-4CC2-8DBF-1335172A1EA4} + EndGlobalSection + GlobalSection(TestCaseManagementSettings) = postSolution + CategoryFile = FreeRTOS_Plus_TCP_Minimal.vsmdi + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/user_settings.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/user_settings.h index b0bdd1c1a..fc077b7a5 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/user_settings.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth_wolfSSL/user_settings.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -45,8 +45,8 @@ #define HAVE_FFDHE_2048 #ifndef WOLFSSL_OPTIONS_IGNORE_SYS -#undef _POSIX_THREADS -#define _POSIX_THREADS + #undef _POSIX_THREADS + #define _POSIX_THREADS #endif #define HAVE_THREAD_LS @@ -93,7 +93,7 @@ #define WOLFSSL_X86_64_BUILD #define WC_NO_ASYNC_THREADING #define HAVE_DH_DEFAULT_PARAMS -#define HAVE___UINT128_T 1 +#define HAVE___UINT128_T 1 #define NO_DSA #define NO_HC128 @@ -102,14 +102,15 @@ #define NO_PSK #define NO_MD4 #define NO_PWDBASED - /*-- Debugging options ------------------------------------------------------ + +/*-- Debugging options ------------------------------------------------------ * * "DEBUG_WOLFSSL" definition enables log to output into stdout. * Note: wolfSSL_Debugging_ON() must be called just after wolfSSL_Init(). *----------------------------------------------------------------------------*/ /*#define DEBUG_WOLFSSL*/ - + #endif /* USER_SETTINGS_H */ diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/DemoTasks/PlaintextMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/DemoTasks/PlaintextMQTTExample.c index 2ab7cb992..58685a298 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/DemoTasks/PlaintextMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/DemoTasks/PlaintextMQTTExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -734,7 +734,7 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) usSubscribePacketIdentifier = MQTT_GetPacketId( pxMQTTContext ); /* Populate subscription list. */ - for(ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { xMQTTSubscription[ ulTopicCount ].qos = MQTTQoS2; xMQTTSubscription[ ulTopicCount ].pTopicFilter = xTopicFilterContext[ ulTopicCount ].pcTopicFilter; @@ -762,7 +762,7 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext ) usSubscribePacketIdentifier ); configASSERT( xResult == MQTTSuccess ); - for(ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { LogInfo( ( "SUBSCRIBE sent for topic %s to broker.\n\n", xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) ); @@ -865,7 +865,7 @@ static void prvMQTTUnsubscribeFromTopics( MQTTContext_t * pxMQTTContext ) memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) ); /* Populate subscription list. */ - for(ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { xMQTTSubscription[ ulTopicCount ].qos = MQTTQoS2; xMQTTSubscription[ ulTopicCount ].pTopicFilter = xTopicFilterContext[ ulTopicCount ].pcTopicFilter; @@ -979,7 +979,7 @@ static void prvMQTTProcessIncomingPublish( MQTTPublishInfo_t * pxPublishInfo ) LogInfo( ( "Incoming QoS : %d\n", pxPublishInfo->qos ) ); /* Verify the received publish is for one of the topics that's been subscribed to. */ - for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { if( ( pxPublishInfo->topicNameLength == strlen( xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) ) && ( strncmp( xTopicFilterContext[ ulTopicCount ].pcTopicFilter, pxPublishInfo->pTopicName, pxPublishInfo->topicNameLength ) == 0 ) ) @@ -1090,7 +1090,7 @@ static void prvInitializeTopicBuffers( void ) int xCharactersWritten; - for(ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++) + for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ ) { /* Write topic strings into buffers. */ xCharactersWritten = snprintf( xTopicFilterContext[ ulTopicCount ].pcTopicFilter, diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj index fc9c9ca36..1ed1ae1e3 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj @@ -1,253 +1,253 @@ - - - - - Debug_with_Libslirp - Win32 - - - Debug_with_Libslirp - x64 - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {95746a42-54e8-4a6c-ae5d-ee5ce3b086bd} - MQTTPlainText - 10.0 - - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - true - - - true - - - false - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug_with_Libslirp + Win32 + + + Debug_with_Libslirp + x64 + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {95746a42-54e8-4a6c-ae5d-ee5ce3b086bd} + MQTTPlainText + 10.0 + + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + true + + + true + + + false + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj.filters index 05cb7c2cb..aad51bb98 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/MQTT_Plain_Text.vcxproj.filters @@ -1,105 +1,105 @@ - - - - - {a37e8d89-e525-4db2-91dd-f0b273a9554f} - - - {24b1b03b-ab28-43e4-bfb9-dae77a95e476} - - - {790aba1c-5d63-417a-89ec-9815b007861f} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {a1ecf026-d7ca-488c-bf1f-fd90a038a04a} - - - {19547751-b333-4f18-8e35-7ac02d769539} - - - {b62c0d53-8fc3-4298-af2c-140e565c2dd7} - - - {a1737e33-ccac-43bb-a7e7-9a5db76108a2} - - - {6fe32746-148f-41f4-9510-146909bc7065} - - - {756eaea5-c266-4321-98a2-68ca62af4639} - - - {d91e912e-60ec-4d8b-bf81-28712853dcef} - - - {c63ec790-9f1f-485b-9c8c-30727bdb38ab} - - - - - Source - - - Source - - - Libraries\coreMQTT - - - Libraries\coreMQTT - - - Libraries\coreMQTT - - - Libraries\Backoff Algorithm - - - Additional Network Transport Files\TCP Sockets Wrapper\ports - - - Additional Network Transport Files\PlaintextTransport - - - - - Header - - - Libraries\coreMQTT\include - - - Libraries\coreMQTT\include - - - Libraries\coreMQTT\include - - - Libraries\coreMQTT\include - - - Libraries\Backoff Algorithm\include - - - Config - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Additional Network Transport Files\PlaintextTransport\include - - + + + + + {a37e8d89-e525-4db2-91dd-f0b273a9554f} + + + {24b1b03b-ab28-43e4-bfb9-dae77a95e476} + + + {790aba1c-5d63-417a-89ec-9815b007861f} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {a1ecf026-d7ca-488c-bf1f-fd90a038a04a} + + + {19547751-b333-4f18-8e35-7ac02d769539} + + + {b62c0d53-8fc3-4298-af2c-140e565c2dd7} + + + {a1737e33-ccac-43bb-a7e7-9a5db76108a2} + + + {6fe32746-148f-41f4-9510-146909bc7065} + + + {756eaea5-c266-4321-98a2-68ca62af4639} + + + {d91e912e-60ec-4d8b-bf81-28712853dcef} + + + {c63ec790-9f1f-485b-9c8c-30727bdb38ab} + + + + + Source + + + Source + + + Libraries\coreMQTT + + + Libraries\coreMQTT + + + Libraries\coreMQTT + + + Libraries\Backoff Algorithm + + + Additional Network Transport Files\TCP Sockets Wrapper\ports + + + Additional Network Transport Files\PlaintextTransport + + + + + Header + + + Libraries\coreMQTT\include + + + Libraries\coreMQTT\include + + + Libraries\coreMQTT\include + + + Libraries\coreMQTT\include + + + Libraries\Backoff Algorithm\include + + + Config + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Additional Network Transport Files\PlaintextTransport\include + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/demo_config.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/demo_config.h index 5b5c42cb0..ec1dd63b6 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -103,7 +103,7 @@ extern void vLoggingPrintf( const char * pcFormatString, * In the Windows port, this stack only holds a structure. The actual * stack is created by an operating system thread. */ -#define democonfigDEMO_STACKSIZE configMINIMAL_STACK_SIZE +#define democonfigDEMO_STACKSIZE configMINIMAL_STACK_SIZE /** * @brief Size of the network buffer for MQTT packets. diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/mqtt_plain_text_demo.sln b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/mqtt_plain_text_demo.sln index 3979b820a..c57894f66 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/mqtt_plain_text_demo.sln +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Plain_Text/mqtt_plain_text_demo.sln @@ -1,134 +1,134 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Plain_Text", "MQTT_Plain_Text.vcxproj", "{95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{40EF7C88-97FB-485A-A7E0-9A53C66A1079}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 - Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 - Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|Win32.ActiveCfg = Debug|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|Win32.Build.0 = Debug|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|x64.ActiveCfg = Debug|x64 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|x64.Build.0 = Debug|x64 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|x86.ActiveCfg = Debug|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|x86.Build.0 = Debug|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|Win32.ActiveCfg = Release|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|Win32.Build.0 = Release|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|x64.ActiveCfg = Release|x64 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|x64.Build.0 = Release|x64 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|x86.ActiveCfg = Release|Win32 - {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {40EF7C88-97FB-485A-A7E0-9A53C66A1079} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {40EF7C88-97FB-485A-A7E0-9A53C66A1079} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {40EF7C88-97FB-485A-A7E0-9A53C66A1079} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {40EF7C88-97FB-485A-A7E0-9A53C66A1079} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {5F7B1074-CE74-4830-B363-0E4C8540F490} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Plain_Text", "MQTT_Plain_Text.vcxproj", "{95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{40EF7C88-97FB-485A-A7E0-9A53C66A1079}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 + Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 + Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|Win32.ActiveCfg = Debug|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|Win32.Build.0 = Debug|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|x64.ActiveCfg = Debug|x64 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|x64.Build.0 = Debug|x64 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|x86.ActiveCfg = Debug|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Debug|x86.Build.0 = Debug|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|Win32.ActiveCfg = Release|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|Win32.Build.0 = Release|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|x64.ActiveCfg = Release|x64 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|x64.Build.0 = Release|x64 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|x86.ActiveCfg = Release|Win32 + {95746A42-54E8-4A6C-AE5D-EE5CE3B086BD}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {40EF7C88-97FB-485A-A7E0-9A53C66A1079} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {40EF7C88-97FB-485A-A7E0-9A53C66A1079} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {40EF7C88-97FB-485A-A7E0-9A53C66A1079} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {40EF7C88-97FB-485A-A7E0-9A53C66A1079} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5F7B1074-CE74-4830-B363-0E4C8540F490} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/DemoTasks/SerializerMQTTExample.c b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/DemoTasks/SerializerMQTTExample.c index 1794ab87f..9652742d1 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/DemoTasks/SerializerMQTTExample.c +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/DemoTasks/SerializerMQTTExample.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj index 480bd0e6a..d2ed2f7d2 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj @@ -1,251 +1,251 @@ - - - - - Debug_with_Libslirp - Win32 - - - Debug_with_Libslirp - x64 - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {b7a01d2b-cf81-4a65-bc54-af2185f6e51a} - MQTTSerializer - 10.0 - - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - true - - - true - - - false - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - - - Console - true - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - - - Console - true - Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) - - - xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" -xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - - - {be362ac0-b10b-4276-b84e-6304652ba228} - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug_with_Libslirp + Win32 + + + Debug_with_Libslirp + x64 + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {b7a01d2b-cf81-4a65-bc54-af2185f6e51a} + MQTTSerializer + 10.0 + + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + true + + + true + + + false + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + + + Console + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + + + Console + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + xcopy /y /d "..\..\..\ThirdParty\glib\build\glib\glib-2.0-0.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\proxy-libintl\intl-8.dll" "$(OutDir)" +xcopy /y /d "..\..\..\ThirdParty\glib\build\subprojects\pcre2-10.42\pcre2-8-0.dll" "$(OutDir)" + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .\;..\Common;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + + + {be362ac0-b10b-4276-b84e-6304652ba228} + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj.filters b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj.filters index c399baa02..3d8d8c04f 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/MQTT_Serializer.vcxproj.filters @@ -1,99 +1,99 @@ - - - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {c63fcf3c-291e-4a43-8d51-b3b2088d3484} - - - {85ff296f-e223-414f-80cd-d87dc9259078} - - - {8a756be6-7242-4a34-9362-ef6e8ad35184} - - - {cb653e6c-88fe-4459-9f27-cff2d989a836} - - - {e3a50e05-5c8d-4781-8de1-280e54287e8f} - - - {988f1a57-3c63-4bf4-921a-3c2d6ccdef87} - - - {db5d7d6e-c204-4bac-8f70-e87544bab0a8} - - - {193af596-fbfc-4137-b379-86800ad349c7} - - - {0139998f-b0d7-4a3f-b8c9-1aaf280f4d67} - - - {523b14fc-53d8-4912-b0b4-b1b074028256} - - - {f209512b-d606-4c03-92dd-92a83de92f18} - - - - - Source - - - Source - - - Additional Libraries\coreMQTT - - - Additional Libraries\Backoff Algorithm - - - Additional Network Transport Files\TCP Sockets Wrapper\ports - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - - - Header - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\Backoff Algorithm\include - - - Config - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {c63fcf3c-291e-4a43-8d51-b3b2088d3484} + + + {85ff296f-e223-414f-80cd-d87dc9259078} + + + {8a756be6-7242-4a34-9362-ef6e8ad35184} + + + {cb653e6c-88fe-4459-9f27-cff2d989a836} + + + {e3a50e05-5c8d-4781-8de1-280e54287e8f} + + + {988f1a57-3c63-4bf4-921a-3c2d6ccdef87} + + + {db5d7d6e-c204-4bac-8f70-e87544bab0a8} + + + {193af596-fbfc-4137-b379-86800ad349c7} + + + {0139998f-b0d7-4a3f-b8c9-1aaf280f4d67} + + + {523b14fc-53d8-4912-b0b4-b1b074028256} + + + {f209512b-d606-4c03-92dd-92a83de92f18} + + + + + Source + + + Source + + + Additional Libraries\coreMQTT + + + Additional Libraries\Backoff Algorithm + + + Additional Network Transport Files\TCP Sockets Wrapper\ports + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + + + Header + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\Backoff Algorithm\include + + + Config + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/demo_config.h b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/demo_config.h index 6ed773e0a..bd23c72f4 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,7 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ diff --git a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/mqtt_serializer_demo.sln b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/mqtt_serializer_demo.sln index fe504e669..16a609a5c 100644 --- a/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/mqtt_serializer_demo.sln +++ b/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Serializer/mqtt_serializer_demo.sln @@ -1,134 +1,134 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32929.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Serializer", "MQTT_Serializer.vcxproj", "{B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{49B9A974-3D8D-4D3A-B007-D565A2C03509}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 - Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 - Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|Win32.ActiveCfg = Debug|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|Win32.Build.0 = Debug|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|x64.ActiveCfg = Debug|x64 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|x64.Build.0 = Debug|x64 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|x86.ActiveCfg = Debug|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|x86.Build.0 = Debug|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|Win32.ActiveCfg = Release|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|Win32.Build.0 = Release|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|x64.ActiveCfg = Release|x64 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|x64.Build.0 = Release|x64 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|x86.ActiveCfg = Release|Win32 - {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|x86.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 - {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 - {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 - {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C90E6CC5-818B-4C97-8876-0986D989387C} = {49B9A974-3D8D-4D3A-B007-D565A2C03509} - {72C209C4-49A4-4942-A201-44706C9D77EC} = {49B9A974-3D8D-4D3A-B007-D565A2C03509} - {BE362AC0-B10B-4276-B84E-6304652BA228} = {49B9A974-3D8D-4D3A-B007-D565A2C03509} - {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {49B9A974-3D8D-4D3A-B007-D565A2C03509} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {78C72B59-BC55-4BF6-B64B-DE44AC17E01A} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32929.386 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MQTT_Serializer", "MQTT_Serializer.vcxproj", "{B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS+TCP", "..\..\..\VisualStudio_StaticProjects\FreeRTOS+TCP\FreeRTOS+TCP.vcxproj", "{C90E6CC5-818B-4C97-8876-0986D989387C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeRTOS-Kernel", "..\..\..\VisualStudio_StaticProjects\FreeRTOS-Kernel\FreeRTOS-Kernel.vcxproj", "{72C209C4-49A4-4942-A201-44706C9D77EC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "..\..\..\VisualStudio_StaticProjects\Logging\Logging.vcxproj", "{BE362AC0-B10B-4276-B84E-6304652BA228}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MbedTLS", "..\..\..\VisualStudio_StaticProjects\MbedTLS\MbedTLS.vcxproj", "{E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Statically Linked Libraries", "Statically Linked Libraries", "{49B9A974-3D8D-4D3A-B007-D565A2C03509}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_with_Libslirp|Win32 = Debug_with_Libslirp|Win32 + Debug_with_Libslirp|x64 = Debug_with_Libslirp|x64 + Debug_with_Libslirp|x86 = Debug_with_Libslirp|x86 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|Win32.ActiveCfg = Debug|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|Win32.Build.0 = Debug|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|x64.ActiveCfg = Debug|x64 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|x64.Build.0 = Debug|x64 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|x86.ActiveCfg = Debug|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Debug|x86.Build.0 = Debug|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|Win32.ActiveCfg = Release|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|Win32.Build.0 = Release|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|x64.ActiveCfg = Release|x64 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|x64.Build.0 = Release|x64 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|x86.ActiveCfg = Release|Win32 + {B7A01D2B-CF81-4A65-BC54-AF2185F6E51A}.Release|x86.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|Win32.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.ActiveCfg = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x64.Build.0 = Debug|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.ActiveCfg = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Debug|x86.Build.0 = Debug|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|Win32.Build.0 = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.ActiveCfg = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x64.Build.0 = Release|x64 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.ActiveCfg = Release|Win32 + {C90E6CC5-818B-4C97-8876-0986D989387C}.Release|x86.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|Win32.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.ActiveCfg = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x64.Build.0 = Debug|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.ActiveCfg = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Debug|x86.Build.0 = Debug|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|Win32.Build.0 = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.ActiveCfg = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x64.Build.0 = Release|x64 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.ActiveCfg = Release|Win32 + {72C209C4-49A4-4942-A201-44706C9D77EC}.Release|x86.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|Win32.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.ActiveCfg = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x64.Build.0 = Debug|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.ActiveCfg = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Debug|x86.Build.0 = Debug|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|Win32.Build.0 = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.ActiveCfg = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x64.Build.0 = Release|x64 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.ActiveCfg = Release|Win32 + {BE362AC0-B10B-4276-B84E-6304652BA228}.Release|x86.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|Win32.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.ActiveCfg = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x64.Build.0 = Debug_with_Libslirp|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.ActiveCfg = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug_with_Libslirp|x86.Build.0 = Debug_with_Libslirp|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|Win32.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.ActiveCfg = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x64.Build.0 = Debug|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.ActiveCfg = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Debug|x86.Build.0 = Debug|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|Win32.Build.0 = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.ActiveCfg = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x64.Build.0 = Release|x64 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.ActiveCfg = Release|Win32 + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C90E6CC5-818B-4C97-8876-0986D989387C} = {49B9A974-3D8D-4D3A-B007-D565A2C03509} + {72C209C4-49A4-4942-A201-44706C9D77EC} = {49B9A974-3D8D-4D3A-B007-D565A2C03509} + {BE362AC0-B10B-4276-B84E-6304652BA228} = {49B9A974-3D8D-4D3A-B007-D565A2C03509} + {E1016F3E-94E9-4864-9FD8-1D7C1FEFBFD7} = {49B9A974-3D8D-4D3A-B007-D565A2C03509} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {78C72B59-BC55-4BF6-B64B-DE44AC17E01A} + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/PKCS11_Mqtt_MutualAuthDemo.c b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/PKCS11_Mqtt_MutualAuthDemo.c index 001da9a21..2ecde1989 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/PKCS11_Mqtt_MutualAuthDemo.c +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/PKCS11_Mqtt_MutualAuthDemo.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/README.md b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/README.md index 8c8bc772f..e718c3f62 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/README.md +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/README.md @@ -7,7 +7,7 @@ To do this, use either the python script pkcs11_demo_setup.py or openssl. If you choose to use the python script, pass in the absolute path of your PEM files. If you are to use openssl, the following commands should be sufficient in converting from PEM to DER. -Certificate conversion: +Certificate conversion: openssl x509 -outform der -in $CERT_IN_NAME -out $CERT_OUT_NAME Key conversion: diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.sln b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.sln index 166373043..293f27e98 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.sln +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj index f989b3c6c..d043acf39 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj @@ -1,208 +1,208 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {382dc80f-e278-4bc9-9db6-59014486da0f} - corePKCS11_MQTT_Mutual_Auth - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - $(VC_IncludePath);$(WindowsSDK_IncludePath);.;..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\Source\Application-Protocols\network_transport;..\..\Source\Utilities\backoff_algorithm\source\include;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;$(IncludePath) - - - $(VC_IncludePath);$(WindowsSDK_IncludePath);.;..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\Source\Application-Protocols\network_transport;..\..\Source\Utilities\backoff_algorithm\source\include;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;$(IncludePath) - - - $(VC_IncludePath);$(WindowsSDK_IncludePath);.;..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\Source\Application-Protocols\network_transport;..\..\Source\Utilities\backoff_algorithm\source\include;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;$(IncludePath) - - - $(VC_IncludePath);$(WindowsSDK_IncludePath);.;..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\Source\Application-Protocols\network_transport;..\..\Source\Utilities\backoff_algorithm\source\include;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;$(IncludePath) - - - false - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .;..\Common;DemoTasks\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - true - - - Console - true - %(AdditionalDependencies) - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .;..\Common;DemoTasks\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - true - - - Console - true - true - true - %(AdditionalDependencies) - - - - - Level3 - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .;..\Common;DemoTasks\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - true - - - Console - true - %(AdditionalDependencies) - - - - - Level3 - true - true - true - MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - .;..\Common;DemoTasks\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) - true - - - Console - true - true - true - %(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {19f0ff1a-3368-491a-9932-a2f089508f51} - - - {c90e6cc5-818b-4c97-8876-0986d989387c} - false - false - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - false - false - - - {be362ac0-b10b-4276-b84e-6304652ba228} - false - - - {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {382dc80f-e278-4bc9-9db6-59014486da0f} + corePKCS11_MQTT_Mutual_Auth + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + $(VC_IncludePath);$(WindowsSDK_IncludePath);.;..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\Source\Application-Protocols\network_transport;..\..\Source\Utilities\backoff_algorithm\source\include;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;$(IncludePath) + + + $(VC_IncludePath);$(WindowsSDK_IncludePath);.;..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\Source\Application-Protocols\network_transport;..\..\Source\Utilities\backoff_algorithm\source\include;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;$(IncludePath) + + + $(VC_IncludePath);$(WindowsSDK_IncludePath);.;..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\Source\Application-Protocols\network_transport;..\..\Source\Utilities\backoff_algorithm\source\include;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;$(IncludePath) + + + $(VC_IncludePath);$(WindowsSDK_IncludePath);.;..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\Source\Application-Protocols\network_transport;..\..\Source\Utilities\backoff_algorithm\source\include;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;$(IncludePath) + + + false + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .;..\Common;DemoTasks\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + true + + + Console + true + %(AdditionalDependencies) + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .;..\Common;DemoTasks\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + true + + + Console + true + true + true + %(AdditionalDependencies) + + + + + Level3 + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .;..\Common;DemoTasks\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + true + + + Console + true + %(AdditionalDependencies) + + + + + Level3 + true + true + true + MBEDTLS_CONFIG_FILE="mbedtls_config_v3.2.1.h";_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + .;..\Common;DemoTasks\include;..\..\..\Source\Application-Protocols\network_transport\tcp_sockets_wrapper\include;..\..\..\Source\Application-Protocols\network_transport;..\..\..\Source\Utilities\backoff_algorithm\source\include;%(AdditionalIncludeDirectories) + true + + + Console + true + true + true + %(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {19f0ff1a-3368-491a-9932-a2f089508f51} + + + {c90e6cc5-818b-4c97-8876-0986d989387c} + false + false + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + false + false + + + {be362ac0-b10b-4276-b84e-6304652ba228} + false + + + {e1016f3e-94e9-4864-9fd8-1d7c1fefbfd7} + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj.filters b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj.filters index 22bf9c090..0cd220a29 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/corePKCS11_MQTT_Mutual_Auth.vcxproj.filters @@ -1,114 +1,114 @@ - - - - - {e00920f1-720e-47ca-bc96-560169f2449a} - - - {5cef0fbc-ffb0-4466-9b74-4d8dcc8ecec9} - - - {0034e320-851e-4e07-9d64-d77eea7aeff4} - - - {d940fb10-f2ca-4a5e-8eb6-c923966d27b5} - - - {1f476ab8-0e55-4104-8b14-406c207a7bd0} - - - {9ba295d2-b09d-4f81-a555-f1f147331f54} - - - {4c489f8b-5912-4146-8581-7971a075425a} - - - {a442e1bd-e141-45a4-860d-a8eccab1b8c2} - - - {c69eabd6-7eed-4959-9351-41b8c3b731b8} - - - {64a78119-97f6-4252-b793-87cb6e7902d1} - - - {d970b960-e49e-47dc-a92a-dbbb2b549448} - - - {adfc7ae7-9377-42fa-8bf3-b2d80b42e0d6} - - - {c9148635-f681-48fe-97e7-7ac76048db9f} - - - - - Additional Libraries\backoff_algorithm - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Libraries\coreMQTT - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Additional Network Transport Files\TCP Sockets Wrapper\ports - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport - - - Source - - - Source - - - - - Additional Libraries\backoff_algorithm - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Libraries\coreMQTT\include - - - Additional Network Transport Files\TCP Sockets Wrapper\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include - - - Header - - - Config - - + + + + + {e00920f1-720e-47ca-bc96-560169f2449a} + + + {5cef0fbc-ffb0-4466-9b74-4d8dcc8ecec9} + + + {0034e320-851e-4e07-9d64-d77eea7aeff4} + + + {d940fb10-f2ca-4a5e-8eb6-c923966d27b5} + + + {1f476ab8-0e55-4104-8b14-406c207a7bd0} + + + {9ba295d2-b09d-4f81-a555-f1f147331f54} + + + {4c489f8b-5912-4146-8581-7971a075425a} + + + {a442e1bd-e141-45a4-860d-a8eccab1b8c2} + + + {c69eabd6-7eed-4959-9351-41b8c3b731b8} + + + {64a78119-97f6-4252-b793-87cb6e7902d1} + + + {d970b960-e49e-47dc-a92a-dbbb2b549448} + + + {adfc7ae7-9377-42fa-8bf3-b2d80b42e0d6} + + + {c9148635-f681-48fe-97e7-7ac76048db9f} + + + + + Additional Libraries\backoff_algorithm + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Libraries\coreMQTT + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Additional Network Transport Files\TCP Sockets Wrapper\ports + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport + + + Source + + + Source + + + + + Additional Libraries\backoff_algorithm + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Libraries\coreMQTT\include + + + Additional Network Transport Files\TCP Sockets Wrapper\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Additional Network Transport Files\TCP Sockets Wrapper + MbedTLS Transport\include + + + Header + + + Config + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/core_mqtt_config.h b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/core_mqtt_config.h index e763c5b10..5f293106c 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/core_mqtt_config.h +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/core_mqtt_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,8 +20,10 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS + * */ + #ifndef CORE_MQTT_CONFIG_H #define CORE_MQTT_CONFIG_H diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/demo_config.h b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/demo_config.h index 4fe7257b7..52e31d7bf 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/demo_config.h +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,7 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ diff --git a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/main.c index eb044083f..5ac4da7cc 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/corePKCS11_MQTT_Mutual_Auth_Windows_Simulator/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -81,4 +81,3 @@ int main( void ) } } /*-----------------------------------------------------------*/ - diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/CorePKCS11_Demos.sln b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/CorePKCS11_Demos.sln index 0ecb18988..0c081943e 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/CorePKCS11_Demos.sln +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/CorePKCS11_Demos.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/CorePKCS11_Demos.vcxproj.filters b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/CorePKCS11_Demos.vcxproj.filters index 96ff1c399..0531971f6 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/CorePKCS11_Demos.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/CorePKCS11_Demos.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/demo_helpers.c b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/demo_helpers.c index 9188c847a..ae54f4601 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/demo_helpers.c +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/demo_helpers.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/demo_helpers.h b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/demo_helpers.h index aa23ea11a..0c41b10e4 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/demo_helpers.h +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/demo_helpers.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/management_and_rng.c b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/management_and_rng.c index 3f782e667..55c38eab8 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/management_and_rng.c +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/management_and_rng.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/mechanisms_and_digests.c b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/mechanisms_and_digests.c index 920731a12..527620ad9 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/mechanisms_and_digests.c +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/mechanisms_and_digests.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/objects.c b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/objects.c index 4d2075a96..d6d388732 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/objects.c +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/objects.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/pkcs11_demos.h b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/pkcs11_demos.h index 166896edf..651040f10 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/pkcs11_demos.h +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/pkcs11_demos.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -44,7 +44,7 @@ void vPKCS11MechanismsAndDigestDemo( void ); */ void vPKCS11ObjectDemo( void ); -/* Prototype for the PKCS #11 "Sign and Verify" demo. This demo covers how +/* Prototype for the PKCS #11 "Sign and Verify" demo. This demo covers how * PKCS #11 can be used to sign a message, and verify the integrity of a message * using private and public keys. * diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/sign_and_verify.c b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/sign_and_verify.c index efb93e751..09acf9e44 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/sign_and_verify.c +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/examples/sign_and_verify.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/main.c index 1161abd83..06be93293 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -79,11 +79,11 @@ int main( void ) /* Create the SNTP client task that is responsible for synchronizing system time with the time servers * periodically. This is created as a high priority task to keep the SNTP client operation unhindered. */ - xTaskCreate( prvPKCS11DemoTask, /* Function that implements the task. */ - "PKCS11 Demo", /* Text name for the task - only used for debugging. */ - configPKCS11_DEMO_STACK_SIZE, /* Size of stack (in words, not bytes) to allocate for the task. */ - NULL, /* Task parameter - not used in this case. */ - configMAX_PRIORITIES - 1, /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */ + xTaskCreate( prvPKCS11DemoTask, /* Function that implements the task. */ + "PKCS11 Demo", /* Text name for the task - only used for debugging. */ + configPKCS11_DEMO_STACK_SIZE, /* Size of stack (in words, not bytes) to allocate for the task. */ + NULL, /* Task parameter - not used in this case. */ + configMAX_PRIORITIES - 1, /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */ NULL ); /* Start the RTOS scheduler. */ diff --git a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/pkcs11_demo_config.h b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/pkcs11_demo_config.h index e44c6e00a..52648c382 100644 --- a/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/pkcs11_demo_config.h +++ b/FreeRTOS-Plus/Demo/corePKCS11_Windows_Simulator/pkcs11_demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/SNTPClientTask.c b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/SNTPClientTask.c index 0a11d6341..77a8ea09d 100644 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/SNTPClientTask.c +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/SNTPClientTask.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -799,10 +799,10 @@ static int32_t UdpTransport_Recv( NetworkContext_t * pNetworkContext, * the server. */ #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) if( ( bytesReceived > 0 ) && ( ( FreeRTOS_ntohl( sourceAddress.sin_address.ulIP_IPv4 ) != serverAddr ) || - ( FreeRTOS_ntohs( sourceAddress.sin_port ) != serverPort ) ) ) + ( FreeRTOS_ntohs( sourceAddress.sin_port ) != serverPort ) ) ) #else if( ( bytesReceived > 0 ) && ( ( FreeRTOS_ntohl( sourceAddress.sin_addr ) != serverAddr ) || - ( FreeRTOS_ntohs( sourceAddress.sin_port ) != serverPort ) ) ) + ( FreeRTOS_ntohs( sourceAddress.sin_port ) != serverPort ) ) ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ { bytesReceived = 0; @@ -811,20 +811,20 @@ static int32_t UdpTransport_Recv( NetworkContext_t * pNetworkContext, /* Convert the IP address of the sender's address to string for logging. */ char stringAddr[ 16 ]; - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) { FreeRTOS_inet_ntoa( sourceAddress.sin_address.ulIP_IPv4, stringAddr ); } - #else + #else { FreeRTOS_inet_ntoa( sourceAddress.sin_addr, stringAddr ); } - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ - /* Log about reception of packet from unexpected sender. */ - LogWarn( ( "Received UDP packet from unexpected source: Addr=%s Port=%u", - stringAddr, FreeRTOS_ntohs( sourceAddress.sin_port ) ) ); - #endif + /* Log about reception of packet from unexpected sender. */ + LogWarn( ( "Received UDP packet from unexpected source: Addr=%s Port=%u", + stringAddr, FreeRTOS_ntohs( sourceAddress.sin_port ) ) ); + #endif /* if defined( LIBRARY_LOG_LEVEL ) && ( LIBRARY_LOG_LEVEL != LOG_NONE ) */ } /* Translate the return code of timeout to the UDP transport interface expected diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/SampleAppTask.c b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/SampleAppTask.c index 862aab7d9..e6d06062a 100644 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/SampleAppTask.c +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/SampleAppTask.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/common_demo_include.h b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/common_demo_include.h index 00fbb9ed8..52ea6d6d2 100644 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/common_demo_include.h +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/common_demo_include.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/coreSNTP_Demo.vcxproj.filters b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/coreSNTP_Demo.vcxproj.filters index 5a2bd1137..763d02de3 100644 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/coreSNTP_Demo.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/coreSNTP_Demo.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_sntp_config.h b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_sntp_config.h index a3bdd2fc2..90f0e7851 100644 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_sntp_config.h +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_sntp_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_sntp_demo.sln b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_sntp_demo.sln index 8505ef263..b02339b4a 100644 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_sntp_demo.sln +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_sntp_demo.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33027.164 diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/demo_config.h b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/demo_config.h index db1ff7f77..c6e3a5de5 100644 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/demo_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/main.c index 29d8071c0..b65211219 100644 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -66,7 +66,7 @@ int main( void ) /* Create the task that represents an application needing wall-clock time. */ xTaskCreate( sampleAppTask, /* Function that implements the task. */ - "SampleAppTask", /* Text name for the task - only used for debugging. */ + "SampleAppTask", /* Text name for the task - only used for debugging. */ democonfigDEMO_STACKSIZE, /* Size of stack (in words, not bytes) to allocate for the task. */ NULL, /* Task parameter - not used in this case. */ tskIDLE_PRIORITY, /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */ diff --git a/FreeRTOS-Plus/Demo/readme.txt b/FreeRTOS-Plus/Demo/readme.txt index c64f142b3..5064d624b 100644 --- a/FreeRTOS-Plus/Demo/readme.txt +++ b/FreeRTOS-Plus/Demo/readme.txt @@ -1,9 +1,9 @@ -Directories: - -+ The FreeRTOS-Plus/Demo directory contains a demo application for every most of - the FreeRTOS+ components. Lots of the demo applications use the FreeRTOS - Windows simulator for easy evaluation. Be aware that FreeRTOS is much slower - and not deterministic when executed in a simulated environment. - -+ See http://www.freertos.org/plus - +Directories: + ++ The FreeRTOS-Plus/Demo directory contains a demo application for every most of + the FreeRTOS+ components. Lots of the demo applications use the FreeRTOS + Windows simulator for easy evaluation. Be aware that FreeRTOS is much slower + and not deterministic when executed in a simulated environment. + ++ See http://www.freertos.org/plus + diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_bio_tcp_sockets_wrapper.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_bio_tcp_sockets_wrapper.c index 71349ee30..f3f577b21 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_bio_tcp_sockets_wrapper.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_bio_tcp_sockets_wrapper.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_bio_tcp_sockets_wrapper.h b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_bio_tcp_sockets_wrapper.h index 9b2957f6e..c93396525 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_bio_tcp_sockets_wrapper.h +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_bio_tcp_sockets_wrapper.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_pk_pkcs11.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_pk_pkcs11.c index 873cafb43..373a831c5 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_pk_pkcs11.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_pk_pkcs11.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_pkcs11.h b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_pkcs11.h index beb90a082..289184d05 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_pkcs11.h +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_pkcs11.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_rng_pkcs11.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_rng_pkcs11.c index 2bfdd5bec..04e877f73 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_rng_pkcs11.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/mbedtls_rng_pkcs11.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/include/tcp_sockets_wrapper.h b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/include/tcp_sockets_wrapper.h index 2d4072ba8..5d8f8da17 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/include/tcp_sockets_wrapper.h +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/include/tcp_sockets_wrapper.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/cellular/tcp_sockets_wrapper.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/cellular/tcp_sockets_wrapper.c index b7467ce15..367828ca9 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/cellular/tcp_sockets_wrapper.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/cellular/tcp_sockets_wrapper.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -538,7 +538,7 @@ static BaseType_t prvCellularSocketRegisterCallback( CellularSocketHandle_t cell if( socketStatus != CELLULAR_SUCCESS ) { - LogError( ( "Failed to SocketRegisterSocketOpenCallbac. Socket status %d.", socketStatus ) ); + LogError( ( "Failed to SocketRegisterSocketOpenCallback. Socket status %d.", socketStatus ) ); retRegCallback = TCP_SOCKETS_ERRNO_ERROR; } } diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/sockets_wrapper.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/sockets_wrapper.c index e387d7312..d630fe753 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/sockets_wrapper.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/sockets_wrapper.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -93,15 +93,17 @@ BaseType_t Sockets_Connect( Socket_t * pTcpSocket, serverAddress.sin_port = FreeRTOS_htons( port ); serverAddress.sin_len = ( uint8_t ) sizeof( serverAddress ); - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - serverAddress.sin_address.ulIP_IPv4 = ( uint32_t ) FreeRTOS_gethostbyname( pHostName ); - /* Check for errors from DNS lookup. */ - if( serverAddress.sin_address.ulIP_IPv4 == 0U ) - #else - serverAddress.sin_addr = ( uint32_t ) FreeRTOS_gethostbyname( pHostName ); - /* Check for errors from DNS lookup. */ - if( serverAddress.sin_addr == 0U ) - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + serverAddress.sin_address.ulIP_IPv4 = ( uint32_t ) FreeRTOS_gethostbyname( pHostName ); + + /* Check for errors from DNS lookup. */ + if( serverAddress.sin_address.ulIP_IPv4 == 0U ) + #else + serverAddress.sin_addr = ( uint32_t ) FreeRTOS_gethostbyname( pHostName ); + + /* Check for errors from DNS lookup. */ + if( serverAddress.sin_addr == 0U ) + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ { LogError( ( "Failed to connect to server: DNS resolution failed: Hostname=%s.", diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/sockets_wrapper.h b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/sockets_wrapper.h index 0ec3e9009..b7aea2a7c 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/sockets_wrapper.h +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/sockets_wrapper.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -37,7 +37,7 @@ #include "FreeRTOS_Sockets.h" #include "FreeRTOS_DNS.h" -#define SOCKETS_INVALID_SOCKET ( ( Socket_t ) ~0U ) +#define SOCKETS_INVALID_SOCKET ( ( Socket_t ) ~0U ) /** * @brief Establish a connection to server. diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/tcp_sockets_wrapper.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/tcp_sockets_wrapper.c index 393ea2e2b..c02eae41c 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/tcp_sockets_wrapper.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/tcp_sockets_wrapper/ports/freertos_plus_tcp/tcp_sockets_wrapper.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -117,15 +117,17 @@ BaseType_t TCP_Sockets_Connect( Socket_t * pTcpSocket, serverAddress.sin_port = FreeRTOS_htons( port ); serverAddress.sin_len = ( uint8_t ) sizeof( serverAddress ); -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - serverAddress.sin_address.ulIP_IPv4 = ( uint32_t ) FreeRTOS_gethostbyname( pHostName ); - /* Check for errors from DNS lookup. */ - if( serverAddress.sin_address.ulIP_IPv4 == 0U ) -#else - serverAddress.sin_addr = ( uint32_t ) FreeRTOS_gethostbyname( pHostName ); - /* Check for errors from DNS lookup. */ - if( serverAddress.sin_addr == 0U ) -#endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + serverAddress.sin_address.ulIP_IPv4 = ( uint32_t ) FreeRTOS_gethostbyname( pHostName ); + + /* Check for errors from DNS lookup. */ + if( serverAddress.sin_address.ulIP_IPv4 == 0U ) + #else + serverAddress.sin_addr = ( uint32_t ) FreeRTOS_gethostbyname( pHostName ); + + /* Check for errors from DNS lookup. */ + if( serverAddress.sin_addr == 0U ) + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ { LogError( ( "Failed to connect to server: DNS resolution failed: Hostname=%s.", diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls.c index 69dea5db0..0b8008e34 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -210,12 +210,12 @@ static TlsTransportStatus_t tlsHandshake( NetworkContext_t * pNetworkContext, * @brief Initialize mbedTLS. * * @param[out] entropyContext mbed TLS entropy context for generation of random numbers. - * @param[out] ctrDrgbContext mbed TLS CTR DRBG context for generation of random numbers. + * @param[out] ctrDrbgContext mbed TLS CTR DRBG context for generation of random numbers. * * @return #TLS_TRANSPORT_SUCCESS, or #TLS_TRANSPORT_INTERNAL_ERROR. */ static TlsTransportStatus_t initMbedtls( mbedtls_entropy_context * pEntropyContext, - mbedtls_ctr_drbg_context * pCtrDrgbContext ); + mbedtls_ctr_drbg_context * pCtrDrbgContext ); /*-----------------------------------------------------------*/ @@ -240,7 +240,7 @@ static void sslContextFree( SSLContext_t * pSslContext ) mbedtls_x509_crt_free( &( pSslContext->clientCert ) ); mbedtls_pk_free( &( pSslContext->privKey ) ); mbedtls_entropy_free( &( pSslContext->entropyContext ) ); - mbedtls_ctr_drbg_free( &( pSslContext->ctrDrgbContext ) ); + mbedtls_ctr_drbg_free( &( pSslContext->ctrDrbgContext ) ); mbedtls_ssl_config_free( &( pSslContext->config ) ); } /*-----------------------------------------------------------*/ @@ -321,7 +321,7 @@ static int32_t setPrivateKey( SSLContext_t * pSslContext, privateKeySize, NULL, 0, mbedtls_ctr_drbg_random, - &( pSslContext->ctrDrgbContext ) ); + &( pSslContext->ctrDrbgContext ) ); #endif /* if MBEDTLS_VERSION_NUMBER < 0x03000000 */ if( mbedtlsError != 0 ) @@ -351,7 +351,7 @@ static int32_t setCredentials( SSLContext_t * pSslContext, MBEDTLS_SSL_VERIFY_REQUIRED ); mbedtls_ssl_conf_rng( &( pSslContext->config ), mbedtls_ctr_drbg_random, - &( pSslContext->ctrDrgbContext ) ); + &( pSslContext->ctrDrbgContext ) ); mbedtls_ssl_conf_cert_profile( &( pSslContext->config ), &( pSslContext->certProfile ) ); @@ -429,6 +429,7 @@ static void setOptionalConfigurations( SSLContext_t * pSslContext, /* Set Maximum Fragment Length if enabled. */ #ifdef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + /* Enable the max fragment extension. 4096 bytes is currently the largest fragment size permitted. * See RFC 8449 https://tools.ietf.org/html/rfc8449 for more information. * @@ -574,7 +575,7 @@ static TlsTransportStatus_t tlsHandshake( NetworkContext_t * pNetworkContext, /*-----------------------------------------------------------*/ static TlsTransportStatus_t initMbedtls( mbedtls_entropy_context * pEntropyContext, - mbedtls_ctr_drbg_context * pCtrDrgbContext ) + mbedtls_ctr_drbg_context * pCtrDrbgContext ) { TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS; int32_t mbedtlsError = 0; @@ -586,7 +587,7 @@ static TlsTransportStatus_t initMbedtls( mbedtls_entropy_context * pEntropyConte /* Initialize contexts for random number generation. */ mbedtls_entropy_init( pEntropyContext ); - mbedtls_ctr_drbg_init( pCtrDrgbContext ); + mbedtls_ctr_drbg_init( pCtrDrbgContext ); if( mbedtlsError != 0 ) { @@ -599,7 +600,7 @@ static TlsTransportStatus_t initMbedtls( mbedtls_entropy_context * pEntropyConte if( returnStatus == TLS_TRANSPORT_SUCCESS ) { /* Seed the random number generator. */ - mbedtlsError = mbedtls_ctr_drbg_seed( pCtrDrgbContext, + mbedtlsError = mbedtls_ctr_drbg_seed( pCtrDrbgContext, mbedtls_entropy_func, pEntropyContext, NULL, @@ -686,7 +687,7 @@ TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext, isSocketConnected = pdTRUE; returnStatus = initMbedtls( &( pTlsTransportParams->sslContext.entropyContext ), - &( pTlsTransportParams->sslContext.ctrDrgbContext ) ); + &( pTlsTransportParams->sslContext.ctrDrbgContext ) ); } /* Initialize TLS contexts and set credentials. */ diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls.h b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls.h index 8d4845973..99e1b66e3 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls.h +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -97,7 +97,7 @@ typedef struct SSLContext mbedtls_x509_crt clientCert; /**< @brief Client certificate context. */ mbedtls_pk_context privKey; /**< @brief Client private key context. */ mbedtls_entropy_context entropyContext; /**< @brief Entropy context for random number generation. */ - mbedtls_ctr_drbg_context ctrDrgbContext; /**< @brief CTR DRBG context for random number generation. */ + mbedtls_ctr_drbg_context ctrDrbgContext; /**< @brief CTR DRBG context for random number generation. */ } SSLContext_t; /** diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls_pkcs11.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls_pkcs11.c index 009edb5d9..01342eb0c 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls_pkcs11.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls_pkcs11.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls_pkcs11.h b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls_pkcs11.h index e2435ebae..27d1b0948 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls_pkcs11.h +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_mbedtls_pkcs11.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_plaintext.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_plaintext.c index 0245bb0fa..e0526e522 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_plaintext.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_plaintext.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_plaintext.h b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_plaintext.h index ce1235155..14008d518 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_plaintext.h +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_plaintext.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -118,7 +118,7 @@ PlaintextTransportStatus_t Plaintext_FreeRTOS_Disconnect( const NetworkContext_t /** * @brief Receives data from an established TCP connection. - * + * * @note When the number of bytes requested is 1, the TCP socket's Rx stream * is checked for available bytes to read. If there are none, this function * immediately returns 0 without blocking. diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_wolfSSL.c b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_wolfSSL.c index b513ce49e..847dcf038 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_wolfSSL.c +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_wolfSSL.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_wolfSSL.h b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_wolfSSL.h index 50a4d319e..ee26ff2bb 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_wolfSSL.h +++ b/FreeRTOS-Plus/Source/Application-Protocols/network_transport/transport_wolfSSL.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -71,8 +71,8 @@ */ typedef struct SSLContext { - WOLFSSL_CTX* ctx; /**< @brief wolfSSL context */ - WOLFSSL* ssl; /**< @brief wolfSSL ssl session context */ + WOLFSSL_CTX * ctx; /**< @brief wolfSSL context */ + WOLFSSL * ssl; /**< @brief wolfSSL ssl session context */ } SSLContext_t; /** diff --git a/FreeRTOS-Plus/Source/Application-Protocols/readme.txt b/FreeRTOS-Plus/Source/Application-Protocols/readme.txt index e6749f1fc..7cd7d6245 100644 --- a/FreeRTOS-Plus/Source/Application-Protocols/readme.txt +++ b/FreeRTOS-Plus/Source/Application-Protocols/readme.txt @@ -6,10 +6,10 @@ the same transport interface definition. Directories: -+ coreMQTT contains the implementation of the coreMQTT library. ++ coreMQTT contains the implementation of the coreMQTT library. + coreMQTT-Agent contains the implementation of the coreMQTT Agent library. + coreHTTP contains the implementation of the coreHTTP library. + coreSNTP contains the implementation of the coreSNTP library. -+ network_transport contains multiple implementations for the transport interface. ++ network_transport contains multiple implementations for the transport interface. For more details on the above libraries, see: https://www.freertos.org/application-protocols.html. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.c index b8825f500..783ed3b2e 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.c @@ -1,386 +1,395 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* Standard includes. */ -#include -#include - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* Utils includes. */ -#include "FreeRTOS_CLI.h" - -/* If the application writer needs to place the buffer used by the CLI at a -fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in -FreeRTOSConfig.h, then declare an array with the following name and size in -one of the application files: - char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ]; -*/ -#ifndef configAPPLICATION_PROVIDES_cOutputBuffer - #define configAPPLICATION_PROVIDES_cOutputBuffer 0 -#endif - -/* - * Register the command passed in using the pxCommandToRegister parameter - * and using pxCliDefinitionListItemBuffer as the memory for command line - * list items. Registering a command adds the command to the list of - * commands that are handled by the command interpreter. Once a command - * has been registered it can be executed from the command line. - */ -static void prvRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister, - CLI_Definition_List_Item_t * pxCliDefinitionListItemBuffer ); - -/* - * The callback function that is executed when "help" is entered. This is the - * only default command that is always present. - */ -static BaseType_t prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* - * Return the number of parameters that follow the command name. - */ -static int8_t prvGetNumberOfParameters( const char *pcCommandString ); - -/* The definition of the "help" command. This command is always at the front -of the list of registered commands. */ -static const CLI_Command_Definition_t xHelpCommand = -{ - "help", - "\r\nhelp:\r\n Lists all the registered commands\r\n\r\n", - prvHelpCommand, - 0 -}; - -/* The definition of the list of commands. Commands that are registered are -added to this list. */ -static CLI_Definition_List_Item_t xRegisteredCommands = -{ - &xHelpCommand, /* The first command in the list is always the help command, defined in this file. */ - NULL /* The next pointer is initialised to NULL, as there are no other registered commands yet. */ -}; - -/* A buffer into which command outputs can be written is declared here, rather -than in the command console implementation, to allow multiple command consoles -to share the same buffer. For example, an application may allow access to the -command interpreter by UART and by Ethernet. Sharing a buffer is done purely -to save RAM. Note, however, that the command console itself is not re-entrant, -so only one command interpreter interface can be used at any one time. For that -reason, no attempt at providing mutual exclusion to the cOutputBuffer array is -attempted. - -configAPPLICATION_PROVIDES_cOutputBuffer is provided to allow the application -writer to provide their own cOutputBuffer declaration in cases where the -buffer needs to be placed at a fixed address (rather than by the linker). */ -#if( configAPPLICATION_PROVIDES_cOutputBuffer == 0 ) - static char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ]; -#else - extern char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ]; -#endif - - -/*-----------------------------------------------------------*/ - -#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - - BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister ) - { - BaseType_t xReturn = pdFAIL; - CLI_Definition_List_Item_t *pxNewListItem; - - /* Check the parameter is not NULL. */ - configASSERT( pxCommandToRegister != NULL ); - - /* Create a new list item that will reference the command being registered. */ - pxNewListItem = ( CLI_Definition_List_Item_t * ) pvPortMalloc( sizeof( CLI_Definition_List_Item_t ) ); - configASSERT( pxNewListItem != NULL ); - - if( pxNewListItem != NULL ) - { - prvRegisterCommand( pxCommandToRegister, pxNewListItem ); - xReturn = pdPASS; - } - - return xReturn; - } - -#endif /* #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ -/*-----------------------------------------------------------*/ - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - - BaseType_t FreeRTOS_CLIRegisterCommandStatic( const CLI_Command_Definition_t * const pxCommandToRegister, - CLI_Definition_List_Item_t * pxCliDefinitionListItemBuffer ) - { - /* Check the parameters are not NULL. */ - configASSERT( pxCommandToRegister != NULL ); - configASSERT( pxCliDefinitionListItemBuffer != NULL ); - - prvRegisterCommand( pxCommandToRegister, pxCliDefinitionListItemBuffer ); - - return pdPASS; - } - -#endif /* #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ -/*-----------------------------------------------------------*/ - -BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, char * pcWriteBuffer, size_t xWriteBufferLen ) -{ -static const CLI_Definition_List_Item_t *pxCommand = NULL; -BaseType_t xReturn = pdTRUE; -const char *pcRegisteredCommandString; -size_t xCommandStringLength; - - /* Note: This function is not re-entrant. It must not be called from more - thank one task. */ - - if( pxCommand == NULL ) - { - /* Search for the command string in the list of registered commands. */ - for( pxCommand = &xRegisteredCommands; pxCommand != NULL; pxCommand = pxCommand->pxNext ) - { - pcRegisteredCommandString = pxCommand->pxCommandLineDefinition->pcCommand; - xCommandStringLength = strlen( pcRegisteredCommandString ); - - /* To ensure the string lengths match exactly, so as not to pick up - a sub-string of a longer command, check the byte after the expected - end of the string is either the end of the string or a space before - a parameter. */ - if( strncmp( pcCommandInput, pcRegisteredCommandString, xCommandStringLength ) == 0 ) - { - if( ( pcCommandInput[ xCommandStringLength ] == ' ' ) || ( pcCommandInput[ xCommandStringLength ] == 0x00 ) ) - { - /* The command has been found. Check it has the expected - number of parameters. If cExpectedNumberOfParameters is -1, - then there could be a variable number of parameters and no - check is made. */ - if( pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters >= 0 ) - { - if( prvGetNumberOfParameters( pcCommandInput ) != pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters ) - { - xReturn = pdFALSE; - } - } - - break; - } - } - } - } - - if( ( pxCommand != NULL ) && ( xReturn == pdFALSE ) ) - { - /* The command was found, but the number of parameters with the command - was incorrect. */ - strncpy( pcWriteBuffer, "Incorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n", xWriteBufferLen ); - pxCommand = NULL; - } - else if( pxCommand != NULL ) - { - /* Call the callback function that is registered to this command. */ - xReturn = pxCommand->pxCommandLineDefinition->pxCommandInterpreter( pcWriteBuffer, xWriteBufferLen, pcCommandInput ); - - /* If xReturn is pdFALSE, then no further strings will be returned - after this one, and pxCommand can be reset to NULL ready to search - for the next entered command. */ - if( xReturn == pdFALSE ) - { - pxCommand = NULL; - } - } - else - { - /* pxCommand was NULL, the command was not found. */ - strncpy( pcWriteBuffer, "Command not recognised. Enter 'help' to view a list of available commands.\r\n\r\n", xWriteBufferLen ); - xReturn = pdFALSE; - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -char *FreeRTOS_CLIGetOutputBuffer( void ) -{ - return cOutputBuffer; -} -/*-----------------------------------------------------------*/ - -const char *FreeRTOS_CLIGetParameter( const char *pcCommandString, UBaseType_t uxWantedParameter, BaseType_t *pxParameterStringLength ) -{ -UBaseType_t uxParametersFound = 0; -const char *pcReturn = NULL; - - *pxParameterStringLength = 0; - - while( uxParametersFound < uxWantedParameter ) - { - /* Index the character pointer past the current word. If this is the start - of the command string then the first word is the command itself. */ - while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) ) - { - pcCommandString++; - } - - /* Find the start of the next string. */ - while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) == ' ' ) ) - { - pcCommandString++; - } - - /* Was a string found? */ - if( *pcCommandString != 0x00 ) - { - /* Is this the start of the required parameter? */ - uxParametersFound++; - - if( uxParametersFound == uxWantedParameter ) - { - /* How long is the parameter? */ - pcReturn = pcCommandString; - while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) ) - { - ( *pxParameterStringLength )++; - pcCommandString++; - } - - if( *pxParameterStringLength == 0 ) - { - pcReturn = NULL; - } - - break; - } - } - else - { - break; - } - } - - return pcReturn; -} -/*-----------------------------------------------------------*/ - -static void prvRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister, - CLI_Definition_List_Item_t * pxCliDefinitionListItemBuffer ) -{ -static CLI_Definition_List_Item_t *pxLastCommandInList = &xRegisteredCommands; - - /* Check the parameters are not NULL. */ - configASSERT( pxCommandToRegister != NULL ); - configASSERT( pxCliDefinitionListItemBuffer != NULL ); - - taskENTER_CRITICAL(); - { - /* Reference the command being registered from the newly created - list item. */ - pxCliDefinitionListItemBuffer->pxCommandLineDefinition = pxCommandToRegister; - - /* The new list item will get added to the end of the list, so - pxNext has nowhere to point. */ - pxCliDefinitionListItemBuffer->pxNext = NULL; - - /* Add the newly created list item to the end of the already existing - list. */ - pxLastCommandInList->pxNext = pxCliDefinitionListItemBuffer; - - /* Set the end of list marker to the new list item. */ - pxLastCommandInList = pxCliDefinitionListItemBuffer; - } - taskEXIT_CRITICAL(); -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ) -{ -static const CLI_Definition_List_Item_t * pxCommand = NULL; -BaseType_t xReturn; - - ( void ) pcCommandString; - - if( pxCommand == NULL ) - { - /* Reset the pxCommand pointer back to the start of the list. */ - pxCommand = &xRegisteredCommands; - } - - /* Return the next command help string, before moving the pointer on to - the next command in the list. */ - strncpy( pcWriteBuffer, pxCommand->pxCommandLineDefinition->pcHelpString, xWriteBufferLen ); - pxCommand = pxCommand->pxNext; - - if( pxCommand == NULL ) - { - /* There are no more commands in the list, so there will be no more - strings to return after this one and pdFALSE should be returned. */ - xReturn = pdFALSE; - } - else - { - xReturn = pdTRUE; - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -static int8_t prvGetNumberOfParameters( const char *pcCommandString ) -{ -int8_t cParameters = 0; -BaseType_t xLastCharacterWasSpace = pdFALSE; - - /* Count the number of space delimited words in pcCommandString. */ - while( *pcCommandString != 0x00 ) - { - if( ( *pcCommandString ) == ' ' ) - { - if( xLastCharacterWasSpace != pdTRUE ) - { - cParameters++; - xLastCharacterWasSpace = pdTRUE; - } - } - else - { - xLastCharacterWasSpace = pdFALSE; - } - - pcCommandString++; - } - - /* If the command string ended with spaces, then there will have been too - many parameters counted. */ - if( xLastCharacterWasSpace == pdTRUE ) - { - cParameters--; - } - - /* The value returned is one less than the number of space delimited words, - as the first word should be the command itself. */ - return cParameters; -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Utils includes. */ +#include "FreeRTOS_CLI.h" + +/* If the application writer needs to place the buffer used by the CLI at a + * fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in + * FreeRTOSConfig.h, then declare an array with the following name and size in + * one of the application files: + * char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ]; + */ +#ifndef configAPPLICATION_PROVIDES_cOutputBuffer + #define configAPPLICATION_PROVIDES_cOutputBuffer 0 +#endif + +/* + * Register the command passed in using the pxCommandToRegister parameter + * and using pxCliDefinitionListItemBuffer as the memory for command line + * list items. Registering a command adds the command to the list of + * commands that are handled by the command interpreter. Once a command + * has been registered it can be executed from the command line. + */ +static void prvRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister, + CLI_Definition_List_Item_t * pxCliDefinitionListItemBuffer ); + +/* + * The callback function that is executed when "help" is entered. This is the + * only default command that is always present. + */ +static BaseType_t prvHelpCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* + * Return the number of parameters that follow the command name. + */ +static int8_t prvGetNumberOfParameters( const char * pcCommandString ); + +/* The definition of the "help" command. This command is always at the front + * of the list of registered commands. */ +static const CLI_Command_Definition_t xHelpCommand = +{ + "help", + "\r\nhelp:\r\n Lists all the registered commands\r\n\r\n", + prvHelpCommand, + 0 +}; + +/* The definition of the list of commands. Commands that are registered are + * added to this list. */ +static CLI_Definition_List_Item_t xRegisteredCommands = +{ + &xHelpCommand, /* The first command in the list is always the help command, defined in this file. */ + NULL /* The next pointer is initialised to NULL, as there are no other registered commands yet. */ +}; + +/* A buffer into which command outputs can be written is declared here, rather +* than in the command console implementation, to allow multiple command consoles +* to share the same buffer. For example, an application may allow access to the +* command interpreter by UART and by Ethernet. Sharing a buffer is done purely +* to save RAM. Note, however, that the command console itself is not re-entrant, +* so only one command interpreter interface can be used at any one time. For that +* reason, no attempt at providing mutual exclusion to the cOutputBuffer array is +* attempted. +* +* configAPPLICATION_PROVIDES_cOutputBuffer is provided to allow the application +* writer to provide their own cOutputBuffer declaration in cases where the +* buffer needs to be placed at a fixed address (rather than by the linker). */ +#if ( configAPPLICATION_PROVIDES_cOutputBuffer == 0 ) + static char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ]; +#else + extern char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ]; +#endif + + +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister ) + { + BaseType_t xReturn = pdFAIL; + CLI_Definition_List_Item_t * pxNewListItem; + + /* Check the parameter is not NULL. */ + configASSERT( pxCommandToRegister != NULL ); + + /* Create a new list item that will reference the command being registered. */ + pxNewListItem = ( CLI_Definition_List_Item_t * ) pvPortMalloc( sizeof( CLI_Definition_List_Item_t ) ); + configASSERT( pxNewListItem != NULL ); + + if( pxNewListItem != NULL ) + { + prvRegisterCommand( pxCommandToRegister, pxNewListItem ); + xReturn = pdPASS; + } + + return xReturn; + } + +#endif /* #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t FreeRTOS_CLIRegisterCommandStatic( const CLI_Command_Definition_t * const pxCommandToRegister, + CLI_Definition_List_Item_t * pxCliDefinitionListItemBuffer ) + { + /* Check the parameters are not NULL. */ + configASSERT( pxCommandToRegister != NULL ); + configASSERT( pxCliDefinitionListItemBuffer != NULL ); + + prvRegisterCommand( pxCommandToRegister, pxCliDefinitionListItemBuffer ); + + return pdPASS; + } + +#endif /* #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, + char * pcWriteBuffer, + size_t xWriteBufferLen ) +{ + static const CLI_Definition_List_Item_t * pxCommand = NULL; + BaseType_t xReturn = pdTRUE; + const char * pcRegisteredCommandString; + size_t xCommandStringLength; + + /* Note: This function is not re-entrant. It must not be called from more + * thank one task. */ + + if( pxCommand == NULL ) + { + /* Search for the command string in the list of registered commands. */ + for( pxCommand = &xRegisteredCommands; pxCommand != NULL; pxCommand = pxCommand->pxNext ) + { + pcRegisteredCommandString = pxCommand->pxCommandLineDefinition->pcCommand; + xCommandStringLength = strlen( pcRegisteredCommandString ); + + /* To ensure the string lengths match exactly, so as not to pick up + * a sub-string of a longer command, check the byte after the expected + * end of the string is either the end of the string or a space before + * a parameter. */ + if( strncmp( pcCommandInput, pcRegisteredCommandString, xCommandStringLength ) == 0 ) + { + if( ( pcCommandInput[ xCommandStringLength ] == ' ' ) || ( pcCommandInput[ xCommandStringLength ] == 0x00 ) ) + { + /* The command has been found. Check it has the expected + * number of parameters. If cExpectedNumberOfParameters is -1, + * then there could be a variable number of parameters and no + * check is made. */ + if( pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters >= 0 ) + { + if( prvGetNumberOfParameters( pcCommandInput ) != pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters ) + { + xReturn = pdFALSE; + } + } + + break; + } + } + } + } + + if( ( pxCommand != NULL ) && ( xReturn == pdFALSE ) ) + { + /* The command was found, but the number of parameters with the command + * was incorrect. */ + strncpy( pcWriteBuffer, "Incorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n", xWriteBufferLen ); + pxCommand = NULL; + } + else if( pxCommand != NULL ) + { + /* Call the callback function that is registered to this command. */ + xReturn = pxCommand->pxCommandLineDefinition->pxCommandInterpreter( pcWriteBuffer, xWriteBufferLen, pcCommandInput ); + + /* If xReturn is pdFALSE, then no further strings will be returned + * after this one, and pxCommand can be reset to NULL ready to search + * for the next entered command. */ + if( xReturn == pdFALSE ) + { + pxCommand = NULL; + } + } + else + { + /* pxCommand was NULL, the command was not found. */ + strncpy( pcWriteBuffer, "Command not recognised. Enter 'help' to view a list of available commands.\r\n\r\n", xWriteBufferLen ); + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +char * FreeRTOS_CLIGetOutputBuffer( void ) +{ + return cOutputBuffer; +} +/*-----------------------------------------------------------*/ + +const char * FreeRTOS_CLIGetParameter( const char * pcCommandString, + UBaseType_t uxWantedParameter, + BaseType_t * pxParameterStringLength ) +{ + UBaseType_t uxParametersFound = 0; + const char * pcReturn = NULL; + + *pxParameterStringLength = 0; + + while( uxParametersFound < uxWantedParameter ) + { + /* Index the character pointer past the current word. If this is the start + * of the command string then the first word is the command itself. */ + while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) ) + { + pcCommandString++; + } + + /* Find the start of the next string. */ + while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) == ' ' ) ) + { + pcCommandString++; + } + + /* Was a string found? */ + if( *pcCommandString != 0x00 ) + { + /* Is this the start of the required parameter? */ + uxParametersFound++; + + if( uxParametersFound == uxWantedParameter ) + { + /* How long is the parameter? */ + pcReturn = pcCommandString; + + while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) ) + { + ( *pxParameterStringLength )++; + pcCommandString++; + } + + if( *pxParameterStringLength == 0 ) + { + pcReturn = NULL; + } + + break; + } + } + else + { + break; + } + } + + return pcReturn; +} +/*-----------------------------------------------------------*/ + +static void prvRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister, + CLI_Definition_List_Item_t * pxCliDefinitionListItemBuffer ) +{ + static CLI_Definition_List_Item_t * pxLastCommandInList = &xRegisteredCommands; + + /* Check the parameters are not NULL. */ + configASSERT( pxCommandToRegister != NULL ); + configASSERT( pxCliDefinitionListItemBuffer != NULL ); + + taskENTER_CRITICAL(); + { + /* Reference the command being registered from the newly created + * list item. */ + pxCliDefinitionListItemBuffer->pxCommandLineDefinition = pxCommandToRegister; + + /* The new list item will get added to the end of the list, so + * pxNext has nowhere to point. */ + pxCliDefinitionListItemBuffer->pxNext = NULL; + + /* Add the newly created list item to the end of the already existing + * list. */ + pxLastCommandInList->pxNext = pxCliDefinitionListItemBuffer; + + /* Set the end of list marker to the new list item. */ + pxLastCommandInList = pxCliDefinitionListItemBuffer; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvHelpCommand( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ) +{ + static const CLI_Definition_List_Item_t * pxCommand = NULL; + BaseType_t xReturn; + + ( void ) pcCommandString; + + if( pxCommand == NULL ) + { + /* Reset the pxCommand pointer back to the start of the list. */ + pxCommand = &xRegisteredCommands; + } + + /* Return the next command help string, before moving the pointer on to + * the next command in the list. */ + strncpy( pcWriteBuffer, pxCommand->pxCommandLineDefinition->pcHelpString, xWriteBufferLen ); + pxCommand = pxCommand->pxNext; + + if( pxCommand == NULL ) + { + /* There are no more commands in the list, so there will be no more + * strings to return after this one and pdFALSE should be returned. */ + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static int8_t prvGetNumberOfParameters( const char * pcCommandString ) +{ + int8_t cParameters = 0; + BaseType_t xLastCharacterWasSpace = pdFALSE; + + /* Count the number of space delimited words in pcCommandString. */ + while( *pcCommandString != 0x00 ) + { + if( ( *pcCommandString ) == ' ' ) + { + if( xLastCharacterWasSpace != pdTRUE ) + { + cParameters++; + xLastCharacterWasSpace = pdTRUE; + } + } + else + { + xLastCharacterWasSpace = pdFALSE; + } + + pcCommandString++; + } + + /* If the command string ended with spaces, then there will have been too + * many parameters counted. */ + if( xLastCharacterWasSpace == pdTRUE ) + { + cParameters--; + } + + /* The value returned is one less than the number of space delimited words, + * as the first word should be the command itself. */ + return cParameters; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.h index 810724f98..10e4986a0 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.h @@ -1,122 +1,127 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef COMMAND_INTERPRETER_H -#define COMMAND_INTERPRETER_H - -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - -/* The prototype to which callback functions used to process command line -commands must comply. pcWriteBuffer is a buffer into which the output from -executing the command can be written, xWriteBufferLen is the length, in bytes of -the pcWriteBuffer buffer, and pcCommandString is the entire string as input by -the user (from which parameters can be extracted).*/ -typedef BaseType_t (*pdCOMMAND_LINE_CALLBACK)( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString ); - -/* The structure that defines command line commands. A command line command -should be defined by declaring a const structure of this type. */ -typedef struct xCOMMAND_LINE_INPUT -{ - const char * const pcCommand; /* The command that causes pxCommandInterpreter to be executed. For example "help". Must be all lower case. */ - const char * const pcHelpString; /* String that describes how to use the command. Should start with the command itself, and end with "\r\n". For example "help: Returns a list of all the commands\r\n". */ - const pdCOMMAND_LINE_CALLBACK pxCommandInterpreter; /* A pointer to the callback function that will return the output generated by the command. */ - int8_t cExpectedNumberOfParameters; /* Commands expect a fixed number of parameters, which may be zero. */ -} CLI_Command_Definition_t; - -/* The structure that defines a command line list entry. */ -typedef struct xCOMMAND_INPUT_LIST -{ - const CLI_Command_Definition_t *pxCommandLineDefinition; - struct xCOMMAND_INPUT_LIST *pxNext; -} CLI_Definition_List_Item_t; - -/* For backward compatibility. */ -#define xCommandLineInput CLI_Command_Definition_t - -/* - * Register the command passed in using the pxCommandToRegister parameter. - * Registering a command adds the command to the list of commands that are - * handled by the command interpreter. Once a command has been registered it - * can be executed from the command line. - */ -#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister ); -#endif - -/* - * Static version of the above function which allows the application writer - * to supply the memory used for a command line list entry. - */ -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - BaseType_t FreeRTOS_CLIRegisterCommandStatic( const CLI_Command_Definition_t * const pxCommandToRegister, - CLI_Definition_List_Item_t * pxCliDefinitionListItemBuffer ); -#endif - -/* - * Runs the command interpreter for the command string "pcCommandInput". Any - * output generated by running the command will be placed into pcWriteBuffer. - * xWriteBufferLen must indicate the size, in bytes, of the buffer pointed to - * by pcWriteBuffer. - * - * FreeRTOS_CLIProcessCommand should be called repeatedly until it returns pdFALSE. - * - * pcCmdIntProcessCommand is not reentrant. It must not be called from more - * than one task - or at least - by more than one task at a time. - */ -BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, char * pcWriteBuffer, size_t xWriteBufferLen ); - -/*-----------------------------------------------------------*/ - -/* - * A buffer into which command outputs can be written is declared in the - * main command interpreter, rather than in the command console implementation, - * to allow application that provide access to the command console via multiple - * interfaces to share a buffer, and therefore save RAM. Note, however, that - * the command interpreter itself is not re-entrant, so only one command - * console interface can be used at any one time. For that reason, no attempt - * is made to provide any mutual exclusion mechanism on the output buffer. - * - * FreeRTOS_CLIGetOutputBuffer() returns the address of the output buffer. - */ -char *FreeRTOS_CLIGetOutputBuffer( void ); - -/* - * Return a pointer to the xParameterNumber'th word in pcCommandString. - */ -const char *FreeRTOS_CLIGetParameter( const char *pcCommandString, UBaseType_t uxWantedParameter, BaseType_t *pxParameterStringLength ); - -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ - -#endif /* COMMAND_INTERPRETER_H */ - +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef COMMAND_INTERPRETER_H +#define COMMAND_INTERPRETER_H + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/* The prototype to which callback functions used to process command line + * commands must comply. pcWriteBuffer is a buffer into which the output from + * executing the command can be written, xWriteBufferLen is the length, in bytes of + * the pcWriteBuffer buffer, and pcCommandString is the entire string as input by + * the user (from which parameters can be extracted).*/ +typedef BaseType_t (* pdCOMMAND_LINE_CALLBACK)( char * pcWriteBuffer, + size_t xWriteBufferLen, + const char * pcCommandString ); + +/* The structure that defines command line commands. A command line command + * should be defined by declaring a const structure of this type. */ +typedef struct xCOMMAND_LINE_INPUT +{ + const char * const pcCommand; /* The command that causes pxCommandInterpreter to be executed. For example "help". Must be all lower case. */ + const char * const pcHelpString; /* String that describes how to use the command. Should start with the command itself, and end with "\r\n". For example "help: Returns a list of all the commands\r\n". */ + const pdCOMMAND_LINE_CALLBACK pxCommandInterpreter; /* A pointer to the callback function that will return the output generated by the command. */ + int8_t cExpectedNumberOfParameters; /* Commands expect a fixed number of parameters, which may be zero. */ +} CLI_Command_Definition_t; + +/* The structure that defines a command line list entry. */ +typedef struct xCOMMAND_INPUT_LIST +{ + const CLI_Command_Definition_t * pxCommandLineDefinition; + struct xCOMMAND_INPUT_LIST * pxNext; +} CLI_Definition_List_Item_t; + +/* For backward compatibility. */ +#define xCommandLineInput CLI_Command_Definition_t + +/* + * Register the command passed in using the pxCommandToRegister parameter. + * Registering a command adds the command to the list of commands that are + * handled by the command interpreter. Once a command has been registered it + * can be executed from the command line. + */ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister ); +#endif + +/* + * Static version of the above function which allows the application writer + * to supply the memory used for a command line list entry. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t FreeRTOS_CLIRegisterCommandStatic( const CLI_Command_Definition_t * const pxCommandToRegister, + CLI_Definition_List_Item_t * pxCliDefinitionListItemBuffer ); +#endif + +/* + * Runs the command interpreter for the command string "pcCommandInput". Any + * output generated by running the command will be placed into pcWriteBuffer. + * xWriteBufferLen must indicate the size, in bytes, of the buffer pointed to + * by pcWriteBuffer. + * + * FreeRTOS_CLIProcessCommand should be called repeatedly until it returns pdFALSE. + * + * pcCmdIntProcessCommand is not reentrant. It must not be called from more + * than one task - or at least - by more than one task at a time. + */ +BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, + char * pcWriteBuffer, + size_t xWriteBufferLen ); + +/*-----------------------------------------------------------*/ + +/* + * A buffer into which command outputs can be written is declared in the + * main command interpreter, rather than in the command console implementation, + * to allow application that provide access to the command console via multiple + * interfaces to share a buffer, and therefore save RAM. Note, however, that + * the command interpreter itself is not re-entrant, so only one command + * console interface can be used at any one time. For that reason, no attempt + * is made to provide any mutual exclusion mechanism on the output buffer. + * + * FreeRTOS_CLIGetOutputBuffer() returns the address of the output buffer. + */ +char * FreeRTOS_CLIGetOutputBuffer( void ); + +/* + * Return a pointer to the xParameterNumber'th word in pcCommandString. + */ +const char * FreeRTOS_CLIGetParameter( const char * pcCommandString, + UBaseType_t uxWantedParameter, + BaseType_t * pxParameterStringLength ); + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* COMMAND_INTERPRETER_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/History.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/History.txt index 8c62cf90b..01c95fee0 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/History.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/History.txt @@ -1,32 +1,32 @@ -Changes between V1.0.3 and V1.0.4 released - - + Update to use stdint and the FreeRTOS specific typedefs that were - introduced in FreeRTOS V8.0.0. - -Changes between V1.0.2 and V1.0.3 released - - + Previously, and in line with good software engineering practice, the - FreeRTOS coding standard did not permit the use of char types that were - not explicitly qualified as either signed or unsigned. As a result char - pointers used to reference strings required casts, as did the use of any - standard string handling functions. The casts ensured compiler warnings - were not generated by compilers that defaulted unqualified char types to - be signed or compilers that defaulted unqualified char types to be - unsigned. As it has in later MISRA standards, this rule has now been - relaxed, and unqualified char types are now permitted, but only when: - 1) The char is used to point to a human readable text string. - 2) The char is used to hold a single ASCII character. - -Changes between V1.0.1 and V1.0.2 released 14/10/2013 - - + Changed double quotes (") to single quotes (') in the help string to - allow the strings to be used with JSON in FreeRTOS+Nabto. - -Changes between V1.0.0 and V1.0.1 released 05/07/2012 - - + Change the name of the structure used to map a function that implements - a CLI command to the string used to call the command from - xCommandLineInput to CLI_Command_Definition_t, as it was always intended - to be. A #define was added to map the old name to the new name for - reasons of backward compatibility. - +Changes between V1.0.3 and V1.0.4 released + + + Update to use stdint and the FreeRTOS specific typedefs that were + introduced in FreeRTOS V8.0.0. + +Changes between V1.0.2 and V1.0.3 released + + + Previously, and in line with good software engineering practice, the + FreeRTOS coding standard did not permit the use of char types that were + not explicitly qualified as either signed or unsigned. As a result char + pointers used to reference strings required casts, as did the use of any + standard string handling functions. The casts ensured compiler warnings + were not generated by compilers that defaulted unqualified char types to + be signed or compilers that defaulted unqualified char types to be + unsigned. As it has in later MISRA standards, this rule has now been + relaxed, and unqualified char types are now permitted, but only when: + 1) The char is used to point to a human readable text string. + 2) The char is used to hold a single ASCII character. + +Changes between V1.0.1 and V1.0.2 released 14/10/2013 + + + Changed double quotes (") to single quotes (') in the help string to + allow the strings to be used with JSON in FreeRTOS+Nabto. + +Changes between V1.0.0 and V1.0.1 released 05/07/2012 + + + Change the name of the structure used to map a function that implements + a CLI command to the string used to call the command from + xCommandLineInput to CLI_Command_Definition_t, as it was always intended + to be. A #define was added to map the old name to the new name for + reasons of backward compatibility. + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/LICENSE_INFORMATION.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/LICENSE_INFORMATION.txt index 6812e2716..3486aa618 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/LICENSE_INFORMATION.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/LICENSE_INFORMATION.txt @@ -1,19 +1,19 @@ -FreeRTOS+CLI is released under the following MIT license. - -Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +FreeRTOS+CLI is released under the following MIT license. + +Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/ReadMe.url b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/ReadMe.url index 3a76266ab..afc826fd2 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/ReadMe.url +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/ReadMe.url @@ -1,5 +1,5 @@ -[InternetShortcut] -URL=http://www.freertos.org/cli -IDList= -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/cli +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/readme.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/readme.txt index 0f61b02fd..8309c44ba 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/readme.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/readme.txt @@ -1,4 +1,3 @@ -Contains source and header files that implement FreeRTOS+CLI. See -http://www.FreeRTOS.org/cli for documentation and license information. - - \ No newline at end of file +Contains source and header files that implement FreeRTOS+CLI. See +http://www.FreeRTOS.org/cli for documentation and license information. + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/LinkToDemo.url b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/LinkToDemo.url index e803bf286..a7a7a275d 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/LinkToDemo.url +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/LinkToDemo.url @@ -1,5 +1,5 @@ -[InternetShortcut] -URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_IO/Demo_Applications/LPCXpresso_LPC1769/NXP_LPC1769_Demo_Description.shtml -IDList= -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_IO/Demo_Applications/LPCXpresso_LPC1769/NXP_LPC1769_Demo_Description.shtml +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/readme.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/readme.txt index f5c8d2ff8..f46f88e77 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/readme.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IO/readme.txt @@ -1,7 +1,7 @@ -It is not possible to create an example FreeRTOS+IO project for the Windows -simulator. FreeRTOS+IO information can be found on http://www.FreeRTOS.org/IO. - -A featured demo that includes telnet like functionality, a web server, -a command line interface (using FreeRTOS+CLI) and a FAT file system is -described on +It is not possible to create an example FreeRTOS+IO project for the Windows +simulator. FreeRTOS+IO information can be found on http://www.FreeRTOS.org/IO. + +A featured demo that includes telnet like functionality, a web server, +a command line interface (using FreeRTOS+CLI) and a FAT file system is +described on http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_IO/Demo_Applications/LPCXpresso_LPC1769/NXP_LPC1769_Demo_Description.shtml \ No newline at end of file diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_secure_sockets.tzext.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_secure_sockets.tzext.h index 4fae73e0f..49fd5436e 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_secure_sockets.tzext.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_secure_sockets.tzext.h @@ -1,136 +1,144 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * An example of a Tracealyzer extension for tracing API calls, in this case - * for tracing selected functions in Amazon FreeRTOS/aws_secure_sockets. - * See trcExtensions.h for information on how to use this. - * - * To create your own extension, first make sure to read the documentation - * in trcExtensions.h. Then, to create an extension header file like this - * one, you need to provide: - * - * - Extension Definitions - name and event codes of the extensions. - * - * - Trace Wrappers - calls the original function and traces the event. - * - * - Function Redefinitions - changes the function calls to the trace wrappers. - * - * See the below comments for details about these definitions. Note that you - * also need a matching .xml file for Tracealyzer to understand the data. - * See trcExtensions.h for further information. - */ - -#ifndef _AWS_SECURE_SOCKETS_TZEXT_H -#define _AWS_SECURE_SOCKETS_TZEXT_H - -/***** Extension Definitions *****/ - -/****************************************************************************** - * _NAME - * The name of the extension as a string constant. This name is used by the - * Tracealyzer host application to find the right XML file for interpreting - * the events. Assuming the extension name is "aws_secure_sockets", Tracealyzer - * will look for an XML file named "aws_secure_sockets-.xml", first in - * the folder of the current trace file, next in the Tracealyzer 4/cfg folder. - * For the VERSION part, see the TRC_EXT__VERSION macros below. - * - * Note: The extension name displayed in Tracealyzer is defined in the XML file - * in the EventGroup element (e.g. ) - * - *****************************************************************************/ -#define TRC_EXT_SOCKETS_NAME "aws_secure_sockets" - -/****************************************************************************** - * _VERSION_MAJOR - * _VERSION_MINOR - * _VERSION_PATCH - * - * The version code of the extension (MAJOR.MINOR.PATCH) - * - * If you increment the version code when modifying an extension, you can still - * show old traces recorded using an earlier version of the extension. - * - * Assuming the extension name is "aws_secure_sockets", and the below version - * codes are 1 (MAJOR), 2 (MINOR), 3 (PATCH), Tracealyzer will assume the - * corresponding XML file is named "aws_secure_sockets-v1.2.3.xml". So if then - * view a trace recorded with extension version 1.2.2, those traces will look - * for "aws_secure_sockets-v1.2.2.xml" instead. - * - * Note that major and minor are stored as 8 bit values, while patch is stored - * using 16 bits. They are treated as unsigned integers, so the maximum values - * are 256, 256 and 65535. - *****************************************************************************/ -#define TRC_EXT_SOCKETS_VERSION_MAJOR 1 - -#define TRC_EXT_SOCKETS_VERSION_MINOR 0 - -#define TRC_EXT_SOCKETS_VERSION_PATCH 0 - - -/****************************************************************************** - * _ - * The event codes used in the trace wrapper functions. Important that these - * are relative to _FIRST. - *****************************************************************************/ -#define EVENTCODE_SOCKETS_Connect (TRC_EXT_BASECODE + 0) - -#define EVENTCODE_SOCKETS_Send (TRC_EXT_BASECODE + 1) - -#define EVENTCODE_SOCKETS_Recv (TRC_EXT_BASECODE + 2) - -/****************************************************************************** - * _COUNT - * The number of event codes used by this extension. Should be at least 1. - * Tracealyzer allows for events codes up to 4095. - *****************************************************************************/ -#define TRC_EXT_SOCKETS_COUNT 2 - - -/***** Trace Wrappers *****/ - -#include /* Including the original header file, so that custom data types are understood. */ - -static inline int32_t SOCKETS_Connect__trace( Socket_t xSocket, SocketsSockaddr_t * pxAddress, Socklen_t xAddressLength ) -{ - int32_t ret = SOCKETS_Connect(xSocket, pxAddress, xAddressLength); - - // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. - prvTraceStoreEvent3(EVENTCODE_SOCKETS_Connect, (uint32_t)xSocket, (uint32_t)pxAddress->ulAddress, (uint32_t)ret); - - return ret; -} - -static inline int32_t SOCKETS_Send__trace( Socket_t xSocket, const void * pvBuffer, size_t xDataLength, uint32_t ulFlags ) -{ - int32_t ret = SOCKETS_Send(xSocket, pvBuffer, xDataLength, ulFlags); - - // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. - prvTraceStoreEvent2(EVENTCODE_SOCKETS_Send, (uint32_t)xSocket, (uint32_t)ret); - - return ret; -} - - -static inline int32_t SOCKETS_Recv__trace( Socket_t xSocket, void * pvBuffer, size_t xBufferLength, uint32_t ulFlags ) -{ - int32_t ret = SOCKETS_Recv(xSocket, pvBuffer, xBufferLength, ulFlags); - - // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. - prvTraceStoreEvent2(EVENTCODE_SOCKETS_Recv, (uint32_t)xSocket, (uint32_t)ret); - - return ret; -} - -/***** Function Redefinitions *****/ - -#define SOCKETS_Connect SOCKETS_Connect__trace - -#define SOCKETS_Send SOCKETS_Send__trace - -#define SOCKETS_Recv SOCKETS_Recv__trace - -#endif /* _AWS_SECURE_SOCKETS_TZEXT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * An example of a Tracealyzer extension for tracing API calls, in this case + * for tracing selected functions in Amazon FreeRTOS/aws_secure_sockets. + * See trcExtensions.h for information on how to use this. + * + * To create your own extension, first make sure to read the documentation + * in trcExtensions.h. Then, to create an extension header file like this + * one, you need to provide: + * + * - Extension Definitions - name and event codes of the extensions. + * + * - Trace Wrappers - calls the original function and traces the event. + * + * - Function Redefinitions - changes the function calls to the trace wrappers. + * + * See the below comments for details about these definitions. Note that you + * also need a matching .xml file for Tracealyzer to understand the data. + * See trcExtensions.h for further information. + */ + +#ifndef _AWS_SECURE_SOCKETS_TZEXT_H +#define _AWS_SECURE_SOCKETS_TZEXT_H + +/***** Extension Definitions *****/ + +/****************************************************************************** + * _NAME + * The name of the extension as a string constant. This name is used by the + * Tracealyzer host application to find the right XML file for interpreting + * the events. Assuming the extension name is "aws_secure_sockets", Tracealyzer + * will look for an XML file named "aws_secure_sockets-.xml", first in + * the folder of the current trace file, next in the Tracealyzer 4/cfg folder. + * For the VERSION part, see the TRC_EXT__VERSION macros below. + * + * Note: The extension name displayed in Tracealyzer is defined in the XML file + * in the EventGroup element (e.g. ) + * + *****************************************************************************/ +#define TRC_EXT_SOCKETS_NAME "aws_secure_sockets" + +/****************************************************************************** + * _VERSION_MAJOR + * _VERSION_MINOR + * _VERSION_PATCH + * + * The version code of the extension (MAJOR.MINOR.PATCH) + * + * If you increment the version code when modifying an extension, you can still + * show old traces recorded using an earlier version of the extension. + * + * Assuming the extension name is "aws_secure_sockets", and the below version + * codes are 1 (MAJOR), 2 (MINOR), 3 (PATCH), Tracealyzer will assume the + * corresponding XML file is named "aws_secure_sockets-v1.2.3.xml". So if then + * view a trace recorded with extension version 1.2.2, those traces will look + * for "aws_secure_sockets-v1.2.2.xml" instead. + * + * Note that major and minor are stored as 8 bit values, while patch is stored + * using 16 bits. They are treated as unsigned integers, so the maximum values + * are 256, 256 and 65535. + *****************************************************************************/ +#define TRC_EXT_SOCKETS_VERSION_MAJOR 1 + +#define TRC_EXT_SOCKETS_VERSION_MINOR 0 + +#define TRC_EXT_SOCKETS_VERSION_PATCH 0 + + +/****************************************************************************** + * _ + * The event codes used in the trace wrapper functions. Important that these + * are relative to _FIRST. + *****************************************************************************/ +#define EVENTCODE_SOCKETS_Connect ( TRC_EXT_BASECODE + 0 ) + +#define EVENTCODE_SOCKETS_Send ( TRC_EXT_BASECODE + 1 ) + +#define EVENTCODE_SOCKETS_Recv ( TRC_EXT_BASECODE + 2 ) + +/****************************************************************************** + * _COUNT + * The number of event codes used by this extension. Should be at least 1. + * Tracealyzer allows for events codes up to 4095. + *****************************************************************************/ +#define TRC_EXT_SOCKETS_COUNT 2 + + +/***** Trace Wrappers *****/ + +#include /* Including the original header file, so that custom data types are understood. */ + +static inline int32_t SOCKETS_Connect__trace( Socket_t xSocket, + SocketsSockaddr_t * pxAddress, + Socklen_t xAddressLength ) +{ + int32_t ret = SOCKETS_Connect( xSocket, pxAddress, xAddressLength ); + + /* Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. */ + prvTraceStoreEvent3( EVENTCODE_SOCKETS_Connect, ( uint32_t ) xSocket, ( uint32_t ) pxAddress->ulAddress, ( uint32_t ) ret ); + + return ret; +} + +static inline int32_t SOCKETS_Send__trace( Socket_t xSocket, + const void * pvBuffer, + size_t xDataLength, + uint32_t ulFlags ) +{ + int32_t ret = SOCKETS_Send( xSocket, pvBuffer, xDataLength, ulFlags ); + + /* Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. */ + prvTraceStoreEvent2( EVENTCODE_SOCKETS_Send, ( uint32_t ) xSocket, ( uint32_t ) ret ); + + return ret; +} + + +static inline int32_t SOCKETS_Recv__trace( Socket_t xSocket, + void * pvBuffer, + size_t xBufferLength, + uint32_t ulFlags ) +{ + int32_t ret = SOCKETS_Recv( xSocket, pvBuffer, xBufferLength, ulFlags ); + + /* Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. */ + prvTraceStoreEvent2( EVENTCODE_SOCKETS_Recv, ( uint32_t ) xSocket, ( uint32_t ) ret ); + + return ret; +} + +/***** Function Redefinitions *****/ + +#define SOCKETS_Connect SOCKETS_Connect__trace + +#define SOCKETS_Send SOCKETS_Send__trace + +#define SOCKETS_Recv SOCKETS_Recv__trace + +#endif /* _AWS_SECURE_SOCKETS_TZEXT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_wifi.tzext.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_wifi.tzext.h index 66ce0e878..b2fe8cb6a 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_wifi.tzext.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/aws_wifi.tzext.h @@ -1,135 +1,135 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * An example of a Tracealyzer extension for tracing API calls, in this case - * for tracing selected functions in Amazon FreeRTOS/aws_wifi. - * See trcExtensions.h for information on how to use this. - * - * To create your own extension, first make sure to read the documentation - * in trcExtensions.h. Then, to create an extension header file like this - * one, you need to provide: - * - * - Extension Definitions - name and event codes of the extensions. - * - * - Trace Wrappers - calls the original function and traces the event. - * - * - Function Redefinitions - changes the function calls to the trace wrappers. - * - * See the below comments for details about these definitions. Note that you - * also need a matching .xml file for Tracealyzer to understand the data. - * See trcExtensions.h for further information. - */ - -#ifndef _AWS_WIFI_TZEXT_H -#define _AWS_WIFI_TZEXT_H - -/***** Extension Definitions (must use the same prefix!) *****/ - -/****************************************************************************** - * _NAME - * The name of the extension as a string constant. This name is used by the - * Tracealyzer host application to find the right XML file for interpreting - * the events. Assuming the extension name is "aws_secure_sockets", Tracealyzer - * will look for an XML file named "aws_secure_sockets-.xml", first in - * the folder of the current trace file, next in the Tracealyzer 4/cfg folder. - * For the VERSION part, see the TRC_EXT__VERSION macros below. - * - * Note: The extension name displayed in Tracealyzer is defined in the XML file - * in the EventGroup element (e.g. ) - * - *****************************************************************************/ -#define TRC_EXT_WIFI_NAME "aws_wifi" - -/****************************************************************************** - * _VERSION_MAJOR - * _VERSION_MINOR - * _VERSION_PATCH - * - * The version code of the extension (MAJOR.MINOR.PATCH) - * - * If you increment the version code when modifying an extension, you can still - * show old traces recorded using an earlier version of the extension. - * - * Assuming the extension name is "aws_secure_sockets", and the below version - * codes are 1 (MAJOR), 2 (MINOR), 3 (PATCH), Tracealyzer will assume the - * corresponding XML file is named "aws_secure_sockets-v1.2.3.xml". So if then - * view a trace recorded with extension version 1.2.2, those traces will look - * for "aws_secure_sockets-v1.2.2.xml" instead. - * - * Note that major and minor are stored as 8 bit values, while patch is stored - * using 16 bits. They are treated as unsigned integers, so the maximum values - * are 256, 256 and 65535. - *****************************************************************************/ -#define TRC_EXT_WIFI_VERSION_MAJOR 1 - -#define TRC_EXT_WIFI_VERSION_MINOR 0 - -#define TRC_EXT_WIFI_VERSION_PATCH 0 - -/****************************************************************************** - * _ - * The event codes used in the trace wrapper functions. Important that these - * are relative to _FIRST. - *****************************************************************************/ -#define EVENTCODE_WIFI_On (TRC_EXT_BASECODE + 0) - -#define EVENTCODE_WIFI_Off (TRC_EXT_BASECODE + 1) - -#define EVENTCODE_WIFI_ConnectAP (TRC_EXT_BASECODE + 2) - -/****************************************************************************** - * _COUNT - * The number of event codes used by this extension. Should be at least 1. - * Tracealyzer allows for events codes up to 4095. - *****************************************************************************/ -#define TRC_EXT_WIFI_COUNT 3 - - -/***** Trace Wrappers *****/ - -#include /* Including the original header file, so that custom data types are understood. */ - -static inline WIFIReturnCode_t WIFI_On__trace( void ) -{ - WIFIReturnCode_t ret = WIFI_On(); - - // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. - prvTraceStoreEvent1(EVENTCODE_WIFI_On, (uint32_t)ret); - - return ret; -} - - static inline WIFIReturnCode_t WIFI_Off__trace( void ) - { - WIFIReturnCode_t ret = WIFI_Off(); - - // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. - prvTraceStoreEvent1(EVENTCODE_WIFI_Off, (uint32_t)ret); - - return ret; - } - - static inline WIFIReturnCode_t WIFI_ConnectAP__trace( const WIFINetworkParams_t * const pxNetworkParams ) - { - WIFIReturnCode_t ret = WIFI_ConnectAP(pxNetworkParams); - - // Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. - - prvTraceStoreStringEvent(2, EVENTCODE_WIFI_ConnectAP, pxNetworkParams->pcSSID, pxNetworkParams->xSecurity, ret); - - return ret; - } - -/***** Function Redefinitions *****/ - -#define WIFI_On WIFI_On__trace - -#define WIFI_Off WIFI_Off__trace - -#define WIFI_ConnectAP WIFI_ConnectAP__trace - -#endif /* _AWS_SECURE_SOCKETS2_TZEXT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * An example of a Tracealyzer extension for tracing API calls, in this case + * for tracing selected functions in Amazon FreeRTOS/aws_wifi. + * See trcExtensions.h for information on how to use this. + * + * To create your own extension, first make sure to read the documentation + * in trcExtensions.h. Then, to create an extension header file like this + * one, you need to provide: + * + * - Extension Definitions - name and event codes of the extensions. + * + * - Trace Wrappers - calls the original function and traces the event. + * + * - Function Redefinitions - changes the function calls to the trace wrappers. + * + * See the below comments for details about these definitions. Note that you + * also need a matching .xml file for Tracealyzer to understand the data. + * See trcExtensions.h for further information. + */ + +#ifndef _AWS_WIFI_TZEXT_H +#define _AWS_WIFI_TZEXT_H + +/***** Extension Definitions (must use the same prefix!) *****/ + +/****************************************************************************** + * _NAME + * The name of the extension as a string constant. This name is used by the + * Tracealyzer host application to find the right XML file for interpreting + * the events. Assuming the extension name is "aws_secure_sockets", Tracealyzer + * will look for an XML file named "aws_secure_sockets-.xml", first in + * the folder of the current trace file, next in the Tracealyzer 4/cfg folder. + * For the VERSION part, see the TRC_EXT__VERSION macros below. + * + * Note: The extension name displayed in Tracealyzer is defined in the XML file + * in the EventGroup element (e.g. ) + * + *****************************************************************************/ +#define TRC_EXT_WIFI_NAME "aws_wifi" + +/****************************************************************************** + * _VERSION_MAJOR + * _VERSION_MINOR + * _VERSION_PATCH + * + * The version code of the extension (MAJOR.MINOR.PATCH) + * + * If you increment the version code when modifying an extension, you can still + * show old traces recorded using an earlier version of the extension. + * + * Assuming the extension name is "aws_secure_sockets", and the below version + * codes are 1 (MAJOR), 2 (MINOR), 3 (PATCH), Tracealyzer will assume the + * corresponding XML file is named "aws_secure_sockets-v1.2.3.xml". So if then + * view a trace recorded with extension version 1.2.2, those traces will look + * for "aws_secure_sockets-v1.2.2.xml" instead. + * + * Note that major and minor are stored as 8 bit values, while patch is stored + * using 16 bits. They are treated as unsigned integers, so the maximum values + * are 256, 256 and 65535. + *****************************************************************************/ +#define TRC_EXT_WIFI_VERSION_MAJOR 1 + +#define TRC_EXT_WIFI_VERSION_MINOR 0 + +#define TRC_EXT_WIFI_VERSION_PATCH 0 + +/****************************************************************************** + * _ + * The event codes used in the trace wrapper functions. Important that these + * are relative to _FIRST. + *****************************************************************************/ +#define EVENTCODE_WIFI_On ( TRC_EXT_BASECODE + 0 ) + +#define EVENTCODE_WIFI_Off ( TRC_EXT_BASECODE + 1 ) + +#define EVENTCODE_WIFI_ConnectAP ( TRC_EXT_BASECODE + 2 ) + +/****************************************************************************** + * _COUNT + * The number of event codes used by this extension. Should be at least 1. + * Tracealyzer allows for events codes up to 4095. + *****************************************************************************/ +#define TRC_EXT_WIFI_COUNT 3 + + +/***** Trace Wrappers *****/ + +#include /* Including the original header file, so that custom data types are understood. */ + +static inline WIFIReturnCode_t WIFI_On__trace( void ) +{ + WIFIReturnCode_t ret = WIFI_On(); + + /* Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. */ + prvTraceStoreEvent1( EVENTCODE_WIFI_On, ( uint32_t ) ret ); + + return ret; +} + +static inline WIFIReturnCode_t WIFI_Off__trace( void ) +{ + WIFIReturnCode_t ret = WIFI_Off(); + + /* Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. */ + prvTraceStoreEvent1( EVENTCODE_WIFI_Off, ( uint32_t ) ret ); + + return ret; +} + +static inline WIFIReturnCode_t WIFI_ConnectAP__trace( const WIFINetworkParams_t * const pxNetworkParams ) +{ + WIFIReturnCode_t ret = WIFI_ConnectAP( pxNetworkParams ); + + /* Note: The host-side xml file assumes that ret == 0 means OK, otherwise timeout/error. */ + + prvTraceStoreStringEvent( 2, EVENTCODE_WIFI_ConnectAP, pxNetworkParams->pcSSID, pxNetworkParams->xSecurity, ret ); + + return ret; +} + +/***** Function Redefinitions *****/ + +#define WIFI_On WIFI_On__trace + +#define WIFI_Off WIFI_Off__trace + +#define WIFI_ConnectAP WIFI_ConnectAP__trace + +#endif /* _AWS_SECURE_SOCKETS2_TZEXT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcAssert.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcAssert.h index 563b22243..c2703b6fd 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcAssert.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcAssert.h @@ -1,143 +1,145 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace assert APIs. - */ - -#ifndef TRC_ASSERT_H -#define TRC_ASSERT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_assert_apis Trace Asserts APIs - * @ingroup trace_recorder_apis - * @{ - */ - -#ifndef TRC_CFG_USE_TRACE_ASSERT -#error "TRC_CFG_USE_TRACE_ASSERT is not defined. Please define it in trcConfig.h" -#endif - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -/* Standard assert */ -#define TRC_ASSERT(__condition) if (!(__condition)) { prvTraceAssertCreate(__FILE__, __LINE__); return TRC_FAIL; } - -#define TRC_ASSERT_ALWAYS_EVALUATE TRC_ASSERT - -/* Standard assert with custom on fail actions */ -#define TRC_ASSERT_CUSTOM_ON_FAIL(__condition, __custom_on_fail) if (!(__condition)) { prvTraceAssertCreate(__FILE__, __LINE__); __custom_on_fail; } - -#define TRC_ASSERT_CUSTOM_ON_FAIL_ALWAYS_EVALUATE TRC_ASSERT_CUSTOM_ON_FAIL - -#if (defined(TRC_CFG_TEST_MODE) && (TRC_CFG_TEST_MODE) == 1) - -/* Asserts that two types have an equal size. Condition passed to function to avoid compilers warning about unreachable code due to constant value. */ -#define TRC_ASSERT_EQUAL_SIZE(x, y) if (!prvTraceAssertCheckCondition((TraceBaseType_t)(sizeof(x) == sizeof(y)))) { prvTraceAssertCreate(__FILE__, __LINE__); return TRC_FAIL; } - -/** - * @brief Inlined condition check to get around some compiler warnings for unused variables. - * - * @param[in] condition The condition - */ -inline TraceBaseType_t prvTraceAssertCheckCondition(TraceBaseType_t condition) -{ - return condition; -} - -#else - -#define TRC_ASSERT_EQUAL_SIZE(x, y) - -#endif - -#define TRC_ASSERT_BUFFER_SIZE (sizeof(TraceEntryHandle_t)) - -typedef struct TraceAssertBuffer -{ - uint8_t buffer[TRC_ASSERT_BUFFER_SIZE]; -} TraceAssertBuffer_t; - -/** - * @internal Initializes assert system - * - * @param[in] pxBuffer The assert data buffer - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceAssertInitialize(TraceAssertBuffer_t *pxBuffer); - -/** - * @internal Creates an assert - * - * @param[in] szFilePath File name - * @param[in] uxLineNumber Line number - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -void prvTraceAssertCreate(const char* szFilePath, TraceUnsignedBaseType_t uxLineNumber); - -/** - * @brief Retrieves the assert and line number - * - * @param[out] pxFileNameStringHandle File name string handle - * @param[out] puxLineNumber Line number - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceAssertGet(TraceStringHandle_t* pxFileNameStringHandle, TraceUnsignedBaseType_t* puxLineNumber); - -#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -#define TRC_ASSERT(__condition) - -#define TRC_ASSERT_ALWAYS_EVALUATE(__condition) (void)(__condition) - -#define TRC_ASSERT_CUSTOM_ON_FAIL(__condition, __custom_on_fail) - -#define TRC_ASSERT_CUSTOM_ON_FAIL_ALWAYS_EVALUATE(__condition, __custom_on_fail) (__condition) - -#define TRC_ASSERT_EQUAL_SIZE(x, y) - -typedef struct TraceAssertBuffer -{ - uint32_t buffer[1]; -} TraceAssertBuffer_t; - -#define xTraceAssertInitialize(pxBuffer) ((void)pxBuffer, TRC_SUCCESS) - -#define xTraceAssertGet(pxFileNameStringHandle, puxLineNumber) ((void)pxFileNameStringHandle, (void)puxLineNumber, TRC_FAIL) - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_ASSERT_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace assert APIs. + */ + +#ifndef TRC_ASSERT_H + #define TRC_ASSERT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_assert_apis Trace Asserts APIs + * @ingroup trace_recorder_apis + * @{ + */ + + #ifndef TRC_CFG_USE_TRACE_ASSERT + #error "TRC_CFG_USE_TRACE_ASSERT is not defined. Please define it in trcConfig.h" + #endif + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + +/* Standard assert */ + #define TRC_ASSERT( __condition ) if( !( __condition ) ) { prvTraceAssertCreate( __FILE__, __LINE__ ); return TRC_FAIL; } + + #define TRC_ASSERT_ALWAYS_EVALUATE TRC_ASSERT + +/* Standard assert with custom on fail actions */ + #define TRC_ASSERT_CUSTOM_ON_FAIL( __condition, __custom_on_fail ) if( !( __condition ) ) { prvTraceAssertCreate( __FILE__, __LINE__ ); __custom_on_fail; } + + #define TRC_ASSERT_CUSTOM_ON_FAIL_ALWAYS_EVALUATE TRC_ASSERT_CUSTOM_ON_FAIL + + #if ( defined( TRC_CFG_TEST_MODE ) && ( TRC_CFG_TEST_MODE ) == 1 ) + +/* Asserts that two types have an equal size. Condition passed to function to avoid compilers warning about unreachable code due to constant value. */ + #define TRC_ASSERT_EQUAL_SIZE( x, y ) if( !prvTraceAssertCheckCondition( ( TraceBaseType_t ) ( sizeof( x ) == sizeof( y ) ) ) ) { prvTraceAssertCreate( __FILE__, __LINE__ ); return TRC_FAIL; } + +/** + * @brief Inlined condition check to get around some compiler warnings for unused variables. + * + * @param[in] condition The condition + */ + inline TraceBaseType_t prvTraceAssertCheckCondition( TraceBaseType_t condition ) + { + return condition; + } + + #else /* if ( defined( TRC_CFG_TEST_MODE ) && ( TRC_CFG_TEST_MODE ) == 1 ) */ + + #define TRC_ASSERT_EQUAL_SIZE( x, y ) + + #endif /* if ( defined( TRC_CFG_TEST_MODE ) && ( TRC_CFG_TEST_MODE ) == 1 ) */ + + #define TRC_ASSERT_BUFFER_SIZE ( sizeof( TraceEntryHandle_t ) ) + + typedef struct TraceAssertBuffer + { + uint8_t buffer[ TRC_ASSERT_BUFFER_SIZE ]; + } TraceAssertBuffer_t; + +/** + * @internal Initializes assert system + * + * @param[in] pxBuffer The assert data buffer + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceAssertInitialize( TraceAssertBuffer_t * pxBuffer ); + +/** + * @internal Creates an assert + * + * @param[in] szFilePath File name + * @param[in] uxLineNumber Line number + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + void prvTraceAssertCreate( const char * szFilePath, + TraceUnsignedBaseType_t uxLineNumber ); + +/** + * @brief Retrieves the assert and line number + * + * @param[out] pxFileNameStringHandle File name string handle + * @param[out] puxLineNumber Line number + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceAssertGet( TraceStringHandle_t * pxFileNameStringHandle, + TraceUnsignedBaseType_t * puxLineNumber ); + + #else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + + #define TRC_ASSERT( __condition ) + + #define TRC_ASSERT_ALWAYS_EVALUATE( __condition ) ( void ) ( __condition ) + + #define TRC_ASSERT_CUSTOM_ON_FAIL( __condition, __custom_on_fail ) + + #define TRC_ASSERT_CUSTOM_ON_FAIL_ALWAYS_EVALUATE( __condition, __custom_on_fail ) ( __condition ) + + #define TRC_ASSERT_EQUAL_SIZE( x, y ) + + typedef struct TraceAssertBuffer + { + uint32_t buffer[ 1 ]; + } TraceAssertBuffer_t; + + #define xTraceAssertInitialize( pxBuffer ) ( ( void ) pxBuffer, TRC_SUCCESS ) + + #define xTraceAssertGet( pxFileNameStringHandle, puxLineNumber ) ( ( void ) pxFileNameStringHandle, ( void ) puxLineNumber, TRC_FAIL ) + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_ASSERT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcCounter.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcCounter.h index 086a5382c..bcf444ace 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcCounter.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcCounter.h @@ -1,154 +1,164 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace counter APIs. - */ - -#ifndef TRC_COUNTER_H -#define TRC_COUNTER_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_counter_apis Trace Counter APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @brief Sets trace counter callback. - * - * @param[in] xCallback Callback - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterSetCallback(TraceCounterCallback_t xCallback); - -/** - * @brief Creates trace counter. - * - * @param[in] szName Name. - * @param[in] xInitialValue Initial value. - * @param[in] xLowerLimit Lower limit. - * @param[in] xUpperLimit Upper limit. - * @param[out] pxCounterHandle Uninitialized trace counter handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterCreate(const char* szName, TraceBaseType_t xInitialValue, TraceBaseType_t xLowerLimit, TraceBaseType_t xUpperLimit, TraceCounterHandle_t* pxCounterHandle); - -/** - * @brief Adds value to trace counter. - * - * @param[in] xCounterHandle Initialized trace counter handle. - * @param[in] xValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterAdd(TraceCounterHandle_t xCounterHandle, TraceBaseType_t xValue); - -/** - * @brief Sets trace counter value. - * - * @param[in] xCounterHandle Initialized trace counter handle. - * @param[in] xValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterSet(TraceCounterHandle_t xCounterHandle, TraceBaseType_t xValue); - -/** - * @brief Gets trace counter value. - * - * @param[in] xCounterHandle Initialized trace counter handle. - * @param[out] pxValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterGet(TraceCounterHandle_t xCounterHandle, TraceBaseType_t* pxValue); - -/** - * @brief Increases trace counter value. - * - * @param[in] xCounterHandle Initialized trace counter handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterIncrease(TraceCounterHandle_t xCounterHandle); - -/** - * @brief Decreases trace counter value. - * - * @param[in] xCounterHandle Initialized trace counter handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterDecrease(TraceCounterHandle_t xCounterHandle); - -/** - * @brief Gets trace counter upper limit. - * - * @param[in] xCounterHandle Initialized trace counter handle. - * @param[out] pxValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterGetUpperLimit(TraceCounterHandle_t xCounterHandle, TraceBaseType_t* pxValue); - -/** - * @brief Gets trace counter lower limit. - * - * @param[in] xCounterHandle Initialized trace counter handle. - * @param[out] pxValue Value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterGetLowerLimit(TraceCounterHandle_t xCounterHandle, TraceBaseType_t* pxValue); - -/** - * @brief Gets trace counter name. - * - * @param[in] xCounterHandle Initialized trace counter handle. - * @param[out] pszName Name. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceCounterGetName(TraceCounterHandle_t xCounterHandle, const char** pszName); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_COUNTER_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace counter APIs. + */ + +#ifndef TRC_COUNTER_H + #define TRC_COUNTER_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_counter_apis Trace Counter APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @brief Sets trace counter callback. + * + * @param[in] xCallback Callback + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterSetCallback( TraceCounterCallback_t xCallback ); + +/** + * @brief Creates trace counter. + * + * @param[in] szName Name. + * @param[in] xInitialValue Initial value. + * @param[in] xLowerLimit Lower limit. + * @param[in] xUpperLimit Upper limit. + * @param[out] pxCounterHandle Uninitialized trace counter handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterCreate( const char * szName, + TraceBaseType_t xInitialValue, + TraceBaseType_t xLowerLimit, + TraceBaseType_t xUpperLimit, + TraceCounterHandle_t * pxCounterHandle ); + +/** + * @brief Adds value to trace counter. + * + * @param[in] xCounterHandle Initialized trace counter handle. + * @param[in] xValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterAdd( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t xValue ); + +/** + * @brief Sets trace counter value. + * + * @param[in] xCounterHandle Initialized trace counter handle. + * @param[in] xValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterSet( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t xValue ); + +/** + * @brief Gets trace counter value. + * + * @param[in] xCounterHandle Initialized trace counter handle. + * @param[out] pxValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterGet( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t * pxValue ); + +/** + * @brief Increases trace counter value. + * + * @param[in] xCounterHandle Initialized trace counter handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterIncrease( TraceCounterHandle_t xCounterHandle ); + +/** + * @brief Decreases trace counter value. + * + * @param[in] xCounterHandle Initialized trace counter handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterDecrease( TraceCounterHandle_t xCounterHandle ); + +/** + * @brief Gets trace counter upper limit. + * + * @param[in] xCounterHandle Initialized trace counter handle. + * @param[out] pxValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterGetUpperLimit( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t * pxValue ); + +/** + * @brief Gets trace counter lower limit. + * + * @param[in] xCounterHandle Initialized trace counter handle. + * @param[out] pxValue Value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterGetLowerLimit( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t * pxValue ); + +/** + * @brief Gets trace counter name. + * + * @param[in] xCounterHandle Initialized trace counter handle. + * @param[out] pszName Name. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceCounterGetName( TraceCounterHandle_t xCounterHandle, + const char ** pszName ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_COUNTER_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcDefines.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcDefines.h index 2a7ddc525..d1727b388 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcDefines.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcDefines.h @@ -1,182 +1,182 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Some common defines for the trace recorder. - */ - -#ifndef TRC_DEFINES_H -#define TRC_DEFINES_H - -#define TRC_SUCCESS (0) -#define TRC_FAIL (1) - -#define TRC_FREE_RUNNING_32BIT_INCR 1 -#define TRC_FREE_RUNNING_32BIT_DECR 2 -#define TRC_OS_TIMER_INCR 3 -#define TRC_OS_TIMER_DECR 4 -#define TRC_CUSTOM_TIMER_INCR 5 -#define TRC_CUSTOM_TIMER_DECR 6 - -#define TRC_STATE_IN_STARTUP 0 -#define TRC_STATE_IN_TASKSWITCH 1 -#define TRC_STATE_IN_APPLICATION 2 - -/* Start options for vTraceEnable. */ -#define TRC_START_FROM_HOST 0 -#define TRC_START 1 -#define TRC_START_AWAIT_HOST 2 - -#define TRC_ACKNOWLEDGED (0xABC99123) - -/* Command codes for TzCtrl task */ -#define CMD_SET_ACTIVE 1 /* Start (param1 = 1) or Stop (param1 = 0) */ - -/* The final command code, used to validate commands. */ -#define CMD_LAST_COMMAND 1 - -#define TRC_RECORDER_MODE_SNAPSHOT 0 -#define TRC_RECORDER_MODE_STREAMING 1 - -#define TRC_SNAPSHOT_MODE_RING_BUFFER (0x01) -#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL (0x02) - -#define TRC_RECORDER_BUFFER_ALLOCATION_STATIC (0x00) -#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC (0x01) -#define TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM (0x02) - -#define TRC_OPTION_BIT_SHIFT_IRQ_ORDER 0 -#define TRC_OPTION_BIT_SHIFT_BASE_SIZE 8 - -/******************************************************************************/ -/*** ERROR AND WARNING CODES (check using xTraceErrorGetLast) *****************/ -/******************************************************************************/ - -#define TRC_ERROR_NONE 0x00 - -#define TRC_ERROR_ASSERT 0x01 -#define TRC_ERROR_EVENT_CODE_TOO_LARGE 0x02 -#define TRC_ERROR_ISR_NESTING_OVERFLOW 0x03 -#define TRC_ERROR_DWT_NOT_SUPPORTED 0x04 -#define TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED 0x05 -#define TRC_ERROR_TZCTRLTASK_NOT_CREATED 0x06 -#define TRC_ERROR_STREAM_PORT_WRITE 0x07 - -#define TRC_WARNING_ENTRY_TABLE_SLOTS 0x08 -#define TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH 0x09 -#define TRC_WARNING_EVENT_SIZE_TRUNCATED 0x0A -#define TRC_WARNING_STREAM_PORT_READ 0x0B -#define TRC_WARNING_STREAM_PORT_WRITE 0x0C -#define TRC_WARNING_STREAM_PORT_INITIAL_BLOCKING 0x0D -#define TRC_WARNING_STACKMON_NO_SLOTS 0x0E - -/* Entry Option definitions */ -#define TRC_ENTRY_OPTION_EXCLUDED 0x00000001 -#define TRC_ENTRY_OPTION_HEAP 0x80000000 -#define TRC_ENTRY_OPTION_EXTENSION 0x40000000 -#define TRC_ENTRY_OPTION_STATE_MACHINE 0x20000000 -#define TRC_ENTRY_OPTION_STATE_MACHINE_STATE 0x10000000 -#define TRC_ENTRY_OPTION_INTERVAL 0x08000000 -#define TRC_ENTRY_OPTION_COUNTER 0x04000000 - -#define TRC_RECORDER_COMPONENT_CORE 0x00000001 -#define TRC_RECORDER_COMPONENT_ASSERT 0x00000002 -#define TRC_RECORDER_COMPONENT_BLOB 0x00000004 -#define TRC_RECORDER_COMPONENT_DIAGNOSTICS 0x00000008 -#define TRC_RECORDER_COMPONENT_ENTRY 0x00000010 -#define TRC_RECORDER_COMPONENT_ERROR 0x00000020 -#define TRC_RECORDER_COMPONENT_EVENT 0x00000040 -#define TRC_RECORDER_COMPONENT_EVENT_BUFFER 0x00000080 -#define TRC_RECORDER_COMPONENT_EXTENSION 0x00000100 -#define TRC_RECORDER_COMPONENT_HEAP 0x00000200 -#define TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER 0x00000400 -#define TRC_RECORDER_COMPONENT_INTERVAL 0x00000800 -#define TRC_RECORDER_COMPONENT_ISR 0x00001000 -#define TRC_RECORDER_COMPONENT_MULTI_CORE_EVENT_BUFFER 0x00002000 -#define TRC_RECORDER_COMPONENT_OBJECT 0x00004000 -#define TRC_RECORDER_COMPONENT_PRINT 0x00008000 -#define TRC_RECORDER_COMPONENT_STACK_MONITOR 0x00010000 -#define TRC_RECORDER_COMPONENT_STATE_MACHINE 0x00020000 -#define TRC_RECORDER_COMPONENT_STATIC_BUFFER 0x00040000 -#define TRC_RECORDER_COMPONENT_STRING 0x00080000 -#define TRC_RECORDER_COMPONENT_TASK 0x00100000 -#define TRC_RECORDER_COMPONENT_TIMESTAMP 0x00200000 -#define TRC_RECORDER_COMPONENT_COUNTER 0x00400000 - -/* Filter Groups */ -#define FilterGroup0 (uint16_t)0x0001 -#define FilterGroup1 (uint16_t)0x0002 -#define FilterGroup2 (uint16_t)0x0004 -#define FilterGroup3 (uint16_t)0x0008 -#define FilterGroup4 (uint16_t)0x0010 -#define FilterGroup5 (uint16_t)0x0020 -#define FilterGroup6 (uint16_t)0x0040 -#define FilterGroup7 (uint16_t)0x0080 -#define FilterGroup8 (uint16_t)0x0100 -#define FilterGroup9 (uint16_t)0x0200 -#define FilterGroup10 (uint16_t)0x0400 -#define FilterGroup11 (uint16_t)0x0800 -#define FilterGroup12 (uint16_t)0x1000 -#define FilterGroup13 (uint16_t)0x2000 -#define FilterGroup14 (uint16_t)0x4000 -#define FilterGroup15 (uint16_t)0x8000 - -/****************************************************************************** - * Supported ports - * - * TRC_HARDWARE_PORT_HWIndependent - * A hardware independent fallback option for event timestamping. Provides low - * resolution timestamps based on the OS tick. - * This may be used on the Win32 port, but may also be used on embedded hardware - * platforms. All time durations will be truncated to the OS tick frequency, - * typically 1 KHz. This means that a task or ISR that executes in less than - * 1 ms get an execution time of zero. - * - * TRC_HARDWARE_PORT_APPLICATION_DEFINED - * Allows for defining the port macros in other source code files. - * - * TRC_HARDWARE_PORT_Win32 - * "Accurate" timestamping based on the Windows performance counter for Win32 - * builds. Note that this gives the host machine time, not the kernel time. - * - * Hardware specific ports - * To get accurate timestamping, a hardware timer is necessary. Below are the - * available ports. Some of these are "unofficial", meaning that - * they have not yet been verified by Percepio but have been contributed by - * external developers. They should work, otherwise let us know by emailing - * support@percepio.com. Some work on any OS platform, while other are specific - * to a certain operating system. - *****************************************************************************/ - -/****** Port Name ************************************* Code ** Official ** OS Platform *********/ -#define TRC_HARDWARE_PORT_APPLICATION_DEFINED 98 /* - - */ -#define TRC_HARDWARE_PORT_NOT_SET 99 /* - - */ -#define TRC_HARDWARE_PORT_HWIndependent 0 /* Yes Any */ -#define TRC_HARDWARE_PORT_Win32 1 /* Yes FreeRTOS on Win32 */ -#define TRC_HARDWARE_PORT_Atmel_AT91SAM7 2 /* No Any */ -#define TRC_HARDWARE_PORT_Atmel_UC3A0 3 /* No Any */ -#define TRC_HARDWARE_PORT_ARM_Cortex_M 4 /* Yes Any */ -#define TRC_HARDWARE_PORT_Renesas_RX600 6 /* Yes Any */ -#define TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32 7 /* Yes Any */ -#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 8 /* Yes Any */ -#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430 9 /* No Any */ -#define TRC_HARDWARE_PORT_XILINX_PPC405 11 /* No FreeRTOS */ -#define TRC_HARDWARE_PORT_XILINX_PPC440 12 /* No FreeRTOS */ -#define TRC_HARDWARE_PORT_XILINX_MICROBLAZE 13 /* No Any */ -#define TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5 14 /* No FreeRTOS */ -#define TRC_HARDWARE_PORT_NXP_LPC210X 15 /* No Any */ -#define TRC_HARDWARE_PORT_ARM_CORTEX_A9 16 /* Yes Any */ -#define TRC_HARDWARE_PORT_POWERPC_Z4 17 /* No FreeRTOS */ -#define TRC_HARDWARE_PORT_Altera_NiosII 18 /* Yes Any (Tested with FreeRTOS) */ -#define TRC_HARDWARE_PORT_ZEPHYR 19 /* Yes Zephyr */ -#define TRC_HARDWARE_PORT_XTensa_LX6 20 /* Yes ESP-IDF FreeRTOS */ -#define TRC_HARDWARE_PORT_XTensa_LX7 21 /* Yes ESP-IDF FreeRTOS */ -#define TRC_HARDWARE_PORT_Win64 22 /* Yes FreeRTOS on Win64 */ -#define TRC_HARDWARE_PORT_XMOS_XCOREAI 23 /* Yes FreeRTOS SMP */ -#define TRC_HARDWARE_PORT_RISCV_RV32I 24 /* Yes FreeRTOS */ -#define TRC_HARDWARE_PORT_CYCLONE_V_HPS 25 /* Yes FreeRTOS */ - -#endif /* TRC_PORTDEFINES_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Some common defines for the trace recorder. + */ + +#ifndef TRC_DEFINES_H +#define TRC_DEFINES_H + +#define TRC_SUCCESS ( 0 ) +#define TRC_FAIL ( 1 ) + +#define TRC_FREE_RUNNING_32BIT_INCR 1 +#define TRC_FREE_RUNNING_32BIT_DECR 2 +#define TRC_OS_TIMER_INCR 3 +#define TRC_OS_TIMER_DECR 4 +#define TRC_CUSTOM_TIMER_INCR 5 +#define TRC_CUSTOM_TIMER_DECR 6 + +#define TRC_STATE_IN_STARTUP 0 +#define TRC_STATE_IN_TASKSWITCH 1 +#define TRC_STATE_IN_APPLICATION 2 + +/* Start options for vTraceEnable. */ +#define TRC_START_FROM_HOST 0 +#define TRC_START 1 +#define TRC_START_AWAIT_HOST 2 + +#define TRC_ACKNOWLEDGED ( 0xABC99123 ) + +/* Command codes for TzCtrl task */ +#define CMD_SET_ACTIVE 1 /* Start (param1 = 1) or Stop (param1 = 0) */ + +/* The final command code, used to validate commands. */ +#define CMD_LAST_COMMAND 1 + +#define TRC_RECORDER_MODE_SNAPSHOT 0 +#define TRC_RECORDER_MODE_STREAMING 1 + +#define TRC_SNAPSHOT_MODE_RING_BUFFER ( 0x01 ) +#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL ( 0x02 ) + +#define TRC_RECORDER_BUFFER_ALLOCATION_STATIC ( 0x00 ) +#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC ( 0x01 ) +#define TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM ( 0x02 ) + +#define TRC_OPTION_BIT_SHIFT_IRQ_ORDER 0 +#define TRC_OPTION_BIT_SHIFT_BASE_SIZE 8 + +/******************************************************************************/ +/*** ERROR AND WARNING CODES (check using xTraceErrorGetLast) *****************/ +/******************************************************************************/ + +#define TRC_ERROR_NONE 0x00 + +#define TRC_ERROR_ASSERT 0x01 +#define TRC_ERROR_EVENT_CODE_TOO_LARGE 0x02 +#define TRC_ERROR_ISR_NESTING_OVERFLOW 0x03 +#define TRC_ERROR_DWT_NOT_SUPPORTED 0x04 +#define TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED 0x05 +#define TRC_ERROR_TZCTRLTASK_NOT_CREATED 0x06 +#define TRC_ERROR_STREAM_PORT_WRITE 0x07 + +#define TRC_WARNING_ENTRY_TABLE_SLOTS 0x08 +#define TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH 0x09 +#define TRC_WARNING_EVENT_SIZE_TRUNCATED 0x0A +#define TRC_WARNING_STREAM_PORT_READ 0x0B +#define TRC_WARNING_STREAM_PORT_WRITE 0x0C +#define TRC_WARNING_STREAM_PORT_INITIAL_BLOCKING 0x0D +#define TRC_WARNING_STACKMON_NO_SLOTS 0x0E + +/* Entry Option definitions */ +#define TRC_ENTRY_OPTION_EXCLUDED 0x00000001 +#define TRC_ENTRY_OPTION_HEAP 0x80000000 +#define TRC_ENTRY_OPTION_EXTENSION 0x40000000 +#define TRC_ENTRY_OPTION_STATE_MACHINE 0x20000000 +#define TRC_ENTRY_OPTION_STATE_MACHINE_STATE 0x10000000 +#define TRC_ENTRY_OPTION_INTERVAL 0x08000000 +#define TRC_ENTRY_OPTION_COUNTER 0x04000000 + +#define TRC_RECORDER_COMPONENT_CORE 0x00000001 +#define TRC_RECORDER_COMPONENT_ASSERT 0x00000002 +#define TRC_RECORDER_COMPONENT_BLOB 0x00000004 +#define TRC_RECORDER_COMPONENT_DIAGNOSTICS 0x00000008 +#define TRC_RECORDER_COMPONENT_ENTRY 0x00000010 +#define TRC_RECORDER_COMPONENT_ERROR 0x00000020 +#define TRC_RECORDER_COMPONENT_EVENT 0x00000040 +#define TRC_RECORDER_COMPONENT_EVENT_BUFFER 0x00000080 +#define TRC_RECORDER_COMPONENT_EXTENSION 0x00000100 +#define TRC_RECORDER_COMPONENT_HEAP 0x00000200 +#define TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER 0x00000400 +#define TRC_RECORDER_COMPONENT_INTERVAL 0x00000800 +#define TRC_RECORDER_COMPONENT_ISR 0x00001000 +#define TRC_RECORDER_COMPONENT_MULTI_CORE_EVENT_BUFFER 0x00002000 +#define TRC_RECORDER_COMPONENT_OBJECT 0x00004000 +#define TRC_RECORDER_COMPONENT_PRINT 0x00008000 +#define TRC_RECORDER_COMPONENT_STACK_MONITOR 0x00010000 +#define TRC_RECORDER_COMPONENT_STATE_MACHINE 0x00020000 +#define TRC_RECORDER_COMPONENT_STATIC_BUFFER 0x00040000 +#define TRC_RECORDER_COMPONENT_STRING 0x00080000 +#define TRC_RECORDER_COMPONENT_TASK 0x00100000 +#define TRC_RECORDER_COMPONENT_TIMESTAMP 0x00200000 +#define TRC_RECORDER_COMPONENT_COUNTER 0x00400000 + +/* Filter Groups */ +#define FilterGroup0 ( uint16_t ) 0x0001 +#define FilterGroup1 ( uint16_t ) 0x0002 +#define FilterGroup2 ( uint16_t ) 0x0004 +#define FilterGroup3 ( uint16_t ) 0x0008 +#define FilterGroup4 ( uint16_t ) 0x0010 +#define FilterGroup5 ( uint16_t ) 0x0020 +#define FilterGroup6 ( uint16_t ) 0x0040 +#define FilterGroup7 ( uint16_t ) 0x0080 +#define FilterGroup8 ( uint16_t ) 0x0100 +#define FilterGroup9 ( uint16_t ) 0x0200 +#define FilterGroup10 ( uint16_t ) 0x0400 +#define FilterGroup11 ( uint16_t ) 0x0800 +#define FilterGroup12 ( uint16_t ) 0x1000 +#define FilterGroup13 ( uint16_t ) 0x2000 +#define FilterGroup14 ( uint16_t ) 0x4000 +#define FilterGroup15 ( uint16_t ) 0x8000 + +/****************************************************************************** + * Supported ports + * + * TRC_HARDWARE_PORT_HWIndependent + * A hardware independent fallback option for event timestamping. Provides low + * resolution timestamps based on the OS tick. + * This may be used on the Win32 port, but may also be used on embedded hardware + * platforms. All time durations will be truncated to the OS tick frequency, + * typically 1 KHz. This means that a task or ISR that executes in less than + * 1 ms get an execution time of zero. + * + * TRC_HARDWARE_PORT_APPLICATION_DEFINED + * Allows for defining the port macros in other source code files. + * + * TRC_HARDWARE_PORT_Win32 + * "Accurate" timestamping based on the Windows performance counter for Win32 + * builds. Note that this gives the host machine time, not the kernel time. + * + * Hardware specific ports + * To get accurate timestamping, a hardware timer is necessary. Below are the + * available ports. Some of these are "unofficial", meaning that + * they have not yet been verified by Percepio but have been contributed by + * external developers. They should work, otherwise let us know by emailing + * support@percepio.com. Some work on any OS platform, while other are specific + * to a certain operating system. + *****************************************************************************/ + +/****** Port Name ************************************* Code ** Official ** OS Platform *********/ +#define TRC_HARDWARE_PORT_APPLICATION_DEFINED 98 /* - - */ +#define TRC_HARDWARE_PORT_NOT_SET 99 /* - - */ +#define TRC_HARDWARE_PORT_HWIndependent 0 /* Yes Any */ +#define TRC_HARDWARE_PORT_Win32 1 /* Yes FreeRTOS on Win32 */ +#define TRC_HARDWARE_PORT_Atmel_AT91SAM7 2 /* No Any */ +#define TRC_HARDWARE_PORT_Atmel_UC3A0 3 /* No Any */ +#define TRC_HARDWARE_PORT_ARM_Cortex_M 4 /* Yes Any */ +#define TRC_HARDWARE_PORT_Renesas_RX600 6 /* Yes Any */ +#define TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32 7 /* Yes Any */ +#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 8 /* Yes Any */ +#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430 9 /* No Any */ +#define TRC_HARDWARE_PORT_XILINX_PPC405 11 /* No FreeRTOS */ +#define TRC_HARDWARE_PORT_XILINX_PPC440 12 /* No FreeRTOS */ +#define TRC_HARDWARE_PORT_XILINX_MICROBLAZE 13 /* No Any */ +#define TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5 14 /* No FreeRTOS */ +#define TRC_HARDWARE_PORT_NXP_LPC210X 15 /* No Any */ +#define TRC_HARDWARE_PORT_ARM_CORTEX_A9 16 /* Yes Any */ +#define TRC_HARDWARE_PORT_POWERPC_Z4 17 /* No FreeRTOS */ +#define TRC_HARDWARE_PORT_Altera_NiosII 18 /* Yes Any (Tested with FreeRTOS) */ +#define TRC_HARDWARE_PORT_ZEPHYR 19 /* Yes Zephyr */ +#define TRC_HARDWARE_PORT_XTensa_LX6 20 /* Yes ESP-IDF FreeRTOS */ +#define TRC_HARDWARE_PORT_XTensa_LX7 21 /* Yes ESP-IDF FreeRTOS */ +#define TRC_HARDWARE_PORT_Win64 22 /* Yes FreeRTOS on Win64 */ +#define TRC_HARDWARE_PORT_XMOS_XCOREAI 23 /* Yes FreeRTOS SMP */ +#define TRC_HARDWARE_PORT_RISCV_RV32I 24 /* Yes FreeRTOS */ +#define TRC_HARDWARE_PORT_CYCLONE_V_HPS 25 /* Yes FreeRTOS */ + +#endif /* TRC_PORTDEFINES_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcDiagnostics.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcDiagnostics.h index 449e19f6c..491716815 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcDiagnostics.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcDiagnostics.h @@ -1,145 +1,150 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace diagnostic APIs. - */ - -#ifndef TRC_DIAGNOSTICS_H -#define TRC_DIAGNOSTICS_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define TRC_DIAGNOSTICS_COUNT 5 - -typedef enum TraceDiagnosticsType -{ - TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH = 0x00, - TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM = 0x01, - TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED = 0x02, - TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS = 0x03, - TRC_DIAGNOSTICS_ASSERTS_TRIGGERED = 0x04, -} TraceDiagnosticsType_t; - -typedef struct TraceDiagnosticsBuffer -{ - uint8_t buffer[sizeof(TraceBaseType_t) * (TRC_DIAGNOSTICS_COUNT)]; -} TraceDiagnosticsBuffer_t; - -/** - * @internal Initialize diagnostics - * - * @param[in] pxBuffer Diagnostics buffer - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDiagnosticsInitialize(TraceDiagnosticsBuffer_t* pxBuffer); - -/** - * @brief Retrieve diagnostics value - * - * @param[in] xType Diagnostics type - * @param[out] pxValue Pointer to value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDiagnosticsGet(TraceDiagnosticsType_t xType, TraceBaseType_t* pxValue); - -/** - * @brief Set diagnostics value - * - * @param[in] xType Diagnostics type - * @param[in] xValue Value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDiagnosticsSet(TraceDiagnosticsType_t xType, TraceBaseType_t xValue); - -/** - * @brief Add to diagnostics value - * - * @param[in] xType Diagnostics type - * @param[in] xValue Value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDiagnosticsAdd(TraceDiagnosticsType_t xType, TraceBaseType_t xValue); - -/** - * @brief Increase diagnostics value - * - * @param[in] xType Diagnostics type - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDiagnosticsIncrease(TraceDiagnosticsType_t xType); - -/** - * @brief Decrease diagnostics value - * - * @param[in] xType Diagnostics type - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDiagnosticsDecrease(TraceDiagnosticsType_t xType); - -/** - * @brief Set a new diagnostics value if higher than previous value - * - * @param[in] xType Dagnostics type - * @param[in] xValue Value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDiagnosticsSetIfHigher(TraceDiagnosticsType_t xType, TraceBaseType_t xValue); - -/** - * @brief Set a new diagnostics value if lower than previous value - * - * @param[in] xType Dagnostics type - * @param[in] xValue Value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDiagnosticsSetIfLower(TraceDiagnosticsType_t xType, TraceBaseType_t xValue); - -/** - * @brief Check the diagnostics status - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDiagnosticsCheckStatus(void); - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_DIAGNOSTICS_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace diagnostic APIs. + */ + +#ifndef TRC_DIAGNOSTICS_H + #define TRC_DIAGNOSTICS_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + + #define TRC_DIAGNOSTICS_COUNT 5 + + typedef enum TraceDiagnosticsType + { + TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH = 0x00, + TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM = 0x01, + TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED = 0x02, + TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS = 0x03, + TRC_DIAGNOSTICS_ASSERTS_TRIGGERED = 0x04, + } TraceDiagnosticsType_t; + + typedef struct TraceDiagnosticsBuffer + { + uint8_t buffer[ sizeof( TraceBaseType_t ) * ( TRC_DIAGNOSTICS_COUNT ) ]; + } TraceDiagnosticsBuffer_t; + +/** + * @internal Initialize diagnostics + * + * @param[in] pxBuffer Diagnostics buffer + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDiagnosticsInitialize( TraceDiagnosticsBuffer_t * pxBuffer ); + +/** + * @brief Retrieve diagnostics value + * + * @param[in] xType Diagnostics type + * @param[out] pxValue Pointer to value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDiagnosticsGet( TraceDiagnosticsType_t xType, + TraceBaseType_t * pxValue ); + +/** + * @brief Set diagnostics value + * + * @param[in] xType Diagnostics type + * @param[in] xValue Value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDiagnosticsSet( TraceDiagnosticsType_t xType, + TraceBaseType_t xValue ); + +/** + * @brief Add to diagnostics value + * + * @param[in] xType Diagnostics type + * @param[in] xValue Value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDiagnosticsAdd( TraceDiagnosticsType_t xType, + TraceBaseType_t xValue ); + +/** + * @brief Increase diagnostics value + * + * @param[in] xType Diagnostics type + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDiagnosticsIncrease( TraceDiagnosticsType_t xType ); + +/** + * @brief Decrease diagnostics value + * + * @param[in] xType Diagnostics type + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDiagnosticsDecrease( TraceDiagnosticsType_t xType ); + +/** + * @brief Set a new diagnostics value if higher than previous value + * + * @param[in] xType Dagnostics type + * @param[in] xValue Value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDiagnosticsSetIfHigher( TraceDiagnosticsType_t xType, + TraceBaseType_t xValue ); + +/** + * @brief Set a new diagnostics value if lower than previous value + * + * @param[in] xType Dagnostics type + * @param[in] xValue Value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDiagnosticsSetIfLower( TraceDiagnosticsType_t xType, + TraceBaseType_t xValue ); + +/** + * @brief Check the diagnostics status + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDiagnosticsCheckStatus( void ); + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_DIAGNOSTICS_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEntryTable.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEntryTable.h index e022fbc8a..9f3740ef9 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEntryTable.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEntryTable.h @@ -1,258 +1,271 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace entry table APIs. - */ - -#ifndef TRC_ENTRY_TABLE_H -#define TRC_ENTRY_TABLE_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_entry_table_apis Trace Entry Table APIs - * @ingroup trace_recorder_apis - * @{ - */ - -#define TRC_ENTRY_CREATE_WITH_ADDRESS(_pvAddress, _pxEntryHandle) (xTraceEntryCreate(_pxEntryHandle) == TRC_SUCCESS ? (((TraceEntry_t*)*(_pxEntryHandle))->pvAddress = (_pvAddress), TRC_SUCCESS) : TRC_FAIL) -#define TRC_ENTRY_SET_STATE(xEntryHandle, uiStateIndex, uxState) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(((TraceEntry_t*)(xEntryHandle))->xStates[uiStateIndex] = (uxState), TRC_SUCCESS) -#define TRC_ENTRY_SET_OPTIONS(xEntryHandle, uiMask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(((TraceEntry_t*)(xEntryHandle))->uiOptions |= (uiMask), TRC_SUCCESS) -#define TRC_ENTRY_CLEAR_OPTIONS(xEntryHandle, uiMask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(((TraceEntry_t*)(xEntryHandle))->uiOptions &= ~(uiMask), TRC_SUCCESS) -#define TRC_ENTRY_GET_ADDRESS(xEntryHandle, ppvAddress) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(ppvAddress) = ((TraceEntry_t*)(xEntryHandle))->pvAddress, TRC_SUCCESS) -#define TRC_ENTRY_GET_SYMBOL(xEntryHandle, pszSymbol) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(pszSymbol) = ((TraceEntry_t*)(xEntryHandle))->szSymbol, TRC_SUCCESS) -#define TRC_ENTRY_GET_STATE(xEntryHandle, uiStateIndex, puxState) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puxState) = ((TraceEntry_t*)(xEntryHandle))->xStates[uiStateIndex], TRC_SUCCESS) -#define TRC_ENTRY_GET_OPTIONS(xEntryHandle, puiOptions) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiOptions) = ((TraceEntry_t*)(xEntryHandle))->uiOptions, TRC_SUCCESS) - -#define TRC_ENTRY_TABLE_SLOTS (TRC_CFG_ENTRY_SLOTS) -#define TRC_ENTRY_TABLE_STATE_COUNT (3) -#define TRC_ENTRY_TABLE_SYMBOL_LENGTH (TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH) -#define TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE ((((sizeof(char) * TRC_ENTRY_TABLE_SYMBOL_LENGTH) + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t)) - -/** Trace Entry Structure */ -typedef struct TraceEntry -{ - void* pvAddress; /**< */ - TraceUnsignedBaseType_t xStates[TRC_ENTRY_TABLE_STATE_COUNT]; /**< */ - uint32_t uiOptions; /**< */ - char szSymbol[TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE]; /**< */ -} TraceEntry_t; - -#define TRC_ENTRY_TABLE_SIZE (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + (sizeof(TraceEntry_t) * (TRC_ENTRY_TABLE_SLOTS))) - -/** Trace Entry Table Buffer Structure */ -typedef struct TraceEntryTableBuffer -{ - uint8_t buffer[(TRC_ENTRY_TABLE_SIZE)]; /**< */ -} TraceEntryTableBuffer_t; - -/** - * @internal Initialize trace entry table. - * - * This routine initializes the trace entry table which maps objects to - * symbolic identifiers, state information, and options. - * - * @param[in] pxBuffer Pointer to uninitialized trace entry table buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryTableInitialize(TraceEntryTableBuffer_t* pxBuffer); - -/** - * @brief Creates trace entry. - * - * @param[out] pxEntryHandle Pointer to uninitialized trace entry handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryCreate(TraceEntryHandle_t *pxEntryHandle); - -/** - * @brief Deletes trace entry. - * - * @param[in] xEntryHandle Pointer to initialized trace entry handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryDelete(TraceEntryHandle_t xEntryHandle); - -/** - * @brief Finds trace entry mapped to object address. - * - * @param[in] pvAddress Address of object. - * @param[out] pxEntryHandle Pointer to uninitialized trace entry handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryFind(void* pvAddress, TraceEntryHandle_t* pxEntryHandle); - -/** - * @brief Gets the number of entries in the trace entry table. - * - * @param[out] puiCount Count. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryGetCount(uint32_t* puiCount); - -/** - * @brief Gets trace table entry at index. - * - * @param[in] index Entry index. - * @param[out] pxEntryHandle Pointer to uninitialized trace entry handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryGetAtIndex(uint32_t index, TraceEntryHandle_t* pxEntryHandle); - -/** - * @brief Sets symbol for entry. - * - * @param[in] xEntryHandle Pointer to initialized trace entry handle. - * @param[out] szSymbol Pointer to symbol string, set by function - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntrySetSymbol(TraceEntryHandle_t xEntryHandle, const char* szSymbol); - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -/** - * @brief Creates trace entry mapped to memory address. - * - * @param[in] pvAddress Address. - * @param[out] pxEntryHandle Pointer to uninitialized trace entry handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryCreateWithAddress(void* pvAddress, TraceEntryHandle_t* pxEntryHandle); - -/** - * @brief Sets trace entry state. - * - * @param[in] xEntryHandle Pointer to initialized trace entry handle. - * @param[in] uiStateIndex Index of state (< TRC_ENTRY_TABLE_STATE_COUNT). - * @param[in] uxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntrySetState(TraceEntryHandle_t xEntryHandle, uint32_t uiStateIndex, TraceUnsignedBaseType_t uxState); - -/** - * @brief Sets trace entry option(s). - * - * @param[in] xEntryHandle Pointer to initialized trace entry handle. - * @param[in] uiMask Option(s) set mask. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntrySetOptions(TraceEntryHandle_t xEntryHandle, uint32_t uiMask); - -/** - * @brief Clears trace entry option(s). - * - * @param[in] xEntryHandle Pointer to initialized trace entry handle. - * @param[in] uiMask Options(s) clear mask. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryClearOptions(TraceEntryHandle_t xEntryHandle, uint32_t uiMask); - -/** - * @brief Gets linked address for trace entry. - * - * @param[in] xEntryHandle Pointer to initialized trace entry handle. - * @param[out] ppvAddress Address. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryGetAddress(TraceEntryHandle_t xEntryHandle, void **ppvAddress); - -/** - * @brief Gets symbol for trace entry. - * - * @param[in] xEntryHandle Pointer to initialized trace entry handle. - * @param[out] pszSymbol Symbol. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryGetSymbol(TraceEntryHandle_t xEntryHandle, const char** pszSymbol); - -/** - * @brief Gets state for trace entry. - * - * @param[in] xEntryHandle Pointer to initialized trace entry handle. - * @param[in] uiStateIndex State index (< TRC_ENTRY_TABLE_STATE_COUNT). - * @param[out] puxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryGetState(TraceEntryHandle_t xEntryHandle, uint32_t uiStateIndex, TraceUnsignedBaseType_t *puxState); - -/** - * @brief Gets options for trace entry. - * - * @param[in] xEntryHandle Pointer to initialized trace entry handle. - * @param[out] puiOptions Options. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEntryGetOptions(TraceEntryHandle_t xEntryHandle, uint32_t *puiOptions); - -#else - -#define xTraceEntryCreateWithAddress TRC_ENTRY_CREATE_WITH_ADDRESS - -#define xTraceEntrySetState TRC_ENTRY_SET_STATE -#define xTraceEntrySetOptions TRC_ENTRY_SET_OPTIONS -#define xTraceEntryClearOptions TRC_ENTRY_CLEAR_OPTIONS - -#define xTraceEntryGetAddress TRC_ENTRY_GET_ADDRESS -#define xTraceEntryGetSymbol TRC_ENTRY_GET_SYMBOL -#define xTraceEntryGetState TRC_ENTRY_GET_STATE -#define xTraceEntryGetOptions TRC_ENTRY_GET_OPTIONS - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_ENTRY_TABLE_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace entry table APIs. + */ + +#ifndef TRC_ENTRY_TABLE_H + #define TRC_ENTRY_TABLE_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_entry_table_apis Trace Entry Table APIs + * @ingroup trace_recorder_apis + * @{ + */ + + #define TRC_ENTRY_CREATE_WITH_ADDRESS( _pvAddress, _pxEntryHandle ) ( xTraceEntryCreate( _pxEntryHandle ) == TRC_SUCCESS ? ( ( ( TraceEntry_t * ) *( _pxEntryHandle ) )->pvAddress = ( _pvAddress ), TRC_SUCCESS ) : TRC_FAIL ) + #define TRC_ENTRY_SET_STATE( xEntryHandle, uiStateIndex, uxState ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( ( ( TraceEntry_t * ) ( xEntryHandle ) )->xStates[ uiStateIndex ] = ( uxState ), TRC_SUCCESS ) + #define TRC_ENTRY_SET_OPTIONS( xEntryHandle, uiMask ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( ( ( TraceEntry_t * ) ( xEntryHandle ) )->uiOptions |= ( uiMask ), TRC_SUCCESS ) + #define TRC_ENTRY_CLEAR_OPTIONS( xEntryHandle, uiMask ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( ( ( TraceEntry_t * ) ( xEntryHandle ) )->uiOptions &= ~( uiMask ), TRC_SUCCESS ) + #define TRC_ENTRY_GET_ADDRESS( xEntryHandle, ppvAddress ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( ppvAddress ) = ( ( TraceEntry_t * ) ( xEntryHandle ) )->pvAddress, TRC_SUCCESS ) + #define TRC_ENTRY_GET_SYMBOL( xEntryHandle, pszSymbol ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( pszSymbol ) = ( ( TraceEntry_t * ) ( xEntryHandle ) )->szSymbol, TRC_SUCCESS ) + #define TRC_ENTRY_GET_STATE( xEntryHandle, uiStateIndex, puxState ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( puxState ) = ( ( TraceEntry_t * ) ( xEntryHandle ) )->xStates[ uiStateIndex ], TRC_SUCCESS ) + #define TRC_ENTRY_GET_OPTIONS( xEntryHandle, puiOptions ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( puiOptions ) = ( ( TraceEntry_t * ) ( xEntryHandle ) )->uiOptions, TRC_SUCCESS ) + + #define TRC_ENTRY_TABLE_SLOTS ( TRC_CFG_ENTRY_SLOTS ) + #define TRC_ENTRY_TABLE_STATE_COUNT ( 3 ) + #define TRC_ENTRY_TABLE_SYMBOL_LENGTH ( TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH ) + #define TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE ( ( ( ( sizeof( char ) * TRC_ENTRY_TABLE_SYMBOL_LENGTH ) + ( sizeof( uint32_t ) - 1 ) ) / sizeof( uint32_t ) ) * sizeof( uint32_t ) ) + +/** Trace Entry Structure */ + typedef struct TraceEntry + { + void * pvAddress; /**< */ + TraceUnsignedBaseType_t xStates[ TRC_ENTRY_TABLE_STATE_COUNT ]; /**< */ + uint32_t uiOptions; /**< */ + char szSymbol[ TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE ]; /**< */ + } TraceEntry_t; + + #define TRC_ENTRY_TABLE_SIZE ( sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( uint32_t ) + ( sizeof( TraceEntry_t ) * ( TRC_ENTRY_TABLE_SLOTS ) ) ) + +/** Trace Entry Table Buffer Structure */ + typedef struct TraceEntryTableBuffer + { + uint8_t buffer[ ( TRC_ENTRY_TABLE_SIZE ) ]; /**< */ + } TraceEntryTableBuffer_t; + +/** + * @internal Initialize trace entry table. + * + * This routine initializes the trace entry table which maps objects to + * symbolic identifiers, state information, and options. + * + * @param[in] pxBuffer Pointer to uninitialized trace entry table buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryTableInitialize( TraceEntryTableBuffer_t * pxBuffer ); + +/** + * @brief Creates trace entry. + * + * @param[out] pxEntryHandle Pointer to uninitialized trace entry handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryCreate( TraceEntryHandle_t * pxEntryHandle ); + +/** + * @brief Deletes trace entry. + * + * @param[in] xEntryHandle Pointer to initialized trace entry handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryDelete( TraceEntryHandle_t xEntryHandle ); + +/** + * @brief Finds trace entry mapped to object address. + * + * @param[in] pvAddress Address of object. + * @param[out] pxEntryHandle Pointer to uninitialized trace entry handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryFind( void * pvAddress, + TraceEntryHandle_t * pxEntryHandle ); + +/** + * @brief Gets the number of entries in the trace entry table. + * + * @param[out] puiCount Count. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryGetCount( uint32_t * puiCount ); + +/** + * @brief Gets trace table entry at index. + * + * @param[in] index Entry index. + * @param[out] pxEntryHandle Pointer to uninitialized trace entry handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryGetAtIndex( uint32_t index, + TraceEntryHandle_t * pxEntryHandle ); + +/** + * @brief Sets symbol for entry. + * + * @param[in] xEntryHandle Pointer to initialized trace entry handle. + * @param[out] szSymbol Pointer to symbol string, set by function + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntrySetSymbol( TraceEntryHandle_t xEntryHandle, + const char * szSymbol ); + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + +/** + * @brief Creates trace entry mapped to memory address. + * + * @param[in] pvAddress Address. + * @param[out] pxEntryHandle Pointer to uninitialized trace entry handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryCreateWithAddress( void * pvAddress, + TraceEntryHandle_t * pxEntryHandle ); + +/** + * @brief Sets trace entry state. + * + * @param[in] xEntryHandle Pointer to initialized trace entry handle. + * @param[in] uiStateIndex Index of state (< TRC_ENTRY_TABLE_STATE_COUNT). + * @param[in] uxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntrySetState( TraceEntryHandle_t xEntryHandle, + uint32_t uiStateIndex, + TraceUnsignedBaseType_t uxState ); + +/** + * @brief Sets trace entry option(s). + * + * @param[in] xEntryHandle Pointer to initialized trace entry handle. + * @param[in] uiMask Option(s) set mask. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntrySetOptions( TraceEntryHandle_t xEntryHandle, + uint32_t uiMask ); + +/** + * @brief Clears trace entry option(s). + * + * @param[in] xEntryHandle Pointer to initialized trace entry handle. + * @param[in] uiMask Options(s) clear mask. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryClearOptions( TraceEntryHandle_t xEntryHandle, + uint32_t uiMask ); + +/** + * @brief Gets linked address for trace entry. + * + * @param[in] xEntryHandle Pointer to initialized trace entry handle. + * @param[out] ppvAddress Address. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryGetAddress( TraceEntryHandle_t xEntryHandle, + void ** ppvAddress ); + +/** + * @brief Gets symbol for trace entry. + * + * @param[in] xEntryHandle Pointer to initialized trace entry handle. + * @param[out] pszSymbol Symbol. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryGetSymbol( TraceEntryHandle_t xEntryHandle, + const char ** pszSymbol ); + +/** + * @brief Gets state for trace entry. + * + * @param[in] xEntryHandle Pointer to initialized trace entry handle. + * @param[in] uiStateIndex State index (< TRC_ENTRY_TABLE_STATE_COUNT). + * @param[out] puxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryGetState( TraceEntryHandle_t xEntryHandle, + uint32_t uiStateIndex, + TraceUnsignedBaseType_t * puxState ); + +/** + * @brief Gets options for trace entry. + * + * @param[in] xEntryHandle Pointer to initialized trace entry handle. + * @param[out] puiOptions Options. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEntryGetOptions( TraceEntryHandle_t xEntryHandle, + uint32_t * puiOptions ); + + #else /* if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) */ + + #define xTraceEntryCreateWithAddress TRC_ENTRY_CREATE_WITH_ADDRESS + + #define xTraceEntrySetState TRC_ENTRY_SET_STATE + #define xTraceEntrySetOptions TRC_ENTRY_SET_OPTIONS + #define xTraceEntryClearOptions TRC_ENTRY_CLEAR_OPTIONS + + #define xTraceEntryGetAddress TRC_ENTRY_GET_ADDRESS + #define xTraceEntryGetSymbol TRC_ENTRY_GET_SYMBOL + #define xTraceEntryGetState TRC_ENTRY_GET_STATE + #define xTraceEntryGetOptions TRC_ENTRY_GET_OPTIONS + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_ENTRY_TABLE_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcError.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcError.h index 414e078df..65d091d86 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcError.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcError.h @@ -1,99 +1,99 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace error APIs. - */ - -#ifndef TRC_ERROR_H -#define TRC_ERROR_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_assert_apis Trace Asserts APIs - * @ingroup trace_recorder_apis - * @{ - */ - -#define TRC_ERROR_BUFFER_SIZE (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(TraceStringHandle_t)) - -typedef struct TraceErrorBuffer -{ - uint32_t buffer[(TRC_ERROR_BUFFER_SIZE) / sizeof(uint32_t)]; -} TraceErrorBuffer_t; - -/** - * @internal Initializes the error system - * - * @param[in] pxBuffer Pointer to buffer - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceErrorInitialize(TraceErrorBuffer_t* pxBuffer); - -/** - * @brief Register a warning - * - * @param[in] uiErrorCode Label - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceWarning(uint32_t uiErrorCode); - -/** - * @brief Register an error - * - * @param[in] uiErrorCode Error code - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceError(uint32_t uiErrorCode); - -/** - * @brief Retrieve the string for the last error - * - * @param[out] pszError Error string pointer - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceErrorGetLast(const char** pszError); - -/** - * @brief Clears any errors - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceErrorClear(void); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_ERROR_H*/ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace error APIs. + */ + +#ifndef TRC_ERROR_H + #define TRC_ERROR_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_assert_apis Trace Asserts APIs + * @ingroup trace_recorder_apis + * @{ + */ + + #define TRC_ERROR_BUFFER_SIZE ( sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( TraceStringHandle_t ) ) + + typedef struct TraceErrorBuffer + { + uint32_t buffer[ ( TRC_ERROR_BUFFER_SIZE ) / sizeof( uint32_t ) ]; + } TraceErrorBuffer_t; + +/** + * @internal Initializes the error system + * + * @param[in] pxBuffer Pointer to buffer + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceErrorInitialize( TraceErrorBuffer_t * pxBuffer ); + +/** + * @brief Register a warning + * + * @param[in] uiErrorCode Label + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceWarning( uint32_t uiErrorCode ); + +/** + * @brief Register an error + * + * @param[in] uiErrorCode Error code + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceError( uint32_t uiErrorCode ); + +/** + * @brief Retrieve the string for the last error + * + * @param[out] pszError Error string pointer + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceErrorGetLast( const char ** pszError ); + +/** + * @brief Clears any errors + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceErrorClear( void ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_ERROR_H*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEvent.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEvent.h index 16ac7830a..638def362 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEvent.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEvent.h @@ -1,615 +1,635 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace event APIs. - */ - -#ifndef TRC_EVENT_H -#define TRC_EVENT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_event_apis Trace Event APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @internal Macro helper for setting trace event parameter count. - */ -#define TRC_EVENT_SET_PARAM_COUNT(id, n) (((uint16_t)(id)) | ((((uint16_t)(n)) & 0xF) << 12)) - -/** - * @internal Macro helper for getting trace event parameter count. - */ -#define TRC_EVENT_GET_PARAM_COUNT(id) (((id) >> 12) & 0xF) - -#if (TRC_CFG_CORE_COUNT > 1) -#define TRC_EVENT_SET_EVENT_COUNT(c) (((TRC_CFG_GET_CURRENT_CORE() & 0xF) << 12) | ((uint16_t)(c) & 0xFFF)) -#else -#define TRC_EVENT_SET_EVENT_COUNT(c) (uint16_t)(c) -#endif - -/** - * @internal Macro helpder for setting base event data. - */ -#define SET_BASE_EVENT_DATA(pxEvent, eventId, paramCount, eventCount) \ - ( \ - (pxEvent)->EventID = TRC_EVENT_SET_PARAM_COUNT(eventId, paramCount), \ - (pxEvent)->EventCount = TRC_EVENT_SET_EVENT_COUNT(eventCount), \ - xTraceTimestampGet(&(pxEvent)->TS) \ - ) - -/** - * @internal Macro helper for resetting trace event data. - */ -#define RESET_EVENT_DATA(p) \ - ( \ - (p)->pvBlob = 0, \ - (p)->size = 0, \ - (p)->offset = 0 \ - ) - -/** - * @internal Macro optimization for getting trace event size. - */ -#define TRC_EVENT_GET_SIZE(pvAddress, puiSize) (*(uint32_t*)(puiSize) = sizeof(TraceBaseEvent_t) + (TRC_EVENT_GET_PARAM_COUNT(((TraceBaseEvent_t*)(pvAddress))->EventID)) * sizeof(uint32_t), TRC_SUCCESS) - -/** - * @internal Macro optimization for getting trace event data pointer with an offset. - */ -#define TRC_EVENT_GET_RAW_DATA(xEventHandle, uiOffset, uiSize, ppvData) ((void)(uiSize), *(void**)(ppvData) = (void*)&((uint8_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[uiOffset], TRC_SUCCESS) - -/** - * @internal Macro optimization for getting trace event payload pointer with an offset. - */ -#define TRC_EVENT_GET_PAYLOAD(xEventHandle, uiOffset, uiSize, ppvData) ((void)(uiSize), *(void**)(ppvData) = (void*)&((uint8_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[sizeof(TraceBaseEvent_t) + (uiOffset)], TRC_SUCCESS) - -/** - * @internal Macro optimization for getting trace event remaining payload size. - */ -#define TRC_EVENT_PAYLOAD_REMAINING(xEventHandle, puiValue) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(uint32_t*)(puiValue) = ((TraceEventData_t*)(xEventHandle))->size - ((TraceEventData_t*)(xEventHandle))->offset, TRC_SUCCESS) - -/** - * @internal Macro optimization for getting trace event used payload size. - */ -#define TRC_EVENT_PAYLOAD_USED(xEventHandle, puiValue) (*(uint32_t*)(puiValue) = ((TraceEventData_t*)(xEventHandle))->offset - sizeof(TraceBaseEvent_t), TRC_SUCCESS) - -/** - * @internal Macro optimization getting trace event payload size. - */ -#define TRC_EVENT_PAYLOAD_SIZE(xEventHandle, puiValue) (*(uint32_t*)(puiValue) = ((TraceEventData_t*)(xEventHandle))->size - sizeof(TraceBaseEvent_t), TRC_SUCCESS) - -/** - * @internal Macro optimization for adding a pointer address to trace event. - */ -#define TRC_EVENT_ADD_POINTER(xEventHandle, value) \ - TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ - ((void**)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(void*)] = (value), \ - ((TraceEventData_t*)(xEventHandle))->offset += sizeof(void*), \ - TRC_SUCCESS \ - ) - -/** - * @internal Macro optimization for adding a unsigned base type to trace event. - */ -#define TRC_EVENT_ADD_UNSIGNED_BASE_TYPE(xEventHandle, value) \ - TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ - ((TraceUnsignedBaseType_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(TraceUnsignedBaseType_t)] = (value), \ - ((TraceEventData_t*)(xEventHandle))->offset += sizeof(TraceUnsignedBaseType_t), \ - TRC_SUCCESS \ - ) - -/** - * @internal Macro optimization for adding a 32-bit value to trace event. - */ -#define TRC_EVENT_ADD_32(xEventHandle, value) \ - TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ - ((uint32_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(uint32_t)] = (value), \ - ((TraceEventData_t*)(xEventHandle))->offset += sizeof(uint32_t), \ - TRC_SUCCESS \ - ) - -/** - * @internal Macro optimization for adding a 16-bit value to trace event. - */ -#define TRC_EVENT_ADD_16(xEventHandle, value) \ - TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ - ((uint16_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(uint16_t)] = (value), \ - ((TraceEventData_t*)(xEventHandle))->offset += sizeof(uint16_t), \ - TRC_SUCCESS \ - ) - -/** - * @internal Macro optimization for adding a 8-bit value to trace event. - */ -#define TRC_EVENT_ADD_8(xEventHandle, value) \ - TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ - ((uint8_t*)((TraceEventData_t*)(xEventHandle))->pvBlob)[((TraceEventData_t*)(xEventHandle))->offset / sizeof(uint8_t)] = (value), \ - ((TraceEventData_t*)(xEventHandle))->offset += sizeof(uint8_t), \ - TRC_SUCCESS \ - ) - -/** - * @internal Macro optimization for beginning an offline trace event. - */ -#define TRC_EVENT_BEGIN_OFFLINE(uiEventCode, uiPayloadSize, pxEventHandle) \ - ( \ - (xTraceEventBeginRawOffline(sizeof(TraceBaseEvent_t) + (uiPayloadSize), pxEventHandle)) == TRC_SUCCESS ? \ - ( \ - pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter++, \ - SET_BASE_EVENT_DATA((TraceBaseEvent_t*)(((TraceEventData_t*)*(pxEventHandle))->pvBlob), \ - uiEventCode, \ - (((TraceEventData_t*)*(pxEventHandle))->size - sizeof(TraceBaseEvent_t)) / sizeof(uint32_t), \ - pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventCounter), \ - ((TraceEventData_t*)*(pxEventHandle))->offset += sizeof(TraceBaseEvent_t), \ - TRC_SUCCESS \ - ) : TRC_FAIL \ - ) - -/** - * @internal Macro optimization for ending an offline trace event. - */ -#define TRC_EVENT_END_OFFLINE(xEventHandle) \ - TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( \ - xTraceStreamPortCommit(((TraceEventData_t*)(xEventHandle))->pvBlob, \ - ((TraceEventData_t*)(xEventHandle))->size, &DUMMY_iTraceBytesCommitted), \ - RESET_EVENT_DATA((TraceEventData_t*)(xEventHandle)), \ - TRC_SUCCESS \ - ) - -/** - * @internal Trace Base Event Structure - */ -typedef struct { - uint16_t EventID; /**< */ - uint16_t EventCount; /**< */ - uint32_t TS; /**< */ -} TraceBaseEvent_t; - -/** - * @internal Trace Event Data Structure - */ -typedef struct TraceEventData -{ - void* pvBlob; /**< */ - uint32_t size; /**< */ - uint32_t offset; /**< */ -} TraceEventData_t; - -/** - * @internal Trace Core Event Data Structure - */ -typedef struct TraceCoreEventData -{ - TraceEventData_t eventData[(TRC_CFG_MAX_ISR_NESTING)+1]; /**< */ - uint32_t eventCounter; /**< */ -} TraceCoreEventData_t; - -/** - * @internal Trace Event Data Table Structure. - */ -typedef struct TraceEventDataTable -{ - TraceCoreEventData_t coreEventData[TRC_CFG_CORE_COUNT]; /**< Holds data about current event for each core/isr depth */ -} TraceEventDataTable_t; - -#define TRC_EVENT_DATA_BUFFER_SIZE (sizeof(TraceEventDataTable_t)) - -/** - * @internal Trace Event Data Buffer Structure. - */ -typedef struct TraceEventDataBuffer -{ - uint8_t buffer[TRC_EVENT_DATA_BUFFER_SIZE]; /**< */ -} TraceEventDataBuffer_t; - -extern TraceEventDataTable_t* pxTraceEventDataTable; - -/** - * @internal Initialize event trace system. - * - * @param[in] pxBuffer Pointer to memory that will be used by the event - * trace system. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventInitialize(TraceEventDataBuffer_t* pxBuffer); - -/** - * @brief Gets trace event size. - * - * @param[in] pvAddress Pointer to initialized trace event. - * @param[out] puiSize Size. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventGetSize(void* pvAddress, uint32_t* puiSize); - -/** - * @internal Begins a raw trace event offline. - * - * This routine begins a trace event with specified size. Must call xTraceEventEnd() - * to finalize event creation. Does not care about RecorderEnabled. - * - * @param[in] uiSize Size. - * @param[in] pxEventHandle Pointer to initialized trace event. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventBeginRawOffline(uint32_t uiSize, TraceEventHandle_t* pxEventHandle); - -/** - * @internal Begins a blocking trace event offline. - * - * This routine begins a trace event with specified size. Must call xTraceEventEnd() - * to finalize event creation. Does not care about RecorderEnabled. - * - * @param[in] uiSize Size. - * @param[in] pxEventHandle Pointer to initialized trace event. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventBeginRawOfflineBlocking(uint32_t uiSize, TraceEventHandle_t* pxEventHandle); - -/** - * @internal Begins a trace event offline. - * - * This routine begins a trace event with specified size. Must call xTraceEventEnd() - * to finalize event creation. Does not care about RecorderEnabled. - * - * @param[in] uiSize Size. - * @param[in] pxEventHandle Pointer to initialized trace event. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventBeginOffline TRC_EVENT_BEGIN_OFFLINE - -/** - * @brief Begins a trace event. - * - * This routine begins a trace event with specified size. Must call xTraceEventEnd() - * to finalize event creation. Does not care about RecorderEnabled. - * - * @param[in] uiSize Size. - * @param[in] pxEventHandle Pointer to initialized trace event. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventBegin(uiEventCode, uiTotalPayloadSize, pxEventHandle) \ - (xTraceIsRecorderEnabled() ? xTraceEventBeginOffline(uiEventCode, uiTotalPayloadSize, pxEventHandle) : TRC_FAIL) - -/** - * @internal Ends a trace event offline. - * - * This routine ends the event that was begun by calling on xTraceEventBegin(). - * Does not care about uiRecorderEnabled. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventEndOffline(TraceEventHandle_t xEventHandle); - -/** - * @internal Ends a blocking event offline. - * - * Ends the event that was begun by calling on xTraceEventBegin() - * - * @param[in] xEventHandle Pointer to initialized trace event. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventEndOfflineBlocking(TraceEventHandle_t xEventHandle); - -/** - * @brief Ends a trace event. - * - * This routine ends the event that was begun by calling on xTraceEventBegin(). - * Does not care about uiRecorderEnabled. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventEnd(xEventHandle) \ - (xTraceIsRecorderEnabled() == 0 ? TRC_FAIL : xTraceEventEndOffline(xEventHandle)) - -/** - * @brief Adds data to event payload. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] pvData Pointer to data. - * @param[in] uiSize Size. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventAddData(TraceEventHandle_t xEventHandle, void* pvData, uint32_t uiSize); - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -/** - * @brief Gets trace event data pointer with an offset. - * - * This routine gets a trace event data pointer with an offset. It also verfies - * that the size so it won't go outside its buffer. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] uiOffset Offset. - * @param[in] uiSize Size. - * @param[out] ppvData Data. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventGetRawData(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData); - -/** - * @brief Gets trace event payload pointer with an offset. - * - * This routine gets a trace event payload pointer with an offset. It also verifies - * that the size so it won't go outside its payload buffer. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] uiOffset Offset. - * @param[in] uiSize Size. - * @param[out] ppvData Data. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventGetPayload(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData); - -/** - * @brief Gets the amount of remaining trace event payload. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[out] puiValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventPayloadRemaining(TraceEventHandle_t xEventHandle, uint32_t* puiValue); - -/** - * @brief Gets the amount of used trace event payload. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[out] puiValue Value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventPayloadUsed(TraceEventHandle_t xEventHandle, uint32_t* puiValue); - -/** - * @brief Gets trace event payload size. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[out] puiValue Value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventPayloadSize(TraceEventHandle_t xEventHandle, uint32_t* puiValue); - -/** - * @brief Adds an unsigned base type value as trace event payload - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] uxValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventAddUnsignedBaseType(TraceEventHandle_t xEventHandle, TraceUnsignedBaseType_t uxValue); - -/** - * @brief Adds a pointer address as trace event payload - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] pvAddress Address. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventAddPointer(TraceEventHandle_t xEventHandle, void *pvAddress); - -/** - * @brief Adds an uint32_t as trace event payload - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] value Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventAdd32(TraceEventHandle_t xEventHandle, uint32_t value); - -/** - * @brief Adds an uint16_t as trace event payload - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] value Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventAdd16(TraceEventHandle_t xEventHandle, uint16_t value); - -/** - * @brief Adds an uint8_t as trace event payload. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] value Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventAdd8(TraceEventHandle_t xEventHandle, uint8_t value); - -#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** - * @brief Gets trace event size. - * - * @param[in] pvAddress Pointer to initialized trace event. - * @param[out] puiSize Size. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventGetSize(pvAddress, puiSize) (*(uint32_t*)(puiSize) = sizeof(TraceBaseEvent_t) + (TRC_EVENT_GET_PARAM_COUNT(((TraceBaseEvent_t*)(pvAddress))->EventID)) * sizeof(uint32_t), TRC_SUCCESS) - -/** - * @brief Gets trace event data pointer with an offset. - * - * This routine gets a trace event data pointer with an offset. It also verfies - * that the size so it won't go outside its buffer. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] uiOffset Offset. - * @param[in] uiSize Size. - * @param[out] ppvData Data. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventGetRawData TRC_EVENT_GET_RAW_DATA - -/** - * @brief Gets trace event payload pointer with an offset. - * - * This routine gets a trace event payload pointer with an offset. It also verifies - * that the size so it won't go outside its payload buffer. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] uiOffset Offset. - * @param[in] uiSize Size. - * @param[out] ppvData Data. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventGetPayload TRC_EVENT_GET_PAYLOAD - -/** - * @brief Gets the amount of remaining trace event payload. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[out] puiValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventPayloadRemaining TRC_EVENT_PAYLOAD_REMAINING - -/** - * @brief Gets the amount of used trace event payload. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[out] puiValue Value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventPayloadUsed TRC_EVENT_PAYLOAD_USED - -/** - * @brief Gets trace event payload size. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[out] puiValue Value - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventPayloadSize TRC_EVENT_PAYLOAD_SIZE - -/* Adds a pointer as event payload with no errors checks */ -#define xTraceEventAddPointer TRC_EVENT_ADD_POINTER - -/** - * @brief Adds an unsigned base type value as trace event payload - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] uxValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventAddUnsignedBaseType TRC_EVENT_ADD_UNSIGNED_BASE_TYPE - -/** - * @brief Adds an uint32_t as trace event payload - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] value Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventAdd32 TRC_EVENT_ADD_32 - -/** - * @brief Adds an uint16_t as trace event payload - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] value Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventAdd16 TRC_EVENT_ADD_16 - -/** - * @brief Adds an uint8_t as trace event payload. - * - * @param[in] xEventHandle Pointer to initialized trace event. - * @param[in] value Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceEventAdd8 TRC_EVENT_ADD_8 - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_EVENT_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace event APIs. + */ + +#ifndef TRC_EVENT_H + #define TRC_EVENT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_event_apis Trace Event APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @internal Macro helper for setting trace event parameter count. + */ + #define TRC_EVENT_SET_PARAM_COUNT( id, n ) ( ( ( uint16_t ) ( id ) ) | ( ( ( ( uint16_t ) ( n ) ) & 0xF ) << 12 ) ) + +/** + * @internal Macro helper for getting trace event parameter count. + */ + #define TRC_EVENT_GET_PARAM_COUNT( id ) ( ( ( id ) >> 12 ) & 0xF ) + + #if ( TRC_CFG_CORE_COUNT > 1 ) + #define TRC_EVENT_SET_EVENT_COUNT( c ) ( ( ( TRC_CFG_GET_CURRENT_CORE() & 0xF ) << 12 ) | ( ( uint16_t ) ( c ) & 0xFFF ) ) + #else + #define TRC_EVENT_SET_EVENT_COUNT( c ) ( uint16_t ) ( c ) + #endif + +/** + * @internal Macro helpder for setting base event data. + */ + #define SET_BASE_EVENT_DATA( pxEvent, eventId, paramCount, eventCount ) \ + ( \ + ( pxEvent )->EventID = TRC_EVENT_SET_PARAM_COUNT( eventId, paramCount ), \ + ( pxEvent )->EventCount = TRC_EVENT_SET_EVENT_COUNT( eventCount ), \ + xTraceTimestampGet( &( pxEvent )->TS ) \ + ) + +/** + * @internal Macro helper for resetting trace event data. + */ + #define RESET_EVENT_DATA( p ) \ + ( \ + ( p )->pvBlob = 0, \ + ( p )->size = 0, \ + ( p )->offset = 0 \ + ) + +/** + * @internal Macro optimization for getting trace event size. + */ + #define TRC_EVENT_GET_SIZE( pvAddress, puiSize ) ( *( uint32_t * ) ( puiSize ) = sizeof( TraceBaseEvent_t ) + ( TRC_EVENT_GET_PARAM_COUNT( ( ( TraceBaseEvent_t * ) ( pvAddress ) )->EventID ) ) * sizeof( uint32_t ), TRC_SUCCESS ) + +/** + * @internal Macro optimization for getting trace event data pointer with an offset. + */ + #define TRC_EVENT_GET_RAW_DATA( xEventHandle, uiOffset, uiSize, ppvData ) ( ( void ) ( uiSize ), *( void ** ) ( ppvData ) = ( void * ) &( ( uint8_t * ) ( ( TraceEventData_t * ) ( xEventHandle ) )->pvBlob )[ uiOffset ], TRC_SUCCESS ) + +/** + * @internal Macro optimization for getting trace event payload pointer with an offset. + */ + #define TRC_EVENT_GET_PAYLOAD( xEventHandle, uiOffset, uiSize, ppvData ) ( ( void ) ( uiSize ), *( void ** ) ( ppvData ) = ( void * ) &( ( uint8_t * ) ( ( TraceEventData_t * ) ( xEventHandle ) )->pvBlob )[ sizeof( TraceBaseEvent_t ) + ( uiOffset ) ], TRC_SUCCESS ) + +/** + * @internal Macro optimization for getting trace event remaining payload size. + */ + #define TRC_EVENT_PAYLOAD_REMAINING( xEventHandle, puiValue ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( uint32_t * ) ( puiValue ) = ( ( TraceEventData_t * ) ( xEventHandle ) )->size - ( ( TraceEventData_t * ) ( xEventHandle ) )->offset, TRC_SUCCESS ) + +/** + * @internal Macro optimization for getting trace event used payload size. + */ + #define TRC_EVENT_PAYLOAD_USED( xEventHandle, puiValue ) ( *( uint32_t * ) ( puiValue ) = ( ( TraceEventData_t * ) ( xEventHandle ) )->offset - sizeof( TraceBaseEvent_t ), TRC_SUCCESS ) + +/** + * @internal Macro optimization getting trace event payload size. + */ + #define TRC_EVENT_PAYLOAD_SIZE( xEventHandle, puiValue ) ( *( uint32_t * ) ( puiValue ) = ( ( TraceEventData_t * ) ( xEventHandle ) )->size - sizeof( TraceBaseEvent_t ), TRC_SUCCESS ) + +/** + * @internal Macro optimization for adding a pointer address to trace event. + */ + #define TRC_EVENT_ADD_POINTER( xEventHandle, value ) \ + TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ + ( ( void ** ) ( ( TraceEventData_t * ) ( xEventHandle ) )->pvBlob )[ ( ( TraceEventData_t * ) ( xEventHandle ) )->offset / sizeof( void * ) ] = ( value ), \ + ( ( TraceEventData_t * ) ( xEventHandle ) )->offset += sizeof( void * ), \ + TRC_SUCCESS \ + ) + +/** + * @internal Macro optimization for adding a unsigned base type to trace event. + */ + #define TRC_EVENT_ADD_UNSIGNED_BASE_TYPE( xEventHandle, value ) \ + TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ + ( ( TraceUnsignedBaseType_t * ) ( ( TraceEventData_t * ) ( xEventHandle ) )->pvBlob )[ ( ( TraceEventData_t * ) ( xEventHandle ) )->offset / sizeof( TraceUnsignedBaseType_t ) ] = ( value ), \ + ( ( TraceEventData_t * ) ( xEventHandle ) )->offset += sizeof( TraceUnsignedBaseType_t ), \ + TRC_SUCCESS \ + ) + +/** + * @internal Macro optimization for adding a 32-bit value to trace event. + */ + #define TRC_EVENT_ADD_32( xEventHandle, value ) \ + TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ + ( ( uint32_t * ) ( ( TraceEventData_t * ) ( xEventHandle ) )->pvBlob )[ ( ( TraceEventData_t * ) ( xEventHandle ) )->offset / sizeof( uint32_t ) ] = ( value ), \ + ( ( TraceEventData_t * ) ( xEventHandle ) )->offset += sizeof( uint32_t ), \ + TRC_SUCCESS \ + ) + +/** + * @internal Macro optimization for adding a 16-bit value to trace event. + */ + #define TRC_EVENT_ADD_16( xEventHandle, value ) \ + TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ + ( ( uint16_t * ) ( ( TraceEventData_t * ) ( xEventHandle ) )->pvBlob )[ ( ( TraceEventData_t * ) ( xEventHandle ) )->offset / sizeof( uint16_t ) ] = ( value ), \ + ( ( TraceEventData_t * ) ( xEventHandle ) )->offset += sizeof( uint16_t ), \ + TRC_SUCCESS \ + ) + +/** + * @internal Macro optimization for adding a 8-bit value to trace event. + */ + #define TRC_EVENT_ADD_8( xEventHandle, value ) \ + TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( \ + ( ( uint8_t * ) ( ( TraceEventData_t * ) ( xEventHandle ) )->pvBlob )[ ( ( TraceEventData_t * ) ( xEventHandle ) )->offset / sizeof( uint8_t ) ] = ( value ), \ + ( ( TraceEventData_t * ) ( xEventHandle ) )->offset += sizeof( uint8_t ), \ + TRC_SUCCESS \ + ) + +/** + * @internal Macro optimization for beginning an offline trace event. + */ + #define TRC_EVENT_BEGIN_OFFLINE( uiEventCode, uiPayloadSize, pxEventHandle ) \ + ( \ + ( xTraceEventBeginRawOffline( sizeof( TraceBaseEvent_t ) + ( uiPayloadSize ), pxEventHandle ) ) == TRC_SUCCESS ? \ + ( \ + pxTraceEventDataTable->coreEventData[ TRC_CFG_GET_CURRENT_CORE() ].eventCounter++, \ + SET_BASE_EVENT_DATA( ( TraceBaseEvent_t * ) ( ( ( TraceEventData_t * ) *( pxEventHandle ) )->pvBlob ), \ + uiEventCode, \ + ( ( ( TraceEventData_t * ) *( pxEventHandle ) )->size - sizeof( TraceBaseEvent_t ) ) / sizeof( uint32_t ), \ + pxTraceEventDataTable->coreEventData[ TRC_CFG_GET_CURRENT_CORE() ].eventCounter ), \ + ( ( TraceEventData_t * ) *( pxEventHandle ) )->offset += sizeof( TraceBaseEvent_t ), \ + TRC_SUCCESS \ + ) : TRC_FAIL \ + ) + +/** + * @internal Macro optimization for ending an offline trace event. + */ + #define TRC_EVENT_END_OFFLINE( xEventHandle ) \ + TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( \ + xTraceStreamPortCommit( ( ( TraceEventData_t * ) ( xEventHandle ) )->pvBlob, \ + ( ( TraceEventData_t * ) ( xEventHandle ) )->size, &DUMMY_iTraceBytesCommitted ), \ + RESET_EVENT_DATA( ( TraceEventData_t * ) ( xEventHandle ) ), \ + TRC_SUCCESS \ + ) + +/** + * @internal Trace Base Event Structure + */ + typedef struct + { + uint16_t EventID; /**< */ + uint16_t EventCount; /**< */ + uint32_t TS; /**< */ + } TraceBaseEvent_t; + +/** + * @internal Trace Event Data Structure + */ + typedef struct TraceEventData + { + void * pvBlob; /**< */ + uint32_t size; /**< */ + uint32_t offset; /**< */ + } TraceEventData_t; + +/** + * @internal Trace Core Event Data Structure + */ + typedef struct TraceCoreEventData + { + TraceEventData_t eventData[ ( TRC_CFG_MAX_ISR_NESTING ) + 1 ]; /**< */ + uint32_t eventCounter; /**< */ + } TraceCoreEventData_t; + +/** + * @internal Trace Event Data Table Structure. + */ + typedef struct TraceEventDataTable + { + TraceCoreEventData_t coreEventData[ TRC_CFG_CORE_COUNT ]; /**< Holds data about current event for each core/isr depth */ + } TraceEventDataTable_t; + + #define TRC_EVENT_DATA_BUFFER_SIZE ( sizeof( TraceEventDataTable_t ) ) + +/** + * @internal Trace Event Data Buffer Structure. + */ + typedef struct TraceEventDataBuffer + { + uint8_t buffer[ TRC_EVENT_DATA_BUFFER_SIZE ]; /**< */ + } TraceEventDataBuffer_t; + + extern TraceEventDataTable_t * pxTraceEventDataTable; + +/** + * @internal Initialize event trace system. + * + * @param[in] pxBuffer Pointer to memory that will be used by the event + * trace system. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventInitialize( TraceEventDataBuffer_t * pxBuffer ); + +/** + * @brief Gets trace event size. + * + * @param[in] pvAddress Pointer to initialized trace event. + * @param[out] puiSize Size. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventGetSize( void * pvAddress, + uint32_t * puiSize ); + +/** + * @internal Begins a raw trace event offline. + * + * This routine begins a trace event with specified size. Must call xTraceEventEnd() + * to finalize event creation. Does not care about RecorderEnabled. + * + * @param[in] uiSize Size. + * @param[in] pxEventHandle Pointer to initialized trace event. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventBeginRawOffline( uint32_t uiSize, + TraceEventHandle_t * pxEventHandle ); + +/** + * @internal Begins a blocking trace event offline. + * + * This routine begins a trace event with specified size. Must call xTraceEventEnd() + * to finalize event creation. Does not care about RecorderEnabled. + * + * @param[in] uiSize Size. + * @param[in] pxEventHandle Pointer to initialized trace event. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventBeginRawOfflineBlocking( uint32_t uiSize, + TraceEventHandle_t * pxEventHandle ); + +/** + * @internal Begins a trace event offline. + * + * This routine begins a trace event with specified size. Must call xTraceEventEnd() + * to finalize event creation. Does not care about RecorderEnabled. + * + * @param[in] uiSize Size. + * @param[in] pxEventHandle Pointer to initialized trace event. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventBeginOffline TRC_EVENT_BEGIN_OFFLINE + +/** + * @brief Begins a trace event. + * + * This routine begins a trace event with specified size. Must call xTraceEventEnd() + * to finalize event creation. Does not care about RecorderEnabled. + * + * @param[in] uiSize Size. + * @param[in] pxEventHandle Pointer to initialized trace event. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventBegin( uiEventCode, uiTotalPayloadSize, pxEventHandle ) \ + ( xTraceIsRecorderEnabled() ? xTraceEventBeginOffline( uiEventCode, uiTotalPayloadSize, pxEventHandle ) : TRC_FAIL ) + +/** + * @internal Ends a trace event offline. + * + * This routine ends the event that was begun by calling on xTraceEventBegin(). + * Does not care about uiRecorderEnabled. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventEndOffline( TraceEventHandle_t xEventHandle ); + +/** + * @internal Ends a blocking event offline. + * + * Ends the event that was begun by calling on xTraceEventBegin() + * + * @param[in] xEventHandle Pointer to initialized trace event. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventEndOfflineBlocking( TraceEventHandle_t xEventHandle ); + +/** + * @brief Ends a trace event. + * + * This routine ends the event that was begun by calling on xTraceEventBegin(). + * Does not care about uiRecorderEnabled. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventEnd( xEventHandle ) \ + ( xTraceIsRecorderEnabled() == 0 ? TRC_FAIL : xTraceEventEndOffline( xEventHandle ) ) + +/** + * @brief Adds data to event payload. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] pvData Pointer to data. + * @param[in] uiSize Size. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventAddData( TraceEventHandle_t xEventHandle, + void * pvData, + uint32_t uiSize ); + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + +/** + * @brief Gets trace event data pointer with an offset. + * + * This routine gets a trace event data pointer with an offset. It also verfies + * that the size so it won't go outside its buffer. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] uiOffset Offset. + * @param[in] uiSize Size. + * @param[out] ppvData Data. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventGetRawData( TraceEventHandle_t xEventHandle, + uint32_t uiOffset, + uint32_t uiSize, + void ** ppvData ); + +/** + * @brief Gets trace event payload pointer with an offset. + * + * This routine gets a trace event payload pointer with an offset. It also verifies + * that the size so it won't go outside its payload buffer. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] uiOffset Offset. + * @param[in] uiSize Size. + * @param[out] ppvData Data. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventGetPayload( TraceEventHandle_t xEventHandle, + uint32_t uiOffset, + uint32_t uiSize, + void ** ppvData ); + +/** + * @brief Gets the amount of remaining trace event payload. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[out] puiValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventPayloadRemaining( TraceEventHandle_t xEventHandle, + uint32_t * puiValue ); + +/** + * @brief Gets the amount of used trace event payload. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[out] puiValue Value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventPayloadUsed( TraceEventHandle_t xEventHandle, + uint32_t * puiValue ); + +/** + * @brief Gets trace event payload size. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[out] puiValue Value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventPayloadSize( TraceEventHandle_t xEventHandle, + uint32_t * puiValue ); + +/** + * @brief Adds an unsigned base type value as trace event payload + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] uxValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventAddUnsignedBaseType( TraceEventHandle_t xEventHandle, + TraceUnsignedBaseType_t uxValue ); + +/** + * @brief Adds a pointer address as trace event payload + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] pvAddress Address. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventAddPointer( TraceEventHandle_t xEventHandle, + void * pvAddress ); + +/** + * @brief Adds an uint32_t as trace event payload + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] value Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventAdd32( TraceEventHandle_t xEventHandle, + uint32_t value ); + +/** + * @brief Adds an uint16_t as trace event payload + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] value Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventAdd16( TraceEventHandle_t xEventHandle, + uint16_t value ); + +/** + * @brief Adds an uint8_t as trace event payload. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] value Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventAdd8( TraceEventHandle_t xEventHandle, + uint8_t value ); + + #else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** + * @brief Gets trace event size. + * + * @param[in] pvAddress Pointer to initialized trace event. + * @param[out] puiSize Size. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventGetSize( pvAddress, puiSize ) ( *( uint32_t * ) ( puiSize ) = sizeof( TraceBaseEvent_t ) + ( TRC_EVENT_GET_PARAM_COUNT( ( ( TraceBaseEvent_t * ) ( pvAddress ) )->EventID ) ) * sizeof( uint32_t ), TRC_SUCCESS ) + +/** + * @brief Gets trace event data pointer with an offset. + * + * This routine gets a trace event data pointer with an offset. It also verfies + * that the size so it won't go outside its buffer. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] uiOffset Offset. + * @param[in] uiSize Size. + * @param[out] ppvData Data. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventGetRawData TRC_EVENT_GET_RAW_DATA + +/** + * @brief Gets trace event payload pointer with an offset. + * + * This routine gets a trace event payload pointer with an offset. It also verifies + * that the size so it won't go outside its payload buffer. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] uiOffset Offset. + * @param[in] uiSize Size. + * @param[out] ppvData Data. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventGetPayload TRC_EVENT_GET_PAYLOAD + +/** + * @brief Gets the amount of remaining trace event payload. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[out] puiValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventPayloadRemaining TRC_EVENT_PAYLOAD_REMAINING + +/** + * @brief Gets the amount of used trace event payload. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[out] puiValue Value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventPayloadUsed TRC_EVENT_PAYLOAD_USED + +/** + * @brief Gets trace event payload size. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[out] puiValue Value + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventPayloadSize TRC_EVENT_PAYLOAD_SIZE + +/* Adds a pointer as event payload with no errors checks */ + #define xTraceEventAddPointer TRC_EVENT_ADD_POINTER + +/** + * @brief Adds an unsigned base type value as trace event payload + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] uxValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventAddUnsignedBaseType TRC_EVENT_ADD_UNSIGNED_BASE_TYPE + +/** + * @brief Adds an uint32_t as trace event payload + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] value Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventAdd32 TRC_EVENT_ADD_32 + +/** + * @brief Adds an uint16_t as trace event payload + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] value Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventAdd16 TRC_EVENT_ADD_16 + +/** + * @brief Adds an uint8_t as trace event payload. + * + * @param[in] xEventHandle Pointer to initialized trace event. + * @param[in] value Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceEventAdd8 TRC_EVENT_ADD_8 + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_EVENT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEventBuffer.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEventBuffer.h index 9d70a7a80..502e33aa8 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEventBuffer.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcEventBuffer.h @@ -1,132 +1,138 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace event buffer APIs. - */ - -#ifndef TRC_EVENT_BUFFER_H -#define TRC_EVENT_BUFFER_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_event_buffer_apis Trace Event Buffer APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @def TRC_EVENT_BUFFER_OPTION_SKIP - * @brief Buffer should skip new events when full - */ -#define TRC_EVENT_BUFFER_OPTION_SKIP (0U) - -/** - * @def TRC_EVENT_BUFFER_OPTION_OVERWRITE - * @brief Buffer should overwrite old events when full - */ -#define TRC_EVENT_BUFFER_OPTION_OVERWRITE (1U) - -/** - * @brief Trace Event Buffer Structure - */ -typedef struct TraceEventBuffer -{ - uint32_t uiHead; /**< Head index of buffer */ - uint32_t uiTail; /**< Tail index of buffer */ - uint32_t uiSize; /**< Buffer size */ - uint32_t uiOptions; /**< Options (skip/overwrite when full) */ - uint32_t uiDroppedEvents; /**< Nr of dropped events */ - uint32_t uiFree; /**< Nr of free bytes */ - uint32_t uiTimerWraparounds; /**< Nr of timer wraparounds */ - uint8_t* puiBuffer; /**< Trace Event Buffer: may be NULL */ -} TraceEventBuffer_t; - -/** - * @internal Initialize trace event buffer. - * - * This routine initializes a trace event buffer and assigns it a - * memory area based on the supplied buffer. - * - * Trace event buffer options specifies the buffer behavior regarding - * old data, the alternatives are TRC_EVENT_BUFFER_OPTION_SKIP and - * TRC_EVENT_BUFFER_OPTION_OVERWRITE (mutal exclusive). - * - * @param[out] pxTraceEventBuffer Pointer to uninitialized trace event buffer. - * @param[in] uiOptions Trace event buffer options. - * @param[in] puiBuffer Pointer to buffer that will be used by the trace event buffer. - * @param[in] uiSize Size of buffer - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventBufferInitialize(TraceEventBuffer_t * pxTraceEventBuffer, uint32_t uiOptions, - uint8_t *puiBuffer, uint32_t uiSize); - -/** - * @brief Pushes data into trace event buffer. - * - * This routine attempts to push data into the trace event buffer. - * - * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer. - * @param[in] pxData Pointer to data that should be pushed into trace event buffer. - * @param[in] uiSize Size of data. - * @param[out] piBytesWritten Bytes written. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventBufferPush(TraceEventBuffer_t *pxTraceEventBuffer, void *pxData, uint32_t uiSize, int32_t *piBytesWritten); - -/** - * @brief Transfer trace event buffer data through streamport. - * - * This routine will attempt to transfer all existing data in the trace event - * buffer through the streamport. New data pushed to the trace event buffer - * during the execution of this routine will not be transfered to - * - * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer. - * @param[out] piBytesWritten Bytes written. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventBufferTransfer(TraceEventBuffer_t* pxTraceEventBuffer, int32_t* piBytesWritten); - -/** - * @brief Clears all data from event buffer. - * - * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEventBufferClear(TraceEventBuffer_t* pxTraceEventBuffer); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_EVENT_BUFFER_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace event buffer APIs. + */ + +#ifndef TRC_EVENT_BUFFER_H + #define TRC_EVENT_BUFFER_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_event_buffer_apis Trace Event Buffer APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @def TRC_EVENT_BUFFER_OPTION_SKIP + * @brief Buffer should skip new events when full + */ + #define TRC_EVENT_BUFFER_OPTION_SKIP ( 0U ) + +/** + * @def TRC_EVENT_BUFFER_OPTION_OVERWRITE + * @brief Buffer should overwrite old events when full + */ + #define TRC_EVENT_BUFFER_OPTION_OVERWRITE ( 1U ) + +/** + * @brief Trace Event Buffer Structure + */ + typedef struct TraceEventBuffer + { + uint32_t uiHead; /**< Head index of buffer */ + uint32_t uiTail; /**< Tail index of buffer */ + uint32_t uiSize; /**< Buffer size */ + uint32_t uiOptions; /**< Options (skip/overwrite when full) */ + uint32_t uiDroppedEvents; /**< Nr of dropped events */ + uint32_t uiFree; /**< Nr of free bytes */ + uint32_t uiTimerWraparounds; /**< Nr of timer wraparounds */ + uint8_t * puiBuffer; /**< Trace Event Buffer: may be NULL */ + } TraceEventBuffer_t; + +/** + * @internal Initialize trace event buffer. + * + * This routine initializes a trace event buffer and assigns it a + * memory area based on the supplied buffer. + * + * Trace event buffer options specifies the buffer behavior regarding + * old data, the alternatives are TRC_EVENT_BUFFER_OPTION_SKIP and + * TRC_EVENT_BUFFER_OPTION_OVERWRITE (mutual exclusive). + * + * @param[out] pxTraceEventBuffer Pointer to uninitialized trace event buffer. + * @param[in] uiOptions Trace event buffer options. + * @param[in] puiBuffer Pointer to buffer that will be used by the trace event buffer. + * @param[in] uiSize Size of buffer + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventBufferInitialize( TraceEventBuffer_t * pxTraceEventBuffer, + uint32_t uiOptions, + uint8_t * puiBuffer, + uint32_t uiSize ); + +/** + * @brief Pushes data into trace event buffer. + * + * This routine attempts to push data into the trace event buffer. + * + * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer. + * @param[in] pxData Pointer to data that should be pushed into trace event buffer. + * @param[in] uiSize Size of data. + * @param[out] piBytesWritten Bytes written. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventBufferPush( TraceEventBuffer_t * pxTraceEventBuffer, + void * pxData, + uint32_t uiSize, + int32_t * piBytesWritten ); + +/** + * @brief Transfer trace event buffer data through streamport. + * + * This routine will attempt to transfer all existing data in the trace event + * buffer through the streamport. New data pushed to the trace event buffer + * during the execution of this routine will not be transferred to + * + * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer. + * @param[out] piBytesWritten Bytes written. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventBufferTransfer( TraceEventBuffer_t * pxTraceEventBuffer, + int32_t * piBytesWritten ); + +/** + * @brief Clears all data from event buffer. + * + * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEventBufferClear( TraceEventBuffer_t * pxTraceEventBuffer ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_EVENT_BUFFER_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcExtension.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcExtension.h index 0acb19c08..6073e58e3 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcExtension.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcExtension.h @@ -1,93 +1,102 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace extension APIs. - */ - -#ifndef TRC_EXTENSION_H -#define TRC_EXTENSION_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_extension_apis Trace Extension APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @brief Creates trace extension. - * - * @param[in] szName Name. - * @param[in] uiMajor Major version. - * @param[in] uiMinor Minor version. - * @param[in] uiPatch Patch version. - * @param[in] uiEventCount Event count. - * @param[out] pxExtensionHandle Pointer to uninitialized extension handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceExtensionCreate(const char *szName, uint8_t uiMajor, uint8_t uiMinor, uint16_t uiPatch, uint32_t uiEventCount, TraceExtensionHandle_t *pxExtensionHandle); - -/** - * @brief Gets extension base event id. - * - * @param[in] xExtensionHandle Pointer to initialized extension handle. - * @param[out] puiBaseEventId Base event id. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceExtensionGetBaseEventId(TraceExtensionHandle_t xExtensionHandle, uint32_t *puiBaseEventId); - -/** - * @brief Gets extension event id. - * - * @param[in] xExtensionHandle Pointer to initialized extension handle. - * @param[in] uiLocalEventId Local event id. - * @param[out] puiGlobalEventId Global event id. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceExtensionGetEventId(TraceExtensionHandle_t xExtensionHandle, uint32_t uiLocalEventId, uint32_t *puiGlobalEventId); - -/** - * @brief Gets extension configuration name. - * - * @param[in] xExtensionHandle Pointer to initialized extension handle. - * @param[out] pszName Name. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceExtensionGetConfigName(TraceExtensionHandle_t xExtensionHandle, const char **pszName); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_EXTENSION_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace extension APIs. + */ + +#ifndef TRC_EXTENSION_H + #define TRC_EXTENSION_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_extension_apis Trace Extension APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @brief Creates trace extension. + * + * @param[in] szName Name. + * @param[in] uiMajor Major version. + * @param[in] uiMinor Minor version. + * @param[in] uiPatch Patch version. + * @param[in] uiEventCount Event count. + * @param[out] pxExtensionHandle Pointer to uninitialized extension handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceExtensionCreate( const char * szName, + uint8_t uiMajor, + uint8_t uiMinor, + uint16_t uiPatch, + uint32_t uiEventCount, + TraceExtensionHandle_t * pxExtensionHandle ); + +/** + * @brief Gets extension base event id. + * + * @param[in] xExtensionHandle Pointer to initialized extension handle. + * @param[out] puiBaseEventId Base event id. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceExtensionGetBaseEventId( TraceExtensionHandle_t xExtensionHandle, + uint32_t * puiBaseEventId ); + +/** + * @brief Gets extension event id. + * + * @param[in] xExtensionHandle Pointer to initialized extension handle. + * @param[in] uiLocalEventId Local event id. + * @param[out] puiGlobalEventId Global event id. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceExtensionGetEventId( TraceExtensionHandle_t xExtensionHandle, + uint32_t uiLocalEventId, + uint32_t * puiGlobalEventId ); + +/** + * @brief Gets extension configuration name. + * + * @param[in] xExtensionHandle Pointer to initialized extension handle. + * @param[out] pszName Name. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceExtensionGetConfigName( TraceExtensionHandle_t xExtensionHandle, + const char ** pszName ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_EXTENSION_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h index febe7272f..8b830f1ef 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHardwarePort.h @@ -1,714 +1,724 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The hardware abstraction layer for the trace recorder. - */ - -#ifndef TRC_HARDWARE_PORT_H -#define TRC_HARDWARE_PORT_H - -#include - - -#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET) - #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h" -#endif - -/******************************************************************************* - * TRC_IRQ_PRIORITY_ORDER - * - * Macro which should be defined as an integer of 0 or 1. - * - * This should be 0 if lower IRQ priority values implies higher priority - * levels, such as on ARM Cortex M. If the opposite scheme is used, i.e., - * if higher IRQ priority values means higher priority, this should be 1. - * - * This setting is not critical. It is used only to sort and colorize the - * interrupts in priority order, in case you record interrupts using - * the vTraceStoreISRBegin and vTraceStoreISREnd routines. - * - ****************************************************************************** - * - * HWTC Macros - * - * These macros provides a hardware isolation layer representing the - * hardware timer/counter used for the event timestamping. - * - * TRC_HWTC_COUNT: How to read the current value of the timer/counter. - * - * TRC_HWTC_TYPE: Tells the type of timer/counter used for TRC_HWTC_COUNT: - * - * - TRC_FREE_RUNNING_32BIT_INCR: - * Free-running 32-bit timer/counter, counting upwards from 0. - * - * - TRC_FREE_RUNNING_32BIT_DECR - * Free-running 32-bit timer/counter, counting downwards from 0xFFFFFFFF. - * - * - TRC_OS_TIMER_INCR - * Periodic timer that drives the OS tick interrupt, counting upwards - * from 0 until (TRC_HWTC_PERIOD-1). - * - * - TRC_OS_TIMER_DECR - * Periodic timer that drives the OS tick interrupt, counting downwards - * from TRC_HWTC_PERIOD-1 until 0. - * - * - TRC_CUSTOM_TIMER_INCR - * A custom timer or counter independent of the OS tick, counting - * downwards from TRC_HWTC_PERIOD-1 until 0. (Currently only supported - * in streaming mode). - * - * - TRC_CUSTOM_TIMER_DECR - * A custom timer independent of the OS tick, counting downwards - * from TRC_HWTC_PERIOD-1 until 0. (Currently only supported - * in streaming mode). - * - * TRC_HWTC_PERIOD: The number of HWTC_COUNT ticks until the timer wraps - * around. If using TRC_FREE_RUNNING_32BIT_INCR/DECR, this should be 0. - * - * TRC_HWTC_FREQ_HZ: The clock rate of the TRC_HWTC_COUNT counter in Hz. If using - * TRC_OS_TIMER_INCR/DECR, this is should be TRC_HWTC_PERIOD * TRC_TICK_RATE_HZ. - * If using a free-running timer, this is often TRACE_CPU_CLOCK_HZ (if running at - * the core clock rate). If using TRC_CUSTOM_TIMER_INCR/DECR, this should match - * the clock rate of your custom timer (i.e., TRC_HWTC_COUNT). If the default value - * of TRC_HWTC_FREQ_HZ is incorrect for your setup, you can override it by calling - * vTraceSetFrequency before calling vTraceEnable. - * - * TRC_HWTC_DIVISOR (used in snapshot mode only): - * In snapshot mode, the timestamp resolution is TRC_HWTC_FREQ_HZ/TRC_HWTC_DIVISOR. - * If the timer frequency is very high (hundreds of MHz), we recommend increasing - * the TRC_HWTC_DIVISOR prescaler, to reduce the bandwidth needed to store - * timestamps. This since extra "XTS" events are inserted if the time since the - * previous event exceeds a certain limit (255 or 65535 depending on event type). - * It is advised to keep the time between most events below 65535 native ticks - * (after division by TRC_HWTC_DIVISOR) to avoid frequent XTS events. - ******************************************************************************/ - -#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET) - #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h" -#endif - -#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32) -/* This can be used as a template for any free-running 32-bit counter */ -void vTraceTimerReset(void); -uint32_t uiTraceTimerGetFrequency(void); -uint32_t uiTraceTimerGetValue(void); - -#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR -#define TRC_HWTC_COUNT ((TraceUnsignedBaseType_t)uiTraceTimerGetValue()) -#define TRC_HWTC_PERIOD 0 -#define TRC_HWTC_DIVISOR 1 -#define TRC_HWTC_FREQ_HZ ((TraceUnsignedBaseType_t)uiTraceTimerGetFrequency()) - -#define TRC_IRQ_PRIORITY_ORDER 1 - -#define TRC_PORT_SPECIFIC_INIT() vTraceTimerReset() - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win64) -/* This can be used as a template for any free-running 32-bit counter */ -void vTraceTimerReset(void); -uint32_t uiTraceTimerGetFrequency(void); -uint32_t uiTraceTimerGetValue(void); - -#define TRC_BASE_TYPE int64_t - -#define TRC_UNSIGNED_BASE_TYPE uint64_t - -#define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR -#define TRC_HWTC_COUNT ((TraceUnsignedBaseType_t)uiTraceTimerGetValue()) -#define TRC_HWTC_PERIOD 0 -#define TRC_HWTC_DIVISOR 1 -#define TRC_HWTC_FREQ_HZ ((TraceUnsignedBaseType_t)uiTraceTimerGetFrequency()) - -#define TRC_IRQ_PRIORITY_ORDER 1 - -#define TRC_PORT_SPECIFIC_INIT() vTraceTimerReset() - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_HWIndependent) - /* Timestamping by OS tick only (typically 1 ms resolution) */ - #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR - #define TRC_HWTC_COUNT 0 - #define TRC_HWTC_PERIOD 1 - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ TRC_TICK_RATE_HZ - - /* Set the meaning of IRQ priorities in ISR tracing - see above */ - #define TRC_IRQ_PRIORITY_ORDER NOT_SET - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) - - #ifndef __CORTEX_M - #error "Can't find the CMSIS API. Please include your processor's header file in trcConfig.h" - #endif - - #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_status; - #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = __get_PRIMASK(); __set_PRIMASK(1);} /* PRIMASK disables ALL interrupts - allows for tracing in any ISR */ - #define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(__irq_status);} - - /************************************************************************** - * For Cortex-M3, M4 and M7, the DWT cycle counter is used for timestamping. - * For Cortex-M0 and M0+, the SysTick timer is used since DWT is not - * available. Systick timestamping can also be forced on Cortex-M3, M4 and - * M7 by defining the preprocessor directive TRC_CFG_ARM_CM_USE_SYSTICK, - * either directly below or in trcConfig.h. - * - * #define TRC_CFG_ARM_CM_USE_SYSTICK - **************************************************************************/ - - #if ((__CORTEX_M >= 0x03) && (! defined TRC_CFG_ARM_CM_USE_SYSTICK)) - - void xTraceHardwarePortInitCortexM(void); - - #define TRC_REG_DEMCR (*(volatile uint32_t*)0xE000EDFC) - #define TRC_REG_DWT_CTRL (*(volatile uint32_t*)0xE0001000) - #define TRC_REG_DWT_CYCCNT (*(volatile uint32_t*)0xE0001004) - #define TRC_REG_DWT_EXCCNT (*(volatile uint32_t*)0xE000100C) - - #define TRC_REG_ITM_LOCKACCESS (*(volatile uint32_t*)0xE0001FB0) - #define TRC_ITM_LOCKACCESS_UNLOCK (0xC5ACCE55) - - /* Bit mask for TRCENA bit in DEMCR - Global enable for DWT and ITM */ - #define TRC_DEMCR_TRCENA (1 << 24) - - /* Bit mask for NOPRFCNT bit in DWT_CTRL. If 1, DWT_EXCCNT is not supported */ - #define TRC_DWT_CTRL_NOPRFCNT (1 << 24) - - /* Bit mask for NOCYCCNT bit in DWT_CTRL. If 1, DWT_CYCCNT is not supported */ - #define TRC_DWT_CTRL_NOCYCCNT (1 << 25) - - /* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_EXCCNT */ - #define TRC_DWT_CTRL_EXCEVTENA (1 << 18) - - /* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_CYCCNT */ - #define TRC_DWT_CTRL_CYCCNTENA (1) - - #define TRC_PORT_SPECIFIC_INIT() xTraceHardwarePortInitCortexM() - - #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR - #define TRC_HWTC_COUNT TRC_REG_DWT_CYCCNT - #define TRC_HWTC_PERIOD 0 - #define TRC_HWTC_DIVISOR 4 - #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ - #define TRC_IRQ_PRIORITY_ORDER 0 - - #else - - #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR - #define TRC_HWTC_COUNT (*((volatile uint32_t*)0xE000E018)) - #define TRC_HWTC_PERIOD ((*((volatile uint32_t*)0xE000E014)) + 1) - #define TRC_HWTC_DIVISOR 4 - #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ - #define TRC_IRQ_PRIORITY_ORDER 0 - - #endif - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600) - #define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t __x_irq_status; - #define TRACE_ENTER_CRITICAL_SECTION() { __x_irq_status = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); } - #define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(__x_irq_status); } - - #include - - #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - - #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR - #define TRC_HWTC_COUNT (CMT0.CMCNT) - - #elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) - - /* Decreasing counters better for Tickless Idle? */ - #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR - #define TRC_HWTC_COUNT (CMT0.CMCOR - CMT0.CMCNT) - - #endif - - #define TRC_HWTC_PERIOD (CMT0.CMCOR + 1) - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 1 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32) - - #define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t __x_irq_status; - #define TRACE_ENTER_CRITICAL_SECTION() { __x_irq_status = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); } - #define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(__x_irq_status); } - - #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR - #define TRC_HWTC_COUNT (TMR1) - #define TRC_HWTC_PERIOD (PR1 + 1) - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 1 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48) - - #define TRC_RTIFRC0 *((uint32_t *)0xFFFFFC10) - #define TRC_RTICOMP0 *((uint32_t *)0xFFFFFC50) - #define TRC_RTIUDCP0 *((uint32_t *)0xFFFFFC54) - - #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR - #define TRC_HWTC_COUNT (TRC_RTIFRC0 - (TRC_RTICOMP0 - TRC_RTIUDCP0)) - #define TRC_HWTC_PERIOD (TRC_RTIUDCP0) - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 0 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_AT91SAM7) - - /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ - - #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR - #define TRC_HWTC_COUNT ((uint32_t)(AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF)) - #define TRC_HWTC_PERIOD ((uint32_t)(AT91C_BASE_PITC->PITC_PIMR + 1)) - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 1 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_UC3A0) - - /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO*/ - - /* For Atmel AVR32 (AT32UC3A) */ - - #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR - #define TRC_HWTC_COUNT ((uint32_t)sysreg_read(AVR32_COUNT)) - #define TRC_HWTC_PERIOD ((uint32_t)(sysreg_read(AVR32_COMPARE) + 1)) - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 1 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NXP_LPC210X) - - /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ - - /* Tested with LPC2106, but should work with most LPC21XX chips. */ - - #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR - #define TRC_HWTC_COUNT *((uint32_t *)0xE0004008 ) - #define TRC_HWTC_PERIOD *((uint32_t *)0xE0004018 ) - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 0 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430) - - /* UNOFFICIAL PORT - NOT YET VERIFIED */ - - #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR - #define TRC_HWTC_COUNT (TA0R) - #define TRC_HWTC_PERIOD (((uint16_t)TACCR0)+1) - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 1 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC405) - - /* UNOFFICIAL PORT - NOT YET VERIFIED */ - - #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR - #define TRC_HWTC_COUNT mfspr(0x3db) - #define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRC_TICK_RATE_HZ) - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 0 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC440) - - /* UNOFFICIAL PORT */ - - /* This should work with most PowerPC chips */ - - #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR - #define TRC_HWTC_COUNT mfspr(0x016) - #define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRC_TICK_RATE_HZ) - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 0 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_MICROBLAZE) - - /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ - - /* This should work with most Microblaze configurations. - * It uses the AXI Timer 0 - the tick interrupt source. - * If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required. - */ - #include - - #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR - #define TRC_HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 ) - #define TRC_HWTC_PERIOD (XTmrCtr_GetLoadReg( XPAR_TMRCTR_0_BASEADDR, 0) + 1) - #define TRC_HWTC_DIVISOR 16 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 0 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5) - - extern int cortex_a9_r5_enter_critical(void); - extern void cortex_a9_r5_exit_critical(int irq_already_masked_at_enter); - - #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_mask_status; - - #define TRACE_ENTER_CRITICAL_SECTION() { __irq_mask_status = cortex_a9_r5_enter_critical(); } - - #define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical(__irq_mask_status); } - - #include - - #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR - #define TRC_HWTC_COUNT (*(volatile uint32_t *)(configTIMER_BASEADDR + XTTCPS_COUNT_VALUE_OFFSET)) - #define TRC_HWTC_PERIOD (*(volatile uint32_t *)(configTIMER_BASEADDR + XTTCPS_INTERVAL_VAL_OFFSET)) - #define TRC_HWTC_DIVISOR 16 - #define TRC_HWTC_FREQ_HZ (TRC_HWTC_PERIOD * TRC_TICK_RATE_HZ) - #define TRC_IRQ_PRIORITY_ORDER 0 - - #ifdef __GNUC__ - /* For Arm Cortex-A and Cortex-R in general. */ - static inline uint32_t prvGetCPSR(void) - { - unsigned long ret; - /* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */ - asm volatile (" mrs %0, cpsr" : "=r" (ret) : /* no inputs */ ); - return ret; - } - #else - #error "Only GCC Supported!" - #endif - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII) - - /* OFFICIAL PORT */ - - #include - #include - #include - - #define TRACE_ALLOC_CRITICAL_SECTION() alt_irq_context __irq_status; - #define TRACE_ENTER_CRITICAL_SECTION(){__irq_status = alt_irq_disable_all();} - #define TRACE_EXIT_CRITICAL_SECTION() {alt_irq_enable_all(__irq_status);} - - #define NOT_SET 1 - - /* The base address for the sustem timer set. - * The name user for the system timer can be found in the BSP editor. - * If the name of the timer is sys_tmr SYSTEM_TIMER_BASE should be set to SYS_TMR_BASE. - */ - #define SYSTEM_TIMER_BASE NOT_SET - - #if (SYSTEM_TIMER == NOT_SET) - #error "Set SYSTEM_TIMER_BASE to the timer base used for system ticks." - #endif - - static inline uint32_t altera_nios2_GetTimerSnapReg(void) - { - /* A processor can read the current counter value by first writing to either snapl or snaph to request a coherent snapshot of the counter, - * and then reading snapl and snaph for the full 32-bit value. - */ - IOWR_ALTERA_AVALON_TIMER_SNAPL(SYSTEM_TIMER_BASE, 0); - return (IORD_ALTERA_AVALON_TIMER_SNAPH(SYSTEM_TIMER_BASE) << 16) | IORD_ALTERA_AVALON_TIMER_SNAPL(SYSTEM_TIMER_BASE); - } - - #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR - #define TRC_HWTC_COUNT altera_nios2_GetTimerSnapReg() - #define TRC_HWTC_PERIOD (configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - #define TRC_HWTC_DIVISOR 16 - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 0 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) - - /************************************************************************** - * This hardware port only supports FreeRTOS and the GCC compiler at the - * moment, due to the implementation of critical sections (trcKernelPort.h). - * - * Assuming FreeRTOS is used: - * - * For critical sections, this uses vTaskEnterCritical is when called from - * task context and ulPortSetInterruptMask when called from ISR context. - * Thus, it does not disable all ISRs. This means that the trace recorder - * can only be called from ISRs with priority less or equal to - * configMAX_API_CALL_INTERRUPT_PRIORITY (like FreeRTOS fromISR functions). - * - * This hardware port has been tested on it a Xilinx Zync 7000 (Cortex-A9), - * but should work with all Cortex-A and R processors assuming that - * TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS is set accordingly. - **************************************************************************/ - - extern int cortex_a9_r5_enter_critical(void); - extern void cortex_a9_r5_exit_critical(int irq_already_masked_at_enter); - - #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_mask_status; - - #define TRACE_ENTER_CRITICAL_SECTION() { __irq_mask_status = cortex_a9_r5_enter_critical(); } - - #define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical(__irq_mask_status); } - - /* INPUT YOUR PERIPHERAL BASE ADDRESS HERE (0xF8F00000 for Xilinx Zynq 7000)*/ - #define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0 - - #if (TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS == 0) - #error "Please specify TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS." - #endif - - #define TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET 0x0600 - #define TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x00)) - #define TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x04)) - #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x08)) - - #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK 0x0000FF00 - #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT 8 - #define TRC_CA9_MPCORE_PRIVCTR_PRESCALER (((TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG & TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK) >> TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT) + 1) - - #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR - #define TRC_HWTC_COUNT TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG - #define TRC_HWTC_PERIOD (TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG + 1) - - /**************************************************************************************** - NOTE: The private timer ticks with a very high frequency (half the core-clock usually), - depending on the prescaler used. If a low prescaler is used, the number of HW ticks between - the trace events gets large, and thereby inefficient to store (sometimes extra events are - needed). To improve efficiency, you may use the TRC_HWTC_DIVISOR as an additional prescaler. - *****************************************************************************************/ - #define TRC_HWTC_DIVISOR 1 - - #define TRC_HWTC_FREQ_HZ (TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD) - #define TRC_IRQ_PRIORITY_ORDER 0 - - #ifdef __GNUC__ - /* For Arm Cortex-A and Cortex-R in general. */ - static inline uint32_t prvGetCPSR(void) - { - unsigned long ret; - /* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */ - asm volatile (" mrs %0, cpsr" : "=r" (ret) : /* no inputs */ ); - return ret; - } - #else - #error "Only GCC Supported!" - #endif - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_CYCLONE_V_HPS) - #include "alt_clock_manager.h" - - extern int cortex_a9_r5_enter_critical(void); - extern void cortex_a9_r5_exit_critical(int irq_already_masked_at_enter); - - #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_mask_status; - #define TRACE_ENTER_CRITICAL_SECTION() { __irq_mask_status = cortex_a9_r5_enter_critical(); } - #define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical(__irq_mask_status); } - - #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR - #define TRC_HWTC_COUNT *((uint32_t *)0xFFFEC200) - #define TRC_HWTC_PERIOD 0 - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ (({ \ - uint32_t __freq; \ - alt_clk_freq_get( ALT_CLK_MPU_PERIPH, &__freq ); \ - __freq; \ - })) - #define TRC_IRQ_PRIORITY_ORDER 0 - - #ifdef __GNUC__ - /* For Arm Cortex-A and Cortex-R in general. */ - static inline uint32_t prvGetCPSR(void) - { - unsigned long ret; - /* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */ - __asm__ __volatile__(" mrs %0, cpsr" : "=r" (ret) : /* no inputs */ ); - return ret; - } - #else - #error "Only GCC Supported!" - #endif - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ZEPHYR) - #define TRACE_ALLOC_CRITICAL_SECTION() int key; - #define TRACE_ENTER_CRITICAL_SECTION() { key = irq_lock(); } - #define TRACE_EXIT_CRITICAL_SECTION() { irq_unlock(key); } - - #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR - #define TRC_HWTC_COUNT k_cycle_get_32() - #define TRC_HWTC_PERIOD (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC) - #define TRC_HWTC_DIVISOR 4 - #define TRC_HWTC_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC - #define TRC_IRQ_PRIORITY_ORDER 0 // Lower IRQ priority values are more significant - - #define TRC_PORT_SPECIFIC_INIT() - -#elif ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XTensa_LX6) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XTensa_LX7)) - /** - * @note When running with SMP FreeRTOS we cannot use the CCOUNT register for timestamping, - * instead we use the external 40MHz timer for synchronized timestamping between the cores. - */ - #if CONFIG_FREERTOS_UNICORE == 1 - #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR - #define TRC_HWTC_COUNT ({ unsigned int __ccount; \ - __asm__ __volatile__("rsr.ccount %0" : "=a"(__ccount)); \ - __ccount; }) -#ifdef CONFIG_IDF_TARGET_ESP32 - #define TRC_HWTC_FREQ_HZ (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000) -#elif defined(CONFIG_IDF_TARGET_ESP32S2) - #define TRC_HWTC_FREQ_HZ (CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000) -#else - #error "Invalid IDF target, check your sdkconfig." -#endif - #define TRC_HWTC_PERIOD 0 - #define TRC_HWTC_DIVISOR 4 - #define TRC_IRQ_PRIORITY_ORDER 0 - #else - /** - * @brief Fetch core agnostic timestamp using the external 40MHz timer. This is used by tracerecorder - * when running with both cores. - * - * @return Ticks since the timer started - */ - uint32_t prvGetSMPTimestamp(); - - #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR - #define TRC_HWTC_COUNT prvGetSMPTimestamp() - #define TRC_HWTC_FREQ_HZ 40000000 - #define TRC_HWTC_PERIOD 0 - #define TRC_HWTC_DIVISOR 4 - #define TRC_IRQ_PRIORITY_ORDER 0 - #endif - - #if !defined(TRC_HWTC_FREQ_HZ) - #error "The XTensa LX6/LX7 trace hardware clock frequency is not defined." - #endif - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_RISCV_RV32I) - #define TRACE_ALLOC_CRITICAL_SECTION() unsigned int __irq_status; - #define TRACE_ENTER_CRITICAL_SECTION() __asm__ __volatile__("csrr %0, mstatus \n\t" \ - "csrci mstatus, 8 \n\t" \ - "andi %0, %0, 8 \n\t" \ - : "=r"(__irq_status)) - #define TRACE_EXIT_CRITICAL_SECTION() __asm__ __volatile__("csrr a1, mstatus \n\t" \ - "or %0, %0, a1 \n\t" \ - "csrs mstatus, %0 \n\t" \ - : \ - : "r" (__irq_status) \ - : "a1") - #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR - #define TRC_HWTC_COUNT ({ unsigned int __count; \ - __asm__ __volatile__("rdcycle %0" : "=r"(__count)); \ - __count; }) - #define TRC_HWTC_PERIOD 0 - #define TRC_HWTC_DIVISOR 1 - #define TRC_HWTC_FREQ_HZ 16000000 - #define TRC_IRQ_PRIORITY_ORDER 0 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XMOS_XCOREAI) - #define TRC_PORT_SPECIFIC_INIT() - #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR - #define TRC_HWTC_COUNT xscope_gettime() - #define TRC_HWTC_PERIOD (configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - #define TRC_HWTC_DIVISOR 4 - #define TRC_HWTC_FREQ_HZ 100000000 - #define TRC_IRQ_PRIORITY_ORDER 0 - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4) - - /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ - - #define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t __x_irq_status; - #define TRACE_ENTER_CRITICAL_SECTION() { __x_irq_status = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); } - #define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(__x_irq_status); } - - #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR - //#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING - #define TRC_HWTC_COUNT PIT.TIMER[configTICK_PIT_CHANNEL].CVAL.R // must be the PIT channel used for the systick - #define TRC_HWTC_PERIOD ((configPIT_CLOCK_HZ / configTICK_RATE_HZ) - 1U) // TODO FIXME or maybe not -1? what's the right "period" value? - #define TRC_HWTC_FREQ_HZ configPIT_CLOCK_HZ - #define TRC_HWTC_DIVISOR 1 - #define TRC_IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant - -#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_APPLICATION_DEFINED) - - #if !( defined (TRC_HWTC_TYPE) && defined (TRC_HWTC_COUNT) && defined (TRC_HWTC_PERIOD) && defined (TRC_HWTC_FREQ_HZ) && defined (TRC_IRQ_PRIORITY_ORDER) ) - #error "The hardware port is not completely defined!" - #endif - -#elif (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET) - - #error "TRC_CFG_HARDWARE_PORT had unsupported value!" - #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET - -#endif - -#ifndef TRC_HWTC_DIVISOR - #define TRC_HWTC_DIVISOR 1 -#endif - -#ifndef TRC_PORT_SPECIFIC_INIT - #define TRC_PORT_SPECIFIC_INIT() -#endif - -/* If Win32 port */ -#ifdef WIN32 - - #undef _WIN32_WINNT - #define _WIN32_WINNT 0x0600 - - /* Standard includes. */ - #include - #include - #include - - /*************************************************************************** - * The Win32 port by default saves the trace to file and then kills the - * program when the recorder is stopped, to facilitate quick, simple tests - * of the recorder. - ***************************************************************************/ - #define WIN32_PORT_SAVE_WHEN_STOPPED 1 - #define WIN32_PORT_EXIT_WHEN_STOPPED 1 - -#endif - -#if (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET) - - #ifndef TRC_HWTC_TYPE - #error "TRC_HWTC_TYPE is not set!" - #endif - - #ifndef TRC_HWTC_COUNT - #error "TRC_HWTC_COUNT is not set!" - #endif - - #ifndef TRC_HWTC_PERIOD - #error "TRC_HWTC_PERIOD is not set!" - #endif - - #ifndef TRC_HWTC_DIVISOR - #error "TRC_HWTC_DIVISOR is not set!" - #endif - - #ifndef TRC_IRQ_PRIORITY_ORDER - #error "TRC_IRQ_PRIORITY_ORDER is not set!" - #elif (TRC_IRQ_PRIORITY_ORDER != 0) && (TRC_IRQ_PRIORITY_ORDER != 1) - #error "TRC_IRQ_PRIORITY_ORDER has bad value!" - #endif - - #if (TRC_HWTC_DIVISOR < 1) - #error "TRC_HWTC_DIVISOR must be a non-zero positive value!" - #endif - - #ifndef TRC_HWTC_FREQ_HZ - #error "TRC_HWTC_FREQ_HZ not defined!" - #endif - -#endif - -#ifndef TRACE_ALLOC_CRITICAL_SECTION -#define TRACE_ALLOC_CRITICAL_SECTION() TRC_KERNEL_PORT_ALLOC_CRITICAL_SECTION() -#endif -#ifndef TRACE_ENTER_CRITICAL_SECTION - #define TRACE_ENTER_CRITICAL_SECTION() TRC_KERNEL_PORT_ENTER_CRITICAL_SECTION() -#endif -#ifndef TRACE_EXIT_CRITICAL_SECTION -#define TRACE_EXIT_CRITICAL_SECTION() TRC_KERNEL_PORT_EXIT_CRITICAL_SECTION() -#endif - -#endif /*TRC_SNAPSHOT_HARDWARE_PORT_H*/ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The hardware abstraction layer for the trace recorder. + */ + +#ifndef TRC_HARDWARE_PORT_H +#define TRC_HARDWARE_PORT_H + +#include + + +#if ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET ) + #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h" +#endif + +/******************************************************************************* + * TRC_IRQ_PRIORITY_ORDER + * + * Macro which should be defined as an integer of 0 or 1. + * + * This should be 0 if lower IRQ priority values implies higher priority + * levels, such as on ARM Cortex M. If the opposite scheme is used, i.e., + * if higher IRQ priority values means higher priority, this should be 1. + * + * This setting is not critical. It is used only to sort and colorize the + * interrupts in priority order, in case you record interrupts using + * the vTraceStoreISRBegin and vTraceStoreISREnd routines. + * + ****************************************************************************** + * + * HWTC Macros + * + * These macros provides a hardware isolation layer representing the + * hardware timer/counter used for the event timestamping. + * + * TRC_HWTC_COUNT: How to read the current value of the timer/counter. + * + * TRC_HWTC_TYPE: Tells the type of timer/counter used for TRC_HWTC_COUNT: + * + * - TRC_FREE_RUNNING_32BIT_INCR: + * Free-running 32-bit timer/counter, counting upwards from 0. + * + * - TRC_FREE_RUNNING_32BIT_DECR + * Free-running 32-bit timer/counter, counting downwards from 0xFFFFFFFF. + * + * - TRC_OS_TIMER_INCR + * Periodic timer that drives the OS tick interrupt, counting upwards + * from 0 until (TRC_HWTC_PERIOD-1). + * + * - TRC_OS_TIMER_DECR + * Periodic timer that drives the OS tick interrupt, counting downwards + * from TRC_HWTC_PERIOD-1 until 0. + * + * - TRC_CUSTOM_TIMER_INCR + * A custom timer or counter independent of the OS tick, counting + * downwards from TRC_HWTC_PERIOD-1 until 0. (Currently only supported + * in streaming mode). + * + * - TRC_CUSTOM_TIMER_DECR + * A custom timer independent of the OS tick, counting downwards + * from TRC_HWTC_PERIOD-1 until 0. (Currently only supported + * in streaming mode). + * + * TRC_HWTC_PERIOD: The number of HWTC_COUNT ticks until the timer wraps + * around. If using TRC_FREE_RUNNING_32BIT_INCR/DECR, this should be 0. + * + * TRC_HWTC_FREQ_HZ: The clock rate of the TRC_HWTC_COUNT counter in Hz. If using + * TRC_OS_TIMER_INCR/DECR, this is should be TRC_HWTC_PERIOD * TRC_TICK_RATE_HZ. + * If using a free-running timer, this is often TRACE_CPU_CLOCK_HZ (if running at + * the core clock rate). If using TRC_CUSTOM_TIMER_INCR/DECR, this should match + * the clock rate of your custom timer (i.e., TRC_HWTC_COUNT). If the default value + * of TRC_HWTC_FREQ_HZ is incorrect for your setup, you can override it by calling + * vTraceSetFrequency before calling vTraceEnable. + * + * TRC_HWTC_DIVISOR (used in snapshot mode only): + * In snapshot mode, the timestamp resolution is TRC_HWTC_FREQ_HZ/TRC_HWTC_DIVISOR. + * If the timer frequency is very high (hundreds of MHz), we recommend increasing + * the TRC_HWTC_DIVISOR prescaler, to reduce the bandwidth needed to store + * timestamps. This since extra "XTS" events are inserted if the time since the + * previous event exceeds a certain limit (255 or 65535 depending on event type). + * It is advised to keep the time between most events below 65535 native ticks + * (after division by TRC_HWTC_DIVISOR) to avoid frequent XTS events. + ******************************************************************************/ + +#if ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET ) + #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h" +#endif + +#if ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32 ) +/* This can be used as a template for any free-running 32-bit counter */ + void vTraceTimerReset( void ); + uint32_t uiTraceTimerGetFrequency( void ); + uint32_t uiTraceTimerGetValue( void ); + + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT ( ( TraceUnsignedBaseType_t ) uiTraceTimerGetValue() ) + #define TRC_HWTC_PERIOD 0 + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( ( TraceUnsignedBaseType_t ) uiTraceTimerGetFrequency() ) + + #define TRC_IRQ_PRIORITY_ORDER 1 + + #define TRC_PORT_SPECIFIC_INIT() vTraceTimerReset() + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win64 ) +/* This can be used as a template for any free-running 32-bit counter */ + void vTraceTimerReset( void ); + uint32_t uiTraceTimerGetFrequency( void ); + uint32_t uiTraceTimerGetValue( void ); + + #define TRC_BASE_TYPE int64_t + + #define TRC_UNSIGNED_BASE_TYPE uint64_t + + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT ( ( TraceUnsignedBaseType_t ) uiTraceTimerGetValue() ) + #define TRC_HWTC_PERIOD 0 + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( ( TraceUnsignedBaseType_t ) uiTraceTimerGetFrequency() ) + + #define TRC_IRQ_PRIORITY_ORDER 1 + + #define TRC_PORT_SPECIFIC_INIT() vTraceTimerReset() + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_HWIndependent ) + /* Timestamping by OS tick only (typically 1 ms resolution) */ + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT 0 + #define TRC_HWTC_PERIOD 1 + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ TRC_TICK_RATE_HZ + +/* Set the meaning of IRQ priorities in ISR tracing - see above */ + #define TRC_IRQ_PRIORITY_ORDER NOT_SET + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M ) + + #ifndef __CORTEX_M + #error "Can't find the CMSIS API. Please include your processor's header file in trcConfig.h" + #endif + + #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() { __irq_status = __get_PRIMASK(); __set_PRIMASK( 1 ); } /* PRIMASK disables ALL interrupts - allows for tracing in any ISR */ + #define TRACE_EXIT_CRITICAL_SECTION() { __set_PRIMASK( __irq_status ); } + +/************************************************************************** +* For Cortex-M3, M4 and M7, the DWT cycle counter is used for timestamping. +* For Cortex-M0 and M0+, the SysTick timer is used since DWT is not +* available. Systick timestamping can also be forced on Cortex-M3, M4 and +* M7 by defining the preprocessor directive TRC_CFG_ARM_CM_USE_SYSTICK, +* either directly below or in trcConfig.h. +* +* #define TRC_CFG_ARM_CM_USE_SYSTICK +**************************************************************************/ + + #if ( ( __CORTEX_M >= 0x03 ) && ( !defined TRC_CFG_ARM_CM_USE_SYSTICK ) ) + + void xTraceHardwarePortInitCortexM( void ); + + #define TRC_REG_DEMCR ( *( volatile uint32_t * ) 0xE000EDFC ) + #define TRC_REG_DWT_CTRL ( *( volatile uint32_t * ) 0xE0001000 ) + #define TRC_REG_DWT_CYCCNT ( *( volatile uint32_t * ) 0xE0001004 ) + #define TRC_REG_DWT_EXCCNT ( *( volatile uint32_t * ) 0xE000100C ) + + #define TRC_REG_ITM_LOCKACCESS ( *( volatile uint32_t * ) 0xE0001FB0 ) + #define TRC_ITM_LOCKACCESS_UNLOCK ( 0xC5ACCE55 ) + +/* Bit mask for TRCENA bit in DEMCR - Global enable for DWT and ITM */ + #define TRC_DEMCR_TRCENA ( 1 << 24 ) + +/* Bit mask for NOPRFCNT bit in DWT_CTRL. If 1, DWT_EXCCNT is not supported */ + #define TRC_DWT_CTRL_NOPRFCNT ( 1 << 24 ) + +/* Bit mask for NOCYCCNT bit in DWT_CTRL. If 1, DWT_CYCCNT is not supported */ + #define TRC_DWT_CTRL_NOCYCCNT ( 1 << 25 ) + +/* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_EXCCNT */ + #define TRC_DWT_CTRL_EXCEVTENA ( 1 << 18 ) + +/* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_CYCCNT */ + #define TRC_DWT_CTRL_CYCCNTENA ( 1 ) + + #define TRC_PORT_SPECIFIC_INIT() xTraceHardwarePortInitCortexM() + + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT TRC_REG_DWT_CYCCNT + #define TRC_HWTC_PERIOD 0 + #define TRC_HWTC_DIVISOR 4 + #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ + #define TRC_IRQ_PRIORITY_ORDER 0 + + #else /* if ( ( __CORTEX_M >= 0x03 ) && ( !defined TRC_CFG_ARM_CM_USE_SYSTICK ) ) */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT ( *( ( volatile uint32_t * ) 0xE000E018 ) ) + #define TRC_HWTC_PERIOD ( ( *( ( volatile uint32_t * ) 0xE000E014 ) ) + 1 ) + #define TRC_HWTC_DIVISOR 4 + #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ + #define TRC_IRQ_PRIORITY_ORDER 0 + + #endif /* if ( ( __CORTEX_M >= 0x03 ) && ( !defined TRC_CFG_ARM_CM_USE_SYSTICK ) ) */ + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600 ) + #define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t __x_irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() { __x_irq_status = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); } + #define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK( __x_irq_status ); } + + #include + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT ( CMT0.CMCNT ) + + #elif ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) + +/* Decreasing counters better for Tickless Idle? */ + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT ( CMT0.CMCOR - CMT0.CMCNT ) + + #endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) */ + + #define TRC_HWTC_PERIOD ( CMT0.CMCOR + 1 ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 1 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32 ) + + #define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t __x_irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() { __x_irq_status = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); } + #define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK( __x_irq_status ); } + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT ( TMR1 ) + #define TRC_HWTC_PERIOD ( PR1 + 1 ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 1 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 ) + + #define TRC_RTIFRC0 *( ( uint32_t * ) 0xFFFFFC10 ) + #define TRC_RTICOMP0 *( ( uint32_t * ) 0xFFFFFC50 ) + #define TRC_RTIUDCP0 *( ( uint32_t * ) 0xFFFFFC54 ) + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT ( TRC_RTIFRC0 - ( TRC_RTICOMP0 - TRC_RTIUDCP0 ) ) + #define TRC_HWTC_PERIOD ( TRC_RTIUDCP0 ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_AT91SAM7 ) + +/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT ( ( uint32_t ) ( AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF ) ) + #define TRC_HWTC_PERIOD ( ( uint32_t ) ( AT91C_BASE_PITC->PITC_PIMR + 1 ) ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 1 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_UC3A0 ) + +/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO*/ + +/* For Atmel AVR32 (AT32UC3A) */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT ( ( uint32_t ) sysreg_read( AVR32_COUNT ) ) + #define TRC_HWTC_PERIOD ( ( uint32_t ) ( sysreg_read( AVR32_COMPARE ) + 1 ) ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 1 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NXP_LPC210X ) + +/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ + +/* Tested with LPC2106, but should work with most LPC21XX chips. */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT *( ( uint32_t * ) 0xE0004008 ) + #define TRC_HWTC_PERIOD *( ( uint32_t * ) 0xE0004018 ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430 ) + +/* UNOFFICIAL PORT - NOT YET VERIFIED */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT ( TA0R ) + #define TRC_HWTC_PERIOD ( ( ( uint16_t ) TACCR0 ) + 1 ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 1 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC405 ) + +/* UNOFFICIAL PORT - NOT YET VERIFIED */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT mfspr( 0x3db ) + #define TRC_HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRC_TICK_RATE_HZ ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC440 ) + +/* UNOFFICIAL PORT */ + +/* This should work with most PowerPC chips */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT mfspr( 0x016 ) + #define TRC_HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRC_TICK_RATE_HZ ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_MICROBLAZE ) + +/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ + +/* This should work with most Microblaze configurations. + * It uses the AXI Timer 0 - the tick interrupt source. + * If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required. + */ + #include + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 ) + #define TRC_HWTC_PERIOD ( XTmrCtr_GetLoadReg( XPAR_TMRCTR_0_BASEADDR, 0 ) + 1 ) + #define TRC_HWTC_DIVISOR 16 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5 ) + + extern int cortex_a9_r5_enter_critical( void ); + extern void cortex_a9_r5_exit_critical( int irq_already_masked_at_enter ); + + #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_mask_status; + + #define TRACE_ENTER_CRITICAL_SECTION() { __irq_mask_status = cortex_a9_r5_enter_critical(); } + + #define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical( __irq_mask_status ); } + + #include + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT ( *( volatile uint32_t * ) ( configTIMER_BASEADDR + XTTCPS_COUNT_VALUE_OFFSET ) ) + #define TRC_HWTC_PERIOD ( *( volatile uint32_t * ) ( configTIMER_BASEADDR + XTTCPS_INTERVAL_VAL_OFFSET ) ) + #define TRC_HWTC_DIVISOR 16 + #define TRC_HWTC_FREQ_HZ ( TRC_HWTC_PERIOD * TRC_TICK_RATE_HZ ) + #define TRC_IRQ_PRIORITY_ORDER 0 + + #ifdef __GNUC__ + /* For Arm Cortex-A and Cortex-R in general. */ + static inline uint32_t prvGetCPSR( void ) + { + unsigned long ret; + + /* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */ + asm volatile ( " mrs %0, cpsr" : "=r" ( ret ) : /* no inputs */ ); + return ret; + } + #else + #error "Only GCC Supported!" + #endif /* ifdef __GNUC__ */ + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII ) + +/* OFFICIAL PORT */ + + #include + #include + #include + + #define TRACE_ALLOC_CRITICAL_SECTION() alt_irq_context __irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() { __irq_status = alt_irq_disable_all(); } + #define TRACE_EXIT_CRITICAL_SECTION() { alt_irq_enable_all( __irq_status ); } + + #define NOT_SET 1 + +/* The base address for the system timer set. + * The name user for the system timer can be found in the BSP editor. + * If the name of the timer is sys_tmr SYSTEM_TIMER_BASE should be set to SYS_TMR_BASE. + */ + #define SYSTEM_TIMER_BASE NOT_SET + + #if ( SYSTEM_TIMER == NOT_SET ) + #error "Set SYSTEM_TIMER_BASE to the timer base used for system ticks." + #endif + + static inline uint32_t altera_nios2_GetTimerSnapReg( void ) + { + /* A processor can read the current counter value by first writing to either snapl or snaph to request a coherent snapshot of the counter, + * and then reading snapl and snaph for the full 32-bit value. + */ + IOWR_ALTERA_AVALON_TIMER_SNAPL( SYSTEM_TIMER_BASE, 0 ); + return ( IORD_ALTERA_AVALON_TIMER_SNAPH( SYSTEM_TIMER_BASE ) << 16 ) | IORD_ALTERA_AVALON_TIMER_SNAPL( SYSTEM_TIMER_BASE ); + } + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT altera_nios2_GetTimerSnapReg() + #define TRC_HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) + #define TRC_HWTC_DIVISOR 16 + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9 ) + +/************************************************************************** +* This hardware port only supports FreeRTOS and the GCC compiler at the +* moment, due to the implementation of critical sections (trcKernelPort.h). +* +* Assuming FreeRTOS is used: +* +* For critical sections, this uses vTaskEnterCritical is when called from +* task context and ulPortSetInterruptMask when called from ISR context. +* Thus, it does not disable all ISRs. This means that the trace recorder +* can only be called from ISRs with priority less or equal to +* configMAX_API_CALL_INTERRUPT_PRIORITY (like FreeRTOS fromISR functions). +* +* This hardware port has been tested on it a Xilinx Zync 7000 (Cortex-A9), +* but should work with all Cortex-A and R processors assuming that +* TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS is set accordingly. +**************************************************************************/ + + extern int cortex_a9_r5_enter_critical( void ); + extern void cortex_a9_r5_exit_critical( int irq_already_masked_at_enter ); + + #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_mask_status; + + #define TRACE_ENTER_CRITICAL_SECTION() { __irq_mask_status = cortex_a9_r5_enter_critical(); } + + #define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical( __irq_mask_status ); } + +/* INPUT YOUR PERIPHERAL BASE ADDRESS HERE (0xF8F00000 for Xilinx Zynq 7000)*/ + #define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0 + + #if ( TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS == 0 ) + #error "Please specify TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS." + #endif + + #define TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET 0x0600 + #define TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG ( *( volatile uint32_t * ) ( TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x00 ) ) + #define TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG ( *( volatile uint32_t * ) ( TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x04 ) ) + #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG ( *( volatile uint32_t * ) ( TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x08 ) ) + + #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK 0x0000FF00 + #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT 8 + #define TRC_CA9_MPCORE_PRIVCTR_PRESCALER ( ( ( TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG & TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK ) >> TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT ) + 1 ) + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG + #define TRC_HWTC_PERIOD ( TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG + 1 ) + +/**************************************************************************************** + * NOTE: The private timer ticks with a very high frequency (half the core-clock usually), + * depending on the prescaler used. If a low prescaler is used, the number of HW ticks between + * the trace events gets large, and thereby inefficient to store (sometimes extra events are + * needed). To improve efficiency, you may use the TRC_HWTC_DIVISOR as an additional prescaler. + *****************************************************************************************/ + #define TRC_HWTC_DIVISOR 1 + + #define TRC_HWTC_FREQ_HZ ( TRC_TICK_RATE_HZ * TRC_HWTC_PERIOD ) + #define TRC_IRQ_PRIORITY_ORDER 0 + + #ifdef __GNUC__ + /* For Arm Cortex-A and Cortex-R in general. */ + static inline uint32_t prvGetCPSR( void ) + { + unsigned long ret; + + /* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */ + asm volatile ( " mrs %0, cpsr" : "=r" ( ret ) : /* no inputs */ ); + return ret; + } + #else + #error "Only GCC Supported!" + #endif /* ifdef __GNUC__ */ + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_CYCLONE_V_HPS ) + #include "alt_clock_manager.h" + + extern int cortex_a9_r5_enter_critical( void ); + extern void cortex_a9_r5_exit_critical( int irq_already_masked_at_enter ); + + #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_mask_status; + #define TRACE_ENTER_CRITICAL_SECTION() { __irq_mask_status = cortex_a9_r5_enter_critical(); } + #define TRACE_EXIT_CRITICAL_SECTION() { cortex_a9_r5_exit_critical( __irq_mask_status ); } + + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT *( ( uint32_t * ) 0xFFFEC200 ) + #define TRC_HWTC_PERIOD 0 + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ \ + ( ( { \ + uint32_t __freq; \ + alt_clk_freq_get( ALT_CLK_MPU_PERIPH, &__freq ); \ + __freq; \ + } ) ) + #define TRC_IRQ_PRIORITY_ORDER 0 + + #ifdef __GNUC__ + /* For Arm Cortex-A and Cortex-R in general. */ + static inline uint32_t prvGetCPSR( void ) + { + unsigned long ret; + + /* GCC-style assembly for getting the CPSR/APSR register, where the system execution mode is found. */ + __asm__ __volatile__ ( " mrs %0, cpsr" : "=r" ( ret ) : /* no inputs */ ); + return ret; + } + #else + #error "Only GCC Supported!" + #endif /* ifdef __GNUC__ */ + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ZEPHYR ) + #define TRACE_ALLOC_CRITICAL_SECTION() int key; + #define TRACE_ENTER_CRITICAL_SECTION() { key = irq_lock(); } + #define TRACE_EXIT_CRITICAL_SECTION() { irq_unlock( key ); } + + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT k_cycle_get_32() + #define TRC_HWTC_PERIOD ( CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC ) + #define TRC_HWTC_DIVISOR 4 + #define TRC_HWTC_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC + #define TRC_IRQ_PRIORITY_ORDER 0 /* Lower IRQ priority values are more significant */ + + #define TRC_PORT_SPECIFIC_INIT() + +#elif ( ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XTensa_LX6 ) || ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XTensa_LX7 ) ) + +/** + * @note When running with SMP FreeRTOS we cannot use the CCOUNT register for timestamping, + * instead we use the external 40MHz timer for synchronized timestamping between the cores. + */ + #if CONFIG_FREERTOS_UNICORE == 1 + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT \ + ( { unsigned int __ccount; \ + __asm__ __volatile__ ( "rsr.ccount %0" : "=a" ( __ccount ) ); \ + __ccount; } ) + #ifdef CONFIG_IDF_TARGET_ESP32 + #define TRC_HWTC_FREQ_HZ ( CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000 ) + #elif defined( CONFIG_IDF_TARGET_ESP32S2 ) + #define TRC_HWTC_FREQ_HZ ( CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000 ) + #else + #error "Invalid IDF target, check your sdkconfig." + #endif + #define TRC_HWTC_PERIOD 0 + #define TRC_HWTC_DIVISOR 4 + #define TRC_IRQ_PRIORITY_ORDER 0 + #else /* if CONFIG_FREERTOS_UNICORE == 1 */ + +/** + * @brief Fetch core agnostic timestamp using the external 40MHz timer. This is used by tracerecorder + * when running with both cores. + * + * @return Ticks since the timer started + */ + uint32_t prvGetSMPTimestamp(); + + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT prvGetSMPTimestamp() + #define TRC_HWTC_FREQ_HZ 40000000 + #define TRC_HWTC_PERIOD 0 + #define TRC_HWTC_DIVISOR 4 + #define TRC_IRQ_PRIORITY_ORDER 0 + #endif /* if CONFIG_FREERTOS_UNICORE == 1 */ + + #if !defined( TRC_HWTC_FREQ_HZ ) + #error "The XTensa LX6/LX7 trace hardware clock frequency is not defined." + #endif + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_RISCV_RV32I ) + #define TRACE_ALLOC_CRITICAL_SECTION() unsigned int __irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() \ + __asm__ __volatile__ ( "csrr %0, mstatus \n\t"\ + "csrci mstatus, 8 \n\t"\ + "andi %0, %0, 8 \n\t"\ + : "=r" ( __irq_status ) ) + #define TRACE_EXIT_CRITICAL_SECTION() \ + __asm__ __volatile__ ( "csrr a1, mstatus \n\t"\ + "or %0, %0, a1 \n\t"\ + "csrs mstatus, %0 \n\t"\ + : \ + : "r" ( __irq_status ) \ + : "a1" ) + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT \ + ( { unsigned int __count; \ + __asm__ __volatile__ ( "rdcycle %0" : "=r" ( __count ) ); \ + __count; } ) + #define TRC_HWTC_PERIOD 0 + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ 16000000 + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XMOS_XCOREAI ) + #define TRC_PORT_SPECIFIC_INIT() + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT xscope_gettime() + #define TRC_HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) + #define TRC_HWTC_DIVISOR 4 + #define TRC_HWTC_FREQ_HZ 100000000 + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4 ) + +/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ + + #define TRACE_ALLOC_CRITICAL_SECTION() TraceBaseType_t __x_irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() { __x_irq_status = TRC_KERNEL_PORT_SET_INTERRUPT_MASK(); } + #define TRACE_EXIT_CRITICAL_SECTION() { TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK( __x_irq_status ); } + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + /*#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING */ + #define TRC_HWTC_COUNT PIT.TIMER[ configTICK_PIT_CHANNEL ].CVAL.R /* must be the PIT channel used for the systick */ + #define TRC_HWTC_PERIOD ( ( configPIT_CLOCK_HZ / configTICK_RATE_HZ ) - 1U ) /* TODO FIXME or maybe not -1? what's the right "period" value? */ + #define TRC_HWTC_FREQ_HZ configPIT_CLOCK_HZ + #define TRC_HWTC_DIVISOR 1 + #define TRC_IRQ_PRIORITY_ORDER 1 /* higher IRQ priority values are more significant */ + +#elif ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_APPLICATION_DEFINED ) + + #if !( defined( TRC_HWTC_TYPE ) && defined( TRC_HWTC_COUNT ) && defined( TRC_HWTC_PERIOD ) && defined( TRC_HWTC_FREQ_HZ ) && defined( TRC_IRQ_PRIORITY_ORDER ) ) + #error "The hardware port is not completely defined!" + #endif + +#elif ( TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET ) + + #error "TRC_CFG_HARDWARE_PORT had unsupported value!" + #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET + +#endif /* if ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32 ) */ + +#ifndef TRC_HWTC_DIVISOR + #define TRC_HWTC_DIVISOR 1 +#endif + +#ifndef TRC_PORT_SPECIFIC_INIT + #define TRC_PORT_SPECIFIC_INIT() +#endif + +/* If Win32 port */ +#ifdef WIN32 + + #undef _WIN32_WINNT + #define _WIN32_WINNT 0x0600 + +/* Standard includes. */ + #include + #include + #include + +/*************************************************************************** +* The Win32 port by default saves the trace to file and then kills the +* program when the recorder is stopped, to facilitate quick, simple tests +* of the recorder. +***************************************************************************/ + #define WIN32_PORT_SAVE_WHEN_STOPPED 1 + #define WIN32_PORT_EXIT_WHEN_STOPPED 1 + +#endif /* ifdef WIN32 */ + +#if ( TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET ) + + #ifndef TRC_HWTC_TYPE + #error "TRC_HWTC_TYPE is not set!" + #endif + + #ifndef TRC_HWTC_COUNT + #error "TRC_HWTC_COUNT is not set!" + #endif + + #ifndef TRC_HWTC_PERIOD + #error "TRC_HWTC_PERIOD is not set!" + #endif + + #ifndef TRC_HWTC_DIVISOR + #error "TRC_HWTC_DIVISOR is not set!" + #endif + + #ifndef TRC_IRQ_PRIORITY_ORDER + #error "TRC_IRQ_PRIORITY_ORDER is not set!" + #elif ( TRC_IRQ_PRIORITY_ORDER != 0 ) && ( TRC_IRQ_PRIORITY_ORDER != 1 ) + #error "TRC_IRQ_PRIORITY_ORDER has bad value!" + #endif + + #if ( TRC_HWTC_DIVISOR < 1 ) + #error "TRC_HWTC_DIVISOR must be a non-zero positive value!" + #endif + + #ifndef TRC_HWTC_FREQ_HZ + #error "TRC_HWTC_FREQ_HZ not defined!" + #endif + +#endif /* if ( TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET ) */ + +#ifndef TRACE_ALLOC_CRITICAL_SECTION + #define TRACE_ALLOC_CRITICAL_SECTION() TRC_KERNEL_PORT_ALLOC_CRITICAL_SECTION() +#endif +#ifndef TRACE_ENTER_CRITICAL_SECTION + #define TRACE_ENTER_CRITICAL_SECTION() TRC_KERNEL_PORT_ENTER_CRITICAL_SECTION() +#endif +#ifndef TRACE_EXIT_CRITICAL_SECTION + #define TRACE_EXIT_CRITICAL_SECTION() TRC_KERNEL_PORT_EXIT_CRITICAL_SECTION() +#endif + +#endif /*TRC_SNAPSHOT_HARDWARE_PORT_H*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHeap.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHeap.h index bdff67b6e..028d52d9c 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHeap.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcHeap.h @@ -1,135 +1,146 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace heap APIs. - */ - -#ifndef TRC_HEAP_H -#define TRC_HEAP_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#ifndef TRC_USE_HEAPS -#define TRC_USE_HEAPS 1 -#endif - -#if (TRC_USE_HEAPS == 1) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_heap_apis Trace Heap APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @brief Creates trace heap. - * - * @param[in] szName Name. - * @param[in] uxCurrent Current level. - * @param[in] uxHighWaterMark High water mark - * @param[in] uxMax Maximum level. - * @param[out] pxHeapHandle Pointer to uninitialized trace heap handle. - * @return traceResult - */ -traceResult xTraceHeapCreate(const char *szName, TraceUnsignedBaseType_t uxCurrent, TraceUnsignedBaseType_t uxHighWaterMark, TraceUnsignedBaseType_t uxMax, TraceHeapHandle_t *pxHeapHandle); - -/** - * @brief Signals trace heap alloc. - * - * @param[in] xHeapHandle Pointer to initialized trace heap handle. - * @param[in] pvAddress Address. - * @param[in] uxSize Size. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceHeapAlloc(TraceHeapHandle_t xHeapHandle, void *pvAddress, TraceUnsignedBaseType_t uxSize); - -/** - * @brief Signals trace heap free. - * - * @param[in] xHeapHandle Pointer to initialized trace heap handle. - * @param[in] pvAddress Address. - * @param[in] uxSize Size. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceHeapFree(TraceHeapHandle_t xHeapHandle, void* pvAddress, TraceUnsignedBaseType_t uxSize); - -/** - * @brief Gets trace heap current allocation size. - * - * @param[in] xHeapHandle Pointer to initialized trace heap handle. - * @param[out] puxCurrent Current. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceHeapGetCurrent(TraceHeapHandle_t xHeapHandle, TraceUnsignedBaseType_t *puxCurrent); - -/** - * @brief Gets trace heap high water mark. - * - * @param[in] xHeapHandle Pointer to initialized trace heap handle. - * @param[out] puxHighWaterMark High water mark. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceHeapGetHighWaterMark(TraceHeapHandle_t xHeapHandle, TraceUnsignedBaseType_t *puxHighWaterMark); - -/** - * @brief Gets trace heap max size. - * - * @param[in] xHeapHandle Pointer to initialized trace heap handle. - * @param[out] puxMax Max. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceHeapGetMax(TraceHeapHandle_t xHeapHandle, TraceUnsignedBaseType_t *puxMax); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#else - -#define xTraceHeapCreate(szName, uxCurrent, uxHighWaterMark, uxMax, pxHeapHandle) ((void)szName, (void)uxCurrent, (void)uxHighWaterMark, (void)uxMax, pxHeapHandle != 0 ? TRC_SUCCESS : TRC_FAIL) - -#define xTraceHeapAlloc(xHeapHandle, pvAddress, uxSize) ((void)xHeapHandle, (void)pvAddress, (void)uxSize, TRC_SUCCESS) - -#define xTraceHeapFree(xHeapHandle, pvAddress, uxSize) ((void)xHeapHandle, (void)pvAddress, (void)uxSize, TRC_SUCCESS) - -#define xTraceHeapGetCurrent(xHeapHandle, puxCurrent) ((void)xHeapHandle, puxCurrent != 0 ? *puxCurrent = 0 : 0, puxCurrent != 0 ? TRC_SUCCESS : TRC_FAIL) - -#define xTraceHeapGetHighWaterMark(xHeapHandle, puxHighWaterMark) ((void)xHeapHandle, puxHighWaterMark != 0 ? *puxHighWaterMark = 0 : 0, puxHighWaterMark != 0 ? TRC_SUCCESS : TRC_FAIL) - -#define xTraceHeapGetMax(xHeapHandle, puxMax) ((void)xHeapHandle, puxMax != 0 ? *puxMax = 0 : 0, puxMax != 0 ? TRC_SUCCESS : TRC_FAIL) - -#endif /* (TRC_USE_HEAPS == 1) */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_HEAP_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace heap APIs. + */ + +#ifndef TRC_HEAP_H + #define TRC_HEAP_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #ifndef TRC_USE_HEAPS + #define TRC_USE_HEAPS 1 + #endif + + #if ( TRC_USE_HEAPS == 1 ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_heap_apis Trace Heap APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @brief Creates trace heap. + * + * @param[in] szName Name. + * @param[in] uxCurrent Current level. + * @param[in] uxHighWaterMark High water mark + * @param[in] uxMax Maximum level. + * @param[out] pxHeapHandle Pointer to uninitialized trace heap handle. + * @return traceResult + */ + traceResult xTraceHeapCreate( const char * szName, + TraceUnsignedBaseType_t uxCurrent, + TraceUnsignedBaseType_t uxHighWaterMark, + TraceUnsignedBaseType_t uxMax, + TraceHeapHandle_t * pxHeapHandle ); + +/** + * @brief Signals trace heap alloc. + * + * @param[in] xHeapHandle Pointer to initialized trace heap handle. + * @param[in] pvAddress Address. + * @param[in] uxSize Size. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceHeapAlloc( TraceHeapHandle_t xHeapHandle, + void * pvAddress, + TraceUnsignedBaseType_t uxSize ); + +/** + * @brief Signals trace heap free. + * + * @param[in] xHeapHandle Pointer to initialized trace heap handle. + * @param[in] pvAddress Address. + * @param[in] uxSize Size. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceHeapFree( TraceHeapHandle_t xHeapHandle, + void * pvAddress, + TraceUnsignedBaseType_t uxSize ); + +/** + * @brief Gets trace heap current allocation size. + * + * @param[in] xHeapHandle Pointer to initialized trace heap handle. + * @param[out] puxCurrent Current. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceHeapGetCurrent( TraceHeapHandle_t xHeapHandle, + TraceUnsignedBaseType_t * puxCurrent ); + +/** + * @brief Gets trace heap high water mark. + * + * @param[in] xHeapHandle Pointer to initialized trace heap handle. + * @param[out] puxHighWaterMark High water mark. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceHeapGetHighWaterMark( TraceHeapHandle_t xHeapHandle, + TraceUnsignedBaseType_t * puxHighWaterMark ); + +/** + * @brief Gets trace heap max size. + * + * @param[in] xHeapHandle Pointer to initialized trace heap handle. + * @param[out] puxMax Max. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceHeapGetMax( TraceHeapHandle_t xHeapHandle, + TraceUnsignedBaseType_t * puxMax ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #else /* if ( TRC_USE_HEAPS == 1 ) */ + + #define xTraceHeapCreate( szName, uxCurrent, uxHighWaterMark, uxMax, pxHeapHandle ) ( ( void ) szName, ( void ) uxCurrent, ( void ) uxHighWaterMark, ( void ) uxMax, pxHeapHandle != 0 ? TRC_SUCCESS : TRC_FAIL ) + + #define xTraceHeapAlloc( xHeapHandle, pvAddress, uxSize ) ( ( void ) xHeapHandle, ( void ) pvAddress, ( void ) uxSize, TRC_SUCCESS ) + + #define xTraceHeapFree( xHeapHandle, pvAddress, uxSize ) ( ( void ) xHeapHandle, ( void ) pvAddress, ( void ) uxSize, TRC_SUCCESS ) + + #define xTraceHeapGetCurrent( xHeapHandle, puxCurrent ) ( ( void ) xHeapHandle, puxCurrent != 0 ? *puxCurrent = 0 : 0, puxCurrent != 0 ? TRC_SUCCESS : TRC_FAIL ) + + #define xTraceHeapGetHighWaterMark( xHeapHandle, puxHighWaterMark ) ( ( void ) xHeapHandle, puxHighWaterMark != 0 ? *puxHighWaterMark = 0 : 0, puxHighWaterMark != 0 ? TRC_SUCCESS : TRC_FAIL ) + + #define xTraceHeapGetMax( xHeapHandle, puxMax ) ( ( void ) xHeapHandle, puxMax != 0 ? *puxMax = 0 : 0, puxMax != 0 ? TRC_SUCCESS : TRC_FAIL ) + + #endif /* (TRC_USE_HEAPS == 1) */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_HEAP_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcISR.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcISR.h index 8c95d5419..790cbe76b 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcISR.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcISR.h @@ -1,226 +1,229 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace ISR APIs. - */ - -#ifndef TRC_ISR_H -#define TRC_ISR_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_isr_apis Trace ISR APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @internal Trace ISR Core Info Structure - */ -typedef struct TraceISRCoreInfo -{ - TraceISRHandle_t handleStack[TRC_CFG_MAX_ISR_NESTING]; /**< */ - int32_t stackIndex; /**< */ - int32_t isPendingContextSwitch; /**< */ -} TraceISRCoreInfo_t; - -/** - * @internal Trace ISR Info Structure - */ -typedef struct TraceISRInfo -{ - TraceISRCoreInfo_t coreInfos[TRC_CFG_CORE_COUNT]; /* ISR handles */ -} TraceISRInfo_t; - -/* We expose this to enable faster access */ -extern TraceISRInfo_t* pxTraceISRInfo; - -#define TRACE_ISR_INFO_BUFFER_SIZE (sizeof(TraceISRInfo_t)) - -/** - * @internal Trace ISR Info Buffer - */ -typedef struct TraceISRInfoBuffer -{ - uint8_t buffer[(TRACE_ISR_INFO_BUFFER_SIZE)]; /**< */ -} TraceISRInfoBuffer_t; - -/** - * @internal Initialize ISR trace system. - * - * @param[in] pxBuffer Pointer to memory that will be used by the ISR - * trace system. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceISRInitialize(TraceISRInfoBuffer_t *pxBuffer); - -/** - * @brief Registers trace ISR. - * - * This routine stores a name and priority level for an Interrupt Service Routine, - * to allow for better visualization. Returns a TraceISRHandle_t used by - * xTraceISRBegin/xTraceISREnd. - * - * Example: - * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt - * TraceISRHandle_t xISRTimer1Handle = 0; // The ID set by the recorder - * ... - * xTraceISRRegister("ISRTimer1", PRIO_OF_ISR_TIMER1, &xISRTimer1Handle); - * ... - * void ISR_handler() - * { - * xTraceISRBegin(xISRTimer1Handle); - * ... - * xTraceISREnd(0); - * } - * - * @param[in] szName Name. - * @param[in] uiPriority Priority. - * @param[out] pxISRHandle Pointer to uninitialized ISR trace handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceISRRegister(const char* szName, uint32_t uiPriority, TraceISRHandle_t* pxISRHandle); - -/** - * @brief Registers the beginning of an Interrupt Service Routine. - * - * This routine register the beginning of an ISR using a TraceISRHandle_t. - * See xTraceISRRegister for and example of using ISR tracing. - * - * @param[in] xISRHandle Pointer to initialized ISR trace handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceISRBegin(TraceISRHandle_t xISRHandle); - -/** - * @brief Registers the end of an Interrupt Service Routine. - * - * This routine register the end of an ISR using a TraceISRHandle_t. - * See xTraceISRRegister for and example of using ISR tracing. - * - * The parameter uxIsTaskSwitchRequired indicates if the interrupt has requested - * a task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the - * interrupt is assumed to return to the previous context. - * - * @param[in] xIsTaskSwitchRequired Task switch required. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired); - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -/** - * @brief Gets current trace ISR nesting level. - * - * This routine gets the current trace ISR nesting level for the - * CPU on which it is called. - * - * @param[out] puiValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceISRGetCurrentNesting(int32_t* puiValue); - -/** - * @brief - * - * @return int32_t - */ -int32_t xTraceISRGetCurrentNestingReturned(void); - -/** - * @brief Gets current ISR trace handle. - * - * @param[out] pxISRHandle ISR Handle. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceISRGetCurrent(TraceISRHandle_t* pxISRHandle); - -#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** - * @brief Gets current trace ISR nesting level. - * - * This routine gets the current trace ISR nesting level for the - * CPU on which it is called. - * - * @param[out] puiValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceISRGetCurrentNesting(puiValue) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiValue) = pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()].stackIndex, TRC_SUCCESS) - -/** - * @brief - * - * @return int32_t - */ -#define xTraceISRGetCurrentNestingReturned() (pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()].stackIndex) - -/** - * @brief Gets current trace ISR nesting level. - * - * This routine gets the current trace ISR nesting level for the - * CPU on which it is called. - * - * @param[out] puiValue Value. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceISRGetCurrent(pxISRHandle) (xTraceISRGetCurrentNestingReturned() >= 0 ? (*(pxISRHandle) = pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()].handleStack[xTraceISRGetCurrentNestingReturned()], TRC_SUCCESS) : TRC_FAIL) - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */ -TraceISRHandle_t xTraceSetISRProperties(const char* szName, uint32_t uiPriority); - -/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */ -#define xTraceGetCurrentISRNesting(puiValue) xTraceISRGetCurrentNesting(puiValue) - -/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */ -#define vTraceStoreISRBegin(xISRHandle) xTraceISRBegin(xISRHandle) - -/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */ -#define vTraceStoreISREnd(xIsTaskSwitchRequired) xTraceISREnd(xIsTaskSwitchRequired) - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_ISR_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace ISR APIs. + */ + +#ifndef TRC_ISR_H + #define TRC_ISR_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_isr_apis Trace ISR APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @internal Trace ISR Core Info Structure + */ + typedef struct TraceISRCoreInfo + { + TraceISRHandle_t handleStack[ TRC_CFG_MAX_ISR_NESTING ]; /**< */ + int32_t stackIndex; /**< */ + int32_t isPendingContextSwitch; /**< */ + } TraceISRCoreInfo_t; + +/** + * @internal Trace ISR Info Structure + */ + typedef struct TraceISRInfo + { + TraceISRCoreInfo_t coreInfos[ TRC_CFG_CORE_COUNT ]; /* ISR handles */ + } TraceISRInfo_t; + +/* We expose this to enable faster access */ + extern TraceISRInfo_t * pxTraceISRInfo; + + #define TRACE_ISR_INFO_BUFFER_SIZE ( sizeof( TraceISRInfo_t ) ) + +/** + * @internal Trace ISR Info Buffer + */ + typedef struct TraceISRInfoBuffer + { + uint8_t buffer[ ( TRACE_ISR_INFO_BUFFER_SIZE ) ]; /**< */ + } TraceISRInfoBuffer_t; + +/** + * @internal Initialize ISR trace system. + * + * @param[in] pxBuffer Pointer to memory that will be used by the ISR + * trace system. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceISRInitialize( TraceISRInfoBuffer_t * pxBuffer ); + +/** + * @brief Registers trace ISR. + * + * This routine stores a name and priority level for an Interrupt Service Routine, + * to allow for better visualization. Returns a TraceISRHandle_t used by + * xTraceISRBegin/xTraceISREnd. + * + * Example: + * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt + * TraceISRHandle_t xISRTimer1Handle = 0; // The ID set by the recorder + * ... + * xTraceISRRegister("ISRTimer1", PRIO_OF_ISR_TIMER1, &xISRTimer1Handle); + * ... + * void ISR_handler() + * { + * xTraceISRBegin(xISRTimer1Handle); + * ... + * xTraceISREnd(0); + * } + * + * @param[in] szName Name. + * @param[in] uiPriority Priority. + * @param[out] pxISRHandle Pointer to uninitialized ISR trace handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceISRRegister( const char * szName, + uint32_t uiPriority, + TraceISRHandle_t * pxISRHandle ); + +/** + * @brief Registers the beginning of an Interrupt Service Routine. + * + * This routine register the beginning of an ISR using a TraceISRHandle_t. + * See xTraceISRRegister for and example of using ISR tracing. + * + * @param[in] xISRHandle Pointer to initialized ISR trace handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceISRBegin( TraceISRHandle_t xISRHandle ); + +/** + * @brief Registers the end of an Interrupt Service Routine. + * + * This routine register the end of an ISR using a TraceISRHandle_t. + * See xTraceISRRegister for and example of using ISR tracing. + * + * The parameter uxIsTaskSwitchRequired indicates if the interrupt has requested + * a task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the + * interrupt is assumed to return to the previous context. + * + * @param[in] xIsTaskSwitchRequired Task switch required. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceISREnd( TraceBaseType_t xIsTaskSwitchRequired ); + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + +/** + * @brief Gets current trace ISR nesting level. + * + * This routine gets the current trace ISR nesting level for the + * CPU on which it is called. + * + * @param[out] puiValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceISRGetCurrentNesting( int32_t * puiValue ); + +/** + * @brief + * + * @return int32_t + */ + int32_t xTraceISRGetCurrentNestingReturned( void ); + +/** + * @brief Gets current ISR trace handle. + * + * @param[out] pxISRHandle ISR Handle. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceISRGetCurrent( TraceISRHandle_t * pxISRHandle ); + + #else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** + * @brief Gets current trace ISR nesting level. + * + * This routine gets the current trace ISR nesting level for the + * CPU on which it is called. + * + * @param[out] puiValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceISRGetCurrentNesting( puiValue ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( puiValue ) = pxTraceISRInfo->coreInfos[ TRC_CFG_GET_CURRENT_CORE() ].stackIndex, TRC_SUCCESS ) + +/** + * @brief + * + * @return int32_t + */ + #define xTraceISRGetCurrentNestingReturned() ( pxTraceISRInfo->coreInfos[ TRC_CFG_GET_CURRENT_CORE() ].stackIndex ) + +/** + * @brief Gets current trace ISR nesting level. + * + * This routine gets the current trace ISR nesting level for the + * CPU on which it is called. + * + * @param[out] puiValue Value. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceISRGetCurrent( pxISRHandle ) ( xTraceISRGetCurrentNestingReturned() >= 0 ? ( *( pxISRHandle ) = pxTraceISRInfo->coreInfos[ TRC_CFG_GET_CURRENT_CORE() ].handleStack[ xTraceISRGetCurrentNestingReturned() ], TRC_SUCCESS ) : TRC_FAIL ) + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */ + TraceISRHandle_t xTraceSetISRProperties( const char * szName, + uint32_t uiPriority ); + +/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */ + #define xTraceGetCurrentISRNesting( puiValue ) xTraceISRGetCurrentNesting( puiValue ) + +/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */ + #define vTraceStoreISRBegin( xISRHandle ) xTraceISRBegin( xISRHandle ) + +/** @internal Deprecated - Provides backwards-compability with older recorders for now, will be removed in the future */ + #define vTraceStoreISREnd( xIsTaskSwitchRequired ) xTraceISREnd( xIsTaskSwitchRequired ) + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_ISR_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcInternalEventBuffer.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcInternalEventBuffer.h index 9e7d57429..f5cca3f3b 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcInternalEventBuffer.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcInternalEventBuffer.h @@ -1,107 +1,110 @@ -/* - * Percepio Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * - * @brief Public internal event buffer APIs. - */ - -#ifndef TRC_INTERNAL_BUFFER_H -#define TRC_INTERNAL_BUFFER_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#ifndef TRC_USE_INTERNAL_BUFFER -#define TRC_USE_INTERNAL_BUFFER 1 -#endif - -#if (TRC_USE_INTERNAL_BUFFER == 1) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_internal_event_buffer_apis Trace Internal Event Buffer APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @internal Initializes the internal trace event buffer used by certain stream ports. - * - * @param[in] puiBuffer Pointer to previously allocated memory buffer - * @param[in] uiSize Size of buffer - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceInternalEventBufferInitialize(uint8_t* puiBuffer, uint32_t uiSize); - -/** - * @brief Pushes data to the internal trace event buffer. - * - * @param[in] pvData Pointer to data - * @param[in] uiSize Size of data - * @param[out] piBytesWritten Bytes written. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceInternalEventBufferPush(void *pvData, uint32_t uiSize, int32_t *piBytesWritten); - -/** - * @brief Transfers all internal trace event buffer data using the function - * xTraceStreamPortWriteData(...) as defined in trcStreamPort.h. - * - * This function is intended to be called by the periodic TzCtrl task with a - * suitable delay (e.g. 10-100 ms). - * - * In case of errors from the streaming interface, it registers a warning - * (TRC_WARNING_STREAM_PORT_WRITE) provided by xTraceErrorGetLast(). - * - * @param[out] piBytesWritten Bytes written. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceInternalEventBufferTransfer(int32_t *piBytesWritten); - -/** - * @brief Clears all trace events in the internal trace event buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceInternalEventBufferClear(void); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#else /* (TRC_USE_INTERNAL_BUFFER == 1)*/ - -#define xTraceInternalEventBufferInitialize(puiBuffer, uiSize) ((void)uiSize, puiBuffer != 0 ? TRC_SUCCESS : TRC_FAIL) -#define xTraceInternalEventBufferPush(pvData, uiSize, piBytesWritten) ((void)uiSize, (void)piBytesWritten, pvData != 0 ? TRC_SUCCESS : TRC_FAIL) -#define xTraceInternalEventBufferTransfer(piBytesWritten) ((void)piBytesWritten, TRC_SUCCESS) -#define xTraceInternalEventBufferClear() (void)(TRC_SUCCESS) - -#endif /* (TRC_USE_INTERNAL_BUFFER == 1)*/ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_INTERNAL_BUFFER_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public internal event buffer APIs. + */ + +#ifndef TRC_INTERNAL_BUFFER_H + #define TRC_INTERNAL_BUFFER_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #ifndef TRC_USE_INTERNAL_BUFFER + #define TRC_USE_INTERNAL_BUFFER 1 + #endif + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_internal_event_buffer_apis Trace Internal Event Buffer APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @internal Initializes the internal trace event buffer used by certain stream ports. + * + * @param[in] puiBuffer Pointer to previously allocated memory buffer + * @param[in] uiSize Size of buffer + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceInternalEventBufferInitialize( uint8_t * puiBuffer, + uint32_t uiSize ); + +/** + * @brief Pushes data to the internal trace event buffer. + * + * @param[in] pvData Pointer to data + * @param[in] uiSize Size of data + * @param[out] piBytesWritten Bytes written. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceInternalEventBufferPush( void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ); + +/** + * @brief Transfers all internal trace event buffer data using the function + * xTraceStreamPortWriteData(...) as defined in trcStreamPort.h. + * + * This function is intended to be called by the periodic TzCtrl task with a + * suitable delay (e.g. 10-100 ms). + * + * In case of errors from the streaming interface, it registers a warning + * (TRC_WARNING_STREAM_PORT_WRITE) provided by xTraceErrorGetLast(). + * + * @param[out] piBytesWritten Bytes written. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceInternalEventBufferTransfer( int32_t * piBytesWritten ); + +/** + * @brief Clears all trace events in the internal trace event buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceInternalEventBufferClear( void ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #else /* (TRC_USE_INTERNAL_BUFFER == 1)*/ + + #define xTraceInternalEventBufferInitialize( puiBuffer, uiSize ) ( ( void ) uiSize, puiBuffer != 0 ? TRC_SUCCESS : TRC_FAIL ) + #define xTraceInternalEventBufferPush( pvData, uiSize, piBytesWritten ) ( ( void ) uiSize, ( void ) piBytesWritten, pvData != 0 ? TRC_SUCCESS : TRC_FAIL ) + #define xTraceInternalEventBufferTransfer( piBytesWritten ) ( ( void ) piBytesWritten, TRC_SUCCESS ) + #define xTraceInternalEventBufferClear() ( void ) ( TRC_SUCCESS ) + + #endif /* (TRC_USE_INTERNAL_BUFFER == 1)*/ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_INTERNAL_BUFFER_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcInterval.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcInterval.h index 3f962f1cc..2c67092ea 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcInterval.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcInterval.h @@ -1,86 +1,88 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace interval APIs. - */ - -#ifndef TRC_INTERVAL_H -#define TRC_INTERVAL_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_interval_apis Trace Interval APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @brief Creates trace interval. - * - * @param[in] szName Name. - * @param[out] pxIntervalHandle Pointer to uninitialized trace interval. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceIntervalCreate(const char *szName, TraceIntervalHandle_t *pxIntervalHandle); - -/** - * @brief Starts trace interval. - * - * @param[in] xIntervalHandle Pointer to initialized trace interval. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceIntervalStart(TraceIntervalHandle_t xIntervalHandle); - -/** - * @brief Stops trace interval. - * - * @param[in] xIntervalHandle Pointer to initialized trace interval. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceIntervalStop(TraceIntervalHandle_t xIntervalHandle); - -/** - * @brief Gets trace interval state. - * - * @param[in] xIntervalHandle Pointer to initialized trace interval. - * @param[out] puxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceIntervalGetState(TraceIntervalHandle_t xIntervalHandle, uint32_t *puxState); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_INTERVAL_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace interval APIs. + */ + +#ifndef TRC_INTERVAL_H + #define TRC_INTERVAL_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_interval_apis Trace Interval APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @brief Creates trace interval. + * + * @param[in] szName Name. + * @param[out] pxIntervalHandle Pointer to uninitialized trace interval. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceIntervalCreate( const char * szName, + TraceIntervalHandle_t * pxIntervalHandle ); + +/** + * @brief Starts trace interval. + * + * @param[in] xIntervalHandle Pointer to initialized trace interval. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceIntervalStart( TraceIntervalHandle_t xIntervalHandle ); + +/** + * @brief Stops trace interval. + * + * @param[in] xIntervalHandle Pointer to initialized trace interval. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceIntervalStop( TraceIntervalHandle_t xIntervalHandle ); + +/** + * @brief Gets trace interval state. + * + * @param[in] xIntervalHandle Pointer to initialized trace interval. + * @param[out] puxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceIntervalGetState( TraceIntervalHandle_t xIntervalHandle, + uint32_t * puxState ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_INTERVAL_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h index 8b8819579..1bd6f5469 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelPort.h @@ -1,2971 +1,2993 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * FreeRTOS specific definitions needed by the trace recorder - */ - -#ifndef TRC_KERNEL_PORT_H -#define TRC_KERNEL_PORT_H - -#include -#include /* Defines configUSE_TRACE_FACILITY */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define TRC_USE_TRACEALYZER_RECORDER configUSE_TRACE_FACILITY - -/* FreeRTOS version codes */ -#define FREERTOS_VERSION_NOT_SET 0 -#define TRC_FREERTOS_VERSION_7_3_X 1 /* v7.3 is earliest supported.*/ -#define TRC_FREERTOS_VERSION_7_4_X 2 -#define TRC_FREERTOS_VERSION_7_5_X 3 -#define TRC_FREERTOS_VERSION_7_6_X TRC_FREERTOS_VERSION_7_5_X -#define TRC_FREERTOS_VERSION_8_X_X 4 -#define TRC_FREERTOS_VERSION_9_0_0 5 -#define TRC_FREERTOS_VERSION_9_0_1 6 -#define TRC_FREERTOS_VERSION_9_0_2 7 -#define TRC_FREERTOS_VERSION_10_0_0 8 -#define TRC_FREERTOS_VERSION_10_0_1 TRC_FREERTOS_VERSION_10_0_0 -#define TRC_FREERTOS_VERSION_10_1_0 TRC_FREERTOS_VERSION_10_0_0 -#define TRC_FREERTOS_VERSION_10_1_1 TRC_FREERTOS_VERSION_10_0_0 -#define TRC_FREERTOS_VERSION_10_2_0 TRC_FREERTOS_VERSION_10_0_0 -#define TRC_FREERTOS_VERSION_10_2_1 TRC_FREERTOS_VERSION_10_0_0 -#define TRC_FREERTOS_VERSION_10_3_0 9 -#define TRC_FREERTOS_VERSION_10_3_1 TRC_FREERTOS_VERSION_10_3_0 -#define TRC_FREERTOS_VERSION_10_4_0 10 -#define TRC_FREERTOS_VERSION_10_4_1 TRC_FREERTOS_VERSION_10_4_0 - -/* Legacy FreeRTOS version codes for backwards compatibility with old trace configurations */ -#define TRC_FREERTOS_VERSION_7_3 TRC_FREERTOS_VERSION_7_3_X -#define TRC_FREERTOS_VERSION_7_4 TRC_FREERTOS_VERSION_7_4_X -#define TRC_FREERTOS_VERSION_7_5_OR_7_6 TRC_FREERTOS_VERSION_7_5_X -#define TRC_FREERTOS_VERSION_8_X TRC_FREERTOS_VERSION_8_X_X - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) -#define prvGetStreamBufferType(x) ((( StreamBuffer_t * )(x) )->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER) -#else -#define prvGetStreamBufferType(x) 0 -#endif - -/* Added mainly for our internal testing. This makes it easier to create test applications that - runs on multiple FreeRTOS versions. */ -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X) - /* FreeRTOS v7.x */ - #define STRING_CAST(x) ( (signed char*) x ) - #define TickType portTickType - #define TaskType xTaskHandle -#else - /* FreeRTOS v8.0 and later */ - #define STRING_CAST(x) x - #define TraceKernelPortTickType_t TickType_t - #define TraceKernelPortTaskHandle_t TaskHandle_t -#endif - -#if (defined(TRC_USE_TRACEALYZER_RECORDER)) && (TRC_USE_TRACEALYZER_RECORDER == 1) - -#define TRC_PLATFORM_CFG "FreeRTOS" -#define TRC_PLATFORM_CFG_MAJOR 1 -#define TRC_PLATFORM_CFG_MINOR 0 -#define TRC_PLATFORM_CFG_PATCH 0 - -#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) - -/* Required for stack monitoring */ -#undef INCLUDE_uxTaskGetStackHighWaterMark -#define INCLUDE_uxTaskGetStackHighWaterMark 1 - -#endif - -/* INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 for tracing to work properly */ -#undef INCLUDE_xTaskGetCurrentTaskHandle -#define INCLUDE_xTaskGetCurrentTaskHandle 1 - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) -#include - -#define TRC_KERNEL_PORT_BUFFER_SIZE (sizeof(TraceHeapHandle_t) + sizeof(void*)) -#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) -#define TRC_KERNEL_PORT_BUFFER_SIZE (sizeof(TraceUnsignedBaseType_t)) -#endif - -/** - * @internal The kernel port data buffer - */ -typedef struct TraceKernelPortDataBuffer -{ - uint8_t buffer[TRC_KERNEL_PORT_BUFFER_SIZE]; -} TraceKernelPortDataBuffer_t; - -/** - * @internal Initializes the kernel port - * - * @param[in] pxBuffer Kernel port data buffer - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceKernelPortInitialize(TraceKernelPortDataBuffer_t* pxBuffer); - -/** - * @internal Enables the kernel port - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceKernelPortEnable(void); - -/** - * @internal Calls on FreeRTOS vTaskDelay(...) - * - * @param[in] uiTicks Tick count to delay - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceKernelPortDelay(uint32_t uiTicks); - -/** - * @internal Query if FreeRTOS scheduler is suspended - * - * @retval 1 Scheduler suspended - * @retval 0 Scheduler not suspended - */ -unsigned char xTraceKernelPortIsSchedulerSuspended(void); - -/** - * @brief Kernel specific way to properly allocate critical sections - */ -#define TRC_KERNEL_PORT_ALLOC_CRITICAL_SECTION() - -/** - * @brief Kernel specific way to properly allocate critical sections - */ -#define TRC_KERNEL_PORT_ENTER_CRITICAL_SECTION() portENTER_CRITICAL() - -/** - * @brief Kernel specific way to properly allocate critical sections - */ -#define TRC_KERNEL_PORT_EXIT_CRITICAL_SECTION() portEXIT_CRITICAL() - -/** -* @brief Kernel specific way to set interrupt mask -*/ -#define TRC_KERNEL_PORT_SET_INTERRUPT_MASK() ((TraceBaseType_t)portSET_INTERRUPT_MASK_FROM_ISR()) - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -/** - * @brief Kernel specific way to clear interrupt mask - */ -#define TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(xMask) portCLEAR_INTERRUPT_MASK_FROM_ISR((UBaseType_t)(xMask)) - -#else - -/** - * @brief Kernel specific way to clear interrupt mask - */ -#define TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK(xMask) portCLEAR_INTERRUPT_MASK_FROM_ISR((unsigned portBASE_TYPE)xMask) -#endif - -#if (TRC_CFG_SCHEDULING_ONLY == 0) - -/** - * @brief Set the queue name - * - * @param[in] pvQueue Queue pointer - * @param[in] szName Queue name - */ -void vTraceSetQueueName(void* pvQueue, const char* szName); - -/** - * @brief Set the semaphore name - * - * @param[in] pvSemaphore Semaphore pointer - * @param[in] szName Semaphore name - */ -void vTraceSetSemaphoreName(void* pvSemaphore, const char* szName); - -/** - * @brief Set the mutex name - * - * @param[in] pvMutex Mutex pointer - * @param[in] szName Mutex name - */ -void vTraceSetMutexName(void* pvMutex, const char* szName); - -#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) - -/** - * @brief Set the event group name - * - * @param[in] pvEventGroup Event group pointer - * @param[in] szName Event group name - */ -void vTraceSetEventGroupName(void* pvEventGroup, const char* szName); - -#else - -/** - * @brief Disabled by TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS - */ -#define vTraceSetEventGroupName(__pvEventGroup, __szName) ((void)(__pvEventGroup), (void)(__szName)) - -#endif - -#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) - -/** - * @brief Set the stream buffer name - * - * @param[in] pvStreamBuffer Stream buffer pointer - * @param[in] szName Stream buffer name - */ -void vTraceSetStreamBufferName(void* pvStreamBuffer, const char* szName); - -/** - * @brief Set the message buffer name - * - * @param[in] pvMessageBuffer Message buffer pointer - * @param[in] szName Message buffer name - */ -void vTraceSetMessageBufferName(void* pvMessageBuffer, const char* szName); - -#else - -/** - * @brief Disabled by TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS - */ -#define vTraceSetStreamBufferName(__pvStreamBuffer, __szName) ((void)(__pvStreamBuffer), (void)(__szName)) - -/** - * @brief Disabled by TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS - */ -#define vTraceSetMessageBufferName(__pvMessageBuffer, __szName) ((void)(__pvMessageBuffer), (void)(__szName)) - -#endif - -#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) - - /** - * @internal Retrieves the unused stack for a task - * - * @param[in] pvTask Task pointer - * @param[out] puxUnusedStack The unused stack - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceKernelPortGetUnusedStack(void* pvTask, TraceUnsignedBaseType_t *puxUnusedStack); - -#endif - -#else - -/** - * @brief Disabled by TRC_CFG_SCHEDULING_ONLY - */ -#define vTraceSetQueueName(__pvQueue, __szName) ((void)(__pvQueue), (void)(__szName)) - -/** - * @brief Disabled by TRC_CFG_SCHEDULING_ONLY - */ -#define vTraceSetSemaphoreName(__pvSemaphore, __szName) ((void)(__pvSemaphore), (void)(__szName)) - -/** - * @brief Disabled by TRC_CFG_SCHEDULING_ONLY - */ -#define vTraceSetMutexName(__pvMutex, __szName) ((void)(__pvMutex), (void)(__szName)) - -/** - * @brief Disabled by TRC_CFG_SCHEDULING_ONLY - */ -#define vTraceSetEventGroupName(__pvEventGroup, __szName) ((void)(__pvEventGroup), (void)(__szName)) - -/** - * @brief Disabled by TRC_CFG_SCHEDULING_ONLY - */ -#define vTraceSetStreamBufferName(__pvStreamBuffer, __szName) ((void)(__pvStreamBuffer), (void)(__szName)) - -/** - * @brief Disabled by TRC_CFG_SCHEDULING_ONLY - */ -#define vTraceSetMessageBufferName(__pvMessageBuffer, __szName) ((void)(__pvMessageBuffer), (void)(__szName)) - -/** - * @brief Disabled by TRC_CFG_SCHEDULING_ONLY - */ -#define xTraceKernelPortGetUnusedStack(pvTask, puxUnusedStack) ((void)(pvTask), (void)(puxUnusedStack)) - -#endif - -#if (((TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) && (TRC_CFG_INCLUDE_ISR_TRACING == 1)) || (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)) - -/* Required for ISR tracing and Streaming */ -#undef INCLUDE_xTaskGetSchedulerState -#define INCLUDE_xTaskGetSchedulerState 1 - -#endif - -/** - * @internal Legacy ID used by Tracealyzer to identify FreeRTOS traces - */ -#define TRACE_KERNEL_VERSION 0x1AA1 - -/** - * @internal Kernel specific tick rate frequency definition - */ -#define TRC_TICK_RATE_HZ configTICK_RATE_HZ /* Defined in "FreeRTOS.h" */ - -/** - * @internal Kernel specific CPU clock frequency definition - */ -#define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */ - -/** - * @internal Kernel specific malloc definition - */ -#define TRACE_MALLOC(size) pvPortMalloc(size) - -#if (defined(configUSE_TIMERS) && (configUSE_TIMERS == 1)) - -#undef INCLUDE_xTimerGetTimerDaemonTaskHandle -#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 - -#endif - -#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XMOS_XCOREAI) - -#undef TRC_CFG_CORE_COUNT -#define TRC_CFG_CORE_COUNT configNUM_CORES - -#undef TRC_CFG_GET_CURRENT_CORE -#define TRC_CFG_GET_CURRENT_CORE() rtos_core_id_get() - -#endif - -#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_0_1) - -/** - * @brief Fix for FreeRTOS v9.0.1 to correctly identify xQueuePeek events. - * - * In FreeRTOS v9.0.1, the below trace hooks are incorrectly used from three - * different functions. This as the earlier function xQueueGenericReceive - * has been replaced by xQueuePeek, xQueueSemaphoreTake and xQueueReceive. - * - * xQueueGenericReceive had a parameter "xJustPeeking", used by the trace hooks - * to tell between xQueuePeek events and others. This is no longer present, so - * we need another way to correctly identify peek events. Since all three - * functions call the same trace macros, the context of these macro is unknown. - * - * We therefore check the __LINE__ macro inside of the trace macros. This gives - * the line number of queue.c, where the macros are used. This can be used to - * tell if the context is xQueuePeek or another function. - * __LINE__ is a standard compiler feature since ancient times, so it should - * work on all common compilers. - * - * This might seem as a quite brittle and unusual solution, but works in this - * particular case and is only for FreeRTOS v9.0.1. - * Future versions of FreeRTOS should not need this fix, as we have submitted - * a correction of queue.c with individual trace macros for each function. - */ -#define isQueueReceiveHookActuallyPeek (__LINE__ > 1674) /* Half way between the closes trace points */ - -#elif (TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_9_0_0) - -/** - * @brief Is receive actually a peek - */ -#define isQueueReceiveHookActuallyPeek xJustPeeking - -#elif (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) - -/** - * @brief Is never a peek for this FreeRTOS version - */ -#define isQueueReceiveHookActuallyPeek (__LINE__ < 0) /* instead of pdFALSE to fix a warning of "constant condition" */ - -#endif - -/* Helpers needed to correctly expand names */ -#define TZ__CAT2(a,b) a ## b -#define TZ__CAT(a,b) TZ__CAT2(a, b) - -/* - * The following xQueueGiveFromISR macro hacks make sure xQueueGiveFromISR also has a xCopyPosition parameter - */ - -/* Expands name if this header is included... uxQueueType must be a macro that only exists in queue.c or whatever, and it must expand to nothing or to something that's valid in identifiers */ -#define xQueueGiveFromISR(a,b) TZ__CAT(xQueueGiveFromISR__, uxQueueType) (a,b) - -/* If in queue.c, the "uxQueueType" macro expands to "pcHead". queueSEND_TO_BACK is the value we need to send in */ -#define xQueueGiveFromISR__pcHead(__a, __b) MyWrapper_xQueueGiveFromISR(__a, __b, const BaseType_t xCopyPosition); \ -BaseType_t xQueueGiveFromISR(__a, __b) { return MyWrapper_xQueueGiveFromISR(xQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK); } \ -BaseType_t MyWrapper_xQueueGiveFromISR(__a, __b, const BaseType_t xCopyPosition) - -/* If not in queue.c, "uxQueueType" isn't expanded */ -#define xQueueGiveFromISR__uxQueueType(__a, __b) xQueueGiveFromISR(__a,__b) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) - -/** - * @internal Kernel specific way to get current task handle - */ -#define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle() - -extern uint16_t CurrentFilterMask; -extern uint16_t CurrentFilterGroup; - -/** - * @internal Get specific queue type - * - * @param[in] pvQueue Queue handle - * - * @returns uint8_t Queue type - */ -uint8_t prvTraceGetQueueType(void* pvQueue); - -/** - * @internal Retrieve lower 16-bit of task number - * - * @param[in] pvTask Task handle - * - * @returns uint16_t Lower 16-bit of task number - */ -uint16_t prvTraceGetTaskNumberLow16(void* pvTask); - -/** - * @internal Retrieve upper 16-bit of task number - * - * @param[in] pvTask Task handle - * - * @returns uint16_t Upper 16-bit of task number - */ -uint16_t prvTraceGetTaskNumberHigh16(void* pvTask); - -/** - * @internal Set lower 16-bit of task number - * - * @param[in] pvTask Task handle - * @param[in] uiValue Value - */ -void prvTraceSetTaskNumberLow16(void* pvTask, uint16_t uiValue); - -/** - * @internal Set upper 16-bit of task number - * - * @param[in] pvTask Task handle - * @param[in] uiValue Value - */ -void prvTraceSetTaskNumberHigh16(void* pvTask, uint16_t uiValue); - -/** - * @internal Retrieve lower 16-bit of queue number - * - * @param[in] pvQueue Queue handle - * - * @returns uint16_t Lower 16-bit of queue number - */ -uint16_t prvTraceGetQueueNumberLow16(void* pvQueue); - -/** - * @internal Retrieve upper 16-bit of queue number - * - * @param[in] pvQueuevQueue handle - * - * @returns uint16_t Upper 16-bit of queue number - */ -uint16_t prvTraceGetQueueNumberHigh16(void* pvQueue); - - -/** - * @internal Set lower 16-bit of queue number - * - * @param[in] pvQueue Queue handle - * @param[in] uiValue Value - */ -void prvTraceSetQueueNumberLow16(void* pvQueue, uint16_t uiValue); - - -/** - * @internal Set upper 16-bit of queue number - * - * @param[in] pvQueue Queue handle - * @param[in] uiValue Value - */ -void prvTraceSetQueueNumberHigh16(void* pvQueue, uint16_t uiValue); - -#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -/** - * @internal Retrieve lower 16-bit of timer number - * - * @param[in] pvTimer Timer handle - * - * @returns uint16_t Lower 16-bit of timer number - */ -uint16_t prvTraceGetTimerNumberLow16(void* pvTimer); - -/** - * @internal Retrieve upper 16-bit of timer number - * - * @param[in] pvTimer Timer handle - * - * @returns uint16_t Upper 16-bit of timer number - */ -uint16_t prvTraceGetTimerNumberHigh16(void* pvTimer); - -/** - * @internal Set lower 16-bit of timer number - * - * @param[in] pvTimer Timer handle - * @param[in] uiValue Value - */ -void prvTraceSetTimerNumberLow16(void* pvTimer, uint16_t uiValue); - -/** - * @internal Set upper 16-bit of timer number - * - * @param[in] pvTimer Timer handle - * @param[in] uiValue Value - */ -void prvTraceSetTimerNumberHigh16(void* pvTimer, uint16_t uiValue); - -#endif - -#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -/** - * @internal Retrieve lower 16-bit of event group number - * - * @param[in] pvEventGroup Event group handle - * - * @returns uint16_t Lower 16-bit of event group number - */ -uint16_t prvTraceGetEventGroupNumberLow16(void* pvEventGroup); - -/** - * @internal Retrieve upper 16-bit of event group number - * - * @param[in] pvEventGroup Event group handle - * - * @returns uint16_t Upper 16-bit of event group number - */ -uint16_t prvTraceGetEventGroupNumberHigh16(void* pvEventGroup); - -/** - * @internal Set lower 16-bit of event group number - * - * @param[in] pvEventGroup Event group handle - * @param[in] uiValue Value - */ -void prvTraceSetEventGroupNumberLow16(void* pvEventGroup, uint16_t uiValue); - -/** - * @internal Set upper 16-bit of event group number - * - * @param[in] pvEventGroup Event group handle - * @param[in] uiValue Value - */ -void prvTraceSetEventGroupNumberHigh16(void* handle, uint16_t value); - -#endif - -#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -/** - * @internal Retrieve lower 16-bit of stream buffer number - * - * @param[in] pvStreamBuffer Stream buffer handle - * - * @returns uint16_t Lower 16-bit of stream buffer number - */ -uint16_t prvTraceGetStreamBufferNumberLow16(void* pvStreamBuffer); - -/** - * @internal Retrieve upper 16-bit of stream buffer number - * - * @param[in] pvStreamBuffer Stream buffer handle - * - * @returns uint16_t Upper 16-bit of stream buffer number - */ -uint16_t prvTraceGetStreamBufferNumberHigh16(void* pvStreamBuffer); - -/** - * @internal Set lower 16-bit of stream buffer number - * - * @param[in] pvStreamBuffer Stream buffer handle - * @param[in] uiValue Value - */ -void prvTraceSetStreamBufferNumberLow16(void* pvStreamBuffer, uint16_t uiValue); - -/** - * @internal Set upper 16-bit of stream buffer number - * - * @param[in] pvStreamBuffer Stream buffer handle - * @param[in] uiValue Value - */ -void prvTraceSetStreamBufferNumberHigh16(void* pvStreamBuffer, uint16_t uiValue); - -#endif - -/** - * @brief Retrieve filter of task - * - * @param[in] pxTask Task handle - * - * @returns uint16_t Task filter - */ -#define TRACE_GET_TASK_FILTER(pxTask) prvTraceGetTaskNumberHigh16((void*)pxTask) - -/** - * @brief Set filter of task - * - * @param[in] pxTask Task handle - * @param[in] group Group - */ -#define TRACE_SET_TASK_FILTER(pxTask, group) prvTraceSetTaskNumberHigh16((void*)pxTask, group) - -/** - * @brief Retrieve filter of queue - * - * @param[in] pxQueue Queue handle - * - * @returns uint16_t Queue filter - */ -#define TRACE_GET_QUEUE_FILTER(pxQueue) prvTraceGetQueueNumberHigh16((void*)pxQueue) - -/** - * @brief Set filter of queue - * - * @param[in] pxQueue Queue handle - * @param[in] group Group - */ -#define TRACE_SET_QUEUE_FILTER(pxQueue, group) prvTraceSetQueueNumberHigh16((void*)pxQueue, group) - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -/** - * @brief Retrieve filter of event group - * - * @param[in] pxEventGroup Queue handle - * - * @returns uint16_t Queue filter - */ -#define TRACE_GET_EVENTGROUP_FILTER(pxEventGroup) prvTraceGetEventGroupNumberHigh16((void*)pxEventGroup) - -/** - * @brief Set filter of event group - * - * @param[in] pxEventGroup Queue handle - * @param[in] group Group - */ -#define TRACE_SET_EVENTGROUP_FILTER(pxEventGroup, group) prvTraceSetEventGroupNumberHigh16((void*)pxEventGroup, group) - -#else - -/** - * @brief Disabled by TRC_CFG_FREERTOS_VERSION - */ -#define TRACE_GET_EVENTGROUP_FILTER(pxEventGroup) ((void)(pxEventGroup), 1) - -/** - * @brief Disabled by TRC_CFG_FREERTOS_VERSION - */ -#define TRACE_SET_EVENTGROUP_FILTER(pxEventGroup, group) ((void)(pxEventGroup), (void)(group)) - -#endif - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -/** - * @brief Retrieve filter of timer - * - * @param[in] pxEventGroup Timer handle - * - * @returns uint16_t Timer filter - */ -#define TRACE_GET_TIMER_FILTER(pxTimer) prvTraceGetTimerNumberHigh16((void*)pxTimer) - -/** - * @brief Set filter of timer - * - * @param[in] pxTimer Timer handle - * @param[in] group Group - */ -#define TRACE_SET_TIMER_FILTER(pxTimer, group) prvTraceSetTimerNumberHigh16((void*)pxTimer, group) - -#else - -/** - * @brief Disabled by TRC_CFG_FREERTOS_VERSION - */ -#define TRACE_GET_TIMER_FILTER(pxTimer) ((void)(pxTimer), 1) - -/** - * @brief Disabled by TRC_CFG_FREERTOS_VERSION - */ -#define TRACE_SET_TIMER_FILTER(pxTimer, group) ((void)(pxTimer), (void)(group)) - -#endif - -/** - * @brief Retrieve filter of stream buffer - * - * @param[in] pxStreamBuffer Stream buffer handle - * - * @returns uint16_t Timer filter - */ -#define TRACE_GET_STREAMBUFFER_FILTER(pxStreamBuffer) prvTraceGetStreamBufferNumberHigh16((void*)pxStreamBuffer) - -/** - * @brief Set filter of stream buffer - * - * @param[in] pxStreamBuffer Stream buffer handle - * @param[in] group Group - */ -#define TRACE_SET_STREAMBUFFER_FILTER(pxStreamBuffer, group) prvTraceSetStreamBufferNumberHigh16((void*)pxStreamBuffer, group) - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -/** - * @internal Get object filter - */ -#define TRACE_GET_OBJECT_FILTER(CLASS, pxObject) TRACE_GET_##CLASS##_FILTER(pxObject) - -/** - * @internal Set object filter - */ -#define TRACE_SET_OBJECT_FILTER(CLASS, pxObject, group) TRACE_SET_##CLASS##_FILTER(pxObject, group) - -#else - -/** - * @internal Disabled by TRC_CFG_FREERTOS_VERSION - */ -#define TRACE_GET_OBJECT_FILTER(CLASS, pxObject) 0xFFFF - -/** - * @internal Disabled by TRC_CFG_FREERTOS_VERSION - */ -#define TRACE_SET_OBJECT_FILTER(CLASS, pxObject, group) - -#endif - -/* The object classes */ -#define TRACE_NCLASSES 9 -#define TRACE_CLASS_QUEUE ((traceObjectClass)0) -#define TRACE_CLASS_SEMAPHORE ((traceObjectClass)1) -#define TRACE_CLASS_MUTEX ((traceObjectClass)2) -#define TRACE_CLASS_TASK ((traceObjectClass)3) -#define TRACE_CLASS_ISR ((traceObjectClass)4) -#define TRACE_CLASS_TIMER ((traceObjectClass)5) -#define TRACE_CLASS_EVENTGROUP ((traceObjectClass)6) -#define TRACE_CLASS_STREAMBUFFER ((traceObjectClass)7) -#define TRACE_CLASS_MESSAGEBUFFER ((traceObjectClass)8) - -/* Definitions for Object Table */ -#define TRACE_KERNEL_OBJECT_COUNT ((TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) + (TRC_CFG_NMESSAGEBUFFER)) - -/* Queue properties (except name): current number of message in queue */ -#define PropertyTableSizeQueue ((TRC_CFG_NAME_LEN_QUEUE) + 1) - -/* Semaphore properties (except name): state (signaled = 1, cleared = 0) */ -#define PropertyTableSizeSemaphore ((TRC_CFG_NAME_LEN_SEMAPHORE) + 1) - -/* Mutex properties (except name): owner (task handle, 0 = free) */ -#define PropertyTableSizeMutex ((TRC_CFG_NAME_LEN_MUTEX) + 1) - -/* Task properties (except name): Byte 0: Current priority - Byte 1: state (if already active) - Byte 2: legacy, not used - Byte 3: legacy, not used */ -#define PropertyTableSizeTask ((TRC_CFG_NAME_LEN_TASK) + 4) - -/* ISR properties: Byte 0: priority - Byte 1: state (if already active) */ -#define PropertyTableSizeISR ((TRC_CFG_NAME_LEN_ISR) + 2) - -/* TRC_CFG_NTIMER properties: Byte 0: state (unused for now) */ -#define PropertyTableSizeTimer ((TRC_CFG_NAME_LEN_TIMER) + 1) - -/* TRC_CFG_NEVENTGROUP properties: Byte 0-3: state (unused for now)*/ -#define PropertyTableSizeEventGroup ((TRC_CFG_NAME_LEN_EVENTGROUP) + 4) - -/* TRC_CFG_NSTREAMBUFFER properties: Byte 0-3: state (unused for now)*/ -#define PropertyTableSizeStreamBuffer ((TRC_CFG_NAME_LEN_STREAMBUFFER) + 4) - -/* TRC_CFG_NMESSAGEBUFFER properties: Byte 0-3: state (unused for now)*/ -#define PropertyTableSizeMessageBuffer ((TRC_CFG_NAME_LEN_MESSAGEBUFFER) + 4) - - -/* The layout of the byte array representing the Object Property Table */ -#define StartIndexQueue (0) -#define StartIndexSemaphore (StartIndexQueue + (TRC_CFG_NQUEUE) * PropertyTableSizeQueue) -#define StartIndexMutex (StartIndexSemaphore + (TRC_CFG_NSEMAPHORE) * PropertyTableSizeSemaphore) -#define StartIndexTask (StartIndexMutex + (TRC_CFG_NMUTEX) * PropertyTableSizeMutex) -#define StartIndexISR (StartIndexTask + (TRC_CFG_NTASK) * PropertyTableSizeTask) -#define StartIndexTimer (StartIndexISR + (TRC_CFG_NISR) * PropertyTableSizeISR) -#define StartIndexEventGroup (StartIndexTimer + (TRC_CFG_NTIMER) * PropertyTableSizeTimer) -#define StartIndexStreamBuffer (StartIndexEventGroup + (TRC_CFG_NEVENTGROUP) * PropertyTableSizeEventGroup) -#define StartIndexMessageBuffer (StartIndexStreamBuffer + (TRC_CFG_NSTREAMBUFFER) * PropertyTableSizeStreamBuffer) - -/* Number of bytes used by the object table */ -#define TRACE_OBJECT_TABLE_SIZE (StartIndexMessageBuffer + (TRC_CFG_NMESSAGEBUFFER) * PropertyTableSizeMessageBuffer) - -/* Flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */ -extern int uiInEventGroupSetBitsFromISR; - -/** - * @internal Initialized the object property table - */ -traceResult xTraceKernelPortInitObjectPropertyTable(void); - -/** - * @internal Initialized the object handle stack - */ -traceResult xTraceKernelPortInitObjectHandleStack(void); - -/** - * @internal Retrieve error string - */ -const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass); - -/** - * @internal Retrieve current task handle - */ -void* prvTraceGetCurrentTaskHandle(void); - -extern traceObjectClass TraceQueueClassTable[5]; - - -/*** Event codes for snapshot mode - must match Tracealyzer config files ******/ - -#define NULL_EVENT (0x00UL) - -/******************************************************************************* - * EVENTGROUP_DIV - * - * Miscellaneous events. - ******************************************************************************/ -#define EVENTGROUP_DIV (NULL_EVENT + 1UL) /*0x01*/ -#define DIV_XPS (EVENTGROUP_DIV + 0UL) /*0x01*/ -#define DIV_TASK_READY (EVENTGROUP_DIV + 1UL) /*0x02*/ -#define DIV_NEW_TIME (EVENTGROUP_DIV + 2UL) /*0x03*/ - -/******************************************************************************* - * EVENTGROUP_TS - * - * Events for storing task-switches and interrupts. The RESUME events are - * generated if the task/interrupt is already marked active. - ******************************************************************************/ -#define EVENTGROUP_TS (EVENTGROUP_DIV + 3UL) /*0x04*/ -#define TS_ISR_BEGIN (EVENTGROUP_TS + 0UL) /*0x04*/ -#define TS_ISR_RESUME (EVENTGROUP_TS + 1UL) /*0x05*/ -#define TS_TASK_BEGIN (EVENTGROUP_TS + 2UL) /*0x06*/ -#define TS_TASK_RESUME (EVENTGROUP_TS + 3UL) /*0x07*/ - -/******************************************************************************* - * EVENTGROUP_OBJCLOSE_NAME - * - * About Close Events - * When an object is evicted from the object property table (object close), two - * internal events are stored (EVENTGROUP_OBJCLOSE_NAME and - * EVENTGROUP_OBJCLOSE_PROP), containing the handle-name mapping and object - * properties valid up to this point. - ******************************************************************************/ -#define EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_TS + 4UL) /*0x08*/ - -/******************************************************************************* - * EVENTGROUP_OBJCLOSE_PROP - * - * The internal event carrying properties of deleted objects - * The handle and object class of the closed object is not stored in this event, - * but is assumed to be the same as in the preceding CLOSE event. Thus, these - * two events must be generated from within a critical section. - * When queues are closed, arg1 is the "state" property (i.e., number of - * buffered messages/signals). - * When actors are closed, arg1 is priority, arg2 is handle of the "instance - * finish" event, and arg3 is event code of the "instance finish" event. - * In this case, the lower three bits is the object class of the instance finish - * handle. The lower three bits are not used (always zero) when queues are - * closed since the queue type is given in the previous OBJCLOSE_NAME event. - ******************************************************************************/ -#define EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + 8UL) /*0x10*/ - -/******************************************************************************* - * EVENTGROUP_CREATE - * - * The events in this group are used to log Kernel object creations. - * The lower three bits in the event code gives the object class, i.e., type of - * create operation (task, queue, semaphore, etc). - ******************************************************************************/ -#define EVENTGROUP_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + 8UL) /*0x18*/ - -/******************************************************************************* - * EVENTGROUP_SEND - * - * The events in this group are used to log Send/Give events on queues, - * semaphores and mutexes The lower three bits in the event code gives the - * object class, i.e., what type of object that is operated on (queue, semaphore - * or mutex). - ******************************************************************************/ -#define EVENTGROUP_SEND_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 8UL) /*0x20*/ - -/******************************************************************************* - * EVENTGROUP_RECEIVE - * - * The events in this group are used to log Receive/Take events on queues, - * semaphores and mutexes. The lower three bits in the event code gives the - * object class, i.e., what type of object that is operated on (queue, semaphore - * or mutex). - ******************************************************************************/ -#define EVENTGROUP_RECEIVE_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 8UL) /*0x28*/ - -/* Send/Give operations, from ISR */ -#define EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS \ - (EVENTGROUP_RECEIVE_TRCSUCCESS + 8UL) /*0x30*/ - -/* Receive/Take operations, from ISR */ -#define EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS \ - (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 8UL) /*0x38*/ - -/* "Failed" event type versions of above (timeout, failed allocation, etc) */ -#define EVENTGROUP_KSE_TRCFAILED \ - (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 8UL) /*0x40*/ - -/* Failed create calls - memory allocation failed */ -#define EVENTGROUP_CREATE_OBJ_TRCFAILED (EVENTGROUP_KSE_TRCFAILED) /*0x40*/ - -/* Failed send/give - timeout! */ -#define EVENTGROUP_SEND_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 8UL) /*0x48*/ - -/* Failed receive/take - timeout! */ -#define EVENTGROUP_RECEIVE_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 8UL) /*0x50*/ - -/* Failed non-blocking send/give - queue full */ -#define EVENTGROUP_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 8UL) /*0x58*/ - -/* Failed non-blocking receive/take - queue empty */ -#define EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED \ - (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 8UL) /*0x60*/ - -/* Events when blocking on receive/take */ -#define EVENTGROUP_RECEIVE_TRCBLOCK \ - (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 8UL) /*0x68*/ - -/* Events when blocking on send/give */ -#define EVENTGROUP_SEND_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 8UL) /*0x70*/ - -/* Events on queue peek (receive) */ -#define EVENTGROUP_PEEK_TRCSUCCESS (EVENTGROUP_SEND_TRCBLOCK + 8UL) /*0x78*/ - -/* Events on object delete (vTaskDelete or vQueueDelete) */ -#define EVENTGROUP_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_PEEK_TRCSUCCESS + 8UL) /*0x80*/ - -/* Other events - object class is implied: TASK */ -#define EVENTGROUP_OTHERS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 8UL) /*0x88*/ -#define TASK_DELAY_UNTIL (EVENTGROUP_OTHERS + 0UL) /*0x88*/ -#define TASK_DELAY (EVENTGROUP_OTHERS + 1UL) /*0x89*/ -#define TASK_SUSPEND (EVENTGROUP_OTHERS + 2UL) /*0x8A*/ -#define TASK_RESUME (EVENTGROUP_OTHERS + 3UL) /*0x8B*/ -#define TASK_RESUME_FROM_ISR (EVENTGROUP_OTHERS + 4UL) /*0x8C*/ -#define TASK_PRIORITY_SET (EVENTGROUP_OTHERS + 5UL) /*0x8D*/ -#define TASK_PRIORITY_INHERIT (EVENTGROUP_OTHERS + 6UL) /*0x8E*/ -#define TASK_PRIORITY_DISINHERIT (EVENTGROUP_OTHERS + 7UL) /*0x8F*/ - -#define EVENTGROUP_MISC_PLACEHOLDER (EVENTGROUP_OTHERS + 8UL) /*0x90*/ -#define PEND_FUNC_CALL (EVENTGROUP_MISC_PLACEHOLDER+0UL) /*0x90*/ -#define PEND_FUNC_CALL_FROM_ISR (EVENTGROUP_MISC_PLACEHOLDER+1UL) /*0x91*/ -#define PEND_FUNC_CALL_TRCFAILED (EVENTGROUP_MISC_PLACEHOLDER+2UL) /*0x92*/ -#define PEND_FUNC_CALL_FROM_ISR_TRCFAILED (EVENTGROUP_MISC_PLACEHOLDER+3UL) /*0x93*/ -#define MEM_MALLOC_SIZE (EVENTGROUP_MISC_PLACEHOLDER+4UL) /*0x94*/ -#define MEM_MALLOC_ADDR (EVENTGROUP_MISC_PLACEHOLDER+5UL) /*0x95*/ -#define MEM_FREE_SIZE (EVENTGROUP_MISC_PLACEHOLDER+6UL) /*0x96*/ -#define MEM_FREE_ADDR (EVENTGROUP_MISC_PLACEHOLDER+7UL) /*0x97*/ - -/* User events */ -#define EVENTGROUP_USEREVENT (EVENTGROUP_MISC_PLACEHOLDER + 8UL) /*0x98*/ -#define USER_EVENT (EVENTGROUP_USEREVENT + 0UL) - -/* Allow for 0-15 arguments (the number of args is added to event code) */ -#define USER_EVENT_LAST (EVENTGROUP_USEREVENT + 15UL) /*0xA7*/ - -/******************************************************************************* - * XTS Event - eXtended TimeStamp events - * The timestamps used in the recorder are "differential timestamps" (DTS), i.e. - * the time since the last stored event. The DTS fields are either 1 or 2 bytes - * in the other events, depending on the bytes available in the event struct. - * If the time since the last event (the DTS) is larger than allowed for by - * the DTS field of the current event, an XTS event is inserted immediately - * before the original event. The XTS event contains up to 3 additional bytes - * of the DTS value - the higher bytes of the true DTS value. The lower 1-2 - * bytes are stored in the normal DTS field. - * There are two types of XTS events, XTS8 and XTS16. An XTS8 event is stored - * when there is only room for 1 byte (8 bit) DTS data in the original event, - * which means a limit of 0xFF (255UL). The XTS16 is used when the original event - * has a 16 bit DTS field and thereby can handle values up to 0xFFFF (65535UL). - * - * Using a very high frequency time base can result in many XTS events. - * Preferably, the time between two OS ticks should fit in 16 bits, i.e., - * at most 65535. If your time base has a higher frequency, you can define - * the TRACE - ******************************************************************************/ - -#define EVENTGROUP_SYS (EVENTGROUP_USEREVENT + 16UL) /*0xA8*/ -#define XTS8 (EVENTGROUP_SYS + 0UL) /*0xA8*/ -#define XTS16 (EVENTGROUP_SYS + 1UL) /*0xA9*/ -#define EVENT_BEING_WRITTEN (EVENTGROUP_SYS + 2UL) /*0xAA*/ -#define RESERVED_DUMMY_CODE (EVENTGROUP_SYS + 3UL) /*0xAB*/ -#define LOW_POWER_BEGIN (EVENTGROUP_SYS + 4UL) /*0xAC*/ -#define LOW_POWER_END (EVENTGROUP_SYS + 5UL) /*0xAD*/ -#define XID (EVENTGROUP_SYS + 6UL) /*0xAE*/ -#define XTS16L (EVENTGROUP_SYS + 7UL) /*0xAF*/ - -#define EVENTGROUP_TIMER (EVENTGROUP_SYS + 8UL) /*0xB0*/ -#define TIMER_CREATE (EVENTGROUP_TIMER + 0UL) /*0xB0*/ -#define TIMER_START (EVENTGROUP_TIMER + 1UL) /*0xB1*/ -#define TIMER_RST (EVENTGROUP_TIMER + 2UL) /*0xB2*/ -#define TIMER_STOP (EVENTGROUP_TIMER + 3UL) /*0xB3*/ -#define TIMER_CHANGE_PERIOD (EVENTGROUP_TIMER + 4UL) /*0xB4*/ -#define TIMER_DELETE_OBJ (EVENTGROUP_TIMER + 5UL) /*0xB5*/ -#define TIMER_START_FROM_ISR (EVENTGROUP_TIMER + 6UL) /*0xB6*/ -#define TIMER_RESET_FROM_ISR (EVENTGROUP_TIMER + 7UL) /*0xB7*/ -#define TIMER_STOP_FROM_ISR (EVENTGROUP_TIMER + 8UL) /*0xB8*/ - -#define TIMER_CREATE_TRCFAILED (EVENTGROUP_TIMER + 9UL) /*0xB9*/ -#define TIMER_START_TRCFAILED (EVENTGROUP_TIMER + 10UL) /*0xBA*/ -#define TIMER_RESET_TRCFAILED (EVENTGROUP_TIMER + 11UL) /*0xBB*/ -#define TIMER_STOP_TRCFAILED (EVENTGROUP_TIMER + 12UL) /*0xBC*/ -#define TIMER_CHANGE_PERIOD_TRCFAILED (EVENTGROUP_TIMER + 13UL) /*0xBD*/ -#define TIMER_DELETE_TRCFAILED (EVENTGROUP_TIMER + 14UL) /*0xBE*/ -#define TIMER_START_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 15UL) /*0xBF*/ -#define TIMER_RESET_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 16UL) /*0xC0*/ -#define TIMER_STOP_FROM_ISR_TRCFAILED (EVENTGROUP_TIMER + 17UL) /*0xC1*/ - -#define EVENTGROUP_EG (EVENTGROUP_TIMER + 18UL) /*0xC2*/ -#define EVENT_GROUP_CREATE (EVENTGROUP_EG + 0UL) /*0xC2*/ -#define EVENT_GROUP_CREATE_TRCFAILED (EVENTGROUP_EG + 1UL) /*0xC3*/ -#define EVENT_GROUP_SYNC_TRCBLOCK (EVENTGROUP_EG + 2UL) /*0xC4*/ -#define EVENT_GROUP_SYNC_END (EVENTGROUP_EG + 3UL) /*0xC5*/ -#define EVENT_GROUP_WAIT_BITS_TRCBLOCK (EVENTGROUP_EG + 4UL) /*0xC6*/ -#define EVENT_GROUP_WAIT_BITS_END (EVENTGROUP_EG + 5UL) /*0xC7*/ -#define EVENT_GROUP_CLEAR_BITS (EVENTGROUP_EG + 6UL) /*0xC8*/ -#define EVENT_GROUP_CLEAR_BITS_FROM_ISR (EVENTGROUP_EG + 7UL) /*0xC9*/ -#define EVENT_GROUP_SET_BITS (EVENTGROUP_EG + 8UL) /*0xCA*/ -#define EVENT_GROUP_DELETE_OBJ (EVENTGROUP_EG + 9UL) /*0xCB*/ -#define EVENT_GROUP_SYNC_END_TRCFAILED (EVENTGROUP_EG + 10UL) /*0xCC*/ -#define EVENT_GROUP_WAIT_BITS_END_TRCFAILED (EVENTGROUP_EG + 11UL) /*0xCD*/ -#define EVENT_GROUP_SET_BITS_FROM_ISR (EVENTGROUP_EG + 12UL) /*0xCE*/ -#define EVENT_GROUP_SET_BITS_FROM_ISR_TRCFAILED (EVENTGROUP_EG + 13UL) /*0xCF*/ - -#define TASK_INSTANCE_FINISHED_NEXT_KSE (EVENTGROUP_EG + 14UL) /*0xD0*/ -#define TASK_INSTANCE_FINISHED_DIRECT (EVENTGROUP_EG + 15UL) /*0xD1*/ - -#define TRACE_TASK_NOTIFY_GROUP (EVENTGROUP_EG + 16UL) /*0xD2*/ -#define TRACE_TASK_NOTIFY (TRACE_TASK_NOTIFY_GROUP + 0UL) /*0xD2*/ -#define TRACE_TASK_NOTIFY_TAKE (TRACE_TASK_NOTIFY_GROUP + 1UL) /*0xD3*/ -#define TRACE_TASK_NOTIFY_TAKE_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 2UL) /*0xD4*/ -#define TRACE_TASK_NOTIFY_TAKE_TRCFAILED (TRACE_TASK_NOTIFY_GROUP + 3UL) /*0xD5*/ -#define TRACE_TASK_NOTIFY_WAIT (TRACE_TASK_NOTIFY_GROUP + 4UL) /*0xD6*/ -#define TRACE_TASK_NOTIFY_WAIT_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 5UL) /*0xD7*/ -#define TRACE_TASK_NOTIFY_WAIT_TRCFAILED (TRACE_TASK_NOTIFY_GROUP + 6UL) /*0xD8*/ -#define TRACE_TASK_NOTIFY_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 7UL) /*0xD9*/ -#define TRACE_TASK_NOTIFY_GIVE_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 8UL) /*0xDA*/ - -#define TIMER_EXPIRED (TRACE_TASK_NOTIFY_GROUP + 9UL) /*0xDB*/ - - /* Events on queue peek (receive) */ -#define EVENTGROUP_PEEK_TRCBLOCK (TRACE_TASK_NOTIFY_GROUP + 10UL) /*0xDC*/ -/* peek block on queue: 0xDC */ -/* peek block on semaphore: 0xDD */ -/* peek block on mutex: 0xDE */ - -/* Events on queue peek (receive) */ -#define EVENTGROUP_PEEK_TRCFAILED (EVENTGROUP_PEEK_TRCBLOCK + 3UL) /*0xDF*/ -/* peek failed on queue: 0xDF */ -/* peek failed on semaphore: 0xE0 */ -/* peek failed on mutex: 0xE1 */ - -#define EVENTGROUP_STREAMBUFFER_DIV (EVENTGROUP_PEEK_TRCFAILED + 3UL) /*0xE2*/ -#define TRACE_STREAMBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 0) /*0xE2*/ -#define TRACE_MESSAGEBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 1UL) /*0xE3*/ -#define TRACE_STREAMBUFFER_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 2UL) /*0xE4*/ -#define TRACE_MESSAGEBUFFER_OBJCLOSE_NAME_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 3UL) /*0xE5*/ -#define TRACE_STREAMBUFFER_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 4UL) /*0xE6*/ -#define TRACE_MESSAGEBUFFER_OBJCLOSE_PROP_TRCSUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 5UL) /*0xE7*/ - -#define EVENTGROUP_MALLOC_FAILED (EVENTGROUP_STREAMBUFFER_DIV + 6UL) /*0xE8*/ -#define MEM_MALLOC_SIZE_TRCFAILED (EVENTGROUP_MALLOC_FAILED + 0UL) /*0xE8*/ -#define MEM_MALLOC_ADDR_TRCFAILED (EVENTGROUP_MALLOC_FAILED + 1UL) /*0xE9*/ - -/* The following are using previously "lost" event codes */ -#define TRACE_STREAMBUFFER_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 4UL) /*0x1C*/ -#define TRACE_STREAMBUFFER_CREATE_OBJ_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 4UL) /*0x44*/ -#define TRACE_STREAMBUFFER_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 4UL) /*0x84*/ -#define TRACE_STREAMBUFFER_SEND_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 3UL) /*0x23*/ -#define TRACE_STREAMBUFFER_SEND_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 3UL) /*0x73*/ -#define TRACE_STREAMBUFFER_SEND_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 3UL) /*0x4B*/ -#define TRACE_STREAMBUFFER_RECEIVE_TRCSUCCESS (EVENTGROUP_RECEIVE_TRCSUCCESS + 3UL) /*0x2B*/ -#define TRACE_STREAMBUFFER_RECEIVE_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 3UL) /*0x6B*/ -#define TRACE_STREAMBUFFER_RECEIVE_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 3UL) /*0x53*/ -#define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 3UL) /*0x33*/ -#define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 3UL) /*0x5B*/ -#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 3UL) /*0x3B*/ -#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 3UL) /*0x63*/ - -/* The following are using previously "lost" event codes. These macros aren't even directly referenced, instead we do (equivalent STREAMBUFFER code) + 1. */ -#define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCSUCCESS (EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 5UL) /*0x1D*/ -#define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCFAILED (EVENTGROUP_CREATE_OBJ_TRCFAILED + 5UL) /*0x45*/ -#define TRACE_MESSAGEBUFFER_DELETE_OBJ_TRCSUCCESS (EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 5UL) /*0x85*/ -#define TRACE_MESSAGEBUFFER_SEND_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 4UL) /*0x24*/ -#define TRACE_MESSAGEBUFFER_SEND_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 4UL) /*0x74*/ -#define TRACE_MESSAGEBUFFER_SEND_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 4UL) /*0x4C*/ -#define TRACE_MESSAGEBUFFER_RECEIVE_TRCSUCCESS (EVENTGROUP_RECEIVE_TRCSUCCESS + 4UL) /*0x2C*/ -#define TRACE_MESSAGEBUFFER_RECEIVE_TRCBLOCK (EVENTGROUP_RECEIVE_TRCBLOCK + 4UL) /*0x6C*/ -#define TRACE_MESSAGEBUFFER_RECEIVE_TRCFAILED (EVENTGROUP_RECEIVE_TRCFAILED + 4UL) /*0x54*/ -#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 4UL) /*0x34*/ -#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 4UL) /*0x5C*/ -#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 4UL) /*0x3C*/ -#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCFAILED (EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 4UL) /*0x64*/ - -#define TRACE_QUEUE_SEND_TO_FRONT_TRCSUCCESS (EVENTGROUP_SEND_TRCSUCCESS + 5UL) /*0x25*/ -#define TRACE_QUEUE_SEND_TO_FRONT_TRCBLOCK (EVENTGROUP_SEND_TRCBLOCK + 5UL) /*0x75*/ -#define TRACE_QUEUE_SEND_TO_FRONT_TRCFAILED (EVENTGROUP_SEND_TRCFAILED + 5UL) /*0x4D*/ -#define TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCSUCCESS (EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 5UL) /*0x35*/ -#define TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCFAILED (EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 5UL) /*0x5D*/ - -#define TRACE_UNUSED_STACK (EVENTGROUP_MALLOC_FAILED + 2UL) /*0xEA*/ - -/* LAST EVENT (0xEA) */ - -/**************************** -* MACROS TO GET TRACE CLASS * -****************************/ -#define TRACE_GET_TRACE_CLASS_FROM_TASK_CLASS(kernelClass) (TRACE_CLASS_TASK) -#define TRACE_GET_TRACE_CLASS_FROM_TASK_OBJECT(pxObject) (TRACE_CLASS_TASK) - -#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(kernelClass) TraceQueueClassTable[kernelClass] -#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_OBJECT(pxObject) TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(prvTraceGetQueueType(pxObject)) - -#define TRACE_GET_TRACE_CLASS_FROM_TIMER_CLASS(kernelClass) (TRACE_CLASS_TIMER) -#define TRACE_GET_TRACE_CLASS_FROM_TIMER_OBJECT(pxObject) (TRACE_CLASS_TIMER) - -#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_CLASS(kernelClass) (TRACE_CLASS_EVENTGROUP) -#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_OBJECT(pxObject) (TRACE_CLASS_EVENTGROUP) - -/* TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS can only be accessed with a parameter indicating if it is a MessageBuffer */ -#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS(xIsMessageBuffer) (xIsMessageBuffer == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER) -#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_OBJECT(pxObject) (prvGetStreamBufferType(pxObject) == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER) - -/* Generic versions */ -#define TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_CLASS(kernelClass) -#define TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_OBJECT(pxObject) - -/****************************** -* MACROS TO GET OBJECT NUMBER * -******************************/ -#define TRACE_GET_TASK_NUMBER(pxTCB) (traceHandle)(prvTraceGetTaskNumberLow16(pxTCB)) -#define TRACE_SET_TASK_NUMBER(pxTCB) prvTraceSetTaskNumberLow16(pxTCB, prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TASK, pxTCB))); - -#define TRACE_GET_QUEUE_NUMBER(queue) ( ( traceHandle ) prvTraceGetQueueNumberLow16(queue) ) -#define TRACE_SET_QUEUE_NUMBER(queue) prvTraceSetQueueNumberLow16(queue, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, queue))); - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) -#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) prvTraceGetTimerNumberLow16(tmr) ) -#define TRACE_SET_TIMER_NUMBER(tmr) prvTraceSetTimerNumberLow16(tmr, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr))); -#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ -#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) ((Timer_t*)tmr)->uxTimerNumber ) -#define TRACE_SET_TIMER_NUMBER(tmr) ((Timer_t*)tmr)->uxTimerNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr)); -#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) -#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) prvTraceGetEventGroupNumberLow16(eg) ) -#define TRACE_SET_EVENTGROUP_NUMBER(eg) prvTraceSetEventGroupNumberLow16(eg, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg))); -#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ -#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) uxEventGroupGetNumber(eg) ) -#define TRACE_SET_EVENTGROUP_NUMBER(eg) ((EventGroup_t*)eg)->uxEventGroupNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg)); -#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ - - -#define TRACE_GET_STREAMBUFFER_NUMBER(sb) ( ( traceHandle ) prvTraceGetStreamBufferNumberLow16(sb) ) -#define TRACE_SET_STREAMBUFFER_NUMBER(sb) prvTraceSetStreamBufferNumberLow16(sb, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(STREAMBUFFER, sb))); - -/* Generic versions */ -#define TRACE_GET_OBJECT_NUMBER(CLASS, pxObject) TRACE_GET_##CLASS##_NUMBER(pxObject) -#define TRACE_SET_OBJECT_NUMBER(CLASS, pxObject) TRACE_SET_##CLASS##_NUMBER(pxObject) - -/****************************** -* MACROS TO GET EVENT CODES * -******************************/ -#define TRACE_GET_TASK_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(TASK, kernelClass)) -#define TRACE_GET_QUEUE_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(QUEUE, kernelClass)) -#define TRACE_GET_TIMER_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED -- -#define TRACE_GET_EVENTGROUP_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED -- -#define TRACE_GET_STREAMBUFFER_CLASS_EVENT_CODE(SERVICE, RESULT, isMessageBuffer) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + (uint8_t)isMessageBuffer) - -#define TRACE_GET_TASK_OBJECT_EVENT_CODE(SERVICE, RESULT, pxTCB) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_CLASS_TASK) -#define TRACE_GET_QUEUE_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxObject)) -#define TRACE_GET_TIMER_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED -- -#define TRACE_GET_EVENTGROUP_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED -- -#define TRACE_GET_STREAMBUFFER_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + prvGetStreamBufferType(pxObject)) - -/* Generic versions */ -#define TRACE_GET_CLASS_EVENT_CODE(SERVICE, RESULT, CLASS, kernelClass) TRACE_GET_##CLASS##_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -#define TRACE_GET_OBJECT_EVENT_CODE(SERVICE, RESULT, CLASS, pxObject) TRACE_GET_##CLASS##_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) - -/****************************** -* SPECIAL MACROS FOR TASKS * -******************************/ -#define TRACE_GET_TASK_PRIORITY(pxTCB) ((uint8_t)pxTCB->uxPriority) -#define TRACE_GET_TASK_NAME(pxTCB) ((char*)pxTCB->pcTaskName) - -/*** The trace macros for snapshot mode **************************************/ - -/* A macro that will update the tick count when returning from tickless idle */ -#undef traceINCREASE_TICK_COUNT -#define traceINCREASE_TICK_COUNT( xCount ) - -/* Called for each task that becomes ready */ -#undef traceMOVED_TASK_TO_READY_STATE -#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ - trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB); - -/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */ -#undef traceTASK_INCREMENT_TICK - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0) - -#define traceTASK_INCREMENT_TICK( xTickCount ) \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || xPendedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); } - -#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X) - -#define traceTASK_INCREMENT_TICK( xTickCount ) \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); } - -#else - -#define traceTASK_INCREMENT_TICK( xTickCount ) \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); } - -#endif - -extern volatile uint32_t uiTraceSystemState; - -/* Called on each task-switch */ -#undef traceTASK_SWITCHED_IN -#define traceTASK_SWITCHED_IN() \ - uiTraceSystemState = TRC_STATE_IN_TASKSWITCH; \ - trcKERNEL_HOOKS_TASK_SWITCH(TRACE_GET_CURRENT_TASK()); \ - uiTraceSystemState = TRC_STATE_IN_APPLICATION; - -/* Called on vTaskCreate */ -#undef traceTASK_CREATE -#define traceTASK_CREATE(pxNewTCB) \ - if (pxNewTCB != 0) \ - { \ - trcKERNEL_HOOKS_TASK_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, TASK, pxNewTCB), TASK, pxNewTCB); \ - prvAddTaskToStackMonitor(pxNewTCB); \ - } - -/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */ -#undef traceTASK_CREATE_FAILED -#define traceTASK_CREATE_FAILED() \ - trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, TASK, NOT_USED), TRACE_GET_CLASS_TRACE_CLASS(TASK, NOT_USED)) - -/* Called on vTaskDelete */ -#undef traceTASK_DELETE -#define traceTASK_DELETE( pxTaskToDelete ) \ - { TRACE_ALLOC_CRITICAL_SECTION(); \ - TRACE_ENTER_CRITICAL_SECTION(); \ - trcKERNEL_HOOKS_TASK_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, TASK, pxTaskToDelete), pxTaskToDelete); \ - prvRemoveTaskFromStackMonitor(pxTaskToDelete); \ - TRACE_EXIT_CRITICAL_SECTION(); } - -#if (TRC_CFG_SCHEDULING_ONLY == 0) - -#if defined(configUSE_TICKLESS_IDLE) && (configUSE_TICKLESS_IDLE != 0) - -#undef traceLOW_POWER_IDLE_BEGIN -#define traceLOW_POWER_IDLE_BEGIN() \ - { \ - extern uint32_t trace_disable_timestamp; \ - prvTraceStoreLowPower(0); \ - trace_disable_timestamp = 1; \ - } - -#undef traceLOW_POWER_IDLE_END -#define traceLOW_POWER_IDLE_END() \ - { \ - extern uint32_t trace_disable_timestamp; \ - trace_disable_timestamp = 0; \ - prvTraceStoreLowPower(1); \ - } - -#endif - -/* Called on vTaskSuspend */ -#undef traceTASK_SUSPEND -#define traceTASK_SUSPEND( pxTaskToSuspend ) \ - trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend); - -/* Called from special case with timer only */ -#undef traceTASK_DELAY_SUSPEND -#define traceTASK_DELAY_SUSPEND( pxTaskToSuspend ) \ - trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend); \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); - -/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */ -#undef traceTASK_DELAY -#define traceTASK_DELAY() \ - trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY, pxCurrentTCB, xTicksToDelay); \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); - -/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */ -#undef traceTASK_DELAY_UNTIL -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) - -#define traceTASK_DELAY_UNTIL(xTimeToWake) \ - trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); -#else - -#define traceTASK_DELAY_UNTIL() \ - trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); - -#endif - -/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */ -#undef traceQUEUE_CREATE -#define traceQUEUE_CREATE( pxNewQueue ) \ - trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue); - -/* Called in xQueueCreate, if the queue creation fails */ -#undef traceQUEUE_CREATE_FAILED -#define traceQUEUE_CREATE_FAILED( queueType ) \ - trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, QUEUE, queueType), TRACE_GET_CLASS_TRACE_CLASS(QUEUE, queueType)) - -/* Called on vQueueDelete */ -#undef traceQUEUE_DELETE -#define traceQUEUE_DELETE( pxQueue ) \ - { TRACE_ALLOC_CRITICAL_SECTION(); \ - TRACE_ENTER_CRITICAL_SECTION(); \ - trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ - TRACE_EXIT_CRITICAL_SECTION(); } - -/* This macro is not necessary as of FreeRTOS v9.0.0 */ -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) - -/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */ -#undef traceCREATE_MUTEX -#define traceCREATE_MUTEX( pxNewQueue ) \ - trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue); - -/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */ -#undef traceCREATE_MUTEX_FAILED -#define traceCREATE_MUTEX_FAILED() \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, QUEUE, queueQUEUE_TYPE_MUTEX), 0); - -#endif - -/* Called when the Mutex can not be given, since not holder */ -#undef traceGIVE_MUTEX_RECURSIVE_FAILED -#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, QUEUE, pxMutex), QUEUE, pxMutex); - -/* Called when a message is sent to a queue */ /* CS IS NEW ! */ -#undef traceQUEUE_SEND -#define traceQUEUE_SEND( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_TRCSUCCESS, QUEUE, pxQueue); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)0 : (uint8_t)(pxQueue->uxMessagesWaiting + 1)); - -/* Called when a message is sent to a queue set */ -#undef traceQUEUE_SET_SEND -#define traceQUEUE_SET_SEND( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting + 1)); - -/* Called when a message failed to be sent to a queue (timeout) */ -#undef traceQUEUE_SEND_FAILED -#define traceQUEUE_SEND_FAILED( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_TRCFAILED, QUEUE, pxQueue); - -/* Called when the task is blocked due to a send operation on a full queue */ -#undef traceBLOCKING_ON_QUEUE_SEND -#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCBLOCK, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_TRCBLOCK, QUEUE, pxQueue); - -/* Called when a message is received from a queue */ -#undef traceQUEUE_RECEIVE -#define traceQUEUE_RECEIVE( pxQueue ) \ - if (isQueueReceiveHookActuallyPeek) \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ - } \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()) : (uint8_t)(pxQueue->uxMessagesWaiting - 1)); - -/* Called when a receive operation on a queue fails (timeout) */ -#undef traceQUEUE_RECEIVE_FAILED -#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \ - if (isQueueReceiveHookActuallyPeek) \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); \ - } - -/* Called when the task is blocked due to a receive operation on an empty queue */ -#undef traceBLOCKING_ON_QUEUE_RECEIVE -#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \ - if (isQueueReceiveHookActuallyPeek) \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \ - } \ - if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \ - { \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \ - } - -/* Called on xQueuePeek */ -#undef traceQUEUE_PEEK -#define traceQUEUE_PEEK( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); - -/* Called on xQueuePeek fail/timeout (added in FreeRTOS v9.0.2) */ -#undef traceQUEUE_PEEK_FAILED -#define traceQUEUE_PEEK_FAILED( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); - -/* Called on xQueuePeek blocking (added in FreeRTOS v9.0.2) */ -#undef traceBLOCKING_ON_QUEUE_PEEK -#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, TRCBLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \ - if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \ - { \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \ - } - -/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */ -#undef traceQUEUE_SEND_FROM_ISR -#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCSUCCESS, QUEUE, pxQueue); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting + 1)); - -/* Called when a message send from interrupt context fails (since the queue was full) */ -#undef traceQUEUE_SEND_FROM_ISR_FAILED -#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(xCopyPosition == queueSEND_TO_BACK ? (TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCFAILED, QUEUE, pxQueue)) : TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCFAILED, QUEUE, pxQueue); - -/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */ -#undef traceQUEUE_RECEIVE_FROM_ISR -#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting - 1)); - -/* Called when a message receive from interrupt context fails (since the queue was empty) */ -#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED -#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCFAILED, QUEUE, pxQueue), QUEUE, pxQueue); - -#undef traceQUEUE_REGISTRY_ADD -#define traceQUEUE_REGISTRY_ADD(object, name) prvTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, object), TRACE_GET_OBJECT_NUMBER(QUEUE, object), name); - -/* Called in vTaskPrioritySet */ -#undef traceTASK_PRIORITY_SET -#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \ - trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_SET, pxTask, uxNewPriority); - -/* Called in vTaskPriorityInherit, which is called by Mutex operations */ -#undef traceTASK_PRIORITY_INHERIT -#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \ - trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_INHERIT, pxTask, uxNewPriority); - -/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */ -#undef traceTASK_PRIORITY_DISINHERIT -#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \ - trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_DISINHERIT, pxTask, uxNewPriority); - -/* Called in vTaskResume */ -#undef traceTASK_RESUME -#define traceTASK_RESUME( pxTaskToResume ) \ - trcKERNEL_HOOKS_TASK_RESUME(TASK_RESUME, pxTaskToResume); - -/* Called in vTaskResumeFromISR */ -#undef traceTASK_RESUME_FROM_ISR -#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \ - trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(TASK_RESUME_FROM_ISR, pxTaskToResume); - - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) - -extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t size); - -/* MALLOC and FREE are always stored, no matter if they happen inside filtered task */ -#undef traceMALLOC -#define traceMALLOC( pvAddress, uiSize ) \ - if (pvAddress != 0) \ - { \ - vTraceStoreMemMangEvent(MEM_MALLOC_SIZE, ( uint32_t ) pvAddress, (int32_t)uiSize); \ - } \ - else \ - { \ - vTraceStoreMemMangEvent(MEM_MALLOC_SIZE_TRCFAILED, ( uint32_t ) pvAddress, (int32_t)uiSize); \ - } - -#undef traceFREE -#define traceFREE( pvAddress, uiSize ) \ - vTraceStoreMemMangEvent(MEM_FREE_SIZE, ( uint32_t ) pvAddress, -((int32_t)uiSize)); - -#endif - -#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) - -/* Called in timer.c - xTimerCreate */ -#undef traceTIMER_CREATE -#define traceTIMER_CREATE(tmr) \ - trcKERNEL_HOOKS_OBJECT_CREATE(TIMER_CREATE, TIMER, tmr); - -#undef traceTIMER_CREATE_FAILED -#define traceTIMER_CREATE_FAILED() \ - trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(TIMER_CREATE_TRCFAILED, TRACE_GET_CLASS_TRACE_CLASS(TIMER, NOT_USED)) - -/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */ -#undef traceTIMER_COMMAND_SEND -#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \ - if (xCommandID > tmrCOMMAND_START_DONT_TRACE) \ - { \ - if (xCommandID == tmrCOMMAND_CHANGE_PERIOD) \ - { \ - if (xReturn == pdPASS) { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD, TIMER, tmr, xOptionalValue); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD_TRCFAILED, TIMER, tmr, xOptionalValue); \ - } \ - } \ - else if ((xCommandID == tmrCOMMAND_DELETE) && (xReturn == pdPASS)) \ - { \ - trcKERNEL_HOOKS_OBJECT_DELETE(TIMER_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), TIMER, tmr); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENTGROUP_TIMER + (uint32_t)xCommandID + ((xReturn == pdPASS) ? 0 : (TIMER_CREATE_TRCFAILED - TIMER_CREATE)), TIMER, tmr, xOptionalValue); \ - }\ - } - -#undef traceTIMER_EXPIRED -#define traceTIMER_EXPIRED(tmr) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TIMER_EXPIRED, TIMER, tmr); - -#endif - -#if (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) - -#undef tracePEND_FUNC_CALL -#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \ - if (ret == pdPASS){ \ - trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL, TASK, xTimerGetTimerDaemonTaskHandle() ); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL_TRCFAILED, TASK, xTimerGetTimerDaemonTaskHandle() ); \ - } - -#undef tracePEND_FUNC_CALL_FROM_ISR -#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \ - if (! uiInEventGroupSetBitsFromISR) \ - prvTraceStoreKernelCall(PEND_FUNC_CALL_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTimerGetTimerDaemonTaskHandle()) ); \ - uiInEventGroupSetBitsFromISR = 0; - -#endif - -#endif - -#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) - -#undef traceEVENT_GROUP_CREATE -#define traceEVENT_GROUP_CREATE(eg) \ - trcKERNEL_HOOKS_OBJECT_CREATE(EVENT_GROUP_CREATE, EVENTGROUP, eg) - -#undef traceEVENT_GROUP_CREATE_FAILED -#define traceEVENT_GROUP_CREATE_FAILED() \ - trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(EVENT_GROUP_CREATE_TRCFAILED, TRACE_GET_CLASS_TRACE_CLASS(EVENTGROUP, NOT_USED)) - -#undef traceEVENT_GROUP_DELETE -#define traceEVENT_GROUP_DELETE(eg) \ - { TRACE_ALLOC_CRITICAL_SECTION(); \ - TRACE_ENTER_CRITICAL_SECTION(); \ - trcKERNEL_HOOKS_OBJECT_DELETE(EVENT_GROUP_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP, eg); \ - TRACE_EXIT_CRITICAL_SECTION(); } - -#undef traceEVENT_GROUP_SYNC_BLOCK -#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor); - -#undef traceEVENT_GROUP_SYNC_END -#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \ - if (wasTimeout) \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END, EVENTGROUP, eg, bitsToWaitFor); \ - } - -#undef traceEVENT_GROUP_WAIT_BITS_BLOCK -#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor); \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); - -#undef traceEVENT_GROUP_WAIT_BITS_END -#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \ - if (wasTimeout) \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END, EVENTGROUP, eg, bitsToWaitFor); \ - } - -#undef traceEVENT_GROUP_CLEAR_BITS -#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_CLEAR_BITS, EVENTGROUP, eg, bitsToClear); - -#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR -#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(EVENT_GROUP_CLEAR_BITS_FROM_ISR, EVENTGROUP, eg, bitsToClear); - -#undef traceEVENT_GROUP_SET_BITS -#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SET_BITS, EVENTGROUP, eg, bitsToSet); - -#undef traceEVENT_GROUP_SET_BITS_FROM_ISR -#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(EVENT_GROUP_SET_BITS_FROM_ISR, EVENTGROUP, eg, bitsToSet); \ - uiInEventGroupSetBitsFromISR = 1; - -#endif - -#undef traceTASK_NOTIFY_TAKE -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) - -#define traceTASK_NOTIFY_TAKE() \ - if (pxCurrentTCB->eNotifyState == eNotified){ \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \ - } \ - else{ \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait); \ - } - -#elif (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY_TAKE() \ - if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED){ \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \ - }else{ \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait);} - -#else - -#define traceTASK_NOTIFY_TAKE(index) \ - if (pxCurrentTCB->ucNotifyState[index] == taskNOTIFICATION_RECEIVED){ \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \ - }else{ \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait);} - -#endif - -#undef traceTASK_NOTIFY_TAKE_BLOCK -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY_TAKE_BLOCK() \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCBLOCK, TASK, pxCurrentTCB, xTicksToWait); \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); - -#else - -#define traceTASK_NOTIFY_TAKE_BLOCK(index) \ - trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_TRCBLOCK, TASK, pxCurrentTCB, xTicksToWait); \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); - -#endif - -#undef traceTASK_NOTIFY_WAIT -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) - -#define traceTASK_NOTIFY_WAIT() \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \ - { \ - if (pxCurrentTCB->eNotifyState == eNotified) \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ - else \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ - } - -#elif (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY_WAIT() \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \ - { \ - if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ - else \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ - } - -#else - -#define traceTASK_NOTIFY_WAIT(index) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \ - { \ - if (pxCurrentTCB->ucNotifyState[index] == taskNOTIFICATION_RECEIVED) \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ - else \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ - } - -#endif - -#undef traceTASK_NOTIFY_WAIT_BLOCK -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY_WAIT_BLOCK() \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCBLOCK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); - -#else - -#define traceTASK_NOTIFY_WAIT_BLOCK(index) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxCurrentTCB) & CurrentFilterMask) \ - prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_TRCBLOCK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ - trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); - -#endif - -#undef traceTASK_NOTIFY -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY() \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \ - prvTraceStoreKernelCall(TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); - -#else - -#define traceTASK_NOTIFY(index) \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \ - prvTraceStoreKernelCall(TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); - -#endif - -#undef traceTASK_NOTIFY_FROM_ISR -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY_FROM_ISR() \ - if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \ - prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); - -#else - -#define traceTASK_NOTIFY_FROM_ISR(index) \ - if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \ - prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); - -#endif - -#undef traceTASK_NOTIFY_GIVE_FROM_ISR -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY_GIVE_FROM_ISR() \ - if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \ - prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); - -#else - -#define traceTASK_NOTIFY_GIVE_FROM_ISR(index) \ - if (TRACE_GET_OBJECT_FILTER(TASK, xTaskToNotify) & CurrentFilterMask) \ - prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); - -#endif - -#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) - -#undef traceSTREAM_BUFFER_CREATE -#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \ - trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, TRCSUCCESS, STREAMBUFFER, pxStreamBuffer), STREAMBUFFER, pxStreamBuffer); - -#undef traceSTREAM_BUFFER_CREATE_FAILED -#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \ - trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, TRCFAILED, STREAMBUFFER, xIsMessageBuffer), TRACE_GET_CLASS_TRACE_CLASS(STREAMBUFFER, xIsMessageBuffer)) - -#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED -#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \ - traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) - -#undef traceSTREAM_BUFFER_DELETE -#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \ - trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); - -#undef traceSTREAM_BUFFER_RESET -#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(prvGetStreamBufferType(xStreamBuffer) > 0 ? TRACE_MESSAGEBUFFER_RESET : TRACE_STREAMBUFFER_RESET, STREAMBUFFER, xStreamBuffer); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, 0); - -#undef traceSTREAM_BUFFER_SEND -#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); - -#undef traceBLOCKING_ON_STREAM_BUFFER_SEND -#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCBLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); - -#undef traceSTREAM_BUFFER_SEND_FAILED -#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); - -#undef traceSTREAM_BUFFER_RECEIVE -#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); - - -#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE -#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCBLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); - -#undef traceSTREAM_BUFFER_RECEIVE_FAILED -#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \ - trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); - -#undef traceSTREAM_BUFFER_SEND_FROM_ISR -#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \ - if( xReturn > ( size_t ) 0 ) \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ - } - -#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR -#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \ - if( xReceivedLength > ( size_t ) 0 ) \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ - trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ - } \ - else \ - { \ - trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ - } - -#endif - -#endif - -#endif - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -TraceHeapHandle_t xTraceKernelPortGetSystemHeapHandle(void); - -/*************************************************************************/ -/* KERNEL SPECIFIC OBJECT CONFIGURATION */ -/*************************************************************************/ - -/******************************************************************************* - * The event codes - should match the offline config file. - ******************************************************************************/ - -/*** Event codes for streaming - should match the Tracealyzer config file *****/ -#define PSF_EVENT_NULL_EVENT 0x00 - -#define PSF_EVENT_TRACE_START 0x01 -#define PSF_EVENT_TS_CONFIG 0x02 -#define PSF_EVENT_OBJ_NAME 0x03 -#define PSF_EVENT_TASK_PRIORITY 0x04 -#define PSF_EVENT_TASK_PRIO_INHERIT 0x05 -#define PSF_EVENT_TASK_PRIO_DISINHERIT 0x06 -#define PSF_EVENT_DEFINE_ISR 0x07 - -#define PSF_EVENT_TASK_CREATE 0x10 -#define PSF_EVENT_QUEUE_CREATE 0x11 -#define PSF_EVENT_SEMAPHORE_BINARY_CREATE 0x12 -#define PSF_EVENT_MUTEX_CREATE 0x13 -#define PSF_EVENT_TIMER_CREATE 0x14 -#define PSF_EVENT_EVENTGROUP_CREATE 0x15 -#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE 0x16 -#define PSF_EVENT_MUTEX_RECURSIVE_CREATE 0x17 -#define PSF_EVENT_STREAMBUFFER_CREATE 0x18 -#define PSF_EVENT_MESSAGEBUFFER_CREATE 0x19 - -#define PSF_EVENT_TASK_DELETE 0x20 -#define PSF_EVENT_QUEUE_DELETE 0x21 -#define PSF_EVENT_SEMAPHORE_DELETE 0x22 -#define PSF_EVENT_MUTEX_DELETE 0x23 -#define PSF_EVENT_TIMER_DELETE 0x24 -#define PSF_EVENT_EVENTGROUP_DELETE 0x25 -#define PSF_EVENT_STREAMBUFFER_DELETE 0x28 -#define PSF_EVENT_MESSAGEBUFFER_DELETE 0x29 - -#define PSF_EVENT_TASK_READY 0x30 -#define PSF_EVENT_NEW_TIME 0x31 -#define PSF_EVENT_NEW_TIME_SCHEDULER_SUSPENDED 0x32 -#define PSF_EVENT_ISR_BEGIN 0x33 -#define PSF_EVENT_ISR_RESUME 0x34 -#define PSF_EVENT_TS_BEGIN 0x35 -#define PSF_EVENT_TS_RESUME 0x36 -#define PSF_EVENT_TASK_ACTIVATE 0x37 - -#define PSF_EVENT_MALLOC 0x38 -#define PSF_EVENT_FREE 0x39 - -#define PSF_EVENT_LOWPOWER_BEGIN 0x3A -#define PSF_EVENT_LOWPOWER_END 0x3B - -#define PSF_EVENT_IFE_NEXT 0x3C -#define PSF_EVENT_IFE_DIRECT 0x3D - -#define PSF_EVENT_TASK_CREATE_FAILED 0x40 -#define PSF_EVENT_QUEUE_CREATE_FAILED 0x41 -#define PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED 0x42 -#define PSF_EVENT_MUTEX_CREATE_FAILED 0x43 -#define PSF_EVENT_TIMER_CREATE_FAILED 0x44 -#define PSF_EVENT_EVENTGROUP_CREATE_FAILED 0x45 -#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED 0x46 -#define PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED 0x47 -#define PSF_EVENT_STREAMBUFFER_CREATE_FAILED 0x49 -#define PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED 0x4A - -#define PSF_EVENT_TIMER_DELETE_FAILED 0x48 - -#define PSF_EVENT_QUEUE_SEND 0x50 -#define PSF_EVENT_SEMAPHORE_GIVE 0x51 -#define PSF_EVENT_MUTEX_GIVE 0x52 - -#define PSF_EVENT_QUEUE_SEND_FAILED 0x53 -#define PSF_EVENT_SEMAPHORE_GIVE_FAILED 0x54 -#define PSF_EVENT_MUTEX_GIVE_FAILED 0x55 - -#define PSF_EVENT_QUEUE_SEND_BLOCK 0x56 -#define PSF_EVENT_SEMAPHORE_GIVE_BLOCK 0x57 -#define PSF_EVENT_MUTEX_GIVE_BLOCK 0x58 - -#define PSF_EVENT_QUEUE_SEND_FROMISR 0x59 -#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR 0x5A - -#define PSF_EVENT_QUEUE_SEND_FROMISR_FAILED 0x5C -#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED 0x5D - -#define PSF_EVENT_QUEUE_RECEIVE 0x60 -#define PSF_EVENT_SEMAPHORE_TAKE 0x61 -#define PSF_EVENT_MUTEX_TAKE 0x62 - -#define PSF_EVENT_QUEUE_RECEIVE_FAILED 0x63 -#define PSF_EVENT_SEMAPHORE_TAKE_FAILED 0x64 -#define PSF_EVENT_MUTEX_TAKE_FAILED 0x65 - -#define PSF_EVENT_QUEUE_RECEIVE_BLOCK 0x66 -#define PSF_EVENT_SEMAPHORE_TAKE_BLOCK 0x67 -#define PSF_EVENT_MUTEX_TAKE_BLOCK 0x68 - -#define PSF_EVENT_QUEUE_RECEIVE_FROMISR 0x69 -#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR 0x6A - -#define PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED 0x6C -#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED 0x6D - -#define PSF_EVENT_QUEUE_PEEK 0x70 -#define PSF_EVENT_SEMAPHORE_PEEK 0x71 -#define PSF_EVENT_MUTEX_PEEK 0x72 - -#define PSF_EVENT_QUEUE_PEEK_FAILED 0x73 -#define PSF_EVENT_SEMAPHORE_PEEK_FAILED 0x74 -#define PSF_EVENT_MUTEX_PEEK_FAILED 0x75 - -#define PSF_EVENT_QUEUE_PEEK_BLOCK 0x76 -#define PSF_EVENT_SEMAPHORE_PEEK_BLOCK 0x77 -#define PSF_EVENT_MUTEX_PEEK_BLOCK 0x78 - -#define PSF_EVENT_TASK_DELAY_UNTIL 0x79 -#define PSF_EVENT_TASK_DELAY 0x7A -#define PSF_EVENT_TASK_SUSPEND 0x7B -#define PSF_EVENT_TASK_RESUME 0x7C -#define PSF_EVENT_TASK_RESUME_FROMISR 0x7D - -#define PSF_EVENT_TIMER_PENDFUNCCALL 0x80 -#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR 0x81 -#define PSF_EVENT_TIMER_PENDFUNCCALL_FAILED 0x82 -#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED 0x83 - -#define PSF_EVENT_USER_EVENT 0x90 - -#define PSF_EVENT_TIMER_START 0xA0 -#define PSF_EVENT_TIMER_RESET 0xA1 -#define PSF_EVENT_TIMER_STOP 0xA2 -#define PSF_EVENT_TIMER_CHANGEPERIOD 0xA3 -#define PSF_EVENT_TIMER_START_FROMISR 0xA4 -#define PSF_EVENT_TIMER_RESET_FROMISR 0xA5 -#define PSF_EVENT_TIMER_STOP_FROMISR 0xA6 -#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR 0xA7 -#define PSF_EVENT_TIMER_START_FAILED 0xA8 -#define PSF_EVENT_TIMER_RESET_FAILED 0xA9 -#define PSF_EVENT_TIMER_STOP_FAILED 0xAA -#define PSF_EVENT_TIMER_CHANGEPERIOD_FAILED 0xAB -#define PSF_EVENT_TIMER_START_FROMISR_FAILED 0xAC -#define PSF_EVENT_TIMER_RESET_FROMISR_FAILED 0xAD -#define PSF_EVENT_TIMER_STOP_FROMISR_FAILED 0xAE -#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED 0xAF - -#define PSF_EVENT_EVENTGROUP_SYNC 0xB0 -#define PSF_EVENT_EVENTGROUP_WAITBITS 0xB1 -#define PSF_EVENT_EVENTGROUP_CLEARBITS 0xB2 -#define PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR 0xB3 -#define PSF_EVENT_EVENTGROUP_SETBITS 0xB4 -#define PSF_EVENT_EVENTGROUP_SETBITS_FROMISR 0xB5 -#define PSF_EVENT_EVENTGROUP_SYNC_BLOCK 0xB6 -#define PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK 0xB7 -#define PSF_EVENT_EVENTGROUP_SYNC_FAILED 0xB8 -#define PSF_EVENT_EVENTGROUP_WAITBITS_FAILED 0xB9 - -#define PSF_EVENT_QUEUE_SEND_FRONT 0xC0 -#define PSF_EVENT_QUEUE_SEND_FRONT_FAILED 0xC1 -#define PSF_EVENT_QUEUE_SEND_FRONT_BLOCK 0xC2 -#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR 0xC3 -#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED 0xC4 -#define PSF_EVENT_MUTEX_GIVE_RECURSIVE 0xC5 -#define PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED 0xC6 -#define PSF_EVENT_MUTEX_TAKE_RECURSIVE 0xC7 -#define PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED 0xC8 - -#define PSF_EVENT_TASK_NOTIFY 0xC9 -#define PSF_EVENT_TASK_NOTIFY_WAIT 0xCA -#define PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK 0xCB -#define PSF_EVENT_TASK_NOTIFY_WAIT_FAILED 0xCC -#define PSF_EVENT_TASK_NOTIFY_FROM_ISR 0xCD - -#define PSF_EVENT_TIMER_EXPIRED 0xD2 - -#define PSF_EVENT_STREAMBUFFER_SEND 0xD3 -#define PSF_EVENT_STREAMBUFFER_SEND_BLOCK 0xD4 -#define PSF_EVENT_STREAMBUFFER_SEND_FAILED 0xD5 -#define PSF_EVENT_STREAMBUFFER_RECEIVE 0xD6 -#define PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK 0xD7 -#define PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED 0xD8 -#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR 0xD9 -#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED 0xDA -#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR 0xDB -#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED 0xDC -#define PSF_EVENT_STREAMBUFFER_RESET 0xDD - -#define PSF_EVENT_MESSAGEBUFFER_SEND 0xDE -#define PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK 0xDF -#define PSF_EVENT_MESSAGEBUFFER_SEND_FAILED 0xE0 -#define PSF_EVENT_MESSAGEBUFFER_RECEIVE 0xE1 -#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK 0xE2 -#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED 0xE3 -#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR 0xE4 -#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED 0xE5 -#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR 0xE6 -#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED 0xE7 -#define PSF_EVENT_MESSAGEBUFFER_RESET 0xE8 - -#define PSF_EVENT_MALLOC_FAILED 0xE9 -#define PSF_EVENT_FREE_FAILED 0xEA - -#define PSF_EVENT_UNUSED_STACK 0xEB - -#define PSF_EVENT_STATEMACHINE_STATE_CREATE 0xEC -#define PSF_EVENT_STATEMACHINE_CREATE 0xED -#define PSF_EVENT_STATEMACHINE_STATECHANGE 0xEE - -#define PSF_EVENT_INTERVAL_CREATE 0xEF -#define PSF_EVENT_INTERVAL_STATECHANGE 0xF0 - -#define PSF_EVENT_EXTENSION_CREATE 0xF1 - -#define PSF_EVENT_HEAP_CREATE 0xF2 - -#define PSF_EVENT_COUNTER_CREATE 0xF3 -#define PSF_EVENT_COUNTER_CHANGE 0xF4 -#define PSF_EVENT_COUNTER_LIMIT_EXCEEDED 0xF5 - -#define PSF_EVENT_MUTEX_TAKE_RECURSIVE_BLOCK 0xF6 - -#define TRC_EVENT_LAST_ID PSF_EVENT_COUNTER_LIMIT_EXCEEDED - -/*** The trace macros for streaming ******************************************/ - -/* A macro that will update the tick count when returning from tickless idle */ -#undef traceINCREASE_TICK_COUNT -/* Note: This can handle time adjustments of max 2^32 ticks, i.e., 35 seconds at 120 MHz. Thus, tick-less idle periods longer than 2^32 ticks will appear "compressed" on the time line.*/ -#define traceINCREASE_TICK_COUNT( xCount ) { uint32_t uiTraceTickCount; xTraceTimestampGetOsTickCount(&uiTraceTickCount); xTraceTimestampSetOsTickCount(uiTraceTickCount + (xCount)); } - -#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1) - -#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) if ((uxSchedulerSuspended) == (unsigned portBASE_TYPE) pdFALSE) { prvTraceStoreEvent_Param(PSF_EVENT_NEW_TIME, (uint32_t)(xTickCount)); } - -#else - -#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) - -#endif - -/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */ -#undef traceTASK_INCREMENT_TICK -#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0 - -#define traceTASK_INCREMENT_TICK( xTickCount ) \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || xPendedTicks == 0) { xTraceTimestampSetOsTickCount((xTickCount) + 1); } \ - OS_TICK_EVENT(uxSchedulerSuspended, (xTickCount) + 1) - -#elif TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X - -#define traceTASK_INCREMENT_TICK( xTickCount ) \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0) { xTraceTimestampSetOsTickCount(xTickCount + 1); } \ - OS_TICK_EVENT(uxSchedulerSuspended, xTickCount + 1) - -#else - -#define traceTASK_INCREMENT_TICK( xTickCount ) \ - if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { xTraceTimestampSetOsTickCount(xTickCount + 1); } \ - OS_TICK_EVENT(uxSchedulerSuspended, xTickCount + 1) - -#endif - -/* Called on each task-switch */ -#undef traceTASK_SWITCHED_IN -#define traceTASK_SWITCHED_IN() \ - xTraceTaskSwitch(pxCurrentTCB, pxCurrentTCB->uxPriority) - -/* Called for each task that becomes ready */ -#undef traceMOVED_TASK_TO_READY_STATE -#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ - xTraceTaskReady(pxTCB) - -#undef traceTASK_CREATE -#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 - -#define traceTASK_CREATE(pxNewTCB) \ - if ((pxNewTCB) != 0) \ - { \ - xTraceTaskRegisterWithoutHandle((void*)(pxNewTCB), (pxNewTCB)->pcTaskName, (pxNewTCB)->uxPriority); \ - } - -#else - -#define traceTASK_CREATE(pxNewTCB) \ - if (pxNewTCB != 0) \ - { \ - xTraceTaskRegisterWithoutHandle((void*)pxNewTCB, (const char*)pcName, (uint32_t)uxPriority); \ - } - -#endif - -/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */ -#undef traceTASK_CREATE_FAILED -#define traceTASK_CREATE_FAILED() \ - prvTraceStoreEvent_None(PSF_EVENT_TASK_CREATE_FAILED) - -/* Called on vTaskDelete */ -#undef traceTASK_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical. -#define traceTASK_DELETE( pxTaskToDelete ) \ - xTraceTaskUnregisterWithoutHandle(pxTaskToDelete, (pxTaskToDelete)->uxPriority) - -#if (TRC_CFG_SCHEDULING_ONLY == 0) - -#if (defined(configUSE_TICKLESS_IDLE) && configUSE_TICKLESS_IDLE != 0) - -#undef traceLOW_POWER_IDLE_BEGIN -#define traceLOW_POWER_IDLE_BEGIN() \ - prvTraceStoreEvent_Param(PSF_EVENT_LOWPOWER_BEGIN, xExpectedIdleTime) - -#undef traceLOW_POWER_IDLE_END -#define traceLOW_POWER_IDLE_END() \ - prvTraceStoreEvent_None(PSF_EVENT_LOWPOWER_END) - -#endif - -/* Called on vTaskSuspend */ -#undef traceTASK_SUSPEND -#define traceTASK_SUSPEND( pxTaskToSuspend ) \ - prvTraceStoreEvent_Handle(PSF_EVENT_TASK_SUSPEND, pxTaskToSuspend) - -/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */ -#undef traceTASK_DELAY -#define traceTASK_DELAY() \ - prvTraceStoreEvent_Param(PSF_EVENT_TASK_DELAY, xTicksToDelay) - -/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */ -#undef traceTASK_DELAY_UNTIL -#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 - -#define traceTASK_DELAY_UNTIL(xTimeToWake) \ - prvTraceStoreEvent_Param(PSF_EVENT_TASK_DELAY_UNTIL, (xTimeToWake)) - -#else - -#define traceTASK_DELAY_UNTIL() \ - prvTraceStoreEvent_Param(PSF_EVENT_TASK_DELAY_UNTIL, xTimeToWake) - -#endif - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) - -#define traceQUEUE_CREATE_HELPER() \ - case queueQUEUE_TYPE_MUTEX: \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_MUTEX_CREATE, (void*)pxNewQueue, "", 0); \ - break; \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (void*)pxNewQueue, "", 0); \ - break; - -#else - -#define traceQUEUE_CREATE_HELPER() - -#endif - -/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */ -#undef traceQUEUE_CREATE -#define traceQUEUE_CREATE( pxNewQueue )\ - switch ((pxNewQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_QUEUE_CREATE, (void*)(pxNewQueue), "", (uint32_t)uxQueueLength); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_SEMAPHORE_BINARY_CREATE, (void*)(pxNewQueue), "", 0); \ - break; \ - traceQUEUE_CREATE_HELPER() \ - } - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) - -#define traceQUEUE_CREATE_FAILED_HELPER() \ - case queueQUEUE_TYPE_MUTEX: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_MUTEX_CREATE_FAILED, 0, 0); \ - break; \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED, 0, 0); \ - break; - -#else - -#define traceQUEUE_CREATE_FAILED_HELPER() - -#endif - -/* Called in xQueueCreate, if the queue creation fails */ -#undef traceQUEUE_CREATE_FAILED -#define traceQUEUE_CREATE_FAILED( queueType ) \ - switch (queueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_QUEUE_CREATE_FAILED, 0, uxQueueLength); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED, 0, 0); \ - break; \ - traceQUEUE_CREATE_FAILED_HELPER() \ - } - -#undef traceQUEUE_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical. -#define traceQUEUE_DELETE( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - xTraceObjectUnregisterWithoutHandle(PSF_EVENT_QUEUE_DELETE, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - xTraceObjectUnregisterWithoutHandle(PSF_EVENT_MUTEX_DELETE, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - xTraceObjectUnregisterWithoutHandle(PSF_EVENT_SEMAPHORE_DELETE, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - } - -/* Called in xQueueCreateCountingSemaphore, if the queue creation fails */ -#undef traceCREATE_COUNTING_SEMAPHORE -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -#define traceCREATE_COUNTING_SEMAPHORE() \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (void*)xHandle, "", (uint32_t)uxMaxCount) - -#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X) - -#define traceCREATE_COUNTING_SEMAPHORE() \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (void*)xHandle, "", uxInitialCount) - -#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4_X) - -#define traceCREATE_COUNTING_SEMAPHORE() \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (void*)xHandle, "", uxCountValue) - -#else - -#define traceCREATE_COUNTING_SEMAPHORE() \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (void*)pxHandle, "", uxCountValue) - -#endif - -#undef traceCREATE_COUNTING_SEMAPHORE_FAILED -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxMaxCount) - -#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X) - -#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxInitialCount) - -#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4_X) - -#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue) - -#else - -#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue) - -#endif - - -/* This macro is not necessary as of FreeRTOS v9.0.0 */ -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) - -/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */ -#undef traceCREATE_MUTEX -#define traceCREATE_MUTEX( pxNewQueue ) \ - switch (pxNewQueue->ucQueueType) \ - { \ - case queueQUEUE_TYPE_MUTEX: \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_MUTEX_CREATE, (void*)(pxNewQueue), "", 0); \ - break; \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (void*)(pxNewQueue), "", 0); \ - break; \ - } - -/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */ -#undef traceCREATE_MUTEX_FAILED -#define traceCREATE_MUTEX_FAILED() \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_MUTEX_CREATE_FAILED, 0, 0) -#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ - -/* Called when the Mutex can not be given, since not holder */ -#undef traceGIVE_MUTEX_RECURSIVE_FAILED -#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \ - prvTraceStoreEvent_Handle(PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED, (void*)(pxMutex)) - -/* Called when a message is sent to a queue */ /* CS IS NEW ! */ -#undef traceQUEUE_SEND -#define traceQUEUE_SEND( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParam(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND : PSF_EVENT_QUEUE_SEND_FRONT, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting + 1); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_GIVE, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting + 1); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - prvTraceStoreEvent_Handle(PSF_EVENT_MUTEX_GIVE, (void*)(pxQueue)); \ - break; \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_Handle(PSF_EVENT_MUTEX_GIVE_RECURSIVE, (void*)(pxQueue)); \ - break; \ - } - -#undef traceQUEUE_SET_SEND -#define traceQUEUE_SET_SEND( pxQueue ) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_QUEUE_SEND, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting + 1) - -/* Called when a message failed to be sent to a queue (timeout) */ -#undef traceQUEUE_SEND_FAILED -#define traceQUEUE_SEND_FAILED( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParam(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FAILED, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_GIVE_FAILED, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_Handle(PSF_EVENT_MUTEX_GIVE_FAILED, (void*)(pxQueue)); \ - break; \ - } - -/* Called when the task is blocked due to a send operation on a full queue */ -#undef traceBLOCKING_ON_QUEUE_SEND -#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParam(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_BLOCK : PSF_EVENT_QUEUE_SEND_FRONT_BLOCK, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_GIVE_BLOCK, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_Handle(PSF_EVENT_MUTEX_GIVE_BLOCK, (void*)(pxQueue)); \ - break; \ - } - -/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */ -#undef traceQUEUE_SEND_FROM_ISR -#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParam(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting + 1); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_GIVE_FROMISR, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting + 1); \ - break; \ - } - -/* Called when a message send from interrupt context fails (since the queue was full) */ -#undef traceQUEUE_SEND_FROM_ISR_FAILED -#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParam(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - } - -/* Called when a message is received from a queue */ -#undef traceQUEUE_RECEIVE -#define traceQUEUE_RECEIVE( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - if (isQueueReceiveHookActuallyPeek) \ - { \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_QUEUE_PEEK, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting - 1); \ - } \ - else\ - { \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_QUEUE_RECEIVE, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting - 1); \ - } \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - if (isQueueReceiveHookActuallyPeek) \ - { \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_SEMAPHORE_PEEK, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting - 1); \ - } \ - else \ - { \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_SEMAPHORE_TAKE, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting - 1); \ - } \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - prvTraceStoreEvent_HandleParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK : PSF_EVENT_MUTEX_TAKE, (void*)(pxQueue), xTicksToWait); \ - break; \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_HandleParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK : PSF_EVENT_MUTEX_TAKE_RECURSIVE, (void*)(pxQueue), xTicksToWait); \ - break; \ - } - -/* Called when a receive operation on a queue fails (timeout) */ -#undef traceQUEUE_RECEIVE_FAILED -#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParamParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_FAILED : PSF_EVENT_QUEUE_RECEIVE_FAILED, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParamParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_FAILED : PSF_EVENT_SEMAPHORE_TAKE_FAILED, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - prvTraceStoreEvent_HandleParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_FAILED : PSF_EVENT_MUTEX_TAKE_FAILED, (void*)(pxQueue), xTicksToWait); \ - break; \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_HandleParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_FAILED : PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED, (void*)(pxQueue), xTicksToWait); \ - break; \ - } - -/* Called when the task is blocked due to a receive operation on an empty queue */ -#undef traceBLOCKING_ON_QUEUE_RECEIVE -#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParamParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_BLOCK : PSF_EVENT_QUEUE_RECEIVE_BLOCK, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParamParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_BLOCK : PSF_EVENT_SEMAPHORE_TAKE_BLOCK, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - prvTraceStoreEvent_HandleParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_BLOCK : PSF_EVENT_MUTEX_TAKE_BLOCK, (void*)(pxQueue), xTicksToWait); \ - break; \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_HandleParam(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_BLOCK : PSF_EVENT_MUTEX_TAKE_RECURSIVE_BLOCK, (void*)(pxQueue), xTicksToWait); \ - break; \ - } - -#if (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) - -/* Called when a peek operation on a queue fails (timeout) */ -#undef traceQUEUE_PEEK_FAILED -#define traceQUEUE_PEEK_FAILED( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_QUEUE_PEEK_FAILED, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_SEMAPHORE_PEEK_FAILED, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_MUTEX_PEEK_FAILED, (void*)(pxQueue), xTicksToWait); \ - break; \ - } - -/* Called when the task is blocked due to a peek operation on an empty queue */ -#undef traceBLOCKING_ON_QUEUE_PEEK -#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_QUEUE_PEEK_BLOCK, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_SEMAPHORE_PEEK_BLOCK, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_MUTEX_PEEK_BLOCK, (void*)(pxQueue), xTicksToWait); \ - break; \ - } - -#endif - -/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */ -#undef traceQUEUE_RECEIVE_FROM_ISR -#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_QUEUE_RECEIVE_FROMISR, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting - 1); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_TAKE_FROMISR, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting - 1); \ - break; \ - } - -/* Called when a message receive from interrupt context fails (since the queue was empty) */ -#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED -#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED, (void*)(pxQueue), (pxQueue)->uxMessagesWaiting); \ - break; \ - } - -/* Called on xQueuePeek */ -#undef traceQUEUE_PEEK -#define traceQUEUE_PEEK( pxQueue ) \ - switch ((pxQueue)->ucQueueType) \ - { \ - case queueQUEUE_TYPE_BASE: \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_QUEUE_PEEK, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ - case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ - prvTraceStoreEvent_HandleParamParam(PSF_EVENT_SEMAPHORE_PEEK, (void*)(pxQueue), xTicksToWait, (pxQueue)->uxMessagesWaiting); \ - break; \ - case queueQUEUE_TYPE_MUTEX: \ - case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_MUTEX_PEEK, (void*)(pxQueue), xTicksToWait); \ - break; \ - } - -/* Called in vTaskPrioritySet */ -#undef traceTASK_PRIORITY_SET -#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \ - xTraceTaskSetPriorityWithoutHandle(pxTask, uxNewPriority) - -/* Called in vTaskPriorityInherit, which is called by Mutex operations */ -#undef traceTASK_PRIORITY_INHERIT -#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_TASK_PRIO_INHERIT, (void*)(pxTask), uxNewPriority) - -/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */ -#undef traceTASK_PRIORITY_DISINHERIT -#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_TASK_PRIO_DISINHERIT, (void*)(pxTask), uxNewPriority) - -/* Called in vTaskResume */ -#undef traceTASK_RESUME -#define traceTASK_RESUME( pxTaskToResume ) \ - prvTraceStoreEvent_Handle(PSF_EVENT_TASK_RESUME, (void*)(pxTaskToResume)) - -/* Called in vTaskResumeFromISR */ -#undef traceTASK_RESUME_FROM_ISR -#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \ - prvTraceStoreEvent_Handle(PSF_EVENT_TASK_RESUME_FROMISR, (void*)(pxTaskToResume)) - -#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) - -#undef traceMALLOC -#define traceMALLOC( pvAddress, uiSize ) \ - if (xTraceIsRecorderEnabled()) \ - { \ - xTraceHeapAlloc(xTraceKernelPortGetSystemHeapHandle(), pvAddress, uiSize); \ - } - -#undef traceFREE -#define traceFREE( pvAddress, uiSize ) \ - if (xTraceIsRecorderEnabled()) \ - { \ - xTraceHeapFree(xTraceKernelPortGetSystemHeapHandle(), pvAddress, uiSize); \ - } - -#endif - -#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) - -/* Called in timer.c - xTimerCreate */ -#undef traceTIMER_CREATE -#define traceTIMER_CREATE(tmr) \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_TIMER_CREATE, (void*)(tmr), (const char*)(tmr)->pcTimerName, (uint32_t)(tmr)->xTimerPeriodInTicks) - -#undef traceTIMER_CREATE_FAILED -#define traceTIMER_CREATE_FAILED() \ - prvTraceStoreEvent_None(PSF_EVENT_TIMER_CREATE_FAILED); - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \ - case tmrCOMMAND_RESET: \ - prvTraceStoreEvent_HandleParam((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET : PSF_EVENT_TIMER_RESET_FAILED, (void*)(tmr), xOptionalValue); \ - break; \ - case tmrCOMMAND_START_FROM_ISR: \ - prvTraceStoreEvent_HandleParam((xReturn == pdPASS) ? PSF_EVENT_TIMER_START_FROMISR : PSF_EVENT_TIMER_START_FROMISR_FAILED, (void*)(tmr), xOptionalValue); \ - break; \ - case tmrCOMMAND_RESET_FROM_ISR: \ - prvTraceStoreEvent_HandleParam((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET_FROMISR : PSF_EVENT_TIMER_RESET_FROMISR_FAILED, (void*)(tmr), xOptionalValue); \ - break; \ - case tmrCOMMAND_STOP_FROM_ISR: \ - prvTraceStoreEvent_HandleParam((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP_FROMISR : PSF_EVENT_TIMER_STOP_FROMISR_FAILED, (void*)(tmr), xOptionalValue); \ - break; \ - case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: \ - prvTraceStoreEvent_HandleParam((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR : PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED, (void*)(tmr), xOptionalValue); \ - break; -#else - -#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) - -#endif - -/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */ -#undef traceTIMER_COMMAND_SEND -#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \ - switch(xCommandID) \ - { \ - case tmrCOMMAND_START: \ - prvTraceStoreEvent_Handle(((xReturn) == pdPASS) ? PSF_EVENT_TIMER_START : PSF_EVENT_TIMER_START_FAILED, (void*)(tmr)); \ - break; \ - case tmrCOMMAND_STOP: \ - prvTraceStoreEvent_Handle(((xReturn) == pdPASS) ? PSF_EVENT_TIMER_STOP : PSF_EVENT_TIMER_STOP_FAILED, (void*)(tmr)); \ - break; \ - case tmrCOMMAND_CHANGE_PERIOD: \ - prvTraceStoreEvent_HandleParam(((xReturn) == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD : PSF_EVENT_TIMER_CHANGEPERIOD_FAILED, (void*)(tmr), xOptionalValue); \ - break; \ - case tmrCOMMAND_DELETE: \ - xTraceObjectUnregisterWithoutHandle(((xReturn) == pdPASS) ? PSF_EVENT_TIMER_DELETE : PSF_EVENT_TIMER_DELETE_FAILED, (void*)(tmr), 0); \ - break; \ - traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \ - } - -#undef traceTIMER_EXPIRED -#define traceTIMER_EXPIRED(tmr) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_TIMER_EXPIRED, (void*)(tmr), (uint32_t)((tmr)->pxCallbackFunction)) - -#endif - - -#if (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) - -#undef tracePEND_FUNC_CALL -#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \ - prvTraceStoreEvent_Param(((ret) == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL : PSF_EVENT_TIMER_PENDFUNCCALL_FAILED, (uint32_t)(func)) - -#undef tracePEND_FUNC_CALL_FROM_ISR -#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \ - prvTraceStoreEvent_Param(((ret) == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR : PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED, (uint32_t)(func)) - -#endif - -#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) - -#undef traceEVENT_GROUP_CREATE -#define traceEVENT_GROUP_CREATE(eg) \ - xTraceObjectRegisterWithoutHandle(PSF_EVENT_EVENTGROUP_CREATE, (void*)(eg), 0, (uint32_t)(eg)->uxEventBits) - -#undef traceEVENT_GROUP_DELETE -#define traceEVENT_GROUP_DELETE(eg) \ - xTraceObjectUnregisterWithoutHandle(PSF_EVENT_EVENTGROUP_DELETE, (void*)(eg), (uint32_t)(eg)->uxEventBits) - -#undef traceEVENT_GROUP_CREATE_FAILED -#define traceEVENT_GROUP_CREATE_FAILED() \ - prvTraceStoreEvent_None(PSF_EVENT_EVENTGROUP_CREATE_FAILED) - -#undef traceEVENT_GROUP_SYNC_BLOCK -#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_EVENTGROUP_SYNC_BLOCK, (void*)(eg), bitsToWaitFor) - -#undef traceEVENT_GROUP_SYNC_END -#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \ - prvTraceStoreEvent_HandleParam(((wasTimeout) != pdTRUE) ? PSF_EVENT_EVENTGROUP_SYNC : PSF_EVENT_EVENTGROUP_SYNC_FAILED, (void*)(eg), bitsToWaitFor) - -#undef traceEVENT_GROUP_WAIT_BITS_BLOCK -#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK, (void*)(eg), bitsToWaitFor) - -#undef traceEVENT_GROUP_WAIT_BITS_END -#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \ - prvTraceStoreEvent_HandleParam(((wasTimeout) != pdTRUE) ? PSF_EVENT_EVENTGROUP_WAITBITS : PSF_EVENT_EVENTGROUP_WAITBITS_FAILED, (void*)(eg), bitsToWaitFor) - -#undef traceEVENT_GROUP_CLEAR_BITS -#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_EVENTGROUP_CLEARBITS, (void*)(eg), bitsToClear) - -#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR -#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR, (void*)(eg), bitsToClear) - -#undef traceEVENT_GROUP_SET_BITS -#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_EVENTGROUP_SETBITS, (void*)(eg), bitsToSet) - -#undef traceEVENT_GROUP_SET_BITS_FROM_ISR -#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_EVENTGROUP_SETBITS_FROMISR, (void*)(eg), bitsToSet) - -#endif - -#undef traceTASK_NOTIFY -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY(index) \ - prvTraceStoreEvent_Handle(PSF_EVENT_TASK_NOTIFY, (void*)xTaskToNotify) - -#else - -#define traceTASK_NOTIFY() \ - prvTraceStoreEvent_Handle(PSF_EVENT_TASK_NOTIFY, (void*)xTaskToNotify) - -#endif - -#undef traceTASK_NOTIFY_FROM_ISR -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY_FROM_ISR(index) \ - prvTraceStoreEvent_Handle(PSF_EVENT_TASK_NOTIFY_FROM_ISR, (void*)xTaskToNotify) - -#else - -#define traceTASK_NOTIFY_FROM_ISR() \ - prvTraceStoreEvent_Handle(PSF_EVENT_TASK_NOTIFY_FROM_ISR, (void*)xTaskToNotify) - -#endif - -/* NOTIFY and NOTIFY_GIVE will be handled identically */ -#undef traceTASK_NOTIFY_GIVE_FROM_ISR -#define traceTASK_NOTIFY_GIVE_FROM_ISR traceTASK_NOTIFY_FROM_ISR - -#undef traceTASK_NOTIFY_WAIT -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY_WAIT(index) \ - prvTraceStoreEvent_HandleParam(pxCurrentTCB->ucNotifyState[index] == taskNOTIFICATION_RECEIVED ? PSF_EVENT_TASK_NOTIFY_WAIT : PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (void*)pxCurrentTCB, xTicksToWait) - -#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) - -#define traceTASK_NOTIFY_WAIT() \ - prvTraceStoreEvent_HandleParam(pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED ? PSF_EVENT_TASK_NOTIFY_WAIT : PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (void*)pxCurrentTCB, xTicksToWait) - -#else - -#define traceTASK_NOTIFY_WAIT() \ - prvTraceStoreEvent_HandleParam(pxCurrentTCB->eNotifyState == eNotified ? PSF_EVENT_TASK_NOTIFY_WAIT : PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (void*)pxCurrentTCB, xTicksToWait) - -#endif - -/* WAIT and TAKE will be handled identically */ -#undef traceTASK_NOTIFY_TAKE -#define traceTASK_NOTIFY_TAKE traceTASK_NOTIFY_WAIT - -#undef traceTASK_NOTIFY_WAIT_BLOCK -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0) - -#define traceTASK_NOTIFY_WAIT_BLOCK(index) \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, (void*)pxCurrentTCB, xTicksToWait) - -#else - -#define traceTASK_NOTIFY_WAIT_BLOCK() \ - prvTraceStoreEvent_HandleParam(PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, (void*)pxCurrentTCB, xTicksToWait) - -#endif - -/* WAIT_BLOCK and TAKE_BLOCK will be handled identically */ -#undef traceTASK_NOTIFY_TAKE_BLOCK -#define traceTASK_NOTIFY_TAKE_BLOCK traceTASK_NOTIFY_WAIT_BLOCK - -#undef traceQUEUE_REGISTRY_ADD -#define traceQUEUE_REGISTRY_ADD(object, name) \ - xTraceObjectSetNameWithoutHandle(object, (const char*)(name)); - -#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1) - -#undef traceSTREAM_BUFFER_CREATE -#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \ - xTraceObjectRegisterWithoutHandle((xIsMessageBuffer) == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE : PSF_EVENT_STREAMBUFFER_CREATE, (void*)(pxStreamBuffer), "", (uint32_t)xBufferSizeBytes) - -#undef traceSTREAM_BUFFER_CREATE_FAILED -#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \ - prvTraceStoreEvent_HandleParam((xIsMessageBuffer) == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED : PSF_EVENT_STREAMBUFFER_CREATE_FAILED, 0 , xBufferSizeBytes) - -#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED -#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \ - traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) - -#undef traceSTREAM_BUFFER_DELETE -#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \ - xTraceObjectUnregisterWithoutHandle(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_DELETE : PSF_EVENT_STREAMBUFFER_DELETE, (void*)(xStreamBuffer), prvBytesInBuffer(xStreamBuffer)); - -#undef traceSTREAM_BUFFER_RESET -#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \ - prvTraceStoreEvent_HandleParam(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RESET : PSF_EVENT_STREAMBUFFER_RESET, (void*)(xStreamBuffer), 0) - -#undef traceSTREAM_BUFFER_SEND -#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \ - prvTraceStoreEvent_HandleParam(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND : PSF_EVENT_STREAMBUFFER_SEND, (void*)(xStreamBuffer), prvBytesInBuffer(xStreamBuffer)) - -#undef traceBLOCKING_ON_STREAM_BUFFER_SEND -#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \ - prvTraceStoreEvent_Handle(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK : PSF_EVENT_STREAMBUFFER_SEND_BLOCK, (void*)(xStreamBuffer)) - -#undef traceSTREAM_BUFFER_SEND_FAILED -#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \ - prvTraceStoreEvent_Handle(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FAILED, (void*)(xStreamBuffer)) - -#undef traceSTREAM_BUFFER_RECEIVE -#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \ - prvTraceStoreEvent_HandleParam(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE: PSF_EVENT_STREAMBUFFER_RECEIVE, (void*)(xStreamBuffer), prvBytesInBuffer(xStreamBuffer)) - -#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE -#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \ - prvTraceStoreEvent_Handle(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK: PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK, (void*)(xStreamBuffer)) - -#undef traceSTREAM_BUFFER_RECEIVE_FAILED -#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \ - prvTraceStoreEvent_Handle(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED: PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED, (void*)(xStreamBuffer)) - -#undef traceSTREAM_BUFFER_SEND_FROM_ISR -#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \ - if ( (xReturn) > ( size_t ) 0 ) \ - { \ - prvTraceStoreEvent_HandleParam(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR, (void*)(xStreamBuffer), prvBytesInBuffer(xStreamBuffer)); \ - } \ - else \ - { \ - prvTraceStoreEvent_Handle(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED, (void*)(xStreamBuffer)); \ - } - -#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR -#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \ - if ( (xReceivedLength) > ( size_t ) 0 ) \ - { \ - prvTraceStoreEvent_HandleParam(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR, (void*)(xStreamBuffer), prvBytesInBuffer(xStreamBuffer)); \ - } \ - else \ - { \ - prvTraceStoreEvent_Handle(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED, (void*)(xStreamBuffer)); \ - } - -#endif - -#endif - -#endif - -#else - -/* When recorder is disabled */ -#define vTraceSetQueueName(object, name) -#define vTraceSetSemaphoreName(object, name) -#define vTraceSetMutexName(object, name) -#define vTraceSetEventGroupName(object, name) -#define vTraceSetStreamBufferName(object, name) -#define vTraceSetMessageBufferName(object, name) - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_KERNEL_PORT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * FreeRTOS specific definitions needed by the trace recorder + */ + +#ifndef TRC_KERNEL_PORT_H + #define TRC_KERNEL_PORT_H + + #include + #include /* Defines configUSE_TRACE_FACILITY */ + + #ifdef __cplusplus + extern "C" { + #endif + + #define TRC_USE_TRACEALYZER_RECORDER configUSE_TRACE_FACILITY + +/* FreeRTOS version codes */ + #define FREERTOS_VERSION_NOT_SET 0 + #define TRC_FREERTOS_VERSION_7_3_X 1 /* v7.3 is earliest supported.*/ + #define TRC_FREERTOS_VERSION_7_4_X 2 + #define TRC_FREERTOS_VERSION_7_5_X 3 + #define TRC_FREERTOS_VERSION_7_6_X TRC_FREERTOS_VERSION_7_5_X + #define TRC_FREERTOS_VERSION_8_X_X 4 + #define TRC_FREERTOS_VERSION_9_0_0 5 + #define TRC_FREERTOS_VERSION_9_0_1 6 + #define TRC_FREERTOS_VERSION_9_0_2 7 + #define TRC_FREERTOS_VERSION_10_0_0 8 + #define TRC_FREERTOS_VERSION_10_0_1 TRC_FREERTOS_VERSION_10_0_0 + #define TRC_FREERTOS_VERSION_10_1_0 TRC_FREERTOS_VERSION_10_0_0 + #define TRC_FREERTOS_VERSION_10_1_1 TRC_FREERTOS_VERSION_10_0_0 + #define TRC_FREERTOS_VERSION_10_2_0 TRC_FREERTOS_VERSION_10_0_0 + #define TRC_FREERTOS_VERSION_10_2_1 TRC_FREERTOS_VERSION_10_0_0 + #define TRC_FREERTOS_VERSION_10_3_0 9 + #define TRC_FREERTOS_VERSION_10_3_1 TRC_FREERTOS_VERSION_10_3_0 + #define TRC_FREERTOS_VERSION_10_4_0 10 + #define TRC_FREERTOS_VERSION_10_4_1 TRC_FREERTOS_VERSION_10_4_0 + +/* Legacy FreeRTOS version codes for backwards compatibility with old trace configurations */ + #define TRC_FREERTOS_VERSION_7_3 TRC_FREERTOS_VERSION_7_3_X + #define TRC_FREERTOS_VERSION_7_4 TRC_FREERTOS_VERSION_7_4_X + #define TRC_FREERTOS_VERSION_7_5_OR_7_6 TRC_FREERTOS_VERSION_7_5_X + #define TRC_FREERTOS_VERSION_8_X TRC_FREERTOS_VERSION_8_X_X + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + #define prvGetStreamBufferType( x ) ( ( ( StreamBuffer_t * ) ( x ) )->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) + #else + #define prvGetStreamBufferType( x ) 0 + #endif + +/* Added mainly for our internal testing. This makes it easier to create test applications that + * runs on multiple FreeRTOS versions. */ + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X ) + /* FreeRTOS v7.x */ + #define STRING_CAST( x ) ( ( signed char * ) x ) + #define TickType portTickType + #define TaskType xTaskHandle + #else + /* FreeRTOS v8.0 and later */ + #define STRING_CAST( x ) x + #define TraceKernelPortTickType_t TickType_t + #define TraceKernelPortTaskHandle_t TaskHandle_t + #endif + + #if ( defined( TRC_USE_TRACEALYZER_RECORDER ) ) && ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #define TRC_PLATFORM_CFG "FreeRTOS" + #define TRC_PLATFORM_CFG_MAJOR 1 + #define TRC_PLATFORM_CFG_MINOR 0 + #define TRC_PLATFORM_CFG_PATCH 0 + + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) + +/* Required for stack monitoring */ + #undef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 1 + + #endif + +/* INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 for tracing to work properly */ + #undef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 1 + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + #include + + #define TRC_KERNEL_PORT_BUFFER_SIZE ( sizeof( TraceHeapHandle_t ) + sizeof( void * ) ) + #elif ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) + #define TRC_KERNEL_PORT_BUFFER_SIZE ( sizeof( TraceUnsignedBaseType_t ) ) + #endif + +/** + * @internal The kernel port data buffer + */ + typedef struct TraceKernelPortDataBuffer + { + uint8_t buffer[ TRC_KERNEL_PORT_BUFFER_SIZE ]; + } TraceKernelPortDataBuffer_t; + +/** + * @internal Initializes the kernel port + * + * @param[in] pxBuffer Kernel port data buffer + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceKernelPortInitialize( TraceKernelPortDataBuffer_t * pxBuffer ); + +/** + * @internal Enables the kernel port + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceKernelPortEnable( void ); + +/** + * @internal Calls on FreeRTOS vTaskDelay(...) + * + * @param[in] uiTicks Tick count to delay + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceKernelPortDelay( uint32_t uiTicks ); + +/** + * @internal Query if FreeRTOS scheduler is suspended + * + * @retval 1 Scheduler suspended + * @retval 0 Scheduler not suspended + */ + unsigned char xTraceKernelPortIsSchedulerSuspended( void ); + +/** + * @brief Kernel specific way to properly allocate critical sections + */ + #define TRC_KERNEL_PORT_ALLOC_CRITICAL_SECTION() + +/** + * @brief Kernel specific way to properly allocate critical sections + */ + #define TRC_KERNEL_PORT_ENTER_CRITICAL_SECTION() portENTER_CRITICAL() + +/** + * @brief Kernel specific way to properly allocate critical sections + */ + #define TRC_KERNEL_PORT_EXIT_CRITICAL_SECTION() portEXIT_CRITICAL() + +/** + * @brief Kernel specific way to set interrupt mask + */ + #define TRC_KERNEL_PORT_SET_INTERRUPT_MASK() ( ( TraceBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR() ) + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + +/** + * @brief Kernel specific way to clear interrupt mask + */ + #define TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK( xMask ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( UBaseType_t ) ( xMask ) ) + + #else + +/** + * @brief Kernel specific way to clear interrupt mask + */ + #define TRC_KERNEL_PORT_CLEAR_INTERRUPT_MASK( xMask ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( unsigned portBASE_TYPE ) xMask ) + #endif + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + +/** + * @brief Set the queue name + * + * @param[in] pvQueue Queue pointer + * @param[in] szName Queue name + */ + void vTraceSetQueueName( void * pvQueue, + const char * szName ); + +/** + * @brief Set the semaphore name + * + * @param[in] pvSemaphore Semaphore pointer + * @param[in] szName Semaphore name + */ + void vTraceSetSemaphoreName( void * pvSemaphore, + const char * szName ); + +/** + * @brief Set the mutex name + * + * @param[in] pvMutex Mutex pointer + * @param[in] szName Mutex name + */ + void vTraceSetMutexName( void * pvMutex, + const char * szName ); + + #if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 ) + +/** + * @brief Set the event group name + * + * @param[in] pvEventGroup Event group pointer + * @param[in] szName Event group name + */ + void vTraceSetEventGroupName( void * pvEventGroup, + const char * szName ); + + #else + +/** + * @brief Disabled by TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS + */ + #define vTraceSetEventGroupName( __pvEventGroup, __szName ) ( ( void ) ( __pvEventGroup ), ( void ) ( __szName ) ) + + #endif + + #if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 ) + +/** + * @brief Set the stream buffer name + * + * @param[in] pvStreamBuffer Stream buffer pointer + * @param[in] szName Stream buffer name + */ + void vTraceSetStreamBufferName( void * pvStreamBuffer, + const char * szName ); + +/** + * @brief Set the message buffer name + * + * @param[in] pvMessageBuffer Message buffer pointer + * @param[in] szName Message buffer name + */ + void vTraceSetMessageBufferName( void * pvMessageBuffer, + const char * szName ); + + #else + +/** + * @brief Disabled by TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS + */ + #define vTraceSetStreamBufferName( __pvStreamBuffer, __szName ) ( ( void ) ( __pvStreamBuffer ), ( void ) ( __szName ) ) + +/** + * @brief Disabled by TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS + */ + #define vTraceSetMessageBufferName( __pvMessageBuffer, __szName ) ( ( void ) ( __pvMessageBuffer ), ( void ) ( __szName ) ) + + #endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 ) */ + + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) + +/** + * @internal Retrieves the unused stack for a task + * + * @param[in] pvTask Task pointer + * @param[out] puxUnusedStack The unused stack + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceKernelPortGetUnusedStack( void * pvTask, + TraceUnsignedBaseType_t * puxUnusedStack ); + + #endif + + #else /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + +/** + * @brief Disabled by TRC_CFG_SCHEDULING_ONLY + */ + #define vTraceSetQueueName( __pvQueue, __szName ) ( ( void ) ( __pvQueue ), ( void ) ( __szName ) ) + +/** + * @brief Disabled by TRC_CFG_SCHEDULING_ONLY + */ + #define vTraceSetSemaphoreName( __pvSemaphore, __szName ) ( ( void ) ( __pvSemaphore ), ( void ) ( __szName ) ) + +/** + * @brief Disabled by TRC_CFG_SCHEDULING_ONLY + */ + #define vTraceSetMutexName( __pvMutex, __szName ) ( ( void ) ( __pvMutex ), ( void ) ( __szName ) ) + +/** + * @brief Disabled by TRC_CFG_SCHEDULING_ONLY + */ + #define vTraceSetEventGroupName( __pvEventGroup, __szName ) ( ( void ) ( __pvEventGroup ), ( void ) ( __szName ) ) + +/** + * @brief Disabled by TRC_CFG_SCHEDULING_ONLY + */ + #define vTraceSetStreamBufferName( __pvStreamBuffer, __szName ) ( ( void ) ( __pvStreamBuffer ), ( void ) ( __szName ) ) + +/** + * @brief Disabled by TRC_CFG_SCHEDULING_ONLY + */ + #define vTraceSetMessageBufferName( __pvMessageBuffer, __szName ) ( ( void ) ( __pvMessageBuffer ), ( void ) ( __szName ) ) + +/** + * @brief Disabled by TRC_CFG_SCHEDULING_ONLY + */ + #define xTraceKernelPortGetUnusedStack( pvTask, puxUnusedStack ) ( ( void ) ( pvTask ), ( void ) ( puxUnusedStack ) ) + + #endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + + #if ( ( ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) && ( TRC_CFG_INCLUDE_ISR_TRACING == 1 ) ) || ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) ) + +/* Required for ISR tracing and Streaming */ + #undef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 1 + + #endif + +/** + * @internal Legacy ID used by Tracealyzer to identify FreeRTOS traces + */ + #define TRACE_KERNEL_VERSION 0x1AA1 + +/** + * @internal Kernel specific tick rate frequency definition + */ + #define TRC_TICK_RATE_HZ configTICK_RATE_HZ /* Defined in "FreeRTOS.h" */ + +/** + * @internal Kernel specific CPU clock frequency definition + */ + #define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */ + +/** + * @internal Kernel specific malloc definition + */ + #define TRACE_MALLOC( size ) pvPortMalloc( size ) + + #if ( defined( configUSE_TIMERS ) && ( configUSE_TIMERS == 1 ) ) + + #undef INCLUDE_xTimerGetTimerDaemonTaskHandle + #define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 + + #endif + + #if ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XMOS_XCOREAI ) + + #undef TRC_CFG_CORE_COUNT + #define TRC_CFG_CORE_COUNT configNUM_CORES + + #undef TRC_CFG_GET_CURRENT_CORE + #define TRC_CFG_GET_CURRENT_CORE() rtos_core_id_get() + + #endif + + #if ( TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_0_1 ) + +/** + * @brief Fix for FreeRTOS v9.0.1 to correctly identify xQueuePeek events. + * + * In FreeRTOS v9.0.1, the below trace hooks are incorrectly used from three + * different functions. This as the earlier function xQueueGenericReceive + * has been replaced by xQueuePeek, xQueueSemaphoreTake and xQueueReceive. + * + * xQueueGenericReceive had a parameter "xJustPeeking", used by the trace hooks + * to tell between xQueuePeek events and others. This is no longer present, so + * we need another way to correctly identify peek events. Since all three + * functions call the same trace macros, the context of these macro is unknown. + * + * We therefore check the __LINE__ macro inside of the trace macros. This gives + * the line number of queue.c, where the macros are used. This can be used to + * tell if the context is xQueuePeek or another function. + * __LINE__ is a standard compiler feature since ancient times, so it should + * work on all common compilers. + * + * This might seem as a quite brittle and unusual solution, but works in this + * particular case and is only for FreeRTOS v9.0.1. + * Future versions of FreeRTOS should not need this fix, as we have submitted + * a correction of queue.c with individual trace macros for each function. + */ + #define isQueueReceiveHookActuallyPeek ( __LINE__ > 1674 ) /* Half way between the closes trace points */ + + #elif ( TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_9_0_0 ) + +/** + * @brief Is receive actually a peek + */ + #define isQueueReceiveHookActuallyPeek xJustPeeking + + #elif ( TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1 ) + +/** + * @brief Is never a peek for this FreeRTOS version + */ + #define isQueueReceiveHookActuallyPeek ( __LINE__ < 0 ) /* instead of pdFALSE to fix a warning of "constant condition" */ + + #endif /* if ( TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_0_1 ) */ + +/* Helpers needed to correctly expand names */ + #define TZ__CAT2( a, b ) a ## b + #define TZ__CAT( a, b ) TZ__CAT2( a, b ) + +/* + * The following xQueueGiveFromISR macro hacks make sure xQueueGiveFromISR also has a xCopyPosition parameter + */ + +/* Expands name if this header is included... uxQueueType must be a macro that only exists in queue.c or whatever, and it must expand to nothing or to something that's valid in identifiers */ + #define xQueueGiveFromISR( a, b ) TZ__CAT( xQueueGiveFromISR__, uxQueueType ) ( a, b ) + +/* If in queue.c, the "uxQueueType" macro expands to "pcHead". queueSEND_TO_BACK is the value we need to send in */ + #define xQueueGiveFromISR__pcHead( __a, __b ) \ + MyWrapper_xQueueGiveFromISR( __a, __b, const BaseType_t xCopyPosition ); \ + BaseType_t xQueueGiveFromISR( __a, __b ) { return MyWrapper_xQueueGiveFromISR( xQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ); } \ + BaseType_t MyWrapper_xQueueGiveFromISR( __a, __b, const BaseType_t xCopyPosition ) + +/* If not in queue.c, "uxQueueType" isn't expanded */ + #define xQueueGiveFromISR__uxQueueType( __a, __b ) xQueueGiveFromISR( __a, __b ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) + +/** + * @internal Kernel specific way to get current task handle + */ + #define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle() + + extern uint16_t CurrentFilterMask; + extern uint16_t CurrentFilterGroup; + +/** + * @internal Get specific queue type + * + * @param[in] pvQueue Queue handle + * + * @returns uint8_t Queue type + */ + uint8_t prvTraceGetQueueType( void * pvQueue ); + +/** + * @internal Retrieve lower 16-bit of task number + * + * @param[in] pvTask Task handle + * + * @returns uint16_t Lower 16-bit of task number + */ + uint16_t prvTraceGetTaskNumberLow16( void * pvTask ); + +/** + * @internal Retrieve upper 16-bit of task number + * + * @param[in] pvTask Task handle + * + * @returns uint16_t Upper 16-bit of task number + */ + uint16_t prvTraceGetTaskNumberHigh16( void * pvTask ); + +/** + * @internal Set lower 16-bit of task number + * + * @param[in] pvTask Task handle + * @param[in] uiValue Value + */ + void prvTraceSetTaskNumberLow16( void * pvTask, + uint16_t uiValue ); + +/** + * @internal Set upper 16-bit of task number + * + * @param[in] pvTask Task handle + * @param[in] uiValue Value + */ + void prvTraceSetTaskNumberHigh16( void * pvTask, + uint16_t uiValue ); + +/** + * @internal Retrieve lower 16-bit of queue number + * + * @param[in] pvQueue Queue handle + * + * @returns uint16_t Lower 16-bit of queue number + */ + uint16_t prvTraceGetQueueNumberLow16( void * pvQueue ); + +/** + * @internal Retrieve upper 16-bit of queue number + * + * @param[in] pvQueue Queue handle + * + * @returns uint16_t Upper 16-bit of queue number + */ + uint16_t prvTraceGetQueueNumberHigh16( void * pvQueue ); + + +/** + * @internal Set lower 16-bit of queue number + * + * @param[in] pvQueue Queue handle + * @param[in] uiValue Value + */ + void prvTraceSetQueueNumberLow16( void * pvQueue, + uint16_t uiValue ); + + +/** + * @internal Set upper 16-bit of queue number + * + * @param[in] pvQueue Queue handle + * @param[in] uiValue Value + */ + void prvTraceSetQueueNumberHigh16( void * pvQueue, + uint16_t uiValue ); + + #if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + +/** + * @internal Retrieve lower 16-bit of timer number + * + * @param[in] pvTimer Timer handle + * + * @returns uint16_t Lower 16-bit of timer number + */ + uint16_t prvTraceGetTimerNumberLow16( void * pvTimer ); + +/** + * @internal Retrieve upper 16-bit of timer number + * + * @param[in] pvTimer Timer handle + * + * @returns uint16_t Upper 16-bit of timer number + */ + uint16_t prvTraceGetTimerNumberHigh16( void * pvTimer ); + +/** + * @internal Set lower 16-bit of timer number + * + * @param[in] pvTimer Timer handle + * @param[in] uiValue Value + */ + void prvTraceSetTimerNumberLow16( void * pvTimer, + uint16_t uiValue ); + +/** + * @internal Set upper 16-bit of timer number + * + * @param[in] pvTimer Timer handle + * @param[in] uiValue Value + */ + void prvTraceSetTimerNumberHigh16( void * pvTimer, + uint16_t uiValue ); + + #endif /* if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + + #if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + +/** + * @internal Retrieve lower 16-bit of event group number + * + * @param[in] pvEventGroup Event group handle + * + * @returns uint16_t Lower 16-bit of event group number + */ + uint16_t prvTraceGetEventGroupNumberLow16( void * pvEventGroup ); + +/** + * @internal Retrieve upper 16-bit of event group number + * + * @param[in] pvEventGroup Event group handle + * + * @returns uint16_t Upper 16-bit of event group number + */ + uint16_t prvTraceGetEventGroupNumberHigh16( void * pvEventGroup ); + +/** + * @internal Set lower 16-bit of event group number + * + * @param[in] pvEventGroup Event group handle + * @param[in] uiValue Value + */ + void prvTraceSetEventGroupNumberLow16( void * pvEventGroup, + uint16_t uiValue ); + +/** + * @internal Set upper 16-bit of event group number + * + * @param[in] pvEventGroup Event group handle + * @param[in] uiValue Value + */ + void prvTraceSetEventGroupNumberHigh16( void * handle, + uint16_t value ); + + #endif /* if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + + #if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + +/** + * @internal Retrieve lower 16-bit of stream buffer number + * + * @param[in] pvStreamBuffer Stream buffer handle + * + * @returns uint16_t Lower 16-bit of stream buffer number + */ + uint16_t prvTraceGetStreamBufferNumberLow16( void * pvStreamBuffer ); + +/** + * @internal Retrieve upper 16-bit of stream buffer number + * + * @param[in] pvStreamBuffer Stream buffer handle + * + * @returns uint16_t Upper 16-bit of stream buffer number + */ + uint16_t prvTraceGetStreamBufferNumberHigh16( void * pvStreamBuffer ); + +/** + * @internal Set lower 16-bit of stream buffer number + * + * @param[in] pvStreamBuffer Stream buffer handle + * @param[in] uiValue Value + */ + void prvTraceSetStreamBufferNumberLow16( void * pvStreamBuffer, + uint16_t uiValue ); + +/** + * @internal Set upper 16-bit of stream buffer number + * + * @param[in] pvStreamBuffer Stream buffer handle + * @param[in] uiValue Value + */ + void prvTraceSetStreamBufferNumberHigh16( void * pvStreamBuffer, + uint16_t uiValue ); + + #endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + +/** + * @brief Retrieve filter of task + * + * @param[in] pxTask Task handle + * + * @returns uint16_t Task filter + */ + #define TRACE_GET_TASK_FILTER( pxTask ) prvTraceGetTaskNumberHigh16( ( void * ) pxTask ) + +/** + * @brief Set filter of task + * + * @param[in] pxTask Task handle + * @param[in] group Group + */ + #define TRACE_SET_TASK_FILTER( pxTask, group ) prvTraceSetTaskNumberHigh16( ( void * ) pxTask, group ) + +/** + * @brief Retrieve filter of queue + * + * @param[in] pxQueue Queue handle + * + * @returns uint16_t Queue filter + */ + #define TRACE_GET_QUEUE_FILTER( pxQueue ) prvTraceGetQueueNumberHigh16( ( void * ) pxQueue ) + +/** + * @brief Set filter of queue + * + * @param[in] pxQueue Queue handle + * @param[in] group Group + */ + #define TRACE_SET_QUEUE_FILTER( pxQueue, group ) prvTraceSetQueueNumberHigh16( ( void * ) pxQueue, group ) + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + +/** + * @brief Retrieve filter of event group + * + * @param[in] pxEventGroup Queue handle + * + * @returns uint16_t Queue filter + */ + #define TRACE_GET_EVENTGROUP_FILTER( pxEventGroup ) prvTraceGetEventGroupNumberHigh16( ( void * ) pxEventGroup ) + +/** + * @brief Set filter of event group + * + * @param[in] pxEventGroup Queue handle + * @param[in] group Group + */ + #define TRACE_SET_EVENTGROUP_FILTER( pxEventGroup, group ) prvTraceSetEventGroupNumberHigh16( ( void * ) pxEventGroup, group ) + + #else + +/** + * @brief Disabled by TRC_CFG_FREERTOS_VERSION + */ + #define TRACE_GET_EVENTGROUP_FILTER( pxEventGroup ) ( ( void ) ( pxEventGroup ), 1 ) + +/** + * @brief Disabled by TRC_CFG_FREERTOS_VERSION + */ + #define TRACE_SET_EVENTGROUP_FILTER( pxEventGroup, group ) ( ( void ) ( pxEventGroup ), ( void ) ( group ) ) + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + +/** + * @brief Retrieve filter of timer + * + * @param[in] pxEventGroup Timer handle + * + * @returns uint16_t Timer filter + */ + #define TRACE_GET_TIMER_FILTER( pxTimer ) prvTraceGetTimerNumberHigh16( ( void * ) pxTimer ) + +/** + * @brief Set filter of timer + * + * @param[in] pxTimer Timer handle + * @param[in] group Group + */ + #define TRACE_SET_TIMER_FILTER( pxTimer, group ) prvTraceSetTimerNumberHigh16( ( void * ) pxTimer, group ) + + #else + +/** + * @brief Disabled by TRC_CFG_FREERTOS_VERSION + */ + #define TRACE_GET_TIMER_FILTER( pxTimer ) ( ( void ) ( pxTimer ), 1 ) + +/** + * @brief Disabled by TRC_CFG_FREERTOS_VERSION + */ + #define TRACE_SET_TIMER_FILTER( pxTimer, group ) ( ( void ) ( pxTimer ), ( void ) ( group ) ) + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + +/** + * @brief Retrieve filter of stream buffer + * + * @param[in] pxStreamBuffer Stream buffer handle + * + * @returns uint16_t Timer filter + */ + #define TRACE_GET_STREAMBUFFER_FILTER( pxStreamBuffer ) prvTraceGetStreamBufferNumberHigh16( ( void * ) pxStreamBuffer ) + +/** + * @brief Set filter of stream buffer + * + * @param[in] pxStreamBuffer Stream buffer handle + * @param[in] group Group + */ + #define TRACE_SET_STREAMBUFFER_FILTER( pxStreamBuffer, group ) prvTraceSetStreamBufferNumberHigh16( ( void * ) pxStreamBuffer, group ) + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + +/** + * @internal Get object filter + */ + #define TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) TRACE_GET_ ## CLASS ## _FILTER( pxObject ) + +/** + * @internal Set object filter + */ + #define TRACE_SET_OBJECT_FILTER( CLASS, pxObject, group ) TRACE_SET_ ## CLASS ## _FILTER( pxObject, group ) + + #else + +/** + * @internal Disabled by TRC_CFG_FREERTOS_VERSION + */ + #define TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) 0xFFFF + +/** + * @internal Disabled by TRC_CFG_FREERTOS_VERSION + */ + #define TRACE_SET_OBJECT_FILTER( CLASS, pxObject, group ) + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) */ + +/* The object classes */ + #define TRACE_NCLASSES 9 + #define TRACE_CLASS_QUEUE ( ( traceObjectClass ) 0 ) + #define TRACE_CLASS_SEMAPHORE ( ( traceObjectClass ) 1 ) + #define TRACE_CLASS_MUTEX ( ( traceObjectClass ) 2 ) + #define TRACE_CLASS_TASK ( ( traceObjectClass ) 3 ) + #define TRACE_CLASS_ISR ( ( traceObjectClass ) 4 ) + #define TRACE_CLASS_TIMER ( ( traceObjectClass ) 5 ) + #define TRACE_CLASS_EVENTGROUP ( ( traceObjectClass ) 6 ) + #define TRACE_CLASS_STREAMBUFFER ( ( traceObjectClass ) 7 ) + #define TRACE_CLASS_MESSAGEBUFFER ( ( traceObjectClass ) 8 ) + +/* Definitions for Object Table */ + #define TRACE_KERNEL_OBJECT_COUNT ( ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ) + ( TRC_CFG_NSTREAMBUFFER ) + ( TRC_CFG_NMESSAGEBUFFER ) ) + +/* Queue properties (except name): current number of message in queue */ + #define PropertyTableSizeQueue ( ( TRC_CFG_NAME_LEN_QUEUE ) +1 ) + +/* Semaphore properties (except name): state (signaled = 1, cleared = 0) */ + #define PropertyTableSizeSemaphore ( ( TRC_CFG_NAME_LEN_SEMAPHORE ) +1 ) + +/* Mutex properties (except name): owner (task handle, 0 = free) */ + #define PropertyTableSizeMutex ( ( TRC_CFG_NAME_LEN_MUTEX ) +1 ) + +/* Task properties (except name): Byte 0: Current priority + * Byte 1: state (if already active) + * Byte 2: legacy, not used + * Byte 3: legacy, not used */ + #define PropertyTableSizeTask ( ( TRC_CFG_NAME_LEN_TASK ) +4 ) + +/* ISR properties: Byte 0: priority + * Byte 1: state (if already active) */ + #define PropertyTableSizeISR ( ( TRC_CFG_NAME_LEN_ISR ) +2 ) + +/* TRC_CFG_NTIMER properties: Byte 0: state (unused for now) */ + #define PropertyTableSizeTimer ( ( TRC_CFG_NAME_LEN_TIMER ) +1 ) + +/* TRC_CFG_NEVENTGROUP properties: Byte 0-3: state (unused for now)*/ + #define PropertyTableSizeEventGroup ( ( TRC_CFG_NAME_LEN_EVENTGROUP ) +4 ) + +/* TRC_CFG_NSTREAMBUFFER properties: Byte 0-3: state (unused for now)*/ + #define PropertyTableSizeStreamBuffer ( ( TRC_CFG_NAME_LEN_STREAMBUFFER ) +4 ) + +/* TRC_CFG_NMESSAGEBUFFER properties: Byte 0-3: state (unused for now)*/ + #define PropertyTableSizeMessageBuffer ( ( TRC_CFG_NAME_LEN_MESSAGEBUFFER ) +4 ) + + +/* The layout of the byte array representing the Object Property Table */ + #define StartIndexQueue ( 0 ) + #define StartIndexSemaphore ( StartIndexQueue + ( TRC_CFG_NQUEUE ) *PropertyTableSizeQueue ) + #define StartIndexMutex ( StartIndexSemaphore + ( TRC_CFG_NSEMAPHORE ) *PropertyTableSizeSemaphore ) + #define StartIndexTask ( StartIndexMutex + ( TRC_CFG_NMUTEX ) *PropertyTableSizeMutex ) + #define StartIndexISR ( StartIndexTask + ( TRC_CFG_NTASK ) *PropertyTableSizeTask ) + #define StartIndexTimer ( StartIndexISR + ( TRC_CFG_NISR ) *PropertyTableSizeISR ) + #define StartIndexEventGroup ( StartIndexTimer + ( TRC_CFG_NTIMER ) *PropertyTableSizeTimer ) + #define StartIndexStreamBuffer ( StartIndexEventGroup + ( TRC_CFG_NEVENTGROUP ) *PropertyTableSizeEventGroup ) + #define StartIndexMessageBuffer ( StartIndexStreamBuffer + ( TRC_CFG_NSTREAMBUFFER ) *PropertyTableSizeStreamBuffer ) + +/* Number of bytes used by the object table */ + #define TRACE_OBJECT_TABLE_SIZE ( StartIndexMessageBuffer + ( TRC_CFG_NMESSAGEBUFFER ) *PropertyTableSizeMessageBuffer ) + +/* Flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */ + extern int uiInEventGroupSetBitsFromISR; + +/** + * @internal Initialized the object property table + */ + traceResult xTraceKernelPortInitObjectPropertyTable( void ); + +/** + * @internal Initialized the object handle stack + */ + traceResult xTraceKernelPortInitObjectHandleStack( void ); + +/** + * @internal Retrieve error string + */ + const char * pszTraceGetErrorNotEnoughHandles( traceObjectClass objectclass ); + +/** + * @internal Retrieve current task handle + */ + void * prvTraceGetCurrentTaskHandle( void ); + + extern traceObjectClass TraceQueueClassTable[ 5 ]; + + +/*** Event codes for snapshot mode - must match Tracealyzer config files ******/ + + #define NULL_EVENT ( 0x00UL ) + +/******************************************************************************* + * EVENTGROUP_DIV + * + * Miscellaneous events. + ******************************************************************************/ + #define EVENTGROUP_DIV ( NULL_EVENT + 1UL ) /*0x01*/ + #define DIV_XPS ( EVENTGROUP_DIV + 0UL ) /*0x01*/ + #define DIV_TASK_READY ( EVENTGROUP_DIV + 1UL ) /*0x02*/ + #define DIV_NEW_TIME ( EVENTGROUP_DIV + 2UL ) /*0x03*/ + +/******************************************************************************* + * EVENTGROUP_TS + * + * Events for storing task-switches and interrupts. The RESUME events are + * generated if the task/interrupt is already marked active. + ******************************************************************************/ + #define EVENTGROUP_TS ( EVENTGROUP_DIV + 3UL ) /*0x04*/ + #define TS_ISR_BEGIN ( EVENTGROUP_TS + 0UL ) /*0x04*/ + #define TS_ISR_RESUME ( EVENTGROUP_TS + 1UL ) /*0x05*/ + #define TS_TASK_BEGIN ( EVENTGROUP_TS + 2UL ) /*0x06*/ + #define TS_TASK_RESUME ( EVENTGROUP_TS + 3UL ) /*0x07*/ + +/******************************************************************************* + * EVENTGROUP_OBJCLOSE_NAME + * + * About Close Events + * When an object is evicted from the object property table (object close), two + * internal events are stored (EVENTGROUP_OBJCLOSE_NAME and + * EVENTGROUP_OBJCLOSE_PROP), containing the handle-name mapping and object + * properties valid up to this point. + ******************************************************************************/ + #define EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS ( EVENTGROUP_TS + 4UL ) /*0x08*/ + +/******************************************************************************* + * EVENTGROUP_OBJCLOSE_PROP + * + * The internal event carrying properties of deleted objects + * The handle and object class of the closed object is not stored in this event, + * but is assumed to be the same as in the preceding CLOSE event. Thus, these + * two events must be generated from within a critical section. + * When queues are closed, arg1 is the "state" property (i.e., number of + * buffered messages/signals). + * When actors are closed, arg1 is priority, arg2 is handle of the "instance + * finish" event, and arg3 is event code of the "instance finish" event. + * In this case, the lower three bits is the object class of the instance finish + * handle. The lower three bits are not used (always zero) when queues are + * closed since the queue type is given in the previous OBJCLOSE_NAME event. + ******************************************************************************/ + #define EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS ( EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + 8UL ) /*0x10*/ + +/******************************************************************************* + * EVENTGROUP_CREATE + * + * The events in this group are used to log Kernel object creations. + * The lower three bits in the event code gives the object class, i.e., type of + * create operation (task, queue, semaphore, etc). + ******************************************************************************/ + #define EVENTGROUP_CREATE_OBJ_TRCSUCCESS ( EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + 8UL ) /*0x18*/ + +/******************************************************************************* + * EVENTGROUP_SEND + * + * The events in this group are used to log Send/Give events on queues, + * semaphores and mutexes The lower three bits in the event code gives the + * object class, i.e., what type of object that is operated on (queue, semaphore + * or mutex). + ******************************************************************************/ + #define EVENTGROUP_SEND_TRCSUCCESS ( EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 8UL ) /*0x20*/ + +/******************************************************************************* + * EVENTGROUP_RECEIVE + * + * The events in this group are used to log Receive/Take events on queues, + * semaphores and mutexes. The lower three bits in the event code gives the + * object class, i.e., what type of object that is operated on (queue, semaphore + * or mutex). + ******************************************************************************/ + #define EVENTGROUP_RECEIVE_TRCSUCCESS ( EVENTGROUP_SEND_TRCSUCCESS + 8UL ) /*0x28*/ + +/* Send/Give operations, from ISR */ + #define EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS \ + ( EVENTGROUP_RECEIVE_TRCSUCCESS + 8UL ) /*0x30*/ + +/* Receive/Take operations, from ISR */ + #define EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS \ + ( EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 8UL ) /*0x38*/ + +/* "Failed" event type versions of above (timeout, failed allocation, etc) */ + #define EVENTGROUP_KSE_TRCFAILED \ + ( EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 8UL ) /*0x40*/ + +/* Failed create calls - memory allocation failed */ + #define EVENTGROUP_CREATE_OBJ_TRCFAILED ( EVENTGROUP_KSE_TRCFAILED ) /*0x40*/ + +/* Failed send/give - timeout! */ + #define EVENTGROUP_SEND_TRCFAILED ( EVENTGROUP_CREATE_OBJ_TRCFAILED + 8UL ) /*0x48*/ + +/* Failed receive/take - timeout! */ + #define EVENTGROUP_RECEIVE_TRCFAILED ( EVENTGROUP_SEND_TRCFAILED + 8UL ) /*0x50*/ + +/* Failed non-blocking send/give - queue full */ + #define EVENTGROUP_SEND_FROM_ISR_TRCFAILED ( EVENTGROUP_RECEIVE_TRCFAILED + 8UL ) /*0x58*/ + +/* Failed non-blocking receive/take - queue empty */ + #define EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED \ + ( EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 8UL ) /*0x60*/ + +/* Events when blocking on receive/take */ + #define EVENTGROUP_RECEIVE_TRCBLOCK \ + ( EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 8UL ) /*0x68*/ + +/* Events when blocking on send/give */ + #define EVENTGROUP_SEND_TRCBLOCK ( EVENTGROUP_RECEIVE_TRCBLOCK + 8UL ) /*0x70*/ + +/* Events on queue peek (receive) */ + #define EVENTGROUP_PEEK_TRCSUCCESS ( EVENTGROUP_SEND_TRCBLOCK + 8UL ) /*0x78*/ + +/* Events on object delete (vTaskDelete or vQueueDelete) */ + #define EVENTGROUP_DELETE_OBJ_TRCSUCCESS ( EVENTGROUP_PEEK_TRCSUCCESS + 8UL ) /*0x80*/ + +/* Other events - object class is implied: TASK */ + #define EVENTGROUP_OTHERS ( EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 8UL ) /*0x88*/ + #define TASK_DELAY_UNTIL ( EVENTGROUP_OTHERS + 0UL ) /*0x88*/ + #define TASK_DELAY ( EVENTGROUP_OTHERS + 1UL ) /*0x89*/ + #define TASK_SUSPEND ( EVENTGROUP_OTHERS + 2UL ) /*0x8A*/ + #define TASK_RESUME ( EVENTGROUP_OTHERS + 3UL ) /*0x8B*/ + #define TASK_RESUME_FROM_ISR ( EVENTGROUP_OTHERS + 4UL ) /*0x8C*/ + #define TASK_PRIORITY_SET ( EVENTGROUP_OTHERS + 5UL ) /*0x8D*/ + #define TASK_PRIORITY_INHERIT ( EVENTGROUP_OTHERS + 6UL ) /*0x8E*/ + #define TASK_PRIORITY_DISINHERIT ( EVENTGROUP_OTHERS + 7UL ) /*0x8F*/ + + #define EVENTGROUP_MISC_PLACEHOLDER ( EVENTGROUP_OTHERS + 8UL ) /*0x90*/ + #define PEND_FUNC_CALL ( EVENTGROUP_MISC_PLACEHOLDER + 0UL ) /*0x90*/ + #define PEND_FUNC_CALL_FROM_ISR ( EVENTGROUP_MISC_PLACEHOLDER + 1UL ) /*0x91*/ + #define PEND_FUNC_CALL_TRCFAILED ( EVENTGROUP_MISC_PLACEHOLDER + 2UL ) /*0x92*/ + #define PEND_FUNC_CALL_FROM_ISR_TRCFAILED ( EVENTGROUP_MISC_PLACEHOLDER + 3UL ) /*0x93*/ + #define MEM_MALLOC_SIZE ( EVENTGROUP_MISC_PLACEHOLDER + 4UL ) /*0x94*/ + #define MEM_MALLOC_ADDR ( EVENTGROUP_MISC_PLACEHOLDER + 5UL ) /*0x95*/ + #define MEM_FREE_SIZE ( EVENTGROUP_MISC_PLACEHOLDER + 6UL ) /*0x96*/ + #define MEM_FREE_ADDR ( EVENTGROUP_MISC_PLACEHOLDER + 7UL ) /*0x97*/ + +/* User events */ + #define EVENTGROUP_USEREVENT ( EVENTGROUP_MISC_PLACEHOLDER + 8UL ) /*0x98*/ + #define USER_EVENT ( EVENTGROUP_USEREVENT + 0UL ) + +/* Allow for 0-15 arguments (the number of args is added to event code) */ + #define USER_EVENT_LAST ( EVENTGROUP_USEREVENT + 15UL ) /*0xA7*/ + +/******************************************************************************* + * XTS Event - eXtended TimeStamp events + * The timestamps used in the recorder are "differential timestamps" (DTS), i.e. + * the time since the last stored event. The DTS fields are either 1 or 2 bytes + * in the other events, depending on the bytes available in the event struct. + * If the time since the last event (the DTS) is larger than allowed for by + * the DTS field of the current event, an XTS event is inserted immediately + * before the original event. The XTS event contains up to 3 additional bytes + * of the DTS value - the higher bytes of the true DTS value. The lower 1-2 + * bytes are stored in the normal DTS field. + * There are two types of XTS events, XTS8 and XTS16. An XTS8 event is stored + * when there is only room for 1 byte (8 bit) DTS data in the original event, + * which means a limit of 0xFF (255UL). The XTS16 is used when the original event + * has a 16 bit DTS field and thereby can handle values up to 0xFFFF (65535UL). + * + * Using a very high frequency time base can result in many XTS events. + * Preferably, the time between two OS ticks should fit in 16 bits, i.e., + * at most 65535. If your time base has a higher frequency, you can define + * the TRACE + ******************************************************************************/ + + #define EVENTGROUP_SYS ( EVENTGROUP_USEREVENT + 16UL ) /*0xA8*/ + #define XTS8 ( EVENTGROUP_SYS + 0UL ) /*0xA8*/ + #define XTS16 ( EVENTGROUP_SYS + 1UL ) /*0xA9*/ + #define EVENT_BEING_WRITTEN ( EVENTGROUP_SYS + 2UL ) /*0xAA*/ + #define RESERVED_DUMMY_CODE ( EVENTGROUP_SYS + 3UL ) /*0xAB*/ + #define LOW_POWER_BEGIN ( EVENTGROUP_SYS + 4UL ) /*0xAC*/ + #define LOW_POWER_END ( EVENTGROUP_SYS + 5UL ) /*0xAD*/ + #define XID ( EVENTGROUP_SYS + 6UL ) /*0xAE*/ + #define XTS16L ( EVENTGROUP_SYS + 7UL ) /*0xAF*/ + + #define EVENTGROUP_TIMER ( EVENTGROUP_SYS + 8UL ) /*0xB0*/ + #define TIMER_CREATE ( EVENTGROUP_TIMER + 0UL ) /*0xB0*/ + #define TIMER_START ( EVENTGROUP_TIMER + 1UL ) /*0xB1*/ + #define TIMER_RST ( EVENTGROUP_TIMER + 2UL ) /*0xB2*/ + #define TIMER_STOP ( EVENTGROUP_TIMER + 3UL ) /*0xB3*/ + #define TIMER_CHANGE_PERIOD ( EVENTGROUP_TIMER + 4UL ) /*0xB4*/ + #define TIMER_DELETE_OBJ ( EVENTGROUP_TIMER + 5UL ) /*0xB5*/ + #define TIMER_START_FROM_ISR ( EVENTGROUP_TIMER + 6UL ) /*0xB6*/ + #define TIMER_RESET_FROM_ISR ( EVENTGROUP_TIMER + 7UL ) /*0xB7*/ + #define TIMER_STOP_FROM_ISR ( EVENTGROUP_TIMER + 8UL ) /*0xB8*/ + + #define TIMER_CREATE_TRCFAILED ( EVENTGROUP_TIMER + 9UL ) /*0xB9*/ + #define TIMER_START_TRCFAILED ( EVENTGROUP_TIMER + 10UL ) /*0xBA*/ + #define TIMER_RESET_TRCFAILED ( EVENTGROUP_TIMER + 11UL ) /*0xBB*/ + #define TIMER_STOP_TRCFAILED ( EVENTGROUP_TIMER + 12UL ) /*0xBC*/ + #define TIMER_CHANGE_PERIOD_TRCFAILED ( EVENTGROUP_TIMER + 13UL ) /*0xBD*/ + #define TIMER_DELETE_TRCFAILED ( EVENTGROUP_TIMER + 14UL ) /*0xBE*/ + #define TIMER_START_FROM_ISR_TRCFAILED ( EVENTGROUP_TIMER + 15UL ) /*0xBF*/ + #define TIMER_RESET_FROM_ISR_TRCFAILED ( EVENTGROUP_TIMER + 16UL ) /*0xC0*/ + #define TIMER_STOP_FROM_ISR_TRCFAILED ( EVENTGROUP_TIMER + 17UL ) /*0xC1*/ + + #define EVENTGROUP_EG ( EVENTGROUP_TIMER + 18UL ) /*0xC2*/ + #define EVENT_GROUP_CREATE ( EVENTGROUP_EG + 0UL ) /*0xC2*/ + #define EVENT_GROUP_CREATE_TRCFAILED ( EVENTGROUP_EG + 1UL ) /*0xC3*/ + #define EVENT_GROUP_SYNC_TRCBLOCK ( EVENTGROUP_EG + 2UL ) /*0xC4*/ + #define EVENT_GROUP_SYNC_END ( EVENTGROUP_EG + 3UL ) /*0xC5*/ + #define EVENT_GROUP_WAIT_BITS_TRCBLOCK ( EVENTGROUP_EG + 4UL ) /*0xC6*/ + #define EVENT_GROUP_WAIT_BITS_END ( EVENTGROUP_EG + 5UL ) /*0xC7*/ + #define EVENT_GROUP_CLEAR_BITS ( EVENTGROUP_EG + 6UL ) /*0xC8*/ + #define EVENT_GROUP_CLEAR_BITS_FROM_ISR ( EVENTGROUP_EG + 7UL ) /*0xC9*/ + #define EVENT_GROUP_SET_BITS ( EVENTGROUP_EG + 8UL ) /*0xCA*/ + #define EVENT_GROUP_DELETE_OBJ ( EVENTGROUP_EG + 9UL ) /*0xCB*/ + #define EVENT_GROUP_SYNC_END_TRCFAILED ( EVENTGROUP_EG + 10UL ) /*0xCC*/ + #define EVENT_GROUP_WAIT_BITS_END_TRCFAILED ( EVENTGROUP_EG + 11UL ) /*0xCD*/ + #define EVENT_GROUP_SET_BITS_FROM_ISR ( EVENTGROUP_EG + 12UL ) /*0xCE*/ + #define EVENT_GROUP_SET_BITS_FROM_ISR_TRCFAILED ( EVENTGROUP_EG + 13UL ) /*0xCF*/ + + #define TASK_INSTANCE_FINISHED_NEXT_KSE ( EVENTGROUP_EG + 14UL ) /*0xD0*/ + #define TASK_INSTANCE_FINISHED_DIRECT ( EVENTGROUP_EG + 15UL ) /*0xD1*/ + + #define TRACE_TASK_NOTIFY_GROUP ( EVENTGROUP_EG + 16UL ) /*0xD2*/ + #define TRACE_TASK_NOTIFY ( TRACE_TASK_NOTIFY_GROUP + 0UL ) /*0xD2*/ + #define TRACE_TASK_NOTIFY_TAKE ( TRACE_TASK_NOTIFY_GROUP + 1UL ) /*0xD3*/ + #define TRACE_TASK_NOTIFY_TAKE_TRCBLOCK ( TRACE_TASK_NOTIFY_GROUP + 2UL ) /*0xD4*/ + #define TRACE_TASK_NOTIFY_TAKE_TRCFAILED ( TRACE_TASK_NOTIFY_GROUP + 3UL ) /*0xD5*/ + #define TRACE_TASK_NOTIFY_WAIT ( TRACE_TASK_NOTIFY_GROUP + 4UL ) /*0xD6*/ + #define TRACE_TASK_NOTIFY_WAIT_TRCBLOCK ( TRACE_TASK_NOTIFY_GROUP + 5UL ) /*0xD7*/ + #define TRACE_TASK_NOTIFY_WAIT_TRCFAILED ( TRACE_TASK_NOTIFY_GROUP + 6UL ) /*0xD8*/ + #define TRACE_TASK_NOTIFY_FROM_ISR ( TRACE_TASK_NOTIFY_GROUP + 7UL ) /*0xD9*/ + #define TRACE_TASK_NOTIFY_GIVE_FROM_ISR ( TRACE_TASK_NOTIFY_GROUP + 8UL ) /*0xDA*/ + + #define TIMER_EXPIRED ( TRACE_TASK_NOTIFY_GROUP + 9UL ) /*0xDB*/ + +/* Events on queue peek (receive) */ + #define EVENTGROUP_PEEK_TRCBLOCK ( TRACE_TASK_NOTIFY_GROUP + 10UL ) /*0xDC*/ +/* peek block on queue: 0xDC */ +/* peek block on semaphore: 0xDD */ +/* peek block on mutex: 0xDE */ + +/* Events on queue peek (receive) */ + #define EVENTGROUP_PEEK_TRCFAILED ( EVENTGROUP_PEEK_TRCBLOCK + 3UL ) /*0xDF*/ +/* peek failed on queue: 0xDF */ +/* peek failed on semaphore: 0xE0 */ +/* peek failed on mutex: 0xE1 */ + + #define EVENTGROUP_STREAMBUFFER_DIV ( EVENTGROUP_PEEK_TRCFAILED + 3UL ) /*0xE2*/ + #define TRACE_STREAMBUFFER_RESET ( EVENTGROUP_STREAMBUFFER_DIV + 0 ) /*0xE2*/ + #define TRACE_MESSAGEBUFFER_RESET ( EVENTGROUP_STREAMBUFFER_DIV + 1UL ) /*0xE3*/ + #define TRACE_STREAMBUFFER_OBJCLOSE_NAME_TRCSUCCESS ( EVENTGROUP_STREAMBUFFER_DIV + 2UL ) /*0xE4*/ + #define TRACE_MESSAGEBUFFER_OBJCLOSE_NAME_TRCSUCCESS ( EVENTGROUP_STREAMBUFFER_DIV + 3UL ) /*0xE5*/ + #define TRACE_STREAMBUFFER_OBJCLOSE_PROP_TRCSUCCESS ( EVENTGROUP_STREAMBUFFER_DIV + 4UL ) /*0xE6*/ + #define TRACE_MESSAGEBUFFER_OBJCLOSE_PROP_TRCSUCCESS ( EVENTGROUP_STREAMBUFFER_DIV + 5UL ) /*0xE7*/ + + #define EVENTGROUP_MALLOC_FAILED ( EVENTGROUP_STREAMBUFFER_DIV + 6UL ) /*0xE8*/ + #define MEM_MALLOC_SIZE_TRCFAILED ( EVENTGROUP_MALLOC_FAILED + 0UL ) /*0xE8*/ + #define MEM_MALLOC_ADDR_TRCFAILED ( EVENTGROUP_MALLOC_FAILED + 1UL ) /*0xE9*/ + +/* The following are using previously "lost" event codes */ + #define TRACE_STREAMBUFFER_CREATE_OBJ_TRCSUCCESS ( EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 4UL ) /*0x1C*/ + #define TRACE_STREAMBUFFER_CREATE_OBJ_TRCFAILED ( EVENTGROUP_CREATE_OBJ_TRCFAILED + 4UL ) /*0x44*/ + #define TRACE_STREAMBUFFER_DELETE_OBJ_TRCSUCCESS ( EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 4UL ) /*0x84*/ + #define TRACE_STREAMBUFFER_SEND_TRCSUCCESS ( EVENTGROUP_SEND_TRCSUCCESS + 3UL ) /*0x23*/ + #define TRACE_STREAMBUFFER_SEND_TRCBLOCK ( EVENTGROUP_SEND_TRCBLOCK + 3UL ) /*0x73*/ + #define TRACE_STREAMBUFFER_SEND_TRCFAILED ( EVENTGROUP_SEND_TRCFAILED + 3UL ) /*0x4B*/ + #define TRACE_STREAMBUFFER_RECEIVE_TRCSUCCESS ( EVENTGROUP_RECEIVE_TRCSUCCESS + 3UL ) /*0x2B*/ + #define TRACE_STREAMBUFFER_RECEIVE_TRCBLOCK ( EVENTGROUP_RECEIVE_TRCBLOCK + 3UL ) /*0x6B*/ + #define TRACE_STREAMBUFFER_RECEIVE_TRCFAILED ( EVENTGROUP_RECEIVE_TRCFAILED + 3UL ) /*0x53*/ + #define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCSUCCESS ( EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 3UL ) /*0x33*/ + #define TRACE_STREAMBUFFER_SEND_FROM_ISR_TRCFAILED ( EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 3UL ) /*0x5B*/ + #define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS ( EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 3UL ) /*0x3B*/ + #define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_TRCFAILED ( EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 3UL ) /*0x63*/ + +/* The following are using previously "lost" event codes. These macros aren't even directly referenced, instead we do (equivalent STREAMBUFFER code) + 1. */ + #define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCSUCCESS ( EVENTGROUP_CREATE_OBJ_TRCSUCCESS + 5UL ) /*0x1D*/ + #define TRACE_MESSAGEBUFFER_CREATE_OBJ_TRCFAILED ( EVENTGROUP_CREATE_OBJ_TRCFAILED + 5UL ) /*0x45*/ + #define TRACE_MESSAGEBUFFER_DELETE_OBJ_TRCSUCCESS ( EVENTGROUP_DELETE_OBJ_TRCSUCCESS + 5UL ) /*0x85*/ + #define TRACE_MESSAGEBUFFER_SEND_TRCSUCCESS ( EVENTGROUP_SEND_TRCSUCCESS + 4UL ) /*0x24*/ + #define TRACE_MESSAGEBUFFER_SEND_TRCBLOCK ( EVENTGROUP_SEND_TRCBLOCK + 4UL ) /*0x74*/ + #define TRACE_MESSAGEBUFFER_SEND_TRCFAILED ( EVENTGROUP_SEND_TRCFAILED + 4UL ) /*0x4C*/ + #define TRACE_MESSAGEBUFFER_RECEIVE_TRCSUCCESS ( EVENTGROUP_RECEIVE_TRCSUCCESS + 4UL ) /*0x2C*/ + #define TRACE_MESSAGEBUFFER_RECEIVE_TRCBLOCK ( EVENTGROUP_RECEIVE_TRCBLOCK + 4UL ) /*0x6C*/ + #define TRACE_MESSAGEBUFFER_RECEIVE_TRCFAILED ( EVENTGROUP_RECEIVE_TRCFAILED + 4UL ) /*0x54*/ + #define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCSUCCESS ( EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 4UL ) /*0x34*/ + #define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_TRCFAILED ( EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 4UL ) /*0x5C*/ + #define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCSUCCESS ( EVENTGROUP_RECEIVE_FROM_ISR_TRCSUCCESS + 4UL ) /*0x3C*/ + #define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_TRCFAILED ( EVENTGROUP_RECEIVE_FROM_ISR_TRCFAILED + 4UL ) /*0x64*/ + + #define TRACE_QUEUE_SEND_TO_FRONT_TRCSUCCESS ( EVENTGROUP_SEND_TRCSUCCESS + 5UL ) /*0x25*/ + #define TRACE_QUEUE_SEND_TO_FRONT_TRCBLOCK ( EVENTGROUP_SEND_TRCBLOCK + 5UL ) /*0x75*/ + #define TRACE_QUEUE_SEND_TO_FRONT_TRCFAILED ( EVENTGROUP_SEND_TRCFAILED + 5UL ) /*0x4D*/ + #define TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCSUCCESS ( EVENTGROUP_SEND_FROM_ISR_TRCSUCCESS + 5UL ) /*0x35*/ + #define TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCFAILED ( EVENTGROUP_SEND_FROM_ISR_TRCFAILED + 5UL ) /*0x5D*/ + + #define TRACE_UNUSED_STACK ( EVENTGROUP_MALLOC_FAILED + 2UL ) /*0xEA*/ + +/* LAST EVENT (0xEA) */ + +/**************************** +* MACROS TO GET TRACE CLASS * +****************************/ + #define TRACE_GET_TRACE_CLASS_FROM_TASK_CLASS( kernelClass ) ( TRACE_CLASS_TASK ) + #define TRACE_GET_TRACE_CLASS_FROM_TASK_OBJECT( pxObject ) ( TRACE_CLASS_TASK ) + + #define TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS( kernelClass ) TraceQueueClassTable[ kernelClass ] + #define TRACE_GET_TRACE_CLASS_FROM_QUEUE_OBJECT( pxObject ) TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS( prvTraceGetQueueType( pxObject ) ) + + #define TRACE_GET_TRACE_CLASS_FROM_TIMER_CLASS( kernelClass ) ( TRACE_CLASS_TIMER ) + #define TRACE_GET_TRACE_CLASS_FROM_TIMER_OBJECT( pxObject ) ( TRACE_CLASS_TIMER ) + + #define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_CLASS( kernelClass ) ( TRACE_CLASS_EVENTGROUP ) + #define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_OBJECT( pxObject ) ( TRACE_CLASS_EVENTGROUP ) + +/* TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS can only be accessed with a parameter indicating if it is a MessageBuffer */ + #define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS( xIsMessageBuffer ) ( xIsMessageBuffer == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER ) + #define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_OBJECT( pxObject ) ( prvGetStreamBufferType( pxObject ) == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER ) + +/* Generic versions */ + #define TRACE_GET_CLASS_TRACE_CLASS( CLASS, kernelClass ) TRACE_GET_TRACE_CLASS_FROM_ ## CLASS ## _CLASS( kernelClass ) + #define TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ) TRACE_GET_TRACE_CLASS_FROM_ ## CLASS ## _OBJECT( pxObject ) + +/****************************** +* MACROS TO GET OBJECT NUMBER * +******************************/ + #define TRACE_GET_TASK_NUMBER( pxTCB ) ( traceHandle ) ( prvTraceGetTaskNumberLow16( pxTCB ) ) + #define TRACE_SET_TASK_NUMBER( pxTCB ) prvTraceSetTaskNumberLow16( pxTCB, prvTraceGetObjectHandle( TRACE_GET_OBJECT_TRACE_CLASS( TASK, pxTCB ) ) ); + + #define TRACE_GET_QUEUE_NUMBER( queue ) ( ( traceHandle ) prvTraceGetQueueNumberLow16( queue ) ) + #define TRACE_SET_QUEUE_NUMBER( queue ) prvTraceSetQueueNumberLow16( queue, ( uint16_t ) prvTraceGetObjectHandle( TRACE_GET_OBJECT_TRACE_CLASS( QUEUE, queue ) ) ); + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + #define TRACE_GET_TIMER_NUMBER( tmr ) ( ( traceHandle ) prvTraceGetTimerNumberLow16( tmr ) ) + #define TRACE_SET_TIMER_NUMBER( tmr ) prvTraceSetTimerNumberLow16( tmr, ( uint16_t ) prvTraceGetObjectHandle( TRACE_GET_OBJECT_TRACE_CLASS( TIMER, tmr ) ) ); + #else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + #define TRACE_GET_TIMER_NUMBER( tmr ) ( ( traceHandle ) ( ( Timer_t * ) tmr )->uxTimerNumber ) + #define TRACE_SET_TIMER_NUMBER( tmr ) ( ( Timer_t * ) tmr )->uxTimerNumber = prvTraceGetObjectHandle( TRACE_GET_OBJECT_TRACE_CLASS( TIMER, tmr ) ); + #endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + #define TRACE_GET_EVENTGROUP_NUMBER( eg ) ( ( traceHandle ) prvTraceGetEventGroupNumberLow16( eg ) ) + #define TRACE_SET_EVENTGROUP_NUMBER( eg ) prvTraceSetEventGroupNumberLow16( eg, ( uint16_t ) prvTraceGetObjectHandle( TRACE_GET_OBJECT_TRACE_CLASS( EVENTGROUP, eg ) ) ); + #else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + #define TRACE_GET_EVENTGROUP_NUMBER( eg ) ( ( traceHandle ) uxEventGroupGetNumber( eg ) ) + #define TRACE_SET_EVENTGROUP_NUMBER( eg ) ( ( EventGroup_t * ) eg )->uxEventGroupNumber = prvTraceGetObjectHandle( TRACE_GET_OBJECT_TRACE_CLASS( EVENTGROUP, eg ) ); + #endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + + + #define TRACE_GET_STREAMBUFFER_NUMBER( sb ) ( ( traceHandle ) prvTraceGetStreamBufferNumberLow16( sb ) ) + #define TRACE_SET_STREAMBUFFER_NUMBER( sb ) prvTraceSetStreamBufferNumberLow16( sb, ( uint16_t ) prvTraceGetObjectHandle( TRACE_GET_OBJECT_TRACE_CLASS( STREAMBUFFER, sb ) ) ); + +/* Generic versions */ + #define TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) TRACE_GET_ ## CLASS ## _NUMBER( pxObject ) + #define TRACE_SET_OBJECT_NUMBER( CLASS, pxObject ) TRACE_SET_ ## CLASS ## _NUMBER( pxObject ) + +/****************************** +* MACROS TO GET EVENT CODES * +******************************/ + #define TRACE_GET_TASK_CLASS_EVENT_CODE( SERVICE, RESULT, kernelClass ) ( uint8_t ) ( EVENTGROUP_ ## SERVICE ## _ ## RESULT + TRACE_GET_CLASS_TRACE_CLASS( TASK, kernelClass ) ) + #define TRACE_GET_QUEUE_CLASS_EVENT_CODE( SERVICE, RESULT, kernelClass ) ( uint8_t ) ( EVENTGROUP_ ## SERVICE ## _ ## RESULT + TRACE_GET_CLASS_TRACE_CLASS( QUEUE, kernelClass ) ) + #define TRACE_GET_TIMER_CLASS_EVENT_CODE( SERVICE, RESULT, kernelClass ) -- THIS IS NOT USED-- + #define TRACE_GET_EVENTGROUP_CLASS_EVENT_CODE( SERVICE, RESULT, kernelClass ) -- THIS IS NOT USED-- + #define TRACE_GET_STREAMBUFFER_CLASS_EVENT_CODE( SERVICE, RESULT, isMessageBuffer ) ( uint8_t ) ( TRACE_STREAMBUFFER_ ## SERVICE ## _ ## RESULT + ( uint8_t ) isMessageBuffer ) + + #define TRACE_GET_TASK_OBJECT_EVENT_CODE( SERVICE, RESULT, pxTCB ) ( uint8_t ) ( EVENTGROUP_ ## SERVICE ## _ ## RESULT + TRACE_CLASS_TASK ) + #define TRACE_GET_QUEUE_OBJECT_EVENT_CODE( SERVICE, RESULT, pxObject ) ( uint8_t ) ( EVENTGROUP_ ## SERVICE ## _ ## RESULT + TRACE_GET_OBJECT_TRACE_CLASS( QUEUE, pxObject ) ) + #define TRACE_GET_TIMER_OBJECT_EVENT_CODE( SERVICE, RESULT, UNUSED ) -- THIS IS NOT USED-- + #define TRACE_GET_EVENTGROUP_OBJECT_EVENT_CODE( SERVICE, RESULT, UNUSED ) -- THIS IS NOT USED-- + #define TRACE_GET_STREAMBUFFER_OBJECT_EVENT_CODE( SERVICE, RESULT, pxObject ) ( uint8_t ) ( TRACE_STREAMBUFFER_ ## SERVICE ## _ ## RESULT + prvGetStreamBufferType( pxObject ) ) + +/* Generic versions */ + #define TRACE_GET_CLASS_EVENT_CODE( SERVICE, RESULT, CLASS, kernelClass ) TRACE_GET_ ## CLASS ## _CLASS_EVENT_CODE( SERVICE, RESULT, kernelClass ) + #define TRACE_GET_OBJECT_EVENT_CODE( SERVICE, RESULT, CLASS, pxObject ) TRACE_GET_ ## CLASS ## _OBJECT_EVENT_CODE( SERVICE, RESULT, pxObject ) + +/****************************** +* SPECIAL MACROS FOR TASKS * +******************************/ + #define TRACE_GET_TASK_PRIORITY( pxTCB ) ( ( uint8_t ) pxTCB->uxPriority ) + #define TRACE_GET_TASK_NAME( pxTCB ) ( ( char * ) pxTCB->pcTaskName ) + +/*** The trace macros for snapshot mode **************************************/ + +/* A macro that will update the tick count when returning from tickless idle */ + #undef traceINCREASE_TICK_COUNT + #define traceINCREASE_TICK_COUNT( xCount ) + +/* Called for each task that becomes ready */ + #undef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ + trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE( pxTCB ); + +/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */ + #undef traceTASK_INCREMENT_TICK + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0 ) + + #define traceTASK_INCREMENT_TICK( xTickCount ) \ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || xPendedTicks == 0 ) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) { trcKERNEL_HOOKS_NEW_TIME( DIV_NEW_TIME, xTickCount + 1 ); } + + #elif ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X ) + + #define traceTASK_INCREMENT_TICK( xTickCount ) \ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0 ) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) { trcKERNEL_HOOKS_NEW_TIME( DIV_NEW_TIME, xTickCount + 1 ); } + + #else /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0 ) */ + + #define traceTASK_INCREMENT_TICK( xTickCount ) \ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0 ) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) { trcKERNEL_HOOKS_NEW_TIME( DIV_NEW_TIME, xTickCount + 1 ); } + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0 ) */ + + extern volatile uint32_t uiTraceSystemState; + +/* Called on each task-switch */ + #undef traceTASK_SWITCHED_IN + #define traceTASK_SWITCHED_IN() \ + uiTraceSystemState = TRC_STATE_IN_TASKSWITCH; \ + trcKERNEL_HOOKS_TASK_SWITCH( TRACE_GET_CURRENT_TASK() ); \ + uiTraceSystemState = TRC_STATE_IN_APPLICATION; + +/* Called on vTaskCreate */ + #undef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) \ + if( pxNewTCB != 0 ) \ + { \ + trcKERNEL_HOOKS_TASK_CREATE( TRACE_GET_OBJECT_EVENT_CODE( CREATE_OBJ, TRCSUCCESS, TASK, pxNewTCB ), TASK, pxNewTCB ); \ + prvAddTaskToStackMonitor( pxNewTCB ); \ + } + +/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */ + #undef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() \ + trcKERNEL_HOOKS_OBJECT_CREATE_FAILED( TRACE_GET_CLASS_EVENT_CODE( CREATE_OBJ, TRCFAILED, TASK, NOT_USED ), TRACE_GET_CLASS_TRACE_CLASS( TASK, NOT_USED ) ) + +/* Called on vTaskDelete */ + #undef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) \ + { TRACE_ALLOC_CRITICAL_SECTION(); \ + TRACE_ENTER_CRITICAL_SECTION(); \ + trcKERNEL_HOOKS_TASK_DELETE( TRACE_GET_OBJECT_EVENT_CODE( DELETE_OBJ, TRCSUCCESS, TASK, pxTaskToDelete ), TRACE_GET_OBJECT_EVENT_CODE( OBJCLOSE_NAME, TRCSUCCESS, TASK, pxTaskToDelete ), TRACE_GET_OBJECT_EVENT_CODE( OBJCLOSE_PROP, TRCSUCCESS, TASK, pxTaskToDelete ), pxTaskToDelete ); \ + prvRemoveTaskFromStackMonitor( pxTaskToDelete ); \ + TRACE_EXIT_CRITICAL_SECTION(); } + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + + #if defined( configUSE_TICKLESS_IDLE ) && ( configUSE_TICKLESS_IDLE != 0 ) + + #undef traceLOW_POWER_IDLE_BEGIN + #define traceLOW_POWER_IDLE_BEGIN() \ + { \ + extern uint32_t trace_disable_timestamp; \ + prvTraceStoreLowPower( 0 ); \ + trace_disable_timestamp = 1; \ + } + + #undef traceLOW_POWER_IDLE_END + #define traceLOW_POWER_IDLE_END() \ + { \ + extern uint32_t trace_disable_timestamp; \ + trace_disable_timestamp = 0; \ + prvTraceStoreLowPower( 1 ); \ + } + + #endif /* if defined( configUSE_TICKLESS_IDLE ) && ( configUSE_TICKLESS_IDLE != 0 ) */ + +/* Called on vTaskSuspend */ + #undef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) \ + trcKERNEL_HOOKS_TASK_SUSPEND( TASK_SUSPEND, pxTaskToSuspend ); + +/* Called from special case with timer only */ + #undef traceTASK_DELAY_SUSPEND + #define traceTASK_DELAY_SUSPEND( pxTaskToSuspend ) \ + trcKERNEL_HOOKS_TASK_SUSPEND( TASK_SUSPEND, pxTaskToSuspend ); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + +/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */ + #undef traceTASK_DELAY + #define traceTASK_DELAY() \ + trcKERNEL_HOOKS_TASK_DELAY( TASK_DELAY, pxCurrentTCB, xTicksToDelay ); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + +/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */ + #undef traceTASK_DELAY_UNTIL + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 ) + + #define traceTASK_DELAY_UNTIL( xTimeToWake ) \ + trcKERNEL_HOOKS_TASK_DELAY( TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake ); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + #else + + #define traceTASK_DELAY_UNTIL() \ + trcKERNEL_HOOKS_TASK_DELAY( TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake ); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + + #endif + +/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */ + #undef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) \ + trcKERNEL_HOOKS_OBJECT_CREATE( TRACE_GET_OBJECT_EVENT_CODE( CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue ), QUEUE, pxNewQueue ); + +/* Called in xQueueCreate, if the queue creation fails */ + #undef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( queueType ) \ + trcKERNEL_HOOKS_OBJECT_CREATE_FAILED( TRACE_GET_CLASS_EVENT_CODE( CREATE_OBJ, TRCFAILED, QUEUE, queueType ), TRACE_GET_CLASS_TRACE_CLASS( QUEUE, queueType ) ) + +/* Called on vQueueDelete */ + #undef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) \ + { TRACE_ALLOC_CRITICAL_SECTION(); \ + TRACE_ENTER_CRITICAL_SECTION(); \ + trcKERNEL_HOOKS_OBJECT_DELETE( TRACE_GET_OBJECT_EVENT_CODE( DELETE_OBJ, TRCSUCCESS, QUEUE, pxQueue ), TRACE_GET_OBJECT_EVENT_CODE( OBJCLOSE_NAME, TRCSUCCESS, QUEUE, pxQueue ), TRACE_GET_OBJECT_EVENT_CODE( OBJCLOSE_PROP, TRCSUCCESS, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + TRACE_EXIT_CRITICAL_SECTION(); } + +/* This macro is not necessary as of FreeRTOS v9.0.0 */ + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 ) + +/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */ + #undef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) \ + trcKERNEL_HOOKS_OBJECT_CREATE( TRACE_GET_OBJECT_EVENT_CODE( CREATE_OBJ, TRCSUCCESS, QUEUE, pxNewQueue ), QUEUE, pxNewQueue ); + +/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */ + #undef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY( TRACE_GET_CLASS_EVENT_CODE( CREATE_OBJ, TRCFAILED, QUEUE, queueQUEUE_TYPE_MUTEX ), 0 ); + + #endif /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 ) */ + +/* Called when the Mutex can not be given, since not holder */ + #undef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( SEND, TRCFAILED, QUEUE, pxMutex ), QUEUE, pxMutex ); + +/* Called when a message is sent to a queue */ /* CS IS NEW ! */ + #undef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( xCopyPosition == queueSEND_TO_BACK ? ( TRACE_GET_OBJECT_EVENT_CODE( SEND, TRCSUCCESS, QUEUE, pxQueue ) ) : TRACE_QUEUE_SEND_TO_FRONT_TRCSUCCESS, QUEUE, pxQueue ); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS( QUEUE, pxQueue ) == TRACE_CLASS_MUTEX ? ( uint8_t ) 0 : ( uint8_t ) ( pxQueue->uxMessagesWaiting + 1 ) ); + +/* Called when a message is sent to a queue set */ + #undef traceQUEUE_SET_SEND + #define traceQUEUE_SET_SEND( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( SEND, TRCSUCCESS, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( QUEUE, pxQueue, ( uint8_t ) ( pxQueue->uxMessagesWaiting + 1 ) ); + +/* Called when a message failed to be sent to a queue (timeout) */ + #undef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( xCopyPosition == queueSEND_TO_BACK ? ( TRACE_GET_OBJECT_EVENT_CODE( SEND, TRCFAILED, QUEUE, pxQueue ) ) : TRACE_QUEUE_SEND_TO_FRONT_TRCFAILED, QUEUE, pxQueue ); + +/* Called when the task is blocked due to a send operation on a full queue */ + #undef traceBLOCKING_ON_QUEUE_SEND + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( xCopyPosition == queueSEND_TO_BACK ? ( TRACE_GET_OBJECT_EVENT_CODE( SEND, TRCBLOCK, QUEUE, pxQueue ) ) : TRACE_QUEUE_SEND_TO_FRONT_TRCBLOCK, QUEUE, pxQueue ); + +/* Called when a message is received from a queue */ + #undef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) \ + if( isQueueReceiveHookActuallyPeek ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( PEEK, TRCSUCCESS, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE, TRCSUCCESS, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + } \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS( QUEUE, pxQueue ) == TRACE_CLASS_MUTEX ? ( uint8_t ) TRACE_GET_TASK_NUMBER( TRACE_GET_CURRENT_TASK() ) : ( uint8_t ) ( pxQueue->uxMessagesWaiting - 1 ) ); + +/* Called when a receive operation on a queue fails (timeout) */ + #undef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) \ + if( isQueueReceiveHookActuallyPeek ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( PEEK, TRCFAILED, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE, TRCFAILED, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + } + +/* Called when the task is blocked due to a receive operation on an empty queue */ + #undef traceBLOCKING_ON_QUEUE_RECEIVE + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \ + if( isQueueReceiveHookActuallyPeek ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( PEEK, TRCBLOCK, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE, TRCBLOCK, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + } \ + if( TRACE_GET_OBJECT_TRACE_CLASS( QUEUE, pxQueue ) != TRACE_CLASS_MUTEX ) \ + { \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \ + } + +/* Called on xQueuePeek */ + #undef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( PEEK, TRCSUCCESS, QUEUE, pxQueue ), QUEUE, pxQueue ); + +/* Called on xQueuePeek fail/timeout (added in FreeRTOS v9.0.2) */ + #undef traceQUEUE_PEEK_FAILED + #define traceQUEUE_PEEK_FAILED( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( PEEK, TRCFAILED, QUEUE, pxQueue ), QUEUE, pxQueue ); + +/* Called on xQueuePeek blocking (added in FreeRTOS v9.0.2) */ + #undef traceBLOCKING_ON_QUEUE_PEEK + #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( PEEK, TRCBLOCK, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + if( TRACE_GET_OBJECT_TRACE_CLASS( QUEUE, pxQueue ) != TRACE_CLASS_MUTEX ) \ + { \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \ + } + +/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */ + #undef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( xCopyPosition == queueSEND_TO_BACK ? ( TRACE_GET_OBJECT_EVENT_CODE( SEND_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue ) ) : TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCSUCCESS, QUEUE, pxQueue ); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( QUEUE, pxQueue, ( uint8_t ) ( pxQueue->uxMessagesWaiting + 1 ) ); + +/* Called when a message send from interrupt context fails (since the queue was full) */ + #undef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( xCopyPosition == queueSEND_TO_BACK ? ( TRACE_GET_OBJECT_EVENT_CODE( SEND_FROM_ISR, TRCFAILED, QUEUE, pxQueue ) ) : TRACE_QUEUE_SEND_TO_FRONT_FROM_ISR_TRCFAILED, QUEUE, pxQueue ); + +/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */ + #undef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE_FROM_ISR, TRCSUCCESS, QUEUE, pxQueue ), QUEUE, pxQueue ); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( QUEUE, pxQueue, ( uint8_t ) ( pxQueue->uxMessagesWaiting - 1 ) ); + +/* Called when a message receive from interrupt context fails (since the queue was empty) */ + #undef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE_FROM_ISR, TRCFAILED, QUEUE, pxQueue ), QUEUE, pxQueue ); + + #undef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD( object, name ) prvTraceSetObjectName( TRACE_GET_OBJECT_TRACE_CLASS( QUEUE, object ), TRACE_GET_OBJECT_NUMBER( QUEUE, object ), name ); + +/* Called in vTaskPrioritySet */ + #undef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \ + trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE( TASK_PRIORITY_SET, pxTask, uxNewPriority ); + +/* Called in vTaskPriorityInherit, which is called by Mutex operations */ + #undef traceTASK_PRIORITY_INHERIT + #define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \ + trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE( TASK_PRIORITY_INHERIT, pxTask, uxNewPriority ); + +/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */ + #undef traceTASK_PRIORITY_DISINHERIT + #define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \ + trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE( TASK_PRIORITY_DISINHERIT, pxTask, uxNewPriority ); + +/* Called in vTaskResume */ + #undef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) \ + trcKERNEL_HOOKS_TASK_RESUME( TASK_RESUME, pxTaskToResume ); + +/* Called in vTaskResumeFromISR */ + #undef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \ + trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR( TASK_RESUME_FROM_ISR, pxTaskToResume ); + + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + + #if ( TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1 ) + + extern void vTraceStoreMemMangEvent( uint32_t ecode, + uint32_t address, + int32_t size ); + +/* MALLOC and FREE are always stored, no matter if they happen inside filtered task */ + #undef traceMALLOC + #define traceMALLOC( pvAddress, uiSize ) \ + if( pvAddress != 0 ) \ + { \ + vTraceStoreMemMangEvent( MEM_MALLOC_SIZE, ( uint32_t ) pvAddress, ( int32_t ) uiSize ); \ + } \ + else \ + { \ + vTraceStoreMemMangEvent( MEM_MALLOC_SIZE_TRCFAILED, ( uint32_t ) pvAddress, ( int32_t ) uiSize ); \ + } + + #undef traceFREE + #define traceFREE( pvAddress, uiSize ) \ + vTraceStoreMemMangEvent( MEM_FREE_SIZE, ( uint32_t ) pvAddress, -( ( int32_t ) uiSize ) ); + + #endif /* if ( TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1 ) */ + + #if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 ) + +/* Called in timer.c - xTimerCreate */ + #undef traceTIMER_CREATE + #define traceTIMER_CREATE( tmr ) \ + trcKERNEL_HOOKS_OBJECT_CREATE( TIMER_CREATE, TIMER, tmr ); + + #undef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() \ + trcKERNEL_HOOKS_OBJECT_CREATE_FAILED( TIMER_CREATE_TRCFAILED, TRACE_GET_CLASS_TRACE_CLASS( TIMER, NOT_USED ) ) + +/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */ + #undef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( tmr, xCommandID, xOptionalValue, xReturn ) \ + if( xCommandID > tmrCOMMAND_START_DONT_TRACE ) \ + { \ + if( xCommandID == tmrCOMMAND_CHANGE_PERIOD ) \ + { \ + if( xReturn == pdPASS ) { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TIMER_CHANGE_PERIOD, TIMER, tmr, xOptionalValue ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TIMER_CHANGE_PERIOD_TRCFAILED, TIMER, tmr, xOptionalValue ); \ + } \ + } \ + else if( ( xCommandID == tmrCOMMAND_DELETE ) && ( xReturn == pdPASS ) ) \ + { \ + trcKERNEL_HOOKS_OBJECT_DELETE( TIMER_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS( TIMER, tmr ), EVENTGROUP_OBJCLOSE_PROP_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS( TIMER, tmr ), TIMER, tmr ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( EVENTGROUP_TIMER + ( uint32_t ) xCommandID + ( ( xReturn == pdPASS ) ? 0 : ( TIMER_CREATE_TRCFAILED - TIMER_CREATE ) ), TIMER, tmr, xOptionalValue ); \ + } \ + } + + #undef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( tmr ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TIMER_EXPIRED, TIMER, tmr ); + + #endif /* if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 ) */ + + #if ( TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1 ) + + #undef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL( func, arg1, arg2, ret ) \ + if( ret == pdPASS ) { \ + trcKERNEL_HOOKS_KERNEL_SERVICE( PEND_FUNC_CALL, TASK, xTimerGetTimerDaemonTaskHandle() ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE( PEND_FUNC_CALL_TRCFAILED, TASK, xTimerGetTimerDaemonTaskHandle() ); \ + } + + #undef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR( func, arg1, arg2, ret ) \ + if( !uiInEventGroupSetBitsFromISR ) \ + prvTraceStoreKernelCall( PEND_FUNC_CALL_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( xTimerGetTimerDaemonTaskHandle() ) ); \ + uiInEventGroupSetBitsFromISR = 0; + + #endif /* if ( TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1 ) */ + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) */ + + #if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 ) + + #undef traceEVENT_GROUP_CREATE + #define traceEVENT_GROUP_CREATE( eg ) \ + trcKERNEL_HOOKS_OBJECT_CREATE( EVENT_GROUP_CREATE, EVENTGROUP, eg ) + + #undef traceEVENT_GROUP_CREATE_FAILED + #define traceEVENT_GROUP_CREATE_FAILED() \ + trcKERNEL_HOOKS_OBJECT_CREATE_FAILED( EVENT_GROUP_CREATE_TRCFAILED, TRACE_GET_CLASS_TRACE_CLASS( EVENTGROUP, NOT_USED ) ) + + #undef traceEVENT_GROUP_DELETE + #define traceEVENT_GROUP_DELETE( eg ) \ + { TRACE_ALLOC_CRITICAL_SECTION(); \ + TRACE_ENTER_CRITICAL_SECTION(); \ + trcKERNEL_HOOKS_OBJECT_DELETE( EVENT_GROUP_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS( EVENTGROUP, eg ), EVENTGROUP_OBJCLOSE_NAME_TRCSUCCESS + TRACE_GET_OBJECT_TRACE_CLASS( EVENTGROUP, eg ), EVENTGROUP, eg ); \ + TRACE_EXIT_CRITICAL_SECTION(); } + + #undef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( eg, bitsToSet, bitsToWaitFor ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( EVENT_GROUP_SYNC_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor ); + + #undef traceEVENT_GROUP_SYNC_END + #define traceEVENT_GROUP_SYNC_END( eg, bitsToSet, bitsToWaitFor, wasTimeout ) \ + if( wasTimeout ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( EVENT_GROUP_SYNC_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( EVENT_GROUP_SYNC_END, EVENTGROUP, eg, bitsToWaitFor ); \ + } + + #undef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( eg, bitsToWaitFor ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( EVENT_GROUP_WAIT_BITS_TRCBLOCK, EVENTGROUP, eg, bitsToWaitFor ); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + + #undef traceEVENT_GROUP_WAIT_BITS_END + #define traceEVENT_GROUP_WAIT_BITS_END( eg, bitsToWaitFor, wasTimeout ) \ + if( wasTimeout ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( EVENT_GROUP_WAIT_BITS_END_TRCFAILED, EVENTGROUP, eg, bitsToWaitFor ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( EVENT_GROUP_WAIT_BITS_END, EVENTGROUP, eg, bitsToWaitFor ); \ + } + + #undef traceEVENT_GROUP_CLEAR_BITS + #define traceEVENT_GROUP_CLEAR_BITS( eg, bitsToClear ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( EVENT_GROUP_CLEAR_BITS, EVENTGROUP, eg, bitsToClear ); + + #undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( eg, bitsToClear ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR( EVENT_GROUP_CLEAR_BITS_FROM_ISR, EVENTGROUP, eg, bitsToClear ); + + #undef traceEVENT_GROUP_SET_BITS + #define traceEVENT_GROUP_SET_BITS( eg, bitsToSet ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( EVENT_GROUP_SET_BITS, EVENTGROUP, eg, bitsToSet ); + + #undef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( eg, bitsToSet ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR( EVENT_GROUP_SET_BITS_FROM_ISR, EVENTGROUP, eg, bitsToSet ); \ + uiInEventGroupSetBitsFromISR = 1; + + #endif /* if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 ) */ + + #undef traceTASK_NOTIFY_TAKE + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 ) + + #define traceTASK_NOTIFY_TAKE() \ + if( pxCurrentTCB->eNotifyState == eNotified ) { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait ); \ + } \ + else{ \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait ); \ + } + + #elif ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY_TAKE() \ + if( pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED ) { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait ); \ + } \ + else{ \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait ); } + + #else /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 ) */ + + #define traceTASK_NOTIFY_TAKE( index ) \ + if( pxCurrentTCB->ucNotifyState[ index ] == taskNOTIFICATION_RECEIVED ) { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait ); \ + } \ + else{ \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TRACE_TASK_NOTIFY_TAKE_TRCFAILED, TASK, pxCurrentTCB, xTicksToWait ); } + + #endif /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 ) */ + + #undef traceTASK_NOTIFY_TAKE_BLOCK + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY_TAKE_BLOCK() \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TRACE_TASK_NOTIFY_TAKE_TRCBLOCK, TASK, pxCurrentTCB, xTicksToWait ); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + + #else + + #define traceTASK_NOTIFY_TAKE_BLOCK( index ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( TRACE_TASK_NOTIFY_TAKE_TRCBLOCK, TASK, pxCurrentTCB, xTicksToWait ); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + + #endif + + #undef traceTASK_NOTIFY_WAIT + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 ) + + #define traceTASK_NOTIFY_WAIT() \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxCurrentTCB ) & CurrentFilterMask ) \ + { \ + if( pxCurrentTCB->eNotifyState == eNotified ) \ + prvTraceStoreKernelCallWithParam( TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxCurrentTCB ), xTicksToWait ); \ + else \ + prvTraceStoreKernelCallWithParam( TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxCurrentTCB ), xTicksToWait ); \ + } + + #elif ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY_WAIT() \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxCurrentTCB ) & CurrentFilterMask ) \ + { \ + if( pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED ) \ + prvTraceStoreKernelCallWithParam( TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxCurrentTCB ), xTicksToWait ); \ + else \ + prvTraceStoreKernelCallWithParam( TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxCurrentTCB ), xTicksToWait ); \ + } + + #else /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 ) */ + + #define traceTASK_NOTIFY_WAIT( index ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxCurrentTCB ) & CurrentFilterMask ) \ + { \ + if( pxCurrentTCB->ucNotifyState[ index ] == taskNOTIFICATION_RECEIVED ) \ + prvTraceStoreKernelCallWithParam( TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxCurrentTCB ), xTicksToWait ); \ + else \ + prvTraceStoreKernelCallWithParam( TRACE_TASK_NOTIFY_WAIT_TRCFAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxCurrentTCB ), xTicksToWait ); \ + } + + #endif /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 ) */ + + #undef traceTASK_NOTIFY_WAIT_BLOCK + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY_WAIT_BLOCK() \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxCurrentTCB ) & CurrentFilterMask ) \ + prvTraceStoreKernelCallWithParam( TRACE_TASK_NOTIFY_WAIT_TRCBLOCK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxCurrentTCB ), xTicksToWait ); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + + #else + + #define traceTASK_NOTIFY_WAIT_BLOCK( index ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxCurrentTCB ) & CurrentFilterMask ) \ + prvTraceStoreKernelCallWithParam( TRACE_TASK_NOTIFY_WAIT_TRCBLOCK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxCurrentTCB ), xTicksToWait ); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + + #endif /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 ) */ + + #undef traceTASK_NOTIFY + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY() \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, xTaskToNotify ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( xTaskToNotify ) ); + + #else + + #define traceTASK_NOTIFY( index ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, xTaskToNotify ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( xTaskToNotify ) ); + + #endif /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 ) */ + + #undef traceTASK_NOTIFY_FROM_ISR + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY_FROM_ISR() \ + if( TRACE_GET_OBJECT_FILTER( TASK, xTaskToNotify ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( xTaskToNotify ) ); + + #else + + #define traceTASK_NOTIFY_FROM_ISR( index ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, xTaskToNotify ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( xTaskToNotify ) ); + + #endif + + #undef traceTASK_NOTIFY_GIVE_FROM_ISR + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY_GIVE_FROM_ISR() \ + if( TRACE_GET_OBJECT_FILTER( TASK, xTaskToNotify ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( xTaskToNotify ) ); + + #else + + #define traceTASK_NOTIFY_GIVE_FROM_ISR( index ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, xTaskToNotify ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( xTaskToNotify ) ); + + #endif + + #if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 ) + + #undef traceSTREAM_BUFFER_CREATE + #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \ + trcKERNEL_HOOKS_OBJECT_CREATE( TRACE_GET_OBJECT_EVENT_CODE( CREATE_OBJ, TRCSUCCESS, STREAMBUFFER, pxStreamBuffer ), STREAMBUFFER, pxStreamBuffer ); + + #undef traceSTREAM_BUFFER_CREATE_FAILED + #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \ + trcKERNEL_HOOKS_OBJECT_CREATE_FAILED( TRACE_GET_CLASS_EVENT_CODE( CREATE_OBJ, TRCFAILED, STREAMBUFFER, xIsMessageBuffer ), TRACE_GET_CLASS_TRACE_CLASS( STREAMBUFFER, xIsMessageBuffer ) ) + + #undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED + #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \ + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) + + #undef traceSTREAM_BUFFER_DELETE + #define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \ + trcKERNEL_HOOKS_OBJECT_DELETE( TRACE_GET_OBJECT_EVENT_CODE( DELETE_OBJ, TRCSUCCESS, STREAMBUFFER, xStreamBuffer ), TRACE_GET_OBJECT_EVENT_CODE( OBJCLOSE_NAME, TRCSUCCESS, STREAMBUFFER, xStreamBuffer ), TRACE_GET_OBJECT_EVENT_CODE( OBJCLOSE_PROP, TRCSUCCESS, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); + + #undef traceSTREAM_BUFFER_RESET + #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( prvGetStreamBufferType( xStreamBuffer ) > 0 ? TRACE_MESSAGEBUFFER_RESET : TRACE_STREAMBUFFER_RESET, STREAMBUFFER, xStreamBuffer ); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( STREAMBUFFER, xStreamBuffer, 0 ); + + #undef traceSTREAM_BUFFER_SEND + #define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( SEND, TRCSUCCESS, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( STREAMBUFFER, xStreamBuffer, prvBytesInBuffer( xStreamBuffer ) ); + + #undef traceBLOCKING_ON_STREAM_BUFFER_SEND + #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( SEND, TRCBLOCK, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); + + #undef traceSTREAM_BUFFER_SEND_FAILED + #define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( SEND, TRCFAILED, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); + + #undef traceSTREAM_BUFFER_RECEIVE + #define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE, TRCSUCCESS, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( STREAMBUFFER, xStreamBuffer, prvBytesInBuffer( xStreamBuffer ) ); + + + #undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE + #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE, TRCBLOCK, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); + + #undef traceSTREAM_BUFFER_RECEIVE_FAILED + #define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE, TRCFAILED, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); + + #undef traceSTREAM_BUFFER_SEND_FROM_ISR + #define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \ + if( xReturn > ( size_t ) 0 ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( TRACE_GET_OBJECT_EVENT_CODE( SEND_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( STREAMBUFFER, xStreamBuffer, prvBytesInBuffer( xStreamBuffer ) ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( TRACE_GET_OBJECT_EVENT_CODE( SEND_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); \ + } + + #undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR + #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \ + if( xReceivedLength > ( size_t ) 0 ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE_FROM_ISR, TRCSUCCESS, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE( STREAMBUFFER, xStreamBuffer, prvBytesInBuffer( xStreamBuffer ) ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( TRACE_GET_OBJECT_EVENT_CODE( RECEIVE_FROM_ISR, TRCFAILED, STREAMBUFFER, xStreamBuffer ), STREAMBUFFER, xStreamBuffer ); \ + } + + #endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 ) */ + + #endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + + #endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) */ + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + TraceHeapHandle_t xTraceKernelPortGetSystemHeapHandle( void ); + +/*************************************************************************/ +/* KERNEL SPECIFIC OBJECT CONFIGURATION */ +/*************************************************************************/ + +/******************************************************************************* + * The event codes - should match the offline config file. + ******************************************************************************/ + +/*** Event codes for streaming - should match the Tracealyzer config file *****/ + #define PSF_EVENT_NULL_EVENT 0x00 + + #define PSF_EVENT_TRACE_START 0x01 + #define PSF_EVENT_TS_CONFIG 0x02 + #define PSF_EVENT_OBJ_NAME 0x03 + #define PSF_EVENT_TASK_PRIORITY 0x04 + #define PSF_EVENT_TASK_PRIO_INHERIT 0x05 + #define PSF_EVENT_TASK_PRIO_DISINHERIT 0x06 + #define PSF_EVENT_DEFINE_ISR 0x07 + + #define PSF_EVENT_TASK_CREATE 0x10 + #define PSF_EVENT_QUEUE_CREATE 0x11 + #define PSF_EVENT_SEMAPHORE_BINARY_CREATE 0x12 + #define PSF_EVENT_MUTEX_CREATE 0x13 + #define PSF_EVENT_TIMER_CREATE 0x14 + #define PSF_EVENT_EVENTGROUP_CREATE 0x15 + #define PSF_EVENT_SEMAPHORE_COUNTING_CREATE 0x16 + #define PSF_EVENT_MUTEX_RECURSIVE_CREATE 0x17 + #define PSF_EVENT_STREAMBUFFER_CREATE 0x18 + #define PSF_EVENT_MESSAGEBUFFER_CREATE 0x19 + + #define PSF_EVENT_TASK_DELETE 0x20 + #define PSF_EVENT_QUEUE_DELETE 0x21 + #define PSF_EVENT_SEMAPHORE_DELETE 0x22 + #define PSF_EVENT_MUTEX_DELETE 0x23 + #define PSF_EVENT_TIMER_DELETE 0x24 + #define PSF_EVENT_EVENTGROUP_DELETE 0x25 + #define PSF_EVENT_STREAMBUFFER_DELETE 0x28 + #define PSF_EVENT_MESSAGEBUFFER_DELETE 0x29 + + #define PSF_EVENT_TASK_READY 0x30 + #define PSF_EVENT_NEW_TIME 0x31 + #define PSF_EVENT_NEW_TIME_SCHEDULER_SUSPENDED 0x32 + #define PSF_EVENT_ISR_BEGIN 0x33 + #define PSF_EVENT_ISR_RESUME 0x34 + #define PSF_EVENT_TS_BEGIN 0x35 + #define PSF_EVENT_TS_RESUME 0x36 + #define PSF_EVENT_TASK_ACTIVATE 0x37 + + #define PSF_EVENT_MALLOC 0x38 + #define PSF_EVENT_FREE 0x39 + + #define PSF_EVENT_LOWPOWER_BEGIN 0x3A + #define PSF_EVENT_LOWPOWER_END 0x3B + + #define PSF_EVENT_IFE_NEXT 0x3C + #define PSF_EVENT_IFE_DIRECT 0x3D + + #define PSF_EVENT_TASK_CREATE_FAILED 0x40 + #define PSF_EVENT_QUEUE_CREATE_FAILED 0x41 + #define PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED 0x42 + #define PSF_EVENT_MUTEX_CREATE_FAILED 0x43 + #define PSF_EVENT_TIMER_CREATE_FAILED 0x44 + #define PSF_EVENT_EVENTGROUP_CREATE_FAILED 0x45 + #define PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED 0x46 + #define PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED 0x47 + #define PSF_EVENT_STREAMBUFFER_CREATE_FAILED 0x49 + #define PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED 0x4A + + #define PSF_EVENT_TIMER_DELETE_FAILED 0x48 + + #define PSF_EVENT_QUEUE_SEND 0x50 + #define PSF_EVENT_SEMAPHORE_GIVE 0x51 + #define PSF_EVENT_MUTEX_GIVE 0x52 + + #define PSF_EVENT_QUEUE_SEND_FAILED 0x53 + #define PSF_EVENT_SEMAPHORE_GIVE_FAILED 0x54 + #define PSF_EVENT_MUTEX_GIVE_FAILED 0x55 + + #define PSF_EVENT_QUEUE_SEND_BLOCK 0x56 + #define PSF_EVENT_SEMAPHORE_GIVE_BLOCK 0x57 + #define PSF_EVENT_MUTEX_GIVE_BLOCK 0x58 + + #define PSF_EVENT_QUEUE_SEND_FROMISR 0x59 + #define PSF_EVENT_SEMAPHORE_GIVE_FROMISR 0x5A + + #define PSF_EVENT_QUEUE_SEND_FROMISR_FAILED 0x5C + #define PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED 0x5D + + #define PSF_EVENT_QUEUE_RECEIVE 0x60 + #define PSF_EVENT_SEMAPHORE_TAKE 0x61 + #define PSF_EVENT_MUTEX_TAKE 0x62 + + #define PSF_EVENT_QUEUE_RECEIVE_FAILED 0x63 + #define PSF_EVENT_SEMAPHORE_TAKE_FAILED 0x64 + #define PSF_EVENT_MUTEX_TAKE_FAILED 0x65 + + #define PSF_EVENT_QUEUE_RECEIVE_BLOCK 0x66 + #define PSF_EVENT_SEMAPHORE_TAKE_BLOCK 0x67 + #define PSF_EVENT_MUTEX_TAKE_BLOCK 0x68 + + #define PSF_EVENT_QUEUE_RECEIVE_FROMISR 0x69 + #define PSF_EVENT_SEMAPHORE_TAKE_FROMISR 0x6A + + #define PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED 0x6C + #define PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED 0x6D + + #define PSF_EVENT_QUEUE_PEEK 0x70 + #define PSF_EVENT_SEMAPHORE_PEEK 0x71 + #define PSF_EVENT_MUTEX_PEEK 0x72 + + #define PSF_EVENT_QUEUE_PEEK_FAILED 0x73 + #define PSF_EVENT_SEMAPHORE_PEEK_FAILED 0x74 + #define PSF_EVENT_MUTEX_PEEK_FAILED 0x75 + + #define PSF_EVENT_QUEUE_PEEK_BLOCK 0x76 + #define PSF_EVENT_SEMAPHORE_PEEK_BLOCK 0x77 + #define PSF_EVENT_MUTEX_PEEK_BLOCK 0x78 + + #define PSF_EVENT_TASK_DELAY_UNTIL 0x79 + #define PSF_EVENT_TASK_DELAY 0x7A + #define PSF_EVENT_TASK_SUSPEND 0x7B + #define PSF_EVENT_TASK_RESUME 0x7C + #define PSF_EVENT_TASK_RESUME_FROMISR 0x7D + + #define PSF_EVENT_TIMER_PENDFUNCCALL 0x80 + #define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR 0x81 + #define PSF_EVENT_TIMER_PENDFUNCCALL_FAILED 0x82 + #define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED 0x83 + + #define PSF_EVENT_USER_EVENT 0x90 + + #define PSF_EVENT_TIMER_START 0xA0 + #define PSF_EVENT_TIMER_RESET 0xA1 + #define PSF_EVENT_TIMER_STOP 0xA2 + #define PSF_EVENT_TIMER_CHANGEPERIOD 0xA3 + #define PSF_EVENT_TIMER_START_FROMISR 0xA4 + #define PSF_EVENT_TIMER_RESET_FROMISR 0xA5 + #define PSF_EVENT_TIMER_STOP_FROMISR 0xA6 + #define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR 0xA7 + #define PSF_EVENT_TIMER_START_FAILED 0xA8 + #define PSF_EVENT_TIMER_RESET_FAILED 0xA9 + #define PSF_EVENT_TIMER_STOP_FAILED 0xAA + #define PSF_EVENT_TIMER_CHANGEPERIOD_FAILED 0xAB + #define PSF_EVENT_TIMER_START_FROMISR_FAILED 0xAC + #define PSF_EVENT_TIMER_RESET_FROMISR_FAILED 0xAD + #define PSF_EVENT_TIMER_STOP_FROMISR_FAILED 0xAE + #define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED 0xAF + + #define PSF_EVENT_EVENTGROUP_SYNC 0xB0 + #define PSF_EVENT_EVENTGROUP_WAITBITS 0xB1 + #define PSF_EVENT_EVENTGROUP_CLEARBITS 0xB2 + #define PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR 0xB3 + #define PSF_EVENT_EVENTGROUP_SETBITS 0xB4 + #define PSF_EVENT_EVENTGROUP_SETBITS_FROMISR 0xB5 + #define PSF_EVENT_EVENTGROUP_SYNC_BLOCK 0xB6 + #define PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK 0xB7 + #define PSF_EVENT_EVENTGROUP_SYNC_FAILED 0xB8 + #define PSF_EVENT_EVENTGROUP_WAITBITS_FAILED 0xB9 + + #define PSF_EVENT_QUEUE_SEND_FRONT 0xC0 + #define PSF_EVENT_QUEUE_SEND_FRONT_FAILED 0xC1 + #define PSF_EVENT_QUEUE_SEND_FRONT_BLOCK 0xC2 + #define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR 0xC3 + #define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED 0xC4 + #define PSF_EVENT_MUTEX_GIVE_RECURSIVE 0xC5 + #define PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED 0xC6 + #define PSF_EVENT_MUTEX_TAKE_RECURSIVE 0xC7 + #define PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED 0xC8 + + #define PSF_EVENT_TASK_NOTIFY 0xC9 + #define PSF_EVENT_TASK_NOTIFY_WAIT 0xCA + #define PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK 0xCB + #define PSF_EVENT_TASK_NOTIFY_WAIT_FAILED 0xCC + #define PSF_EVENT_TASK_NOTIFY_FROM_ISR 0xCD + + #define PSF_EVENT_TIMER_EXPIRED 0xD2 + + #define PSF_EVENT_STREAMBUFFER_SEND 0xD3 + #define PSF_EVENT_STREAMBUFFER_SEND_BLOCK 0xD4 + #define PSF_EVENT_STREAMBUFFER_SEND_FAILED 0xD5 + #define PSF_EVENT_STREAMBUFFER_RECEIVE 0xD6 + #define PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK 0xD7 + #define PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED 0xD8 + #define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR 0xD9 + #define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED 0xDA + #define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR 0xDB + #define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED 0xDC + #define PSF_EVENT_STREAMBUFFER_RESET 0xDD + + #define PSF_EVENT_MESSAGEBUFFER_SEND 0xDE + #define PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK 0xDF + #define PSF_EVENT_MESSAGEBUFFER_SEND_FAILED 0xE0 + #define PSF_EVENT_MESSAGEBUFFER_RECEIVE 0xE1 + #define PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK 0xE2 + #define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED 0xE3 + #define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR 0xE4 + #define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED 0xE5 + #define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR 0xE6 + #define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED 0xE7 + #define PSF_EVENT_MESSAGEBUFFER_RESET 0xE8 + + #define PSF_EVENT_MALLOC_FAILED 0xE9 + #define PSF_EVENT_FREE_FAILED 0xEA + + #define PSF_EVENT_UNUSED_STACK 0xEB + + #define PSF_EVENT_STATEMACHINE_STATE_CREATE 0xEC + #define PSF_EVENT_STATEMACHINE_CREATE 0xED + #define PSF_EVENT_STATEMACHINE_STATECHANGE 0xEE + + #define PSF_EVENT_INTERVAL_CREATE 0xEF + #define PSF_EVENT_INTERVAL_STATECHANGE 0xF0 + + #define PSF_EVENT_EXTENSION_CREATE 0xF1 + + #define PSF_EVENT_HEAP_CREATE 0xF2 + + #define PSF_EVENT_COUNTER_CREATE 0xF3 + #define PSF_EVENT_COUNTER_CHANGE 0xF4 + #define PSF_EVENT_COUNTER_LIMIT_EXCEEDED 0xF5 + + #define PSF_EVENT_MUTEX_TAKE_RECURSIVE_BLOCK 0xF6 + + #define TRC_EVENT_LAST_ID PSF_EVENT_COUNTER_LIMIT_EXCEEDED + +/*** The trace macros for streaming ******************************************/ + +/* A macro that will update the tick count when returning from tickless idle */ + #undef traceINCREASE_TICK_COUNT +/* Note: This can handle time adjustments of max 2^32 ticks, i.e., 35 seconds at 120 MHz. Thus, tick-less idle periods longer than 2^32 ticks will appear "compressed" on the time line.*/ + #define traceINCREASE_TICK_COUNT( xCount ) { uint32_t uiTraceTickCount; xTraceTimestampGetOsTickCount( &uiTraceTickCount ); xTraceTimestampSetOsTickCount( uiTraceTickCount + ( xCount ) ); } + + #if ( TRC_CFG_INCLUDE_OSTICK_EVENTS == 1 ) + + #define OS_TICK_EVENT( uxSchedulerSuspended, xTickCount ) if( ( uxSchedulerSuspended ) == ( unsigned portBASE_TYPE ) pdFALSE ) { prvTraceStoreEvent_Param( PSF_EVENT_NEW_TIME, ( uint32_t ) ( xTickCount ) ); } + + #else + + #define OS_TICK_EVENT( uxSchedulerSuspended, xTickCount ) + + #endif + +/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */ + #undef traceTASK_INCREMENT_TICK + #if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0 + + #define traceTASK_INCREMENT_TICK( xTickCount ) \ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || xPendedTicks == 0 ) { xTraceTimestampSetOsTickCount( ( xTickCount ) + 1 ); } \ + OS_TICK_EVENT( uxSchedulerSuspended, ( xTickCount ) + 1 ) + + #elif TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X + + #define traceTASK_INCREMENT_TICK( xTickCount ) \ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0 ) { xTraceTimestampSetOsTickCount( xTickCount + 1 ); } \ + OS_TICK_EVENT( uxSchedulerSuspended, xTickCount + 1 ) + + #else /* if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0 */ + + #define traceTASK_INCREMENT_TICK( xTickCount ) \ + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0 ) { xTraceTimestampSetOsTickCount( xTickCount + 1 ); } \ + OS_TICK_EVENT( uxSchedulerSuspended, xTickCount + 1 ) + + #endif /* if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_3_0 */ + +/* Called on each task-switch */ + #undef traceTASK_SWITCHED_IN + #define traceTASK_SWITCHED_IN() \ + xTraceTaskSwitch( pxCurrentTCB, pxCurrentTCB->uxPriority ) + +/* Called for each task that becomes ready */ + #undef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ + xTraceTaskReady( pxTCB ) + + #undef traceTASK_CREATE + #if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 + + #define traceTASK_CREATE( pxNewTCB ) \ + if( ( pxNewTCB ) != 0 ) \ + { \ + xTraceTaskRegisterWithoutHandle( ( void * ) ( pxNewTCB ), ( pxNewTCB )->pcTaskName, ( pxNewTCB )->uxPriority ); \ + } + + #else + + #define traceTASK_CREATE( pxNewTCB ) \ + if( pxNewTCB != 0 ) \ + { \ + xTraceTaskRegisterWithoutHandle( ( void * ) pxNewTCB, ( const char * ) pcName, ( uint32_t ) uxPriority ); \ + } + + #endif /* if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ + +/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */ + #undef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() \ + prvTraceStoreEvent_None( PSF_EVENT_TASK_CREATE_FAILED ) + +/* Called on vTaskDelete */ + #undef traceTASK_DELETE /* We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical. */ + #define traceTASK_DELETE( pxTaskToDelete ) \ + xTraceTaskUnregisterWithoutHandle( pxTaskToDelete, ( pxTaskToDelete )->uxPriority ) + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + + #if ( defined( configUSE_TICKLESS_IDLE ) && configUSE_TICKLESS_IDLE != 0 ) + + #undef traceLOW_POWER_IDLE_BEGIN + #define traceLOW_POWER_IDLE_BEGIN() \ + prvTraceStoreEvent_Param( PSF_EVENT_LOWPOWER_BEGIN, xExpectedIdleTime ) + + #undef traceLOW_POWER_IDLE_END + #define traceLOW_POWER_IDLE_END() \ + prvTraceStoreEvent_None( PSF_EVENT_LOWPOWER_END ) + + #endif + +/* Called on vTaskSuspend */ + #undef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) \ + prvTraceStoreEvent_Handle( PSF_EVENT_TASK_SUSPEND, pxTaskToSuspend ) + +/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */ + #undef traceTASK_DELAY + #define traceTASK_DELAY() \ + prvTraceStoreEvent_Param( PSF_EVENT_TASK_DELAY, xTicksToDelay ) + +/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */ + #undef traceTASK_DELAY_UNTIL + #if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 + + #define traceTASK_DELAY_UNTIL( xTimeToWake ) \ + prvTraceStoreEvent_Param( PSF_EVENT_TASK_DELAY_UNTIL, ( xTimeToWake ) ) + + #else + + #define traceTASK_DELAY_UNTIL() \ + prvTraceStoreEvent_Param( PSF_EVENT_TASK_DELAY_UNTIL, xTimeToWake ) + + #endif + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 ) + + #define traceQUEUE_CREATE_HELPER() \ + case queueQUEUE_TYPE_MUTEX: \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_MUTEX_CREATE, ( void * ) pxNewQueue, "", 0 ); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_MUTEX_RECURSIVE_CREATE, ( void * ) pxNewQueue, "", 0 ); \ + break; + + #else /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 ) */ + + #define traceQUEUE_CREATE_HELPER() + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 ) */ + +/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */ + #undef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) \ + switch( ( pxNewQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_QUEUE_CREATE, ( void * ) ( pxNewQueue ), "", ( uint32_t ) uxQueueLength ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_SEMAPHORE_BINARY_CREATE, ( void * ) ( pxNewQueue ), "", 0 ); \ + break; \ + traceQUEUE_CREATE_HELPER() \ + } + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 ) + + #define traceQUEUE_CREATE_FAILED_HELPER() \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_MUTEX_CREATE_FAILED, 0, 0 ); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED, 0, 0 ); \ + break; + + #else /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 ) */ + + #define traceQUEUE_CREATE_FAILED_HELPER() + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 ) */ + +/* Called in xQueueCreate, if the queue creation fails */ + #undef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( queueType ) \ + switch( queueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_QUEUE_CREATE_FAILED, 0, uxQueueLength ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED, 0, 0 ); \ + break; \ + traceQUEUE_CREATE_FAILED_HELPER() \ + } + + #undef traceQUEUE_DELETE /* We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical. */ + #define traceQUEUE_DELETE( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + xTraceObjectUnregisterWithoutHandle( PSF_EVENT_QUEUE_DELETE, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + xTraceObjectUnregisterWithoutHandle( PSF_EVENT_MUTEX_DELETE, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + xTraceObjectUnregisterWithoutHandle( PSF_EVENT_SEMAPHORE_DELETE, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + } + +/* Called in xQueueCreateCountingSemaphore, if the queue creation fails */ + #undef traceCREATE_COUNTING_SEMAPHORE + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + + #define traceCREATE_COUNTING_SEMAPHORE() \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_SEMAPHORE_COUNTING_CREATE, ( void * ) xHandle, "", ( uint32_t ) uxMaxCount ) + + #elif ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X ) + + #define traceCREATE_COUNTING_SEMAPHORE() \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_SEMAPHORE_COUNTING_CREATE, ( void * ) xHandle, "", uxInitialCount ) + + #elif ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4_X ) + + #define traceCREATE_COUNTING_SEMAPHORE() \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_SEMAPHORE_COUNTING_CREATE, ( void * ) xHandle, "", uxCountValue ) + + #else /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) */ + + #define traceCREATE_COUNTING_SEMAPHORE() \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_SEMAPHORE_COUNTING_CREATE, ( void * ) pxHandle, "", uxCountValue ) + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) */ + + #undef traceCREATE_COUNTING_SEMAPHORE_FAILED + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxMaxCount ) + + #elif ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_X ) + + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxInitialCount ) + + #elif ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4_X ) + + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue ) + + #else /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) */ + + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue ) + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) */ + + +/* This macro is not necessary as of FreeRTOS v9.0.0 */ + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 ) + +/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */ + #undef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) \ + switch( pxNewQueue->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_MUTEX: \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_MUTEX_CREATE, ( void * ) ( pxNewQueue ), "", 0 ); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_MUTEX_RECURSIVE_CREATE, ( void * ) ( pxNewQueue ), "", 0 ); \ + break; \ + } + +/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */ + #undef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_MUTEX_CREATE_FAILED, 0, 0 ) + #endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ + +/* Called when the Mutex can not be given, since not holder */ + #undef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \ + prvTraceStoreEvent_Handle( PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED, ( void * ) ( pxMutex ) ) + +/* Called when a message is sent to a queue */ /* CS IS NEW ! */ + #undef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParam( xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND : PSF_EVENT_QUEUE_SEND_FRONT, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting + 1 ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_GIVE, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting + 1 ); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent_Handle( PSF_EVENT_MUTEX_GIVE, ( void * ) ( pxQueue ) ); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_Handle( PSF_EVENT_MUTEX_GIVE_RECURSIVE, ( void * ) ( pxQueue ) ); \ + break; \ + } + + #undef traceQUEUE_SET_SEND + #define traceQUEUE_SET_SEND( pxQueue ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_QUEUE_SEND, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting + 1 ) + +/* Called when a message failed to be sent to a queue (timeout) */ + #undef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParam( xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FAILED, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_GIVE_FAILED, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_Handle( PSF_EVENT_MUTEX_GIVE_FAILED, ( void * ) ( pxQueue ) ); \ + break; \ + } + +/* Called when the task is blocked due to a send operation on a full queue */ + #undef traceBLOCKING_ON_QUEUE_SEND + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParam( xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_BLOCK : PSF_EVENT_QUEUE_SEND_FRONT_BLOCK, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_GIVE_BLOCK, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_Handle( PSF_EVENT_MUTEX_GIVE_BLOCK, ( void * ) ( pxQueue ) ); \ + break; \ + } + +/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */ + #undef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParam( xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting + 1 ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_GIVE_FROMISR, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting + 1 ); \ + break; \ + } + +/* Called when a message send from interrupt context fails (since the queue was full) */ + #undef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParam( xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + } + +/* Called when a message is received from a queue */ + #undef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + if( isQueueReceiveHookActuallyPeek ) \ + { \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_QUEUE_PEEK, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting - 1 ); \ + } \ + else \ + { \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_QUEUE_RECEIVE, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting - 1 ); \ + } \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + if( isQueueReceiveHookActuallyPeek ) \ + { \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_SEMAPHORE_PEEK, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting - 1 ); \ + } \ + else \ + { \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_SEMAPHORE_TAKE, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting - 1 ); \ + } \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent_HandleParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK : PSF_EVENT_MUTEX_TAKE, ( void * ) ( pxQueue ), xTicksToWait ); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_HandleParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK : PSF_EVENT_MUTEX_TAKE_RECURSIVE, ( void * ) ( pxQueue ), xTicksToWait ); \ + break; \ + } + +/* Called when a receive operation on a queue fails (timeout) */ + #undef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParamParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_FAILED : PSF_EVENT_QUEUE_RECEIVE_FAILED, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParamParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_FAILED : PSF_EVENT_SEMAPHORE_TAKE_FAILED, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent_HandleParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_FAILED : PSF_EVENT_MUTEX_TAKE_FAILED, ( void * ) ( pxQueue ), xTicksToWait ); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_HandleParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_FAILED : PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED, ( void * ) ( pxQueue ), xTicksToWait ); \ + break; \ + } + +/* Called when the task is blocked due to a receive operation on an empty queue */ + #undef traceBLOCKING_ON_QUEUE_RECEIVE + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParamParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_BLOCK : PSF_EVENT_QUEUE_RECEIVE_BLOCK, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParamParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_BLOCK : PSF_EVENT_SEMAPHORE_TAKE_BLOCK, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent_HandleParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_BLOCK : PSF_EVENT_MUTEX_TAKE_BLOCK, ( void * ) ( pxQueue ), xTicksToWait ); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_HandleParam( isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_BLOCK : PSF_EVENT_MUTEX_TAKE_RECURSIVE_BLOCK, ( void * ) ( pxQueue ), xTicksToWait ); \ + break; \ + } + + #if ( TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1 ) + +/* Called when a peek operation on a queue fails (timeout) */ + #undef traceQUEUE_PEEK_FAILED + #define traceQUEUE_PEEK_FAILED( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_QUEUE_PEEK_FAILED, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_SEMAPHORE_PEEK_FAILED, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_MUTEX_PEEK_FAILED, ( void * ) ( pxQueue ), xTicksToWait ); \ + break; \ + } + +/* Called when the task is blocked due to a peek operation on an empty queue */ + #undef traceBLOCKING_ON_QUEUE_PEEK + #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_QUEUE_PEEK_BLOCK, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_SEMAPHORE_PEEK_BLOCK, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_MUTEX_PEEK_BLOCK, ( void * ) ( pxQueue ), xTicksToWait ); \ + break; \ + } + + #endif /* if ( TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1 ) */ + +/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */ + #undef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_QUEUE_RECEIVE_FROMISR, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting - 1 ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_TAKE_FROMISR, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting - 1 ); \ + break; \ + } + +/* Called when a message receive from interrupt context fails (since the queue was empty) */ + #undef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED, ( void * ) ( pxQueue ), ( pxQueue )->uxMessagesWaiting ); \ + break; \ + } + +/* Called on xQueuePeek */ + #undef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) \ + switch( ( pxQueue )->ucQueueType ) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_QUEUE_PEEK, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent_HandleParamParam( PSF_EVENT_SEMAPHORE_PEEK, ( void * ) ( pxQueue ), xTicksToWait, ( pxQueue )->uxMessagesWaiting ); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_MUTEX_PEEK, ( void * ) ( pxQueue ), xTicksToWait ); \ + break; \ + } + +/* Called in vTaskPrioritySet */ + #undef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \ + xTraceTaskSetPriorityWithoutHandle( pxTask, uxNewPriority ) + +/* Called in vTaskPriorityInherit, which is called by Mutex operations */ + #undef traceTASK_PRIORITY_INHERIT + #define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_TASK_PRIO_INHERIT, ( void * ) ( pxTask ), uxNewPriority ) + +/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */ + #undef traceTASK_PRIORITY_DISINHERIT + #define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_TASK_PRIO_DISINHERIT, ( void * ) ( pxTask ), uxNewPriority ) + +/* Called in vTaskResume */ + #undef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) \ + prvTraceStoreEvent_Handle( PSF_EVENT_TASK_RESUME, ( void * ) ( pxTaskToResume ) ) + +/* Called in vTaskResumeFromISR */ + #undef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \ + prvTraceStoreEvent_Handle( PSF_EVENT_TASK_RESUME_FROMISR, ( void * ) ( pxTaskToResume ) ) + + #if ( TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1 ) + + #undef traceMALLOC + #define traceMALLOC( pvAddress, uiSize ) \ + if( xTraceIsRecorderEnabled() ) \ + { \ + xTraceHeapAlloc( xTraceKernelPortGetSystemHeapHandle(), pvAddress, uiSize ); \ + } + + #undef traceFREE + #define traceFREE( pvAddress, uiSize ) \ + if( xTraceIsRecorderEnabled() ) \ + { \ + xTraceHeapFree( xTraceKernelPortGetSystemHeapHandle(), pvAddress, uiSize ); \ + } + + #endif /* if ( TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1 ) */ + + #if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 ) + +/* Called in timer.c - xTimerCreate */ + #undef traceTIMER_CREATE + #define traceTIMER_CREATE( tmr ) \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_TIMER_CREATE, ( void * ) ( tmr ), ( const char * ) ( tmr )->pcTimerName, ( uint32_t ) ( tmr )->xTimerPeriodInTicks ) + + #undef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() \ + prvTraceStoreEvent_None( PSF_EVENT_TIMER_CREATE_FAILED ); + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + + #define traceTIMER_COMMAND_SEND_8_0_CASES( tmr ) \ + case tmrCOMMAND_RESET: \ + prvTraceStoreEvent_HandleParam( ( xReturn == pdPASS ) ? PSF_EVENT_TIMER_RESET : PSF_EVENT_TIMER_RESET_FAILED, ( void * ) ( tmr ), xOptionalValue ); \ + break; \ + case tmrCOMMAND_START_FROM_ISR: \ + prvTraceStoreEvent_HandleParam( ( xReturn == pdPASS ) ? PSF_EVENT_TIMER_START_FROMISR : PSF_EVENT_TIMER_START_FROMISR_FAILED, ( void * ) ( tmr ), xOptionalValue ); \ + break; \ + case tmrCOMMAND_RESET_FROM_ISR: \ + prvTraceStoreEvent_HandleParam( ( xReturn == pdPASS ) ? PSF_EVENT_TIMER_RESET_FROMISR : PSF_EVENT_TIMER_RESET_FROMISR_FAILED, ( void * ) ( tmr ), xOptionalValue ); \ + break; \ + case tmrCOMMAND_STOP_FROM_ISR: \ + prvTraceStoreEvent_HandleParam( ( xReturn == pdPASS ) ? PSF_EVENT_TIMER_STOP_FROMISR : PSF_EVENT_TIMER_STOP_FROMISR_FAILED, ( void * ) ( tmr ), xOptionalValue ); \ + break; \ + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: \ + prvTraceStoreEvent_HandleParam( ( xReturn == pdPASS ) ? PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR : PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED, ( void * ) ( tmr ), xOptionalValue ); \ + break; + #else /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) */ + + #define traceTIMER_COMMAND_SEND_8_0_CASES( tmr ) + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) */ + +/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */ + #undef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( tmr, xCommandID, xOptionalValue, xReturn ) \ + switch( xCommandID ) \ + { \ + case tmrCOMMAND_START: \ + prvTraceStoreEvent_Handle( ( ( xReturn ) == pdPASS ) ? PSF_EVENT_TIMER_START : PSF_EVENT_TIMER_START_FAILED, ( void * ) ( tmr ) ); \ + break; \ + case tmrCOMMAND_STOP: \ + prvTraceStoreEvent_Handle( ( ( xReturn ) == pdPASS ) ? PSF_EVENT_TIMER_STOP : PSF_EVENT_TIMER_STOP_FAILED, ( void * ) ( tmr ) ); \ + break; \ + case tmrCOMMAND_CHANGE_PERIOD: \ + prvTraceStoreEvent_HandleParam( ( ( xReturn ) == pdPASS ) ? PSF_EVENT_TIMER_CHANGEPERIOD : PSF_EVENT_TIMER_CHANGEPERIOD_FAILED, ( void * ) ( tmr ), xOptionalValue ); \ + break; \ + case tmrCOMMAND_DELETE: \ + xTraceObjectUnregisterWithoutHandle( ( ( xReturn ) == pdPASS ) ? PSF_EVENT_TIMER_DELETE : PSF_EVENT_TIMER_DELETE_FAILED, ( void * ) ( tmr ), 0 ); \ + break; \ + traceTIMER_COMMAND_SEND_8_0_CASES( tmr ) \ + } + + #undef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( tmr ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_TIMER_EXPIRED, ( void * ) ( tmr ), ( uint32_t ) ( ( tmr )->pxCallbackFunction ) ) + + #endif /* if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 ) */ + + + #if ( TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1 ) + + #undef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL( func, arg1, arg2, ret ) \ + prvTraceStoreEvent_Param( ( ( ret ) == pdPASS ) ? PSF_EVENT_TIMER_PENDFUNCCALL : PSF_EVENT_TIMER_PENDFUNCCALL_FAILED, ( uint32_t ) ( func ) ) + + #undef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR( func, arg1, arg2, ret ) \ + prvTraceStoreEvent_Param( ( ( ret ) == pdPASS ) ? PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR : PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED, ( uint32_t ) ( func ) ) + + #endif + + #if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 ) + + #undef traceEVENT_GROUP_CREATE + #define traceEVENT_GROUP_CREATE( eg ) \ + xTraceObjectRegisterWithoutHandle( PSF_EVENT_EVENTGROUP_CREATE, ( void * ) ( eg ), 0, ( uint32_t ) ( eg )->uxEventBits ) + + #undef traceEVENT_GROUP_DELETE + #define traceEVENT_GROUP_DELETE( eg ) \ + xTraceObjectUnregisterWithoutHandle( PSF_EVENT_EVENTGROUP_DELETE, ( void * ) ( eg ), ( uint32_t ) ( eg )->uxEventBits ) + + #undef traceEVENT_GROUP_CREATE_FAILED + #define traceEVENT_GROUP_CREATE_FAILED() \ + prvTraceStoreEvent_None( PSF_EVENT_EVENTGROUP_CREATE_FAILED ) + + #undef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( eg, bitsToSet, bitsToWaitFor ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_EVENTGROUP_SYNC_BLOCK, ( void * ) ( eg ), bitsToWaitFor ) + + #undef traceEVENT_GROUP_SYNC_END + #define traceEVENT_GROUP_SYNC_END( eg, bitsToSet, bitsToWaitFor, wasTimeout ) \ + prvTraceStoreEvent_HandleParam( ( ( wasTimeout ) != pdTRUE ) ? PSF_EVENT_EVENTGROUP_SYNC : PSF_EVENT_EVENTGROUP_SYNC_FAILED, ( void * ) ( eg ), bitsToWaitFor ) + + #undef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( eg, bitsToWaitFor ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK, ( void * ) ( eg ), bitsToWaitFor ) + + #undef traceEVENT_GROUP_WAIT_BITS_END + #define traceEVENT_GROUP_WAIT_BITS_END( eg, bitsToWaitFor, wasTimeout ) \ + prvTraceStoreEvent_HandleParam( ( ( wasTimeout ) != pdTRUE ) ? PSF_EVENT_EVENTGROUP_WAITBITS : PSF_EVENT_EVENTGROUP_WAITBITS_FAILED, ( void * ) ( eg ), bitsToWaitFor ) + + #undef traceEVENT_GROUP_CLEAR_BITS + #define traceEVENT_GROUP_CLEAR_BITS( eg, bitsToClear ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_EVENTGROUP_CLEARBITS, ( void * ) ( eg ), bitsToClear ) + + #undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( eg, bitsToClear ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR, ( void * ) ( eg ), bitsToClear ) + + #undef traceEVENT_GROUP_SET_BITS + #define traceEVENT_GROUP_SET_BITS( eg, bitsToSet ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_EVENTGROUP_SETBITS, ( void * ) ( eg ), bitsToSet ) + + #undef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( eg, bitsToSet ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_EVENTGROUP_SETBITS_FROMISR, ( void * ) ( eg ), bitsToSet ) + + #endif /* if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 ) */ + + #undef traceTASK_NOTIFY + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY( index ) \ + prvTraceStoreEvent_Handle( PSF_EVENT_TASK_NOTIFY, ( void * ) xTaskToNotify ) + + #else + + #define traceTASK_NOTIFY() \ + prvTraceStoreEvent_Handle( PSF_EVENT_TASK_NOTIFY, ( void * ) xTaskToNotify ) + + #endif + + #undef traceTASK_NOTIFY_FROM_ISR + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY_FROM_ISR( index ) \ + prvTraceStoreEvent_Handle( PSF_EVENT_TASK_NOTIFY_FROM_ISR, ( void * ) xTaskToNotify ) + + #else + + #define traceTASK_NOTIFY_FROM_ISR() \ + prvTraceStoreEvent_Handle( PSF_EVENT_TASK_NOTIFY_FROM_ISR, ( void * ) xTaskToNotify ) + + #endif + +/* NOTIFY and NOTIFY_GIVE will be handled identically */ + #undef traceTASK_NOTIFY_GIVE_FROM_ISR + #define traceTASK_NOTIFY_GIVE_FROM_ISR traceTASK_NOTIFY_FROM_ISR + + #undef traceTASK_NOTIFY_WAIT + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY_WAIT( index ) \ + prvTraceStoreEvent_HandleParam( pxCurrentTCB->ucNotifyState[ index ] == taskNOTIFICATION_RECEIVED ? PSF_EVENT_TASK_NOTIFY_WAIT : PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, ( void * ) pxCurrentTCB, xTicksToWait ) + + #elif ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 ) + + #define traceTASK_NOTIFY_WAIT() \ + prvTraceStoreEvent_HandleParam( pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED ? PSF_EVENT_TASK_NOTIFY_WAIT : PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, ( void * ) pxCurrentTCB, xTicksToWait ) + + #else + + #define traceTASK_NOTIFY_WAIT() \ + prvTraceStoreEvent_HandleParam( pxCurrentTCB->eNotifyState == eNotified ? PSF_EVENT_TASK_NOTIFY_WAIT : PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, ( void * ) pxCurrentTCB, xTicksToWait ) + + #endif /* if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 ) */ + +/* WAIT and TAKE will be handled identically */ + #undef traceTASK_NOTIFY_TAKE + #define traceTASK_NOTIFY_TAKE traceTASK_NOTIFY_WAIT + + #undef traceTASK_NOTIFY_WAIT_BLOCK + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_4_0 ) + + #define traceTASK_NOTIFY_WAIT_BLOCK( index ) \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, ( void * ) pxCurrentTCB, xTicksToWait ) + + #else + + #define traceTASK_NOTIFY_WAIT_BLOCK() \ + prvTraceStoreEvent_HandleParam( PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, ( void * ) pxCurrentTCB, xTicksToWait ) + + #endif + +/* WAIT_BLOCK and TAKE_BLOCK will be handled identically */ + #undef traceTASK_NOTIFY_TAKE_BLOCK + #define traceTASK_NOTIFY_TAKE_BLOCK traceTASK_NOTIFY_WAIT_BLOCK + + #undef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD( object, name ) \ + xTraceObjectSetNameWithoutHandle( object, ( const char * ) ( name ) ); + + #if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 ) + + #undef traceSTREAM_BUFFER_CREATE + #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \ + xTraceObjectRegisterWithoutHandle( ( xIsMessageBuffer ) == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE : PSF_EVENT_STREAMBUFFER_CREATE, ( void * ) ( pxStreamBuffer ), "", ( uint32_t ) xBufferSizeBytes ) + + #undef traceSTREAM_BUFFER_CREATE_FAILED + #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \ + prvTraceStoreEvent_HandleParam( ( xIsMessageBuffer ) == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED : PSF_EVENT_STREAMBUFFER_CREATE_FAILED, 0, xBufferSizeBytes ) + + #undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED + #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \ + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) + + #undef traceSTREAM_BUFFER_DELETE + #define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \ + xTraceObjectUnregisterWithoutHandle( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_DELETE : PSF_EVENT_STREAMBUFFER_DELETE, ( void * ) ( xStreamBuffer ), prvBytesInBuffer( xStreamBuffer ) ); + + #undef traceSTREAM_BUFFER_RESET + #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \ + prvTraceStoreEvent_HandleParam( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_RESET : PSF_EVENT_STREAMBUFFER_RESET, ( void * ) ( xStreamBuffer ), 0 ) + + #undef traceSTREAM_BUFFER_SEND + #define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \ + prvTraceStoreEvent_HandleParam( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND : PSF_EVENT_STREAMBUFFER_SEND, ( void * ) ( xStreamBuffer ), prvBytesInBuffer( xStreamBuffer ) ) + + #undef traceBLOCKING_ON_STREAM_BUFFER_SEND + #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \ + prvTraceStoreEvent_Handle( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK : PSF_EVENT_STREAMBUFFER_SEND_BLOCK, ( void * ) ( xStreamBuffer ) ) + + #undef traceSTREAM_BUFFER_SEND_FAILED + #define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \ + prvTraceStoreEvent_Handle( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FAILED, ( void * ) ( xStreamBuffer ) ) + + #undef traceSTREAM_BUFFER_RECEIVE + #define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \ + prvTraceStoreEvent_HandleParam( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE : PSF_EVENT_STREAMBUFFER_RECEIVE, ( void * ) ( xStreamBuffer ), prvBytesInBuffer( xStreamBuffer ) ) + + #undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE + #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \ + prvTraceStoreEvent_Handle( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK : PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK, ( void * ) ( xStreamBuffer ) ) + + #undef traceSTREAM_BUFFER_RECEIVE_FAILED + #define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \ + prvTraceStoreEvent_Handle( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED : PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED, ( void * ) ( xStreamBuffer ) ) + + #undef traceSTREAM_BUFFER_SEND_FROM_ISR + #define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \ + if( ( xReturn ) > ( size_t ) 0 ) \ + { \ + prvTraceStoreEvent_HandleParam( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR, ( void * ) ( xStreamBuffer ), prvBytesInBuffer( xStreamBuffer ) ); \ + } \ + else \ + { \ + prvTraceStoreEvent_Handle( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED, ( void * ) ( xStreamBuffer ) ); \ + } + + #undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR + #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \ + if( ( xReceivedLength ) > ( size_t ) 0 ) \ + { \ + prvTraceStoreEvent_HandleParam( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR, ( void * ) ( xStreamBuffer ), prvBytesInBuffer( xStreamBuffer ) ); \ + } \ + else \ + { \ + prvTraceStoreEvent_Handle( prvGetStreamBufferType( xStreamBuffer ) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED, ( void * ) ( xStreamBuffer ) ); \ + } + + #endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 ) */ + + #endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + + #endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) */ + + #else /* if ( defined( TRC_USE_TRACEALYZER_RECORDER ) ) && ( TRC_USE_TRACEALYZER_RECORDER == 1 ) */ + +/* When recorder is disabled */ + #define vTraceSetQueueName( object, name ) + #define vTraceSetSemaphoreName( object, name ) + #define vTraceSetMutexName( object, name ) + #define vTraceSetEventGroupName( object, name ) + #define vTraceSetStreamBufferName( object, name ) + #define vTraceSetMessageBufferName( object, name ) + + #endif /* if ( defined( TRC_USE_TRACEALYZER_RECORDER ) ) && ( TRC_USE_TRACEALYZER_RECORDER == 1 ) */ + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_KERNEL_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcMultiCoreEventBuffer.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcMultiCoreEventBuffer.h index 7b1bc349d..c80986044 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcMultiCoreEventBuffer.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcMultiCoreEventBuffer.h @@ -1,143 +1,149 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @internal Public trace multicore event buffer APIs. - */ - -#ifndef TRC_MULTI_CORE_EVENT_BUFFER_H -#define TRC_MULTI_CORE_EVENT_BUFFER_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_multi_core_event_buffer_apis Trace Multi-Core Event Buffer APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @brief Trace Multi-Core Event Buffer Structure - */ -typedef struct TraceMultiCoreEventBuffer -{ - TraceEventBuffer_t *xEventBuffer[TRC_CFG_CORE_COUNT]; /**< */ -} TraceMultiCoreEventBuffer_t; - -/** - * @internal Initialize multi-core event buffer. - * - * This routine initializes a multi-core trace event buffer and assignts it - * a memory area based on the supplied buffer. - * - * Trace event buffer options specifies the buffer behavior regarding - * old data, the alternatives are TRC_EVENT_BUFFER_OPTION_SKIP and - * TRC_EVENT_BUFFER_OPTION_OVERWRITE (mutal exclusive). - * - * @param[out] pxTraceMultiCoreEventBuffer Pointer to unitialized multi-core trace event buffer. - * @param[in] uiOptions Trace event buffer options. - * @param[in] puiBuffer Pointer to buffer that will be used by the multi-core trace event buffer. - * @param[in] uiSize Size of buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceMultiCoreEventBufferInitialize(TraceMultiCoreEventBuffer_t* pxTraceMultiCoreEventBuffer, uint32_t uiOptions, - uint8_t* puiBuffer, uint32_t uiSize); - - - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -/** - * @brief Pushes data into multi-core trace event buffer. - * - * This routine attempts to push data into the multi-core trace event buffer. Selection - * of which core the data is pushed for is managed automatically through the - * TRC_CFG_GET_CURRENT_CORE macro which is defined on an RTOS basis. - * - * @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer. - * @param[in] pvData Pointer to data should be pushed into multi-core event buffer. - * @param[in] uiSize Size of data that should be pushed into multi-core trace event buffer. - * @param[out] piBytesWritten Pointer to variable which the routine will write the number - * of bytes that was pushed into the multi-core trace event buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceMultiCoreEventBufferPush(TraceMultiCoreEventBuffer_t* pxTraceMultiCoreEventBuffer, void* pvData, uint32_t uiSize, int32_t* piBytesWritten); - -#else - -/** - * @brief Pushes data into multi-core trace event buffer. - * - * This routine attempts to push data into the multi-core trace event buffer. Selection - * of which core the data is pushed for is managed automatically through the - * TRC_CFG_GET_CURRENT_CORE macro which is defined on an RTOS basis. - * - * @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer. - * @param[in] pvData Pointer to data should be pushed into multi-core event buffer. - * @param[in] uiSize Size of data that should be pushed into multi-core trace event buffer. - * @param[out] piBytesWritten Pointer to variable which the routine will write the number - * of bytes that was pushed into the multi-core trace event buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceMultiCoreEventBufferPush(pxTraceMultiCoreEventBuffer, pvData, uiSize, piBytesWritten) xTraceEventBufferPush((pxTraceMultiCoreEventBuffer)->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], pvData, uiSize, piBytesWritten) - -#endif - -/** - * @brief Transfer multi-core trace event buffer data through streamport. - * - * This routine will attempt to transfer all existing data in the multi-core trace event - * buffer through the streamport. New data pushed to the trace event buffer - * during the execution of this routine will not be transfered to - * - * @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer. - * @param[out] piBytesWritten Pointer to variable which the routine will write the number - * of bytes that was pushed into the multi-core trace event buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceMultiCoreEventBufferTransfer(TraceMultiCoreEventBuffer_t* pxTraceMultiCoreEventBuffer, int32_t* piBytesWritten); - -/** - * @brief Clears all data from event buffer. - * - * @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core trace event buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceMultiCoreEventBufferClear(TraceMultiCoreEventBuffer_t* pxTraceMultiCoreEventBuffer); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_MULTI_CORE_EVENT_BUFFER_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @internal Public trace multicore event buffer APIs. + */ + +#ifndef TRC_MULTI_CORE_EVENT_BUFFER_H + #define TRC_MULTI_CORE_EVENT_BUFFER_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_multi_core_event_buffer_apis Trace Multi-Core Event Buffer APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @brief Trace Multi-Core Event Buffer Structure + */ + typedef struct TraceMultiCoreEventBuffer + { + TraceEventBuffer_t * xEventBuffer[ TRC_CFG_CORE_COUNT ]; /**< */ + } TraceMultiCoreEventBuffer_t; + +/** + * @internal Initialize multi-core event buffer. + * + * This routine initializes a multi-core trace event buffer and assigns it + * a memory area based on the supplied buffer. + * + * Trace event buffer options specifies the buffer behavior regarding + * old data, the alternatives are TRC_EVENT_BUFFER_OPTION_SKIP and + * TRC_EVENT_BUFFER_OPTION_OVERWRITE (mutual exclusive). + * + * @param[out] pxTraceMultiCoreEventBuffer Pointer to uninitialized multi-core trace event buffer. + * @param[in] uiOptions Trace event buffer options. + * @param[in] puiBuffer Pointer to buffer that will be used by the multi-core trace event buffer. + * @param[in] uiSize Size of buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceMultiCoreEventBufferInitialize( TraceMultiCoreEventBuffer_t * pxTraceMultiCoreEventBuffer, + uint32_t uiOptions, + uint8_t * puiBuffer, + uint32_t uiSize ); + + + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + +/** + * @brief Pushes data into multi-core trace event buffer. + * + * This routine attempts to push data into the multi-core trace event buffer. Selection + * of which core the data is pushed for is managed automatically through the + * TRC_CFG_GET_CURRENT_CORE macro which is defined on an RTOS basis. + * + * @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer. + * @param[in] pvData Pointer to data should be pushed into multi-core event buffer. + * @param[in] uiSize Size of data that should be pushed into multi-core trace event buffer. + * @param[out] piBytesWritten Pointer to variable which the routine will write the number + * of bytes that was pushed into the multi-core trace event buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceMultiCoreEventBufferPush( TraceMultiCoreEventBuffer_t * pxTraceMultiCoreEventBuffer, + void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ); + + #else + +/** + * @brief Pushes data into multi-core trace event buffer. + * + * This routine attempts to push data into the multi-core trace event buffer. Selection + * of which core the data is pushed for is managed automatically through the + * TRC_CFG_GET_CURRENT_CORE macro which is defined on an RTOS basis. + * + * @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer. + * @param[in] pvData Pointer to data should be pushed into multi-core event buffer. + * @param[in] uiSize Size of data that should be pushed into multi-core trace event buffer. + * @param[out] piBytesWritten Pointer to variable which the routine will write the number + * of bytes that was pushed into the multi-core trace event buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceMultiCoreEventBufferPush( pxTraceMultiCoreEventBuffer, pvData, uiSize, piBytesWritten ) xTraceEventBufferPush( ( pxTraceMultiCoreEventBuffer )->xEventBuffer[ TRC_CFG_GET_CURRENT_CORE() ], pvData, uiSize, piBytesWritten ) + + #endif /* if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) */ + +/** + * @brief Transfer multi-core trace event buffer data through streamport. + * + * This routine will attempt to transfer all existing data in the multi-core trace event + * buffer through the streamport. New data pushed to the trace event buffer + * during the execution of this routine will not be transferred to + * + * @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core event buffer. + * @param[out] piBytesWritten Pointer to variable which the routine will write the number + * of bytes that was pushed into the multi-core trace event buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceMultiCoreEventBufferTransfer( TraceMultiCoreEventBuffer_t * pxTraceMultiCoreEventBuffer, + int32_t * piBytesWritten ); + +/** + * @brief Clears all data from event buffer. + * + * @param[in] pxTraceMultiCoreEventBuffer Pointer to initialized multi-core trace event buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceMultiCoreEventBufferClear( TraceMultiCoreEventBuffer_t * pxTraceMultiCoreEventBuffer ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_MULTI_CORE_EVENT_BUFFER_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcObject.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcObject.h index 4e3a673f1..793697916 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcObject.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcObject.h @@ -1,202 +1,224 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace object APIs. - */ - -#ifndef TRC_OBJECT_H -#define TRC_OBJECT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_object_apis Trace Object APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @brief Registers trace object. - * - * @param[in] uiEventCode Event code. - * @param[in] pvObject Object. - * @param[in] szName Name. - * @param[in] uxStateCount State count. - * @param[in] uxStates States. - * @param[in] uxOptions Options. - * @param[out] pxObjectHandle Pointer to uninitialized trace object. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceObjectRegisterInternal(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxStateCount, TraceUnsignedBaseType_t uxStates[], TraceUnsignedBaseType_t uxOptions, TraceObjectHandle_t* pxObjectHandle); - -/** - * @brief Registers trace object. - * - * @param[in] uiEventCode Event code. - * @param[in] pvObject Object. - * @param[in] szName Name. - * @param[in] uxState State. - * @param[out] pxObjectHandle Pointer to uninitialized trace object. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceObjectRegister(uint32_t uiEventCode, void *pvObject, const char* szName, TraceUnsignedBaseType_t uxState, TraceObjectHandle_t *pxObjectHandle); - -/** - * @brief Unregisters trace object. - * - * @param[in] xObjectHandle Pointer to initialized trace object. - * @param[in] uiEventCode Event code. - * @param[in] uxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceObjectUnregister(TraceObjectHandle_t xObjectHandle, uint32_t uiEventCode, TraceUnsignedBaseType_t uxState); - -/** - * @brief Sets trace object name. - * - * @param[in] xObjectHandle Pointer to initialized trace object. - * @param[in] szName Name. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceObjectSetName(TraceObjectHandle_t xObjectHandle, const char *szName); - -/** - * @brief Sets trace object state. - * - * @param[in] xObjectHandle Pointer to initialized trace object. - * @param[in] uxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceObjectSetState(xObjectHandle, uxState) xTraceObjectSetSpecificState(xObjectHandle, 0, uxState) - -/** - * @brief Sets trace object specific state state. - * - * @param[in] xObjectHandle Pointer to initialized trace object. - * @param[in] uiIndex State Index. - * @param[in] uxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceObjectSetSpecificState(xObjectHandle, uiIndex, uxState) xTraceEntrySetState((TraceEntryHandle_t)(xObjectHandle), uiIndex, uxState) - -/** - * @brief Sets trace object options. - * - * @param[in] xObjectHandle Pointer to initialized trace object. - * @param[in] uiOptions Options. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceObjectSetOptions(xObjectHandle, uiOptions) xTraceEntrySetOptions((TraceEntryHandle_t)(xObjectHandle), uiOptions) - -/** - * @brief Registers trace object without trace object handle. - * - * @param[in] uiEventCode Event code. - * @param[in] pvObject Object. - * @param[in] szName Name. - * @param[in] uxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceObjectRegisterWithoutHandle(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxState); - -/** - * @brief Unregisters trace object without trace object handle. - * - * @param[in] uiEventCode Event code. - * @param[in] pvObject Object. - * @param[in] uxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceObjectUnregisterWithoutHandle(uint32_t uiEventCode, void* pvObject, TraceUnsignedBaseType_t uxState); - -/** - * @brief Set trace object name without trace object handle. - * - * @param[in] pvObject Object. - * @param[in] szName Name. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceObjectSetNameWithoutHandle(void* pvObject, const char* szName); - -/** - * @brief Set trace object state without trace object handle. - * - * @param[in] pvObject Object. - * @param[in] uxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceObjectSetStateWithoutHandle(pvObject, uxState) xTraceObjectSetSpecificStateWithoutHandle(pvObject, 0, uxState) - -/** - * @brief Sets trace object specific state without trace object - * handle. - * - * @param[in] pvObject Object. - * @param[in] uiIndex State index. - * @param[in] uxState State. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceObjectSetSpecificStateWithoutHandle(void* pvObject, uint32_t uiIndex, TraceUnsignedBaseType_t uxState); - -/** - * @brief Sets trace object options without trace object handle. - * - * @param[in] pvObject Object. - * @param[in] uiOptions Options. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceObjectSetOptionsWithoutHandle(void* pvObject, uint32_t uiOptions); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_OBJECT_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace object APIs. + */ + +#ifndef TRC_OBJECT_H + #define TRC_OBJECT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_object_apis Trace Object APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @brief Registers trace object. + * + * @param[in] uiEventCode Event code. + * @param[in] pvObject Object. + * @param[in] szName Name. + * @param[in] uxStateCount State count. + * @param[in] uxStates States. + * @param[in] uxOptions Options. + * @param[out] pxObjectHandle Pointer to uninitialized trace object. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceObjectRegisterInternal( uint32_t uiEventCode, + void * pvObject, + const char * szName, + TraceUnsignedBaseType_t uxStateCount, + TraceUnsignedBaseType_t uxStates[], + TraceUnsignedBaseType_t uxOptions, + TraceObjectHandle_t * pxObjectHandle ); + +/** + * @brief Registers trace object. + * + * @param[in] uiEventCode Event code. + * @param[in] pvObject Object. + * @param[in] szName Name. + * @param[in] uxState State. + * @param[out] pxObjectHandle Pointer to uninitialized trace object. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceObjectRegister( uint32_t uiEventCode, + void * pvObject, + const char * szName, + TraceUnsignedBaseType_t uxState, + TraceObjectHandle_t * pxObjectHandle ); + +/** + * @brief Unregisters trace object. + * + * @param[in] xObjectHandle Pointer to initialized trace object. + * @param[in] uiEventCode Event code. + * @param[in] uxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceObjectUnregister( TraceObjectHandle_t xObjectHandle, + uint32_t uiEventCode, + TraceUnsignedBaseType_t uxState ); + +/** + * @brief Sets trace object name. + * + * @param[in] xObjectHandle Pointer to initialized trace object. + * @param[in] szName Name. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceObjectSetName( TraceObjectHandle_t xObjectHandle, + const char * szName ); + +/** + * @brief Sets trace object state. + * + * @param[in] xObjectHandle Pointer to initialized trace object. + * @param[in] uxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceObjectSetState( xObjectHandle, uxState ) xTraceObjectSetSpecificState( xObjectHandle, 0, uxState ) + +/** + * @brief Sets trace object specific state state. + * + * @param[in] xObjectHandle Pointer to initialized trace object. + * @param[in] uiIndex State Index. + * @param[in] uxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceObjectSetSpecificState( xObjectHandle, uiIndex, uxState ) xTraceEntrySetState( ( TraceEntryHandle_t ) ( xObjectHandle ), uiIndex, uxState ) + +/** + * @brief Sets trace object options. + * + * @param[in] xObjectHandle Pointer to initialized trace object. + * @param[in] uiOptions Options. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceObjectSetOptions( xObjectHandle, uiOptions ) xTraceEntrySetOptions( ( TraceEntryHandle_t ) ( xObjectHandle ), uiOptions ) + +/** + * @brief Registers trace object without trace object handle. + * + * @param[in] uiEventCode Event code. + * @param[in] pvObject Object. + * @param[in] szName Name. + * @param[in] uxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceObjectRegisterWithoutHandle( uint32_t uiEventCode, + void * pvObject, + const char * szName, + TraceUnsignedBaseType_t uxState ); + +/** + * @brief Unregisters trace object without trace object handle. + * + * @param[in] uiEventCode Event code. + * @param[in] pvObject Object. + * @param[in] uxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceObjectUnregisterWithoutHandle( uint32_t uiEventCode, + void * pvObject, + TraceUnsignedBaseType_t uxState ); + +/** + * @brief Set trace object name without trace object handle. + * + * @param[in] pvObject Object. + * @param[in] szName Name. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceObjectSetNameWithoutHandle( void * pvObject, + const char * szName ); + +/** + * @brief Set trace object state without trace object handle. + * + * @param[in] pvObject Object. + * @param[in] uxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceObjectSetStateWithoutHandle( pvObject, uxState ) xTraceObjectSetSpecificStateWithoutHandle( pvObject, 0, uxState ) + +/** + * @brief Sets trace object specific state without trace object + * handle. + * + * @param[in] pvObject Object. + * @param[in] uiIndex State index. + * @param[in] uxState State. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceObjectSetSpecificStateWithoutHandle( void * pvObject, + uint32_t uiIndex, + TraceUnsignedBaseType_t uxState ); + +/** + * @brief Sets trace object options without trace object handle. + * + * @param[in] pvObject Object. + * @param[in] uiOptions Options. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceObjectSetOptionsWithoutHandle( void * pvObject, + uint32_t uiOptions ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_OBJECT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPrint.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPrint.h index 67574decb..2047417d2 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPrint.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcPrint.h @@ -1,207 +1,213 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace print APIs. - */ - -#ifndef TRC_PRINT_H -#define TRC_PRINT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_print_apis Trace Print APIs - * @ingroup trace_recorder_apis - * @{ - */ - -#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) - -/** @internal */ -#define TRC_PRINT_BUFFER_SIZE (sizeof(TraceStringHandle_t) + sizeof(TraceStringHandle_t)) - -/** - * @internal Trace Print Buffer Structure - */ -typedef struct TracePrintBuffer -{ - uint32_t buffer[(TRC_PRINT_BUFFER_SIZE) / sizeof(uint32_t)]; -} TracePrintBuffer_t; - -/** - * @internal Initialize print trace system. - * - * @param[in] pxBuffer Pointer to memory that will be used by the print - * trace system. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTracePrintInitialize(TracePrintBuffer_t* pxBuffer); - -/** - * @brief Generate "User Events" with unformatted text. - * - * User Events can be used for very efficient application logging, and are shown - * as yellow labels in the main trace view. - * - * You may group User Events into User Event Channels. The yellow User Event - * labels shows the logged string, preceded by the channel name within - * brackets. For example: - * - * "[MyChannel] Hello World!" - * - * The User Event Channels are shown in the View Filter, which makes it easy to - * select what User Events you wish to display. User Event Channels are created - * using xTraceStringRegister(). - * - * Example: - * - * TraceStringHandle_t xChannel = xTraceStringRegister("MyChannel"); - * ... - * xTracePrint(xChannel, "Hello World!"); - * - * @param[in] xChannel Channel. - * @param[in] szString String. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTracePrint(TraceStringHandle_t xChannel, const char* szString); - -/** - * @brief Wrapper for vTracePrintF for printing to default channel. - * - * Wrapper for vTracePrintF, using the default channel. Can be used as a drop-in - * replacement for printf and similar functions, e.g. in a debug logging macro. - * - * Example: - * // Old: #define LogString debug_console_printf - * - * // New, log to Tracealyzer instead: - * #define LogString xTraceConsoleChannelPrintF - * ... - * LogString("My value is: %d", myValue); - * - * @param[in] szFormat Format - * @param[in] ... - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceConsoleChannelPrintF(const char* szFormat, ...); - -/** - * @brief Generates "User Events" with formatted text and data. - * - * Generates "User Events", with formatted text and data, similar to a "printf". - * It is very fast since the actual formatting is done on the host side when the - * trace is displayed. - * - * User Events can be used for very efficient application logging, and are shown - * as yellow labels in the main trace view. - * An advantage of User Events is that data can be plotted in the "User Event - * Signal Plot" view, visualizing any data you log as User Events, discrete - * states or control system signals (e.g. system inputs or outputs). - * - * You may group User Events into User Event Channels. The yellow User Event - * labels show the logged string, preceded by the channel name within brackets. - * - * Example: - * - * "[MyChannel] Hello World!" - * - * The User Event Channels are shown in the View Filter, which makes it easy to - * select what User Events you wish to display. User Event Channels are created - * using xTraceStringRegister(). - * - * Example: - * - * TraceStringHandle_t adc_uechannel = xTraceStringRegister("ADC User Events"); - * ... - * xTracePrintF(adc_uechannel, - * "ADC channel %d: %d volts", - * ch, adc_reading); - * - * All data arguments are assumed to be 32 bit wide. The following formats are - * supported: - * %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> " -42" - * %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> " 42" - * %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> " 2A" - * %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> " 2a" - * %s - string (currently, this must be an earlier stored symbol name) - * - * Up to 15 data arguments are allowed, with a total size of maximum 60 byte - * including 8 byte for the base event fields and the format string. So with - * one data argument, the maximum string length is 48 chars. If this is exceeded - * the string is truncated (4 bytes at a time). - * - * @param[in] xChannel Channel. - * @param[in] szFormat Format. - * @param[in] ... - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTracePrintF(TraceStringHandle_t xChannel, const char* szFormat, ...); - -/** - * @brief Generates "User Events" with formatted text and data. - * - * @param[in] xChannel Channel. - * @param[in] szFormat Format. - * @param[in] xVL Variable list arguments. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceVPrintF(TraceStringHandle_t xChannel, const char* szFormat, va_list xVL); - -#else /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */ - -typedef struct TracePrintBuffer -{ - uint32_t buffer[1]; -} TracePrintBuffer_t; - -#define xTracePrintInitialize(p) ((void)p, p != 0 ? TRC_SUCCESS : TRC_FAIL) - -#define xTracePrint(c, s) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)c, (void)s, TRC_SUCCESS) - -#define xTracePrintF(c, s, ...) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)c, (void)s, TRC_SUCCESS) - -#define xTraceConsoleChannelPrintF(s, ...) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)s, TRC_SUCCESS) - -#define xTraceVPrintF(c, s, v) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)c, (void)s, (void)v, TRC_SUCCESS) - -#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - - -#endif /* TRC_PRINT_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace print APIs. + */ + +#ifndef TRC_PRINT_H + #define TRC_PRINT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_print_apis Trace Print APIs + * @ingroup trace_recorder_apis + * @{ + */ + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) + +/** @internal */ + #define TRC_PRINT_BUFFER_SIZE ( sizeof( TraceStringHandle_t ) + sizeof( TraceStringHandle_t ) ) + +/** + * @internal Trace Print Buffer Structure + */ + typedef struct TracePrintBuffer + { + uint32_t buffer[ ( TRC_PRINT_BUFFER_SIZE ) / sizeof( uint32_t ) ]; + } TracePrintBuffer_t; + +/** + * @internal Initialize print trace system. + * + * @param[in] pxBuffer Pointer to memory that will be used by the print + * trace system. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTracePrintInitialize( TracePrintBuffer_t * pxBuffer ); + +/** + * @brief Generate "User Events" with unformatted text. + * + * User Events can be used for very efficient application logging, and are shown + * as yellow labels in the main trace view. + * + * You may group User Events into User Event Channels. The yellow User Event + * labels shows the logged string, preceded by the channel name within + * brackets. For example: + * + * "[MyChannel] Hello World!" + * + * The User Event Channels are shown in the View Filter, which makes it easy to + * select what User Events you wish to display. User Event Channels are created + * using xTraceStringRegister(). + * + * Example: + * + * TraceStringHandle_t xChannel = xTraceStringRegister("MyChannel"); + * ... + * xTracePrint(xChannel, "Hello World!"); + * + * @param[in] xChannel Channel. + * @param[in] szString String. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTracePrint( TraceStringHandle_t xChannel, + const char * szString ); + +/** + * @brief Wrapper for vTracePrintF for printing to default channel. + * + * Wrapper for vTracePrintF, using the default channel. Can be used as a drop-in + * replacement for printf and similar functions, e.g. in a debug logging macro. + * + * Example: + * // Old: #define LogString debug_console_printf + * + * // New, log to Tracealyzer instead: + * #define LogString xTraceConsoleChannelPrintF + * ... + * LogString("My value is: %d", myValue); + * + * @param[in] szFormat Format + * @param[in] ... + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceConsoleChannelPrintF( const char * szFormat, + ... ); + +/** + * @brief Generates "User Events" with formatted text and data. + * + * Generates "User Events", with formatted text and data, similar to a "printf". + * It is very fast since the actual formatting is done on the host side when the + * trace is displayed. + * + * User Events can be used for very efficient application logging, and are shown + * as yellow labels in the main trace view. + * An advantage of User Events is that data can be plotted in the "User Event + * Signal Plot" view, visualizing any data you log as User Events, discrete + * states or control system signals (e.g. system inputs or outputs). + * + * You may group User Events into User Event Channels. The yellow User Event + * labels show the logged string, preceded by the channel name within brackets. + * + * Example: + * + * "[MyChannel] Hello World!" + * + * The User Event Channels are shown in the View Filter, which makes it easy to + * select what User Events you wish to display. User Event Channels are created + * using xTraceStringRegister(). + * + * Example: + * + * TraceStringHandle_t adc_uechannel = xTraceStringRegister("ADC User Events"); + * ... + * xTracePrintF(adc_uechannel, + * "ADC channel %d: %d volts", + * ch, adc_reading); + * + * All data arguments are assumed to be 32 bit wide. The following formats are + * supported: + * %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> " -42" + * %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> " 42" + * %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> " 2A" + * %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> " 2a" + * %s - string (currently, this must be an earlier stored symbol name) + * + * Up to 15 data arguments are allowed, with a total size of maximum 60 byte + * including 8 byte for the base event fields and the format string. So with + * one data argument, the maximum string length is 48 chars. If this is exceeded + * the string is truncated (4 bytes at a time). + * + * @param[in] xChannel Channel. + * @param[in] szFormat Format. + * @param[in] ... + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTracePrintF( TraceStringHandle_t xChannel, + const char * szFormat, + ... ); + +/** + * @brief Generates "User Events" with formatted text and data. + * + * @param[in] xChannel Channel. + * @param[in] szFormat Format. + * @param[in] xVL Variable list arguments. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceVPrintF( TraceStringHandle_t xChannel, + const char * szFormat, + va_list xVL ); + + #else /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */ + + typedef struct TracePrintBuffer + { + uint32_t buffer[ 1 ]; + } TracePrintBuffer_t; + + #define xTracePrintInitialize( p ) ( ( void ) p, p != 0 ? TRC_SUCCESS : TRC_FAIL ) + + #define xTracePrint( c, s ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( ( void ) c, ( void ) s, TRC_SUCCESS ) + + #define xTracePrintF( c, s, ... ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( ( void ) c, ( void ) s, TRC_SUCCESS ) + + #define xTraceConsoleChannelPrintF( s, ... ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( ( void ) s, TRC_SUCCESS ) + + #define xTraceVPrintF( c, s, v ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( ( void ) c, ( void ) s, ( void ) v, TRC_SUCCESS ) + + #endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */ + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + + +#endif /* TRC_PRINT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h index a91c010d7..40a73be88 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h @@ -1,1880 +1,1910 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef TRC_RECORDER_H -#define TRC_RECORDER_H - -/** - * @file - * - * @brief The public API of the Percepio trace recorder. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Trace Recorder APIs - * @defgroup trace_recorder_apis Trace Recorder APIs - * @{ - * @} - */ - -#define TRC_ACKNOWLEDGED (0xABC99123) - -#include -#include -#include -#include - -#ifndef TRC_CFG_TEST_MODE -#define TRC_CFG_TEST_MODE 0 -#endif - -/* Unless defined by the kernel port, we assume there is no support for - * the classic snapshot mode and default to streaming mode where - * the new RingBuffer snapshot mode provides snapshot functionality. - */ -#ifndef TRC_CFG_RECORDER_MODE -#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_STREAMING -#endif - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) -#include -#include - -/* Calls xTraceError if the _assert condition is false. For void functions, -where no return value is to be provided. */ -#define TRC_ASSERT_VOID(_assert, _err) if (! (_assert)){ prvTraceError(_err); return; } - -/* Calls xTraceError if the _assert condition is false. For non-void functions, -where a return value is to be provided. */ -#define TRC_ASSERT_RET(_assert, _err, _return) if (! (_assert)){ prvTraceError(_err); return _return; } - -typedef uint8_t traceUBChannel; -typedef uint8_t traceObjectClass; - -#undef traceHandle -#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) -typedef uint16_t traceHandle; -#else /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */ -typedef uint8_t traceHandle; -#endif /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */ - -#include -#include - -/* Not yet available in snapshot mode */ -#define vTraceConsoleChannelPrintF(fmt, ...) (void) -#define xTraceConsoleChannelPrintF(fmt, ...) (void) -#define prvTraceStoreEvent_None(...) -#define prvTraceStoreEvent_Handle(...) -#define prvTraceStoreEvent_Param(...) -#define prvTraceStoreEvent_HandleParam(...) -#define prvTraceStoreEvent_ParamParam(...) -#define prvTraceStoreEvent_HandleParamParam(...) -#define prvTraceStoreEvent_ParamParamParam(...) - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) */ - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) -#include -#include - -/* Unless specified in trcConfig.h we assume this is a single core target */ -#ifndef TRC_CFG_CORE_COUNT -#define TRC_CFG_CORE_COUNT 1 -#endif - -/* Unless specified in trcConfig.h we assume this is a single core target */ -#ifndef TRC_CFG_GET_CURRENT_CORE -#define TRC_CFG_GET_CURRENT_CORE() 0 -#endif - -/* Unless specified in trcConfig.h or trcKernelPortConfig.h we assume - * GCC statement expressions aren't supported. */ -#ifndef TRC_CFG_USE_GCC_STATEMENT_EXPR -#define TRC_CFG_USE_GCC_STATEMENT_EXPR 0 -#endif - -/* Backwards compatibility */ -typedef TraceISRHandle_t traceHandle; - -/* Maximum event size */ -#define TRC_MAX_BLOB_SIZE (16 * sizeof(uint32_t)) - -/* Platform name length */ -#define TRC_PLATFORM_CFG_LENGTH 8 - -/* Header size */ -#define TRC_HEADER_BUFFER_SIZE (sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + (sizeof(char) * (TRC_PLATFORM_CFG_LENGTH)) + sizeof(uint16_t) + sizeof(uint8_t) + sizeof(uint8_t)) - -typedef struct TraceHeaderBuffer -{ - uint8_t buffer[TRC_HEADER_BUFFER_SIZE]; -} TraceHeaderBuffer_t; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -/******************************************************************************/ -/*** Common API - both Snapshot and Streaming mode ****************************/ -/******************************************************************************/ - -/** - * @brief - * - * Initializes the recorder data. xTraceInitialize() or xTraceEnable(...) - * must be called before any attempts at adding trace data/information. - * See xTraceEnable(...) for more information. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceInitialize(void); - -/** - * @brief - * - * This function enables tracing. - * To use the trace recorder, the startup must call xTraceInitialize() or - * xTraceEnable(...) before any RTOS calls are made (including "create" calls). - * Three start options are provided: - * - * TRC_START: Starts the tracing directly. In snapshot mode this allows for - * starting the trace at any point in your code, assuming xTraceInitialize() - * has been called in the startup. Can also be used for streaming without - * Tracealyzer control, e.g. to a local flash file system (assuming such a - * "stream port", see trcStreamPort.h). - * - * TRC_START_AWAIT_HOST: For streaming mode only. Initializes the trace recorder - * if necessary and waits for a Start command from Tracealyzer ("Start Recording" - * button). This call is intentionally blocking! By calling xTraceEnable with - * this option from the startup code, you start tracing at this point and capture - * the early events. - * - * TRC_START_FROM_HOST: For streaming mode only. Initializes the trace recorder - * if necessary and creates a task that waits for a Start command from - * Tracealyzer ("Start Recording" button). This call is not blocking. - * - * @example Usage examples - * - * Snapshot trace, from startup: - * - * xTraceEnable(TRC_START); // Will call xTraceInitialize() - * - * - * Snapshot trace, from a later point: - * - * xTraceInitialize(); - * - * ... - * xTraceEnable(TRC_START); // e.g., in task context, at some relevant event - * - * Streaming trace, from startup (can only be used with certain stream ports): - * - * xTraceInitialize(); - * - * xTraceEnable(TRC_START); - * - * Streaming trace, from startup: - * - * xTraceEnable(TRC_START_AWAIT_HOST); // Blocks! - * - * - * Streaming trace, from a later point: - * - * xTraceInitialize(); - * - * xTraceEnable(TRC_START); - * - * Streaming trace, system executes normally until host starts tracing: - * - * xTraceInitialize(); - * - * xTraceEnable(TRC_START_FROM_HOST) - * - * @param[in] uiStartOption Start option. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceEnable(uint32_t uiStartOption); - -/** - * @brief Disables tracing. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceDisable(void); - -/** - * @brief - * - * For snapshot mode only: Sets the "filter group" to assign when creating - * RTOS objects, such as tasks, queues, semaphores and mutexes. This together - * with vTraceSetFilterMask allows you to control what events that are recorded, - * based on the objects they refer to. - * - * There are 16 filter groups named FilterGroup0 .. FilterGroup15. - * - * Note: We don't recommend filtering out the Idle task, so make sure to call - * vTraceSetFilterGroup just before initializing the RTOS, in order to assign - * such "default" objects to the right Filter Group (typically group 0). - * - * Example: - * - * // Assign tasks T1 to FilterGroup0 (default) - * - * - * // Assign Q1 and Q2 to FilterGroup1 - * vTraceSetFilterGroup(FilterGroup1); - * - * - * - * // Assigns Q3 to FilterGroup2 - * vTraceSetFilterGroup(FilterGroup2); - * - * - * // Only include FilterGroup0 and FilterGroup2, exclude FilterGroup1 (Q1 and Q2) from the trace - * vTraceSetFilterMask( FilterGroup0 | FilterGroup2 ); - * - * // Assign the default RTOS objects (e.g. Idle task) to FilterGroup0 - * vTraceSetFilterGroup(FilterGroup0); - * - * - * Note that you may define your own names for the filter groups using - * preprocessor definitions, to make the code easier to understand. - * - * Example: - * - * #define BASE FilterGroup0 - * #define USB_EVENTS FilterGroup1 - * #define CAN_EVENTS FilterGroup2 - * - * Note that filtering per event type (regardless of object) is also available - * in trcKernelPortConfig.h for certain kernels. - * - * @param[in] filterGroup Filter group - */ -void vTraceSetFilterGroup(uint16_t filterGroup); - -/** - * @brief - * - * For snapshot mode only: Sets the "filter mask" that is used to filter - * the events by object. This can be used to reduce the trace data rate, i.e., - * if your streaming interface is a bottleneck or if you want longer snapshot - * traces without increasing the buffer size. - * - * Note: There are two kinds of filters in the recorder. The other filter type - * excludes all events of certain kinds (e.g., OS ticks). See trcConfig.h. - * - * The filtering is based on bitwise AND with the Filter Group ID, assigned - * to RTOS objects such as tasks, queues, semaphores and mutexes. - * This together with vTraceSetFilterGroup allows you to control what - * events that are recorded, based on the objects they refer to. - * - * See example for vTraceSetFilterGroup. - * - * @param[in] filterMask Filter mask - */ -void vTraceSetFilterMask(uint16_t filterMask); - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) - -#include - -/** - * @brief Returns lower 16 bits of a value - * - * @param[in] value The starting value - */ -#define TRACE_GET_LOW16(value) ((uint16_t)((value) & 0x0000FFFF)) - -/** - * @brief Returns upper 16 bits - * - * @param[in] value The starting value - */ -#define TRACE_GET_HIGH16(value) ((uint16_t)(((value) >> 16) & 0x0000FFFF)) - -/** - * @brief Sets lower 16 bits - * - * @param[in] current The starting value - * @param[in] value The value to set - */ -#define TRACE_SET_LOW16(current, value) (((current) & 0xFFFF0000) | (value)) - -/** - * @brief Sets upper 16 bits - * - * @param[in] current The starting value - * @param[in] value The value to set - */ -#define TRACE_SET_HIGH16(current, value) (((current) & 0x0000FFFF) | (((uint32_t)(value)) << 16)) - -#if defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) -/** - * @brief Adds a task to the stack monitor - * - * @param[in] task The task - */ -void prvAddTaskToStackMonitor(void* task); - -/** - * @brief Remove a task from the stack monitor - * - * @param[in] task The task - */ -void prvRemoveTaskFromStackMonitor(void* task); - -/** - * @brief Reports on the current stack usage - */ -void prvReportStackUsage(void); - -#else /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ - -#define prvAddTaskToStackMonitor(task) -#define prvRemoveTaskFromStackMonitor(task) -#define prvReportStackUsage() - -#endif /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ - -/** - * @brief Query if recorder is enabled - * - * @retval 1 if recorder is enabled - * @retval 0 if recorder is disabled - */ -uint32_t xTraceIsRecorderEnabled(void); - -/** - * @brief - * - * @retval 1 if recorder is initialized - * @retval 0 if recorder isn't initialized - */ -uint32_t xTraceIsRecorderInitialized(void); - -/** - * @brief - * - * Creates an event that ends the current task instance at this very instant. - * This makes the viewer to splits the current fragment at this point and begin - * a new actor instance, even if no task-switch has occurred. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskInstanceFinishedNow(void); - -/** - * @brief - * - * Marks the current "task instance" as finished on the next kernel call. - * - * If that kernel call is blocking, the instance ends after the blocking event - * and the corresponding return event is then the start of the next instance. - * If the kernel call is not blocking, the viewer instead splits the current - * fragment right before the kernel call, which makes this call the first event - * of the next instance. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskInstanceFinishedNext(void); - -/** - * @brief Registers a string and returns a handle that can be used when tracing - * - * @param[in] label Label - * @param[out] pxString String handle - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStringRegister(const char* label, TraceStringHandle_t* pxString); - -/** - * @brief Registers a string and returns a handle that can be used when tracing - * - * @deprecated Backwards compatibility - * - * @param[in] name Name. - * - * @return TraceStringHandle_t String handle - */ -TraceStringHandle_t xTraceRegisterString(const char* name); - -#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) -/** - * @brief - * - * Generates "User Events", with formatted text and data, similar to a "printf". - * User Events can be used for very efficient logging from your application code. - * It is very fast since the actual string formatting is done on the host side, - * when the trace is displayed. The execution time is just some microseconds on - * a 32-bit MCU. - * - * User Events are shown as yellow labels in the main trace view of $PNAME. - * - * An advantage of User Events is that data can be plotted in the "User Event - * Signal Plot" view, visualizing any data you log as User Events, discrete - * states or control system signals (e.g. system inputs or outputs). - * - * You may group User Events into User Event Channels. The yellow User Event - * labels show the logged string, preceded by the channel name within brackets. - * - * Example: - * - * "[MyChannel] Hello World!" - * - * The User Event Channels are shown in the View Filter, which makes it easy to - * select what User Events you wish to display. User Event Channels are created - * using xTraceStringRegister(). - * - * Example: - * - * TraceStringHandle_t adc_uechannel; - * xTraceStringRegister("ADC User Events", &adc_uechannel); - * ... - * xTracePrintF(adc_uechannel, - * "ADC channel %d: %d volts", - * ch, adc_reading); - * - * The following format specifiers are supported in both modes: - * %d - signed integer. - * %u - unsigned integer. - * %X - hexadecimal, uppercase. - * %x - hexadecimal, lowercase. - * %s - string (see comment below) - * - * For integer formats (%d, %u, %x, %X) you may also use width and padding. - * If using -42 as data argument, two examples are: - * "%05d" -> "-0042" - * "%5d" -> " -42". - * - * String arguments are supported in both snapshot and streaming, but in streaming - * mode you need to use xTraceStringRegister and use the returned TraceStringHandle_t as - * the argument. In snapshot you simply provide a char* as argument. - * - * Snapshot: xTracePrintF(myChn, "my string: %s", str); - * Streaming: xTracePrintF(myChn, "my string: %s", strTraceString); - * - * In snapshot mode you can specify 8-bit or 16-bit arguments to reduce RAM usage: - * %hd -> 16 bit (h) signed integer (d). - * %bu -> 8 bit (b) unsigned integer (u). - * - * However, in streaming mode all data arguments are assumed to be 32 bit wide. - * Width specifiers (e.g. %hd) are accepted but ignored (%hd treated like %d). - * - * The maximum event size also differs between the modes. In streaming this is - * limited by a maximum payload size of 52 bytes, including format string and - * data arguments. So if using one data argument, the format string is limited - * to 48 byte, etc. If this is exceeded, the format string is truncated and you - * get a warning in Tracealyzer. - * - * In snapshot mode you are limited to maximum 15 arguments, that must not exceed - * 32 bytes in total (not counting the format string). If exceeded, the recorder - * logs an internal error (displayed when opening the trace) and stops recording. - * - * @param[in] chn Channel. - * @param[in] fmt Formatting. - * @param[in] ... - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTracePrintF(TraceStringHandle_t chn, const char* fmt, ...); -#else -#define xTracePrintF(chn, fmt, ...) ((void)(chn), (void)(fmt), TRC_SUCCESS) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ -#endif - -#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) -/** - * @brief - * - * xTracePrintF variant that accepts a va_list. - * See xTracePrintF documentation for further details. - * - * @param[in] eventLabel - * @param[in] formatStr - * @param[in] vl - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceVPrintF(TraceStringHandle_t eventLabel, const char* formatStr, va_list vl); -#else -#define xTraceVPrintF(chn, formatStr, vl) ((void)(chn), (void)(formatStr), (void)(vl), TRC_SUCCESS) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ -#endif - -#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) -/** - * @brief A faster version of xTracePrintF, that only allows for logging a string. - * - * Example: - * - * TraceStringHandle_t chn; - * xTraceStringRegister("MyChannel", &chn); - * ... - * xTracePrint(chn, "Hello World!"); - * - * @param[in] chn Channel. - * @param[in] str String. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTracePrint(TraceStringHandle_t chn, const char* str); -#else -#define xTracePrint(chn, str) ((void)(chn), (void)(str), TRC_SUCCESS) -#endif - -/******************************************************************************/ -/*** Extended API for Snapshot mode *******************************************/ -/******************************************************************************/ - -/** - * @brief Trace stop callback type. - */ -typedef void(*TRACE_STOP_HOOK)(void); - -/** - * @brief Sets a function to be called when the recorder is stopped. - * - * @note Snapshot mode only! - * - * @param[in] stopHookFunction - */ -void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction); - -/** - * @brief - * - * Resets the recorder. - * - * Only necessary if a restart is desired - this is not - * needed in the startup initialization. - * - * @note Snapshot mode only! - */ -void vTraceClear(void); - -/*****************************************************************************/ -/*** INTERNAL SNAPSHOT FUNCTIONS *********************************************/ -/*****************************************************************************/ - -#define TRC_UNUSED - -#ifndef TRC_CFG_INCLUDE_OBJECT_DELETE -#define TRC_CFG_INCLUDE_OBJECT_DELETE 0 -#endif - -#ifndef TRC_CFG_INCLUDE_READY_EVENTS -#define TRC_CFG_INCLUDE_READY_EVENTS 1 -#endif - -#ifndef TRC_CFG_INCLUDE_OSTICK_EVENTS -#define TRC_CFG_INCLUDE_OSTICK_EVENTS 0 -#endif - -/* This macro will create a task in the object table */ -#undef trcKERNEL_HOOKS_TASK_CREATE -#define trcKERNEL_HOOKS_TASK_CREATE(SERVICE, CLASS, pxTCB) \ - if ((pxTCB) != 0) \ - { \ - TRACE_SET_OBJECT_NUMBER(TASK, pxTCB); \ - TRACE_SET_OBJECT_FILTER(TASK, pxTCB, CurrentFilterGroup); \ - prvTraceSetObjectName(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_NAME(pxTCB)); \ - prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \ - } \ - else \ - { \ - /* pxTCB is null */ \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - { \ - prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, 0); \ - } \ - } - -/* This macro will remove the task and store it in the event buffer */ -#undef trcKERNEL_HOOKS_TASK_DELETE -#define trcKERNEL_HOOKS_TASK_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, pxTCB) \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \ - prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \ - prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \ - prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \ - prvTraceSetObjectState(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TASK_STATE_INSTANCE_NOT_ACTIVE); \ - prvTraceFreeObjectHandle(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); - - -/* This macro will setup a task in the object table */ -#undef trcKERNEL_HOOKS_OBJECT_CREATE -#define trcKERNEL_HOOKS_OBJECT_CREATE(SERVICE, CLASS, pxObject) \ - TRACE_SET_OBJECT_NUMBER(CLASS, pxObject); \ - TRACE_SET_OBJECT_FILTER(CLASS, pxObject, CurrentFilterGroup); \ - prvMarkObjectAsUsed(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));\ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \ - prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), 0); - -/* This macro will setup a task in the object table */ -#undef trcKERNEL_HOOKS_OBJECT_CREATE_FAILED -#define trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(SERVICE, TRACE_CLASS)\ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - { \ - prvTraceStoreKernelCall(SERVICE, TRACE_CLASS, 0); \ - } - -/* This macro will remove the object and store it in the event buffer */ -#undef trcKERNEL_HOOKS_OBJECT_DELETE -#define trcKERNEL_HOOKS_OBJECT_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, CLASS, pxObject) \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \ - prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \ - prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \ - prvTraceFreeObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); - -/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE -#define trcKERNEL_HOOKS_KERNEL_SERVICE(SERVICE, CLASS, pxObject) \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); - -/* This macro will create a call to a kernel service with a certain result, with a null object as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT -#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT(SERVICE, TRACECLASS) \ - if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACECLASS, 0); - -/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM -#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(SERVICE, CLASS, pxObject, param) \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \ - prvTraceStoreKernelCallWithParam(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint32_t)param); - -/* This macro will create a call to a kernel service with a certain result, with a null object and other value as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM -#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM(SERVICE, TRACECLASS, param) \ - if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - prvTraceStoreKernelCallWithParam(SERVICE, TRACECLASS, 0, param); - -/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY -#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(SERVICE, param) \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, (uint32_t)param); - -/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR -#define trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR(SERVICE, CLASS, pxObject) \ - if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); - -/* This macro will create a call to a kernel service with a certain result, with a null object as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR -#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR(SERVICE, TRACECLASS) \ - prvTraceStoreKernelCall(SERVICE, TRACECLASS, 0); - -/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR -#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR(SERVICE, CLASS, pxObject, param) \ - if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \ - prvTraceStoreKernelCallWithParam(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint32_t)param); - -/* This macro will create a call to a kernel service with a certain result, with a null object and other value as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR -#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR(SERVICE, TRACECLASS, param) \ - prvTraceStoreKernelCallWithParam(SERVICE, TRACECLASS, 0, param); - -/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ -#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR -#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR(SERVICE, param) \ - prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, (uint32_t)param); - -/* This macro will set the state for an object */ -#undef trcKERNEL_HOOKS_SET_OBJECT_STATE -#define trcKERNEL_HOOKS_SET_OBJECT_STATE(CLASS, pxObject, STATE) \ - prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint8_t)STATE); - -/* This macro will flag a certain task as a finished instance */ -#undef trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED -#define trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED() \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - prvTraceSetTaskInstanceFinished(TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK())); - -#if (TRC_CFG_INCLUDE_READY_EVENTS == 1) -/* This macro will create an event to indicate that a task became Ready */ -#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE -#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \ - prvTraceStoreTaskReady(TRACE_GET_TASK_NUMBER(pxTCB)); -#else /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/ -#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE -#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB) -#endif /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/ - -/* This macro will update the internal tick counter and call prvTracePortGetTimeStamp(0) to update the internal counters */ -#undef trcKERNEL_HOOKS_INCREMENT_TICK -#define trcKERNEL_HOOKS_INCREMENT_TICK() \ - { \ - extern uint32_t uiTraceTickCount; \ - uiTraceTickCount++; \ - prvTracePortGetTimeStamp(0); \ - } - -#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1) -/* This macro will create an event indicating that the OS tick count has increased */ -#undef trcKERNEL_HOOKS_NEW_TIME -#define trcKERNEL_HOOKS_NEW_TIME(SERVICE, xValue) \ - prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue); -#else /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/ -#undef trcKERNEL_HOOKS_NEW_TIME -#define trcKERNEL_HOOKS_NEW_TIME(SERVICE, xValue) -#endif /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/ - -/* This macro will create a task switch event to the currently executing task */ -#undef trcKERNEL_HOOKS_TASK_SWITCH -#define trcKERNEL_HOOKS_TASK_SWITCH( pxTCB ) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \ - prvTraceStoreTaskswitch(TRACE_GET_TASK_NUMBER(pxTCB)); - -/* This macro will create an event to indicate that the task has been suspended */ -#undef trcKERNEL_HOOKS_TASK_SUSPEND -#define trcKERNEL_HOOKS_TASK_SUSPEND(SERVICE, pxTCB) \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \ - prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB)); - -/* This macro will create an event to indicate that a task has called a wait/delay function */ -#undef trcKERNEL_HOOKS_TASK_DELAY -#define trcKERNEL_HOOKS_TASK_DELAY(SERVICE, pxTCB, xValue) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \ - { \ - prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue); \ - prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB)); \ - } - -/* This macro will create an event to indicate that a task has gotten its priority changed */ -#undef trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE -#define trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(SERVICE, pxTCB, uxNewPriority) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \ - { \ - prvTraceStoreKernelCallWithParam(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), prvTraceGetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)));\ - prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), (uint8_t)uxNewPriority); \ - } - -/* This macro will create an event to indicate that the task has been resumed */ -#undef trcKERNEL_HOOKS_TASK_RESUME -#define trcKERNEL_HOOKS_TASK_RESUME(SERVICE, pxTCB) \ - if (TRACE_GET_OBJECT_FILTER(TASK, TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); - -/* This macro will create an event to indicate that the task has been resumed from ISR */ -#undef trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR -#define trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR(SERVICE, pxTCB) \ - if (TRACE_GET_OBJECT_FILTER(TASK, pxTCB) & CurrentFilterMask) \ - prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); - -#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1 -/** - * @brief Dynamically enables ready events - * - * @param[in] flag Flag - */ -void prvTraceSetReadyEventsEnabled(uint32_t flag); - -/** - * @brief Stores a Task Ready event - * - * @param[in] handle Task handle - */ -void prvTraceStoreTaskReady(traceHandle handle); -#else -#define prvTraceSetReadyEventsEnabled(status) (void)status; -#endif - -/** - * @brief Stores a Low Power mode event - * - * @param[in] flag Flag - */ -void prvTraceStoreLowPower(uint32_t flag); - -/** - * @brief Stores a Task Switch event - * - * @param[in] task_handle Task - */ -void prvTraceStoreTaskswitch(traceHandle task_handle); - -#if (TRC_CFG_SCHEDULING_ONLY == 0) - -/** - * @brief Stores a Kernel Service call event with an Object handle parameter - * - * @param[in] eventcode Event code - * @param[in] objectClass Object class - * @param[in] objectNumber Object handle - */ -void prvTraceStoreKernelCall(uint32_t eventcode, traceObjectClass objectClass, uint32_t objectNumber); - -/** - * @brief Stores a Kernel Service call event with only a numeric parameter - * - * @param[in] evtcode Event code - * @param[in] param Parameter - */ -void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param); - -/** - * @brief Stores a Kernel Service call event with an Object handle and a numeric parameter - * - * @param[in] evtcode Event code - * @param[in] objectClass Object class - * @param[in] objectNumber Object handle - * @param[in] param Parameter - */ -void prvTraceStoreKernelCallWithParam(uint32_t evtcode, traceObjectClass objectClass, - uint32_t objectNumber, uint32_t param); -#else - -#define prvTraceStoreKernelCall(eventcode, objectClass, byteParam) {} -#define prvTraceStoreKernelCallWithNumericParamOnly(evtcode, param) {} -#define prvTraceStoreKernelCallWithParam(evtcode, objectClass, objectNumber, param) {} - -#endif - -/** - * @brief Flags a task instance as finished - * - * @param[in] handle Task handle - */ -void prvTraceSetTaskInstanceFinished(traceHandle handle); - -/** - * @brief Set priority - * - * @param[in] objectclass Object class - * @param[in] id Object handle - * @param[in] value Value - */ -void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value); - -/** - * @brief Get priority - * - * @param[in] objectclass Object class - * @param[in] id Object handle - * - * @return uint8_t Value - */ -uint8_t prvTraceGetPriorityProperty(uint8_t objectclass, traceHandle id); - -/** - * @brief Set object state - * - * @param[in] objectclass Object class - * @param[in] id Object handle - * @param[in] value Value - */ -void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value); - -/** - * @brief Mark object as used - * - * @param[in] objectclass Object class - * @param[in] handle Object handle - */ -void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle); - -/** - * @brief Stores the name of an object because it is being deleted - * - * @param[in] evtcode Event code - * @param[in] handle Object handle - * @param[in] objectclass Object class - */ -void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle, - traceObjectClass objectclass); - -/** - * @brief Stores the property of an object because it is being deleted - * - * @param[in] evtcode Event code - * @param[in] handle Object handle - * @param[in] objectclass Object class - */ -void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle, - traceObjectClass objectclass); - -/* Internal constants for task state */ -#define TASK_STATE_INSTANCE_NOT_ACTIVE 0 -#define TASK_STATE_INSTANCE_ACTIVE 1 - - -#if (TRC_CFG_INCLUDE_ISR_TRACING == 0) - -#undef vTraceSetISRProperties -#define vTraceSetISRProperties(handle, name, priority) (void)(handle), (void)(name), (void)(priority) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ - -#undef vTraceStoreISRBegin -#define vTraceStoreISRBegin(x) (void)(x) - -#undef vTraceStoreISREnd -#define vTraceStoreISREnd(x) (void)(x) - -#undef xTraceSetISRProperties -#define xTraceSetISRProperties(name, priority) ((void)(name), (void)(priority), (traceHandle)0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */ - -#endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/ - -/** - * @brief - * - * Returns a pointer to the recorder data structure. Use this together with - * uiTraceGetTraceBufferSize if you wish to implement an own store/upload - * solution, e.g., in case a debugger connection is not available for uploading - * the data. - * - * @return void* Buffer pointer - */ -void* xTraceGetTraceBuffer(void); - -/** - * @brief - * - * Gets the size of the recorder data structure. For use together with - * xTraceGetTraceBuffer if you wish to implement an own store/upload solution, - * e.g., in case a debugger connection is not available for uploading the data. - * - * @return uint32_t Buffer size - */ -uint32_t uiTraceGetTraceBufferSize(void); - -#if (TRC_CFG_SCHEDULING_ONLY == 1) -#undef TRC_CFG_INCLUDE_USER_EVENTS -#define TRC_CFG_INCLUDE_USER_EVENTS 0 -#endif /*(TRC_CFG_SCHEDULING_ONLY == 1)*/ - -#if ((TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) - -/** - * @brief Register a channel and fixed format string for use with the separate User Event Buffer functions - * - * @param[in] channel Channel name handle - * @param[in] formatStr Format string that will be used for all events on this channel - * - * @return traceUBChannel Channel handle - */ -traceUBChannel xTraceRegisterUBChannel(TraceStringHandle_t channel, TraceStringHandle_t formatStr); - -/** - * @brief Creates a User Event using the channel, previously set format string and data parameters - * - * @param[in] channel Channel - * @param[in] ... - */ -void vTraceUBData(traceUBChannel channel, ...); - -/** - * @brief Creates a User Event using the channel and previously set string - * - * @param[in] channel Channel - */ -void vTraceUBEvent(traceUBChannel channel); -#else -#define xTraceRegisterChannelFormat(eventLabel, formatStr) ((void)(eventLabel), (void)(formatStr), 0) -#define vTraceUBData(label, ...) (void)(label) -#endif /*(TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)*/ - -#define NEventCodes 0x100 - -/* Our local critical sections for the recorder */ -#define trcCRITICAL_SECTION_BEGIN() {TRACE_ENTER_CRITICAL_SECTION(); recorder_busy++;} -#define trcCRITICAL_SECTION_END() {recorder_busy--; TRACE_EXIT_CRITICAL_SECTION();} - -#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) - #define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY TRACE_ALLOC_CRITICAL_SECTION - #define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_BEGIN - #define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_END -#else - #define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY() {} - #define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY() recorder_busy++; - #define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--; -#endif - -/** - * @brief Object handle stack struct. - * - * This data-structure is used to provide a mechanism for 1-byte trace object - * handles. This way, only 1 byte is necessary instead of 4 bytes (a pointer) - * when storing a reference to an object. This allows for up to 255 objects of - * each object class active at any given moment. There can be more "historic" - * objects, that have been deleted - that number is only limited by the size of - * the symbol table. - * - * Note that handle zero (0) is not used, it is a code for an invalid handle. - * - * This data structure keeps track of the FREE handles, not the handles in use. - * This data structure contains one stack per object class. When a handle is - * allocated to an object, the next free handle is popped from the stack. When - * a handle is released (on object delete), it is pushed back on the stack. - * Note that there is no initialization code that pushed the free handles - * initially, that is not necessary due to the following optimization: - * - * The stack of handles (objectHandles) is initially all zeros. Since zero - * is not a valid handle, that is a signal of additional handles needed. - * If a zero is received when popping a new handle, it is replaced by the - * index of the popped handle instead. - */ -typedef struct -{ - uint16_t indexOfNextAvailableHandle[ TRACE_NCLASSES ]; /**< For each object class, the index of the next handle to allocate */ - uint16_t lowestIndexOfClass[ TRACE_NCLASSES ]; /**< The lowest index of this class (constant) */ - uint16_t highestIndexOfClass[ TRACE_NCLASSES ]; /**< The highest index of this class (constant) */ - uint16_t handleCountWaterMarksOfClass[ TRACE_NCLASSES ]; /**< The highest use count for this class (for statistics) */ - traceHandle objectHandles[ TRACE_KERNEL_OBJECT_COUNT ]; /**< The free object handles - a set of stacks within this array */ -} objectHandleStackType; - -extern objectHandleStackType objectHandleStacks; - -/** - * @brief Object property table struct - * - * The Object Table contains name and other properties of the objects (tasks, - * queues, mutexes, etc). The below data structures defines the properties of - * each object class and are used to cast the byte buffer into a cleaner format. - * - * The values in the object table are continuously overwritten and always - * represent the current state. If a property is changed during runtime, the OLD - * value should be stored in the trace buffer, not the new value (since the new - * value is found in the Object Property Table). - * - * For close events this mechanism is the old names are stored in the symbol - * table), for "priority set" (the old priority is stored in the event data) - * and for "isActive", where the value decides if the task switch event type - * should be "new" or "resume". - */ -typedef struct -{ - /* = NCLASSES */ - uint32_t NumberOfObjectClasses; /**< */ - uint32_t ObjectPropertyTableSizeInBytes; /**< */ - - /* This is used to calculate the index in the dynamic object table - (handle - 1 - nofStaticObjects = index)*/ -#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) - traceHandle NumberOfObjectsPerClass[2*((TRACE_NCLASSES+1)/2)]; /** */ -#else - traceHandle NumberOfObjectsPerClass[4*((TRACE_NCLASSES+3)/4)]; /** */ -#endif - /* Allocation size rounded up to the closest multiple of 4 */ - uint8_t NameLengthPerClass[ 4*((TRACE_NCLASSES+3)/4) ]; /**< */ - - /* Allocation size rounded up to the closest multiple of 2 */ - uint8_t TotalPropertyBytesPerClass[ 4*((TRACE_NCLASSES+3)/4) ]; /**< */ - - /* */ - uint16_t StartIndexOfClass[ 2*((TRACE_NCLASSES+1)/2) ]; /**< */ - - /* The actual handles issued, should be Initiated to all zeros */ - uint8_t objbytes[ 4*((TRACE_OBJECT_TABLE_SIZE+3)/4) ]; /**< */ -} ObjectPropertyTableType; - -/** - * @brief Symbol table structure - */ -typedef struct -{ - /* = SYMBOL_HISTORY_TABLE_SIZE_IN_BYTES */ - uint32_t symTableSize; /**< */ - - /* Entry 0 is reserved. Any reference to entry 0 implies NULL*/ - uint32_t nextFreeSymbolIndex; /**< */ - - /* Size rounded up to closest multiple of 4, to avoid alignment issues*/ - uint8_t symbytes[4*(((TRC_CFG_SYMBOL_TABLE_SIZE)+3)/4)]; /**< */ - - /* Used for lookups - Up to 64 linked lists within the symbol table - connecting all entries with the same 6 bit checksum. - This field holds the current list heads. Should be initiated to zeros */ - uint16_t latestEntryOfChecksum[64]; /**< */ -} symbolTableType; - - -/******************************************************************************* - * The data structures of the different events, all 4 bytes long - ******************************************************************************/ - -typedef struct -{ - uint8_t type; - uint8_t objHandle; - uint16_t dts; /* differential timestamp - time since last event */ -} TSEvent, TREvent; - -typedef struct -{ - uint8_t type; - uint8_t dummy; - uint16_t dts; /* differential timestamp - time since last event */ -} LPEvent; - -typedef struct -{ - uint8_t type; - uint8_t objHandle; - uint16_t dts; /* differential timestamp - time since last event */ -} KernelCall; - -typedef struct -{ - uint8_t type; - uint8_t objHandle; - uint8_t param; - uint8_t dts; /* differential timestamp - time since last event */ -} KernelCallWithParamAndHandle; - -typedef struct -{ - uint8_t type; - uint8_t dts; /* differential timestamp - time since last event */ - uint16_t param; -} KernelCallWithParam16; - -typedef struct -{ - uint8_t type; - uint8_t objHandle; /* the handle of the closed object */ - uint16_t symbolIndex; /* the name of the closed object */ -} ObjCloseNameEvent; - -typedef struct -{ - uint8_t type; - uint8_t arg1; - uint8_t arg2; - uint8_t arg3; -} ObjClosePropEvent; - -typedef struct -{ - uint8_t type; - uint8_t unused1; - uint8_t unused2; - uint8_t dts; -} TaskInstanceStatusEvent; - -typedef struct -{ - uint8_t type; - uint8_t dts; - uint16_t payload; /* the name of the user event */ -} UserEvent; - -typedef struct -{ - uint8_t type; - - /* 8 bits extra for storing DTS, if it does not fit in ordinary event - (this one is always MSB if used) */ - uint8_t xts_8; - - /* 16 bits extra for storing DTS, if it does not fit in ordinary event. */ - uint16_t xts_16; -} XTSEvent; - -typedef struct -{ - uint8_t type; - - uint8_t xps_8; - uint16_t xps_16; -} XPSEvent; - -typedef struct{ - uint8_t type; - uint8_t dts; - uint16_t size; -} MemEventSize; - -typedef struct{ - uint8_t type; - uint8_t addr_high; - uint16_t addr_low; -} MemEventAddr; - -/******************************************************************************* - * The separate user event buffer structure. Can be enabled in trcConfig.h. - ******************************************************************************/ - -#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) -typedef struct -{ - TraceStringHandle_t name; - TraceStringHandle_t defaultFormat; -} ChannelFormatPair; - -typedef struct -{ - uint16_t bufferID; - uint16_t version; - uint32_t wraparoundCounter; - uint32_t numberOfSlots; - uint32_t nextSlotToWrite; - uint8_t numberOfChannels; - uint8_t padding1; - uint8_t padding2; - uint8_t padding3; - ChannelFormatPair channels[(TRC_CFG_UB_CHANNELS)+1]; - uint8_t channelBuffer[((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) + 3) & 0xFFFFFFFC]; /* 1 byte per slot, with padding for 4 byte alignment */ - uint8_t dataBuffer[(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) * 4]; /* 4 bytes per slot */ - -} UserEventBuffer; -#endif /* (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) */ - -/******************************************************************************* - * The main data structure, read by Tracealyzer from the RAM dump - ******************************************************************************/ - -typedef struct -{ - volatile uint8_t startmarker0; /* Volatile is important, see init code. */ - volatile uint8_t startmarker1; - volatile uint8_t startmarker2; - volatile uint8_t startmarker3; - volatile uint8_t startmarker4; - volatile uint8_t startmarker5; - volatile uint8_t startmarker6; - volatile uint8_t startmarker7; - volatile uint8_t startmarker8; - volatile uint8_t startmarker9; - volatile uint8_t startmarker10; - volatile uint8_t startmarker11; - - /* Used to determine Kernel and Endianess */ - uint16_t version; - - /* Currently 7 */ - uint8_t minor_version; - - /* This should be 0 if lower IRQ priority values implies higher priority - levels, such as on ARM Cortex M. If the opposite scheme is used, i.e., - if higher IRQ priority values means higher priority, this should be 1. */ - uint8_t irq_priority_order; - - /* sizeof(RecorderDataType) - just for control */ - uint32_t filesize; - - /* Current number of events recorded */ - uint32_t numEvents; - - /* The buffer size, in number of event records */ - uint32_t maxEvents; - - /* The event buffer index, where to write the next event */ - uint32_t nextFreeIndex; - - /* 1 if the buffer is full, 0 otherwise */ - uint32_t bufferIsFull; - - /* The frequency of the clock/timer/counter used as time base */ - uint32_t frequency; - - /* The absolute timestamp of the last stored event, in the native - timebase, modulo frequency! */ - uint32_t absTimeLastEvent; - - /* The number of seconds in total - lasts for 136 years */ - uint32_t absTimeLastEventSecond; - - /* 1 if the recorder has been started, 0 if not yet started or stopped. - This is a 32 bit variable due to alignment issues. */ - uint32_t recorderActive; - - /* If > 0, tells the maximum time between two traced ISRs that execute - back-to-back. If the time between vTraceStoreISREnd and a directly - following vTraceISRBegin is above isrTailchainingThreshold, we assume a - return to the previous context in between the ISRs, otherwise we assume - the have executed back-to-back and don't show any fragment of the previous - context in between. */ - uint32_t isrTailchainingThreshold; - - /* The maximum amount of heap memory that was allocated */ - uint32_t heapMemMaxUsage; - - /* The amount of heap memory used */ - uint32_t heapMemUsage; - - /* 0xF0F0F0F0 - for control only */ - int32_t debugMarker0; - - /* Set to value of TRC_CFG_USE_16BIT_OBJECT_HANDLES */ - uint32_t isUsing16bitHandles; - - /* The Object Property Table holds information about currently active - tasks, queues, and other recorded objects. This is updated on each - create call and includes object name and other properties. */ - ObjectPropertyTableType ObjectPropertyTable; - - /* 0xF1F1F1F1 - for control only */ - int32_t debugMarker1; - - /* The Symbol Table stores strings for User Events and is also used to - store names of deleted objects, which still may be in the trace but no - longer are available. */ - symbolTableType SymbolTable; - - /* For inclusion of float support, and for endian detection of floats. - The value should be (float)1 or (uint32_t)0 */ -#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1) - float exampleFloatEncoding; -#else - uint32_t exampleFloatEncoding; -#endif - /* This is non-zero if an internal error occurred in the recorder, e.g., if - one of the Nxxx constants was too small. The systemInfo string will then - contain an error message that is displayed when attempting to view the - trace file. */ - uint32_t internalErrorOccured; - - /* 0xF2F2F2F2 - for control only */ - int32_t debugMarker2; - - /* Error messages from the recorder. */ - char systemInfo[80]; - - /* 0xF3F3F3F3 - for control only */ - int32_t debugMarker3; - - /* The event data, in 4-byte records */ - uint8_t eventData[ (TRC_CFG_EVENT_BUFFER_SIZE) * 4 ]; - -#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) - UserEventBuffer userEventBuffer; -#endif - - /* This should always be 0 */ - uint32_t endOfSecondaryBlocks; - - uint8_t endmarker0; - uint8_t endmarker1; - uint8_t endmarker2; - uint8_t endmarker3; - uint8_t endmarker4; - uint8_t endmarker5; - uint8_t endmarker6; - uint8_t endmarker7; - uint8_t endmarker8; - uint8_t endmarker9; - uint8_t endmarker10; - uint8_t endmarker11; -} RecorderDataType; - -extern RecorderDataType* RecorderDataPtr; - -/* Internal functions */ - -/** - * @brief Signals a trace error - * - * @param[in] msg Message - */ -void prvTraceError(const char* msg); - -/** - * @brief - * - * Returns the current time based on the HWTC macros which provide a hardware - * isolation layer towards the hardware timer/counter. - * - * The HWTC macros and prvTracePortGetTimeStamp is the main porting issue - * or the trace recorder library. Typically you should not need to change - * the code of prvTracePortGetTimeStamp if using the HWTC macros. - * - * @param[out] puiTimestamp Timestamp - */ -void prvTracePortGetTimeStamp(uint32_t *puiTimestamp); - -/** - * @brief Reserve an object handle - * - * @param[in] objectclass Object class - * - * @return traceHandle - */ -traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass); - -/** - * @brief Free an object handle - * - * @param[in] objectclass Object class - * @param[in] handle Handle - */ -void prvTraceFreeObjectHandle(traceObjectClass objectclass, - traceHandle handle); - -/* Private function. Use the public functions in trcKernelPort.h */ - -/** - * @brief Set the object name - * - * @param[in] objectclass Object class - * @param[in] handle Handle - * @param[in] name Name - */ -void prvTraceSetObjectName(traceObjectClass objectclass, - traceHandle handle, - const char* name); - -/* Internal macros */ - -#define TRACE_PROPERTY_NAME_GET(objectclass, objecthandle) \ - (const char*)(& RecorderDataPtr->ObjectPropertyTable.objbytes \ - [uiIndexOfObject(objecthandle, objectclass)]) - -#define TRACE_PROPERTY_OBJECT_STATE(objectclass, handle) \ - RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \ - + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass]] - -#define TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle) \ - RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \ - + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass] + 1] - -/* DEBUG ASSERTS */ -#if defined TRC_CFG_USE_TRACE_ASSERT && TRC_CFG_USE_TRACE_ASSERT != 0 -#define TRACE_ASSERT(eval, msg, defRetVal) \ - if (!(eval)) \ - { \ - prvTraceError("TRACE_ASSERT: " msg); \ - return defRetVal; \ - } -#else -#define TRACE_ASSERT(eval, msg, defRetVal) -#endif - -typedef RecorderDataType TraceRecorderDataBuffer_t; - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/ - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#ifndef TRC_EXTERNAL_BUFFERS -#define TRC_EXTERNAL_BUFFERS 0 -#endif - -typedef struct TraceRecorderData -{ - uint32_t uiSessionCounter; - uint32_t uiRecorderEnabled; - uint32_t uiTraceSystemState; - - TraceAssertBuffer_t xAssertBuffer; -#if (TRC_EXTERNAL_BUFFERS == 0) - TraceHeaderBuffer_t xHeaderBuffer; - TraceEntryTableBuffer_t xEntryTableBuffer; - TraceTimestampBuffer_t xTimestampBuffer; -#endif - TraceStreamPortBuffer_t xStreamPortBuffer; - TraceStaticBufferBuffer_t xStaticBufferBuffer; - TraceEventDataBuffer_t xEventDataBuffer; - TracePrintBuffer_t xPrintBuffer; - TraceErrorBuffer_t xErrorBuffer; - TraceISRInfoBuffer_t xISRInfoBuffer; - TraceKernelPortDataBuffer_t xKernelPortBuffer; - TraceTaskInfoBuffer_t xTaskInfoBuffer; - TraceStackMonitorBuffer_t xStackMonitorBuffer; - TraceDiagnosticsBuffer_t xDiagnosticsBuffer; -} TraceRecorderData_t; - -extern TraceRecorderData_t* pxTraceRecorderData; -extern uint32_t RecorderInitialized; - -#define TRC_RECORDER_DATA_BUFFER_SIZE (sizeof(TraceRecorderData_t)) - -typedef struct TraceRecorderDataBuffer -{ - uint8_t buffer[(TRC_RECORDER_DATA_BUFFER_SIZE)]; -} TraceRecorderDataBuffer_t; - -/** - * @brief Initializes the header data - * - * @param[in] pxBuffer Pointer to header buffer - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceHeaderInitialize(TraceHeaderBuffer_t* pxBuffer); - -/** - * @brief Query if recorder is enabled - * - * @retval 1 Recorder enabled - * @retval 0 Recorder not enabled - */ -#define xTraceIsRecorderEnabled() (xTraceIsRecorderInitialized() & pxTraceRecorderData->uiRecorderEnabled) - -/** - * @brief Query if recorder initialized - * - * @retval 1 Recorder initialized - * @retval 0 Recorder not initialized - */ -#define xTraceIsRecorderInitialized() xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_CORE) - -/** - * @brief Flag component as initialized - * - * @param[in] uiComponentBit Component bit - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceSetComponentInitialized(uiComponentBit) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(RecorderInitialized |= (uiComponentBit), TRC_SUCCESS) - -/** - * @brief Query if component is initialized - * - * @param[in] uiComponentBit Component bit - * - * @retval 1 Component initialized - * @retval 0 Component not initialized - */ -#define xTraceIsComponentInitialized(uiComponentBit) ((RecorderInitialized & (uiComponentBit)) ? 1 : 0) - -/** - * @brief Set the trace state - * - * @param[in] uiState State - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceStateSet(uiState) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceRecorderData->uiTraceSystemState = (uiState), TRC_SUCCESS) - -/** - * @brief Query the trace state - * - * @param[out] puiState State - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceStateGet(puiState) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiState) = pxTraceRecorderData->uiTraceSystemState, TRC_SUCCESS) - -/** - * @brief Call this function periodically - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTzCtrl(void); - -/******************************************************************************/ -/*** INTERNAL STREAMING FUNCTIONS *********************************************/ -/******************************************************************************/ - -/** - * @brief Stores an event without parameters - * - * @param[in] _eventID Event id - */ -#define prvTraceStoreEvent_None(_eventID) \ - { \ - TraceEventHandle_t _xEventHandle = 0; \ - if (xTraceEventBegin(_eventID, 0, &_xEventHandle) == TRC_SUCCESS) \ - { \ - xTraceEventEnd(_xEventHandle); \ - } \ - } - -/** - * @brief Stores an event with a handle parameter - * - * @param[in] _eventID Event id - * @param[in] _handle Handle - */ -#define prvTraceStoreEvent_Handle(_eventID, _handle) \ - { \ - TraceEventHandle_t _xEventHandle = 0; \ - if (xTraceEventBegin(_eventID, sizeof(void*), &_xEventHandle) == TRC_SUCCESS) \ - { \ - xTraceEventAddPointer(_xEventHandle, (void*)(_handle)); \ - xTraceEventEnd(_xEventHandle); \ - } \ - } - -/** - * @brief Stores an event with one 32-bit parameter - * - * @param[in] _eventID Event id - * @param[in] _param1 Param - */ -#define prvTraceStoreEvent_Param(_eventID, _param1) \ - { \ - TraceEventHandle_t _xEventHandle = 0; \ - if (xTraceEventBegin(_eventID, sizeof(uint32_t), &_xEventHandle) == TRC_SUCCESS) \ - { \ - xTraceEventAdd32(_xEventHandle, (uint32_t)(_param1)); \ - xTraceEventEnd(_xEventHandle); \ - } \ - } - -/** - * @brief Stores an event with a handle and one 32-bit parameter - * - * @param[in] _eventID Event id - * @param[in] _handle Handle - * @param[in] _param1 Param - */ -#define prvTraceStoreEvent_HandleParam(_eventID, _handle, _param1) \ - { \ - TraceEventHandle_t _xEventHandle = 0; \ - if (xTraceEventBegin(_eventID, sizeof(void*) + sizeof(uint32_t), &_xEventHandle) == TRC_SUCCESS) \ - { \ - xTraceEventAddPointer(_xEventHandle, (void*)(_handle)); \ - xTraceEventAdd32(_xEventHandle, (uint32_t)(_param1)); \ - xTraceEventEnd(_xEventHandle); \ - } \ - } - -/** - * @brief Stores an event with two 32-bit parameters - * - * @param[in] _eventID Event id - * @param[in] _param1 Param 1 - * @param[in] _param2 Param 2 - */ -#define prvTraceStoreEvent_ParamParam(_eventID, _param1, _param2) \ - { \ - TraceEventHandle_t _xEventHandle = 0; \ - if (xTraceEventBegin(_eventID, sizeof(uint32_t) + sizeof(uint32_t), &_xEventHandle) == TRC_SUCCESS) \ - { \ - xTraceEventAdd32(_xEventHandle, (uint32_t)(_param1)); \ - xTraceEventAdd32(_xEventHandle, (uint32_t)(_param2)); \ - xTraceEventEnd(_xEventHandle); \ - } \ - } - -/** - * @brief Stores an event with a handle and two 32-bit parameters - * - * @param[in] _eventID Event id - * @param[in] _handle Handle - * @param[in] _param1 Param 1 - * @param[in] _param2 Param 2 - */ -#define prvTraceStoreEvent_HandleParamParam(_eventID, _handle, _param1, _param2) \ - { \ - TraceEventHandle_t _xEventHandle = 0; \ - if (xTraceEventBegin(_eventID, sizeof(void*) + sizeof(uint32_t) + sizeof(uint32_t), &_xEventHandle) == TRC_SUCCESS) \ - { \ - xTraceEventAddPointer(_xEventHandle, (void*)(_handle)); \ - xTraceEventAdd32(_xEventHandle, (uint32_t)(_param1)); \ - xTraceEventAdd32(_xEventHandle, (uint32_t)(_param2)); \ - xTraceEventEnd(_xEventHandle); \ - } \ - } - -/** - * @brief Stores an event with three 32-bit parameters - * - * @param[in] _eventID Event id - * @param[in] _param1 Param 1 - * @param[in] _param2 Param 2 - * @param[in] _param3 Param 3 - */ -#define prvTraceStoreEvent_ParamParamParam(_eventID, _param1, _param2, _param3) \ - { \ - TraceEventHandle_t _xEventHandle = 0; \ - if (xTraceEventBegin(_eventID, sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t), &_xEventHandle) == TRC_SUCCESS) \ - { \ - xTraceEventAdd32(_xEventHandle, (uint32_t)(_param1)); \ - xTraceEventAdd32(_xEventHandle, (uint32_t)(_param2)); \ - xTraceEventAdd32(_xEventHandle, (uint32_t)(_param3)); \ - xTraceEventEnd(_xEventHandle); \ - } \ - } - -/** - * @brief Snapshot mode only. Trace stop hook. - * - * @param[in] x - */ -#define vTraceSetStopHook(x) (void)(x) - -/** - * @brief Snapshot mode only. Initialize timestamps. - */ -#define vTraceInitTimestamps() - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM) -/** - * @brief Set the recorder data buffer - * - * @param[in] pxBuffer Pointer to the recorder data buffer - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceSetBuffer(TraceRecorderDataBuffer_t *pxBuffer); -#else -#define xTraceSetBuffer(p) (TRC_SUCCESS) -#endif - -/** - * @brief Retrieve the event buffer and event buffer size - * - * @param[out] ppvBuffer Pointer where event buffer pointer will be written - * @param[out] puiSize Event buffer size - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceGetEventBuffer(void** ppvBuffer, TraceUnsignedBaseType_t * puiSize); - -#else /* when TRC_USE_TRACEALYZER_RECORDER == 0 */ - -#define xTraceInitialize() (TRC_SUCCESS) -#define xTraceEnable(x) ((void)(x), TRC_SUCCESS) -#define xTraceDisable() (TRC_SUCCESS) -#define xTraceStringRegister(x, y) ((void)(x), (void)y, TRC_SUCCESS) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */ -#define xTracePrint(chn, ...) ((void)(chn), TRC_SUCCESS) -#define xTracePrintF(chn, fmt, ...) ((void)(chn), (void)(fmt), TRC_SUCCESS) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ -#define xTraceVPrintF(chn, formatStr, vl) ((void)(chn), (void)(formatStr), (void)(vl), TRC_SUCCESS) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ -#define xTraceTaskInstanceFinishedNow() -#define xTraceTaskInstanceFinishedNext() -#define vTraceStoreISRBegin(x) (void)(x) -#define vTraceStoreISREnd(x) (void)(x) -#define xTraceSetISRProperties(a, b) ((void)(a), (void)(b), (traceHandle)0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */ -#define xTraceRegisterChannelFormat(eventLabel, formatStr) ((void)(eventLabel), (void)(formatStr), 0) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */ -#define vTraceUBData(label, ...) (void)(label) - -#define vTraceSetFilterGroup(x) (void)(x) -#define vTraceSetFilterMask(x) (void)(x) - -#define prvTraceSetReadyEventsEnabled(status) (void)(status) - -#define vTraceExcludeTask(handle) (void)(handle) - -#define vTraceConsoleChannelPrintF(fmt, ...) (void)(fmt) - -#ifndef TRC_ALLOC_CUSTOM_BUFFER -#define TRC_ALLOC_CUSTOM_BUFFER(bufname) -#endif - -#define xTraceIsRecorderEnabled() (0) -#define xTraceIsRecorderInitialized() (0) - -#define xTraceSetBuffer(p) (TRC_SUCCESS) -#define xTraceGetEventBuffer(p) (TRC_FAIL) - -#define vTraceSetStopHook(x) (void)(x) - -#define TraceRecorderDataBuffer_t uint32_t - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -/** - * @deprecated Backwards compatibility. Use xTraceInitialize instead. - */ -#define vTraceInitialize (void)xTraceInitialize - -/** - * @deprecated Backwards compatibility. Use xTraceEnable instead. - */ -#define vTraceEnable (void)xTraceEnable - -/** - * @deprecated Backwards compatibility. Use xTraceDisable instead. - */ -#define vTraceStop (void)xTraceDisable - -/** - * @deprecated Backwards compatibility. Use xTraceTaskInstanceFinishedNow instead. - */ -#define vTraceInstanceFinishedNow (void)xTraceTaskInstanceFinishedNow - -/** - * @deprecated Backwards compatibility. Use xTraceTaskInstanceFinishedNext instead. - */ -#define vTraceInstanceFinishedNext (void)xTraceTaskInstanceFinishedNext - -/** - * @deprecated Backwards compatibility. Use xTracePrintF instead. - */ -#define vTracePrintF (void)xTracePrintF - -/** - * @deprecated Backwards compatibility. Use xTraceVPrintF instead. - */ -#define vTraceVPrintF (void)xTraceVPrintF - -/** - * @deprecated Backwards compatibility. Use xTracePrint instead. - */ -#define vTracePrint (void)xTracePrint - -/** - * @deprecated Backwards compatibility. Use xTraceSetBuffer instead. - */ -#define vTraceSetRecorderDataBuffer(pxBuffer) xTraceSetBuffer((TraceRecorderDataBuffer_t*)(pxBuffer)) - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_RECORDER_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TRC_RECORDER_H + #define TRC_RECORDER_H + +/** + * @file + * + * @brief The public API of the Percepio trace recorder. + */ + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @brief Trace Recorder APIs + * @defgroup trace_recorder_apis Trace Recorder APIs + * @{ + * @} + */ + + #define TRC_ACKNOWLEDGED ( 0xABC99123 ) + + #include + #include + #include + #include + + #ifndef TRC_CFG_TEST_MODE + #define TRC_CFG_TEST_MODE 0 + #endif + +/* Unless defined by the kernel port, we assume there is no support for + * the classic snapshot mode and default to streaming mode where + * the new RingBuffer snapshot mode provides snapshot functionality. + */ + #ifndef TRC_CFG_RECORDER_MODE + #define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_STREAMING + #endif + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) + #include + #include + +/* Calls xTraceError if the _assert condition is false. For void functions, + * where no return value is to be provided. */ + #define TRC_ASSERT_VOID( _assert, _err ) if( !( _assert ) ) { prvTraceError( _err ); return; } + +/* Calls xTraceError if the _assert condition is false. For non-void functions, + * where a return value is to be provided. */ + #define TRC_ASSERT_RET( _assert, _err, _return ) if( !( _assert ) ) { prvTraceError( _err ); return _return; } + + typedef uint8_t traceUBChannel; + typedef uint8_t traceObjectClass; + + #undef traceHandle + #if ( TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1 ) + typedef uint16_t traceHandle; + #else /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */ + typedef uint8_t traceHandle; + #endif /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */ + + #include + #include + +/* Not yet available in snapshot mode */ + #define vTraceConsoleChannelPrintF( fmt, ... ) ( void ) + #define xTraceConsoleChannelPrintF( fmt, ... ) ( void ) + #define prvTraceStoreEvent_None( ... ) + #define prvTraceStoreEvent_Handle( ... ) + #define prvTraceStoreEvent_Param( ... ) + #define prvTraceStoreEvent_HandleParam( ... ) + #define prvTraceStoreEvent_ParamParam( ... ) + #define prvTraceStoreEvent_HandleParamParam( ... ) + #define prvTraceStoreEvent_ParamParamParam( ... ) + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) */ + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + #include + #include + +/* Unless specified in trcConfig.h we assume this is a single core target */ + #ifndef TRC_CFG_CORE_COUNT + #define TRC_CFG_CORE_COUNT 1 + #endif + +/* Unless specified in trcConfig.h we assume this is a single core target */ + #ifndef TRC_CFG_GET_CURRENT_CORE + #define TRC_CFG_GET_CURRENT_CORE() 0 + #endif + +/* Unless specified in trcConfig.h or trcKernelPortConfig.h we assume + * GCC statement expressions aren't supported. */ + #ifndef TRC_CFG_USE_GCC_STATEMENT_EXPR + #define TRC_CFG_USE_GCC_STATEMENT_EXPR 0 + #endif + +/* Backwards compatibility */ + typedef TraceISRHandle_t traceHandle; + +/* Maximum event size */ + #define TRC_MAX_BLOB_SIZE ( 16 * sizeof( uint32_t ) ) + +/* Platform name length */ + #define TRC_PLATFORM_CFG_LENGTH 8 + +/* Header size */ + #define TRC_HEADER_BUFFER_SIZE ( sizeof( uint32_t ) + sizeof( uint16_t ) + sizeof( uint16_t ) + sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( uint32_t ) + ( sizeof( char ) * ( TRC_PLATFORM_CFG_LENGTH ) ) + sizeof( uint16_t ) + sizeof( uint8_t ) + sizeof( uint8_t ) ) + + typedef struct TraceHeaderBuffer + { + uint8_t buffer[ TRC_HEADER_BUFFER_SIZE ]; + } TraceHeaderBuffer_t; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + +/******************************************************************************/ +/*** Common API - both Snapshot and Streaming mode ****************************/ +/******************************************************************************/ + +/** + * @brief + * + * Initializes the recorder data. xTraceInitialize() or xTraceEnable(...) + * must be called before any attempts at adding trace data/information. + * See xTraceEnable(...) for more information. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceInitialize( void ); + +/** + * @brief + * + * This function enables tracing. + * To use the trace recorder, the startup must call xTraceInitialize() or + * xTraceEnable(...) before any RTOS calls are made (including "create" calls). + * Three start options are provided: + * + * TRC_START: Starts the tracing directly. In snapshot mode this allows for + * starting the trace at any point in your code, assuming xTraceInitialize() + * has been called in the startup. Can also be used for streaming without + * Tracealyzer control, e.g. to a local flash file system (assuming such a + * "stream port", see trcStreamPort.h). + * + * TRC_START_AWAIT_HOST: For streaming mode only. Initializes the trace recorder + * if necessary and waits for a Start command from Tracealyzer ("Start Recording" + * button). This call is intentionally blocking! By calling xTraceEnable with + * this option from the startup code, you start tracing at this point and capture + * the early events. + * + * TRC_START_FROM_HOST: For streaming mode only. Initializes the trace recorder + * if necessary and creates a task that waits for a Start command from + * Tracealyzer ("Start Recording" button). This call is not blocking. + * + * @example Usage examples + * + * Snapshot trace, from startup: + * + * xTraceEnable(TRC_START); // Will call xTraceInitialize() + * + * + * Snapshot trace, from a later point: + * + * xTraceInitialize(); + * + * ... + * xTraceEnable(TRC_START); // e.g., in task context, at some relevant event + * + * Streaming trace, from startup (can only be used with certain stream ports): + * + * xTraceInitialize(); + * + * xTraceEnable(TRC_START); + * + * Streaming trace, from startup: + * + * xTraceEnable(TRC_START_AWAIT_HOST); // Blocks! + * + * + * Streaming trace, from a later point: + * + * xTraceInitialize(); + * + * xTraceEnable(TRC_START); + * + * Streaming trace, system executes normally until host starts tracing: + * + * xTraceInitialize(); + * + * xTraceEnable(TRC_START_FROM_HOST) + * + * @param[in] uiStartOption Start option. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceEnable( uint32_t uiStartOption ); + +/** + * @brief Disables tracing. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceDisable( void ); + +/** + * @brief + * + * For snapshot mode only: Sets the "filter group" to assign when creating + * RTOS objects, such as tasks, queues, semaphores and mutexes. This together + * with vTraceSetFilterMask allows you to control what events that are recorded, + * based on the objects they refer to. + * + * There are 16 filter groups named FilterGroup0 .. FilterGroup15. + * + * Note: We don't recommend filtering out the Idle task, so make sure to call + * vTraceSetFilterGroup just before initializing the RTOS, in order to assign + * such "default" objects to the right Filter Group (typically group 0). + * + * Example: + * + * // Assign tasks T1 to FilterGroup0 (default) + * + * + * // Assign Q1 and Q2 to FilterGroup1 + * vTraceSetFilterGroup(FilterGroup1); + * + * + * + * // Assigns Q3 to FilterGroup2 + * vTraceSetFilterGroup(FilterGroup2); + * + * + * // Only include FilterGroup0 and FilterGroup2, exclude FilterGroup1 (Q1 and Q2) from the trace + * vTraceSetFilterMask( FilterGroup0 | FilterGroup2 ); + * + * // Assign the default RTOS objects (e.g. Idle task) to FilterGroup0 + * vTraceSetFilterGroup(FilterGroup0); + * + * + * Note that you may define your own names for the filter groups using + * preprocessor definitions, to make the code easier to understand. + * + * Example: + * + * #define BASE FilterGroup0 + * #define USB_EVENTS FilterGroup1 + * #define CAN_EVENTS FilterGroup2 + * + * Note that filtering per event type (regardless of object) is also available + * in trcKernelPortConfig.h for certain kernels. + * + * @param[in] filterGroup Filter group + */ + void vTraceSetFilterGroup( uint16_t filterGroup ); + +/** + * @brief + * + * For snapshot mode only: Sets the "filter mask" that is used to filter + * the events by object. This can be used to reduce the trace data rate, i.e., + * if your streaming interface is a bottleneck or if you want longer snapshot + * traces without increasing the buffer size. + * + * Note: There are two kinds of filters in the recorder. The other filter type + * excludes all events of certain kinds (e.g., OS ticks). See trcConfig.h. + * + * The filtering is based on bitwise AND with the Filter Group ID, assigned + * to RTOS objects such as tasks, queues, semaphores and mutexes. + * This together with vTraceSetFilterGroup allows you to control what + * events that are recorded, based on the objects they refer to. + * + * See example for vTraceSetFilterGroup. + * + * @param[in] filterMask Filter mask + */ + void vTraceSetFilterMask( uint16_t filterMask ); + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) + + #include + +/** + * @brief Returns lower 16 bits of a value + * + * @param[in] value The starting value + */ + #define TRACE_GET_LOW16( value ) ( ( uint16_t ) ( ( value ) & 0x0000FFFF ) ) + +/** + * @brief Returns upper 16 bits + * + * @param[in] value The starting value + */ + #define TRACE_GET_HIGH16( value ) ( ( uint16_t ) ( ( ( value ) >> 16 ) & 0x0000FFFF ) ) + +/** + * @brief Sets lower 16 bits + * + * @param[in] current The starting value + * @param[in] value The value to set + */ + #define TRACE_SET_LOW16( current, value ) ( ( ( current ) & 0xFFFF0000 ) | ( value ) ) + +/** + * @brief Sets upper 16 bits + * + * @param[in] current The starting value + * @param[in] value The value to set + */ + #define TRACE_SET_HIGH16( current, value ) ( ( ( current ) & 0x0000FFFF ) | ( ( ( uint32_t ) ( value ) ) << 16 ) ) + + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) + +/** + * @brief Adds a task to the stack monitor + * + * @param[in] task The task + */ + void prvAddTaskToStackMonitor( void * task ); + +/** + * @brief Remove a task from the stack monitor + * + * @param[in] task The task + */ + void prvRemoveTaskFromStackMonitor( void * task ); + +/** + * @brief Reports on the current stack usage + */ + void prvReportStackUsage( void ); + + #else /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ + + #define prvAddTaskToStackMonitor( task ) + #define prvRemoveTaskFromStackMonitor( task ) + #define prvReportStackUsage() + + #endif /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ + +/** + * @brief Query if recorder is enabled + * + * @retval 1 if recorder is enabled + * @retval 0 if recorder is disabled + */ + uint32_t xTraceIsRecorderEnabled( void ); + +/** + * @brief + * + * @retval 1 if recorder is initialized + * @retval 0 if recorder isn't initialized + */ + uint32_t xTraceIsRecorderInitialized( void ); + +/** + * @brief + * + * Creates an event that ends the current task instance at this very instant. + * This makes the viewer to splits the current fragment at this point and begin + * a new actor instance, even if no task-switch has occurred. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskInstanceFinishedNow( void ); + +/** + * @brief + * + * Marks the current "task instance" as finished on the next kernel call. + * + * If that kernel call is blocking, the instance ends after the blocking event + * and the corresponding return event is then the start of the next instance. + * If the kernel call is not blocking, the viewer instead splits the current + * fragment right before the kernel call, which makes this call the first event + * of the next instance. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskInstanceFinishedNext( void ); + +/** + * @brief Registers a string and returns a handle that can be used when tracing + * + * @param[in] label Label + * @param[out] pxString String handle + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStringRegister( const char * label, + TraceStringHandle_t * pxString ); + +/** + * @brief Registers a string and returns a handle that can be used when tracing + * + * @deprecated Backwards compatibility + * + * @param[in] name Name. + * + * @return TraceStringHandle_t String handle + */ + TraceStringHandle_t xTraceRegisterString( const char * name ); + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) + +/** + * @brief + * + * Generates "User Events", with formatted text and data, similar to a "printf". + * User Events can be used for very efficient logging from your application code. + * It is very fast since the actual string formatting is done on the host side, + * when the trace is displayed. The execution time is just some microseconds on + * a 32-bit MCU. + * + * User Events are shown as yellow labels in the main trace view of $PNAME. + * + * An advantage of User Events is that data can be plotted in the "User Event + * Signal Plot" view, visualizing any data you log as User Events, discrete + * states or control system signals (e.g. system inputs or outputs). + * + * You may group User Events into User Event Channels. The yellow User Event + * labels show the logged string, preceded by the channel name within brackets. + * + * Example: + * + * "[MyChannel] Hello World!" + * + * The User Event Channels are shown in the View Filter, which makes it easy to + * select what User Events you wish to display. User Event Channels are created + * using xTraceStringRegister(). + * + * Example: + * + * TraceStringHandle_t adc_uechannel; + * xTraceStringRegister("ADC User Events", &adc_uechannel); + * ... + * xTracePrintF(adc_uechannel, + * "ADC channel %d: %d volts", + * ch, adc_reading); + * + * The following format specifiers are supported in both modes: + * %d - signed integer. + * %u - unsigned integer. + * %X - hexadecimal, uppercase. + * %x - hexadecimal, lowercase. + * %s - string (see comment below) + * + * For integer formats (%d, %u, %x, %X) you may also use width and padding. + * If using -42 as data argument, two examples are: + * "%05d" -> "-0042" + * "%5d" -> " -42". + * + * String arguments are supported in both snapshot and streaming, but in streaming + * mode you need to use xTraceStringRegister and use the returned TraceStringHandle_t as + * the argument. In snapshot you simply provide a char* as argument. + * + * Snapshot: xTracePrintF(myChn, "my string: %s", str); + * Streaming: xTracePrintF(myChn, "my string: %s", strTraceString); + * + * In snapshot mode you can specify 8-bit or 16-bit arguments to reduce RAM usage: + * %hd -> 16 bit (h) signed integer (d). + * %bu -> 8 bit (b) unsigned integer (u). + * + * However, in streaming mode all data arguments are assumed to be 32 bit wide. + * Width specifiers (e.g. %hd) are accepted but ignored (%hd treated like %d). + * + * The maximum event size also differs between the modes. In streaming this is + * limited by a maximum payload size of 52 bytes, including format string and + * data arguments. So if using one data argument, the format string is limited + * to 48 byte, etc. If this is exceeded, the format string is truncated and you + * get a warning in Tracealyzer. + * + * In snapshot mode you are limited to maximum 15 arguments, that must not exceed + * 32 bytes in total (not counting the format string). If exceeded, the recorder + * logs an internal error (displayed when opening the trace) and stops recording. + * + * @param[in] chn Channel. + * @param[in] fmt Formatting. + * @param[in] ... + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTracePrintF( TraceStringHandle_t chn, + const char * fmt, + ... ); + #else + #define xTracePrintF( chn, fmt, ... ) ( ( void ) ( chn ), ( void ) ( fmt ), TRC_SUCCESS ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ + #endif + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) + +/** + * @brief + * + * xTracePrintF variant that accepts a va_list. + * See xTracePrintF documentation for further details. + * + * @param[in] eventLabel + * @param[in] formatStr + * @param[in] vl + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceVPrintF( TraceStringHandle_t eventLabel, + const char * formatStr, + va_list vl ); + #else + #define xTraceVPrintF( chn, formatStr, vl ) ( ( void ) ( chn ), ( void ) ( formatStr ), ( void ) ( vl ), TRC_SUCCESS ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ + #endif + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) + +/** + * @brief A faster version of xTracePrintF, that only allows for logging a string. + * + * Example: + * + * TraceStringHandle_t chn; + * xTraceStringRegister("MyChannel", &chn); + * ... + * xTracePrint(chn, "Hello World!"); + * + * @param[in] chn Channel. + * @param[in] str String. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTracePrint( TraceStringHandle_t chn, + const char * str ); + #else + #define xTracePrint( chn, str ) ( ( void ) ( chn ), ( void ) ( str ), TRC_SUCCESS ) + #endif + +/******************************************************************************/ +/*** Extended API for Snapshot mode *******************************************/ +/******************************************************************************/ + +/** + * @brief Trace stop callback type. + */ + typedef void (* TRACE_STOP_HOOK)( void ); + +/** + * @brief Sets a function to be called when the recorder is stopped. + * + * @note Snapshot mode only! + * + * @param[in] stopHookFunction + */ + void vTraceSetStopHook( TRACE_STOP_HOOK stopHookFunction ); + +/** + * @brief + * + * Resets the recorder. + * + * Only necessary if a restart is desired - this is not + * needed in the startup initialization. + * + * @note Snapshot mode only! + */ + void vTraceClear( void ); + +/*****************************************************************************/ +/*** INTERNAL SNAPSHOT FUNCTIONS *********************************************/ +/*****************************************************************************/ + + #define TRC_UNUSED + + #ifndef TRC_CFG_INCLUDE_OBJECT_DELETE + #define TRC_CFG_INCLUDE_OBJECT_DELETE 0 + #endif + + #ifndef TRC_CFG_INCLUDE_READY_EVENTS + #define TRC_CFG_INCLUDE_READY_EVENTS 1 + #endif + + #ifndef TRC_CFG_INCLUDE_OSTICK_EVENTS + #define TRC_CFG_INCLUDE_OSTICK_EVENTS 0 + #endif + +/* This macro will create a task in the object table */ + #undef trcKERNEL_HOOKS_TASK_CREATE + #define trcKERNEL_HOOKS_TASK_CREATE( SERVICE, CLASS, pxTCB ) \ + if( ( pxTCB ) != 0 ) \ + { \ + TRACE_SET_OBJECT_NUMBER( TASK, pxTCB ); \ + TRACE_SET_OBJECT_FILTER( TASK, pxTCB, CurrentFilterGroup ); \ + prvTraceSetObjectName( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_GET_TASK_NAME( pxTCB ) ); \ + prvTraceSetPriorityProperty( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_GET_TASK_PRIORITY( pxTCB ) ); \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ); \ + } \ + else \ + { \ + /* pxTCB is null */ \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + { \ + prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, 0 ); \ + } \ + } + +/* This macro will remove the task and store it in the event buffer */ + #undef trcKERNEL_HOOKS_TASK_DELETE + #define trcKERNEL_HOOKS_TASK_DELETE( SERVICE, SERVICE_NAME, SERVICE_PROP, pxTCB ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ); \ + prvTraceStoreObjectNameOnCloseEvent( SERVICE_NAME, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_CLASS_TASK ); \ + prvTraceStoreObjectPropertiesOnCloseEvent( SERVICE_PROP, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_CLASS_TASK ); \ + prvTraceSetPriorityProperty( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_GET_TASK_PRIORITY( pxTCB ) ); \ + prvTraceSetObjectState( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), TASK_STATE_INSTANCE_NOT_ACTIVE ); \ + prvTraceFreeObjectHandle( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ); + + +/* This macro will setup a task in the object table */ + #undef trcKERNEL_HOOKS_OBJECT_CREATE + #define trcKERNEL_HOOKS_OBJECT_CREATE( SERVICE, CLASS, pxObject ) \ + TRACE_SET_OBJECT_NUMBER( CLASS, pxObject ); \ + TRACE_SET_OBJECT_FILTER( CLASS, pxObject, CurrentFilterGroup ); \ + prvMarkObjectAsUsed( TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) ); \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) ); \ + prvTraceSetObjectState( TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), 0 ); + +/* This macro will setup a task in the object table */ + #undef trcKERNEL_HOOKS_OBJECT_CREATE_FAILED + #define trcKERNEL_HOOKS_OBJECT_CREATE_FAILED( SERVICE, TRACE_CLASS ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + { \ + prvTraceStoreKernelCall( SERVICE, TRACE_CLASS, 0 ); \ + } + +/* This macro will remove the object and store it in the event buffer */ + #undef trcKERNEL_HOOKS_OBJECT_DELETE + #define trcKERNEL_HOOKS_OBJECT_DELETE( SERVICE, SERVICE_NAME, SERVICE_PROP, CLASS, pxObject ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) ); \ + prvTraceStoreObjectNameOnCloseEvent( SERVICE_NAME, TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ) ); \ + prvTraceStoreObjectPropertiesOnCloseEvent( SERVICE_PROP, TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ) ); \ + prvTraceFreeObjectHandle( TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) ); + +/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE + #define trcKERNEL_HOOKS_KERNEL_SERVICE( SERVICE, CLASS, pxObject ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) ); + +/* This macro will create a call to a kernel service with a certain result, with a null object as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT + #define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT( SERVICE, TRACECLASS ) \ + if( TRACE_GET_TASK_FILTER( TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACECLASS, 0 ); + +/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM + #define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( SERVICE, CLASS, pxObject, param ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \ + prvTraceStoreKernelCallWithParam( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), ( uint32_t ) param ); + +/* This macro will create a call to a kernel service with a certain result, with a null object and other value as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM + #define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM( SERVICE, TRACECLASS, param ) \ + if( TRACE_GET_TASK_FILTER( TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + prvTraceStoreKernelCallWithParam( SERVICE, TRACECLASS, 0, param ); + +/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY + #define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY( SERVICE, param ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + prvTraceStoreKernelCallWithNumericParamOnly( SERVICE, ( uint32_t ) param ); + +/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR + #define trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( SERVICE, CLASS, pxObject ) \ + if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) ); + +/* This macro will create a call to a kernel service with a certain result, with a null object as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR + #define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR( SERVICE, TRACECLASS ) \ + prvTraceStoreKernelCall( SERVICE, TRACECLASS, 0 ); + +/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR + #define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR( SERVICE, CLASS, pxObject, param ) \ + if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \ + prvTraceStoreKernelCallWithParam( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), ( uint32_t ) param ); + +/* This macro will create a call to a kernel service with a certain result, with a null object and other value as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR + #define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR( SERVICE, TRACECLASS, param ) \ + prvTraceStoreKernelCallWithParam( SERVICE, TRACECLASS, 0, param ); + +/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ + #undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR + #define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR( SERVICE, param ) \ + prvTraceStoreKernelCallWithNumericParamOnly( SERVICE, ( uint32_t ) param ); + +/* This macro will set the state for an object */ + #undef trcKERNEL_HOOKS_SET_OBJECT_STATE + #define trcKERNEL_HOOKS_SET_OBJECT_STATE( CLASS, pxObject, STATE ) \ + prvTraceSetObjectState( TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), ( uint8_t ) STATE ); + +/* This macro will flag a certain task as a finished instance */ + #undef trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED + #define trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED() \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + prvTraceSetTaskInstanceFinished( TRACE_GET_TASK_NUMBER( TRACE_GET_CURRENT_TASK() ) ); + + #if ( TRC_CFG_INCLUDE_READY_EVENTS == 1 ) +/* This macro will create an event to indicate that a task became Ready */ + #undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE + #define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE( pxTCB ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \ + prvTraceStoreTaskReady( TRACE_GET_TASK_NUMBER( pxTCB ) ); + #else /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/ + #undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE + #define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE( pxTCB ) + #endif /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/ + +/* This macro will update the internal tick counter and call prvTracePortGetTimeStamp(0) to update the internal counters */ + #undef trcKERNEL_HOOKS_INCREMENT_TICK + #define trcKERNEL_HOOKS_INCREMENT_TICK() \ + { \ + extern uint32_t uiTraceTickCount; \ + uiTraceTickCount++; \ + prvTracePortGetTimeStamp( 0 ); \ + } + + #if ( TRC_CFG_INCLUDE_OSTICK_EVENTS == 1 ) +/* This macro will create an event indicating that the OS tick count has increased */ + #undef trcKERNEL_HOOKS_NEW_TIME + #define trcKERNEL_HOOKS_NEW_TIME( SERVICE, xValue ) \ + prvTraceStoreKernelCallWithNumericParamOnly( SERVICE, xValue ); + #else /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/ + #undef trcKERNEL_HOOKS_NEW_TIME + #define trcKERNEL_HOOKS_NEW_TIME( SERVICE, xValue ) + #endif /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/ + +/* This macro will create a task switch event to the currently executing task */ + #undef trcKERNEL_HOOKS_TASK_SWITCH + #define trcKERNEL_HOOKS_TASK_SWITCH( pxTCB ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \ + prvTraceStoreTaskswitch( TRACE_GET_TASK_NUMBER( pxTCB ) ); + +/* This macro will create an event to indicate that the task has been suspended */ + #undef trcKERNEL_HOOKS_TASK_SUSPEND + #define trcKERNEL_HOOKS_TASK_SUSPEND( SERVICE, pxTCB ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ); \ + prvTraceSetTaskInstanceFinished( ( uint8_t ) TRACE_GET_TASK_NUMBER( pxTCB ) ); + +/* This macro will create an event to indicate that a task has called a wait/delay function */ + #undef trcKERNEL_HOOKS_TASK_DELAY + #define trcKERNEL_HOOKS_TASK_DELAY( SERVICE, pxTCB, xValue ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \ + { \ + prvTraceStoreKernelCallWithNumericParamOnly( SERVICE, xValue ); \ + prvTraceSetTaskInstanceFinished( ( uint8_t ) TRACE_GET_TASK_NUMBER( pxTCB ) ); \ + } + +/* This macro will create an event to indicate that a task has gotten its priority changed */ + #undef trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE + #define trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE( SERVICE, pxTCB, uxNewPriority ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \ + { \ + prvTraceStoreKernelCallWithParam( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), prvTraceGetPriorityProperty( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ) ); \ + prvTraceSetPriorityProperty( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), ( uint8_t ) uxNewPriority ); \ + } + +/* This macro will create an event to indicate that the task has been resumed */ + #undef trcKERNEL_HOOKS_TASK_RESUME + #define trcKERNEL_HOOKS_TASK_RESUME( SERVICE, pxTCB ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ); + +/* This macro will create an event to indicate that the task has been resumed from ISR */ + #undef trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR + #define trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR( SERVICE, pxTCB ) \ + if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \ + prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ); + + #if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1 + +/** + * @brief Dynamically enables ready events + * + * @param[in] flag Flag + */ + void prvTraceSetReadyEventsEnabled( uint32_t flag ); + +/** + * @brief Stores a Task Ready event + * + * @param[in] handle Task handle + */ + void prvTraceStoreTaskReady( traceHandle handle ); + #else + #define prvTraceSetReadyEventsEnabled( status ) ( void ) status; + #endif + +/** + * @brief Stores a Low Power mode event + * + * @param[in] flag Flag + */ + void prvTraceStoreLowPower( uint32_t flag ); + +/** + * @brief Stores a Task Switch event + * + * @param[in] task_handle Task + */ + void prvTraceStoreTaskswitch( traceHandle task_handle ); + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + +/** + * @brief Stores a Kernel Service call event with an Object handle parameter + * + * @param[in] eventcode Event code + * @param[in] objectClass Object class + * @param[in] objectNumber Object handle + */ + void prvTraceStoreKernelCall( uint32_t eventcode, + traceObjectClass objectClass, + uint32_t objectNumber ); + +/** + * @brief Stores a Kernel Service call event with only a numeric parameter + * + * @param[in] evtcode Event code + * @param[in] param Parameter + */ + void prvTraceStoreKernelCallWithNumericParamOnly( uint32_t evtcode, + uint32_t param ); + +/** + * @brief Stores a Kernel Service call event with an Object handle and a numeric parameter + * + * @param[in] evtcode Event code + * @param[in] objectClass Object class + * @param[in] objectNumber Object handle + * @param[in] param Parameter + */ + void prvTraceStoreKernelCallWithParam( uint32_t evtcode, + traceObjectClass objectClass, + uint32_t objectNumber, + uint32_t param ); + #else /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + + #define prvTraceStoreKernelCall( eventcode, objectClass, byteParam ) {} + #define prvTraceStoreKernelCallWithNumericParamOnly( evtcode, param ) {} + #define prvTraceStoreKernelCallWithParam( evtcode, objectClass, objectNumber, param ) {} + + #endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + +/** + * @brief Flags a task instance as finished + * + * @param[in] handle Task handle + */ + void prvTraceSetTaskInstanceFinished( traceHandle handle ); + +/** + * @brief Set priority + * + * @param[in] objectclass Object class + * @param[in] id Object handle + * @param[in] value Value + */ + void prvTraceSetPriorityProperty( uint8_t objectclass, + traceHandle id, + uint8_t value ); + +/** + * @brief Get priority + * + * @param[in] objectclass Object class + * @param[in] id Object handle + * + * @return uint8_t Value + */ + uint8_t prvTraceGetPriorityProperty( uint8_t objectclass, + traceHandle id ); + +/** + * @brief Set object state + * + * @param[in] objectclass Object class + * @param[in] id Object handle + * @param[in] value Value + */ + void prvTraceSetObjectState( uint8_t objectclass, + traceHandle id, + uint8_t value ); + +/** + * @brief Mark object as used + * + * @param[in] objectclass Object class + * @param[in] handle Object handle + */ + void prvMarkObjectAsUsed( traceObjectClass objectclass, + traceHandle handle ); + +/** + * @brief Stores the name of an object because it is being deleted + * + * @param[in] evtcode Event code + * @param[in] handle Object handle + * @param[in] objectclass Object class + */ + void prvTraceStoreObjectNameOnCloseEvent( uint8_t evtcode, + traceHandle handle, + traceObjectClass objectclass ); + +/** + * @brief Stores the property of an object because it is being deleted + * + * @param[in] evtcode Event code + * @param[in] handle Object handle + * @param[in] objectclass Object class + */ + void prvTraceStoreObjectPropertiesOnCloseEvent( uint8_t evtcode, + traceHandle handle, + traceObjectClass objectclass ); + +/* Internal constants for task state */ + #define TASK_STATE_INSTANCE_NOT_ACTIVE 0 + #define TASK_STATE_INSTANCE_ACTIVE 1 + + + #if ( TRC_CFG_INCLUDE_ISR_TRACING == 0 ) + + #undef vTraceSetISRProperties + #define vTraceSetISRProperties( handle, name, priority ) ( void ) ( handle ), ( void ) ( name ), ( void ) ( priority ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ + + #undef vTraceStoreISRBegin + #define vTraceStoreISRBegin( x ) ( void ) ( x ) + + #undef vTraceStoreISREnd + #define vTraceStoreISREnd( x ) ( void ) ( x ) + + #undef xTraceSetISRProperties + #define xTraceSetISRProperties( name, priority ) ( ( void ) ( name ), ( void ) ( priority ), ( traceHandle ) 0 ) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */ + + #endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/ + +/** + * @brief + * + * Returns a pointer to the recorder data structure. Use this together with + * uiTraceGetTraceBufferSize if you wish to implement an own store/upload + * solution, e.g., in case a debugger connection is not available for uploading + * the data. + * + * @return void* Buffer pointer + */ + void * xTraceGetTraceBuffer( void ); + +/** + * @brief + * + * Gets the size of the recorder data structure. For use together with + * xTraceGetTraceBuffer if you wish to implement an own store/upload solution, + * e.g., in case a debugger connection is not available for uploading the data. + * + * @return uint32_t Buffer size + */ + uint32_t uiTraceGetTraceBufferSize( void ); + + #if ( TRC_CFG_SCHEDULING_ONLY == 1 ) + #undef TRC_CFG_INCLUDE_USER_EVENTS + #define TRC_CFG_INCLUDE_USER_EVENTS 0 + #endif /*(TRC_CFG_SCHEDULING_ONLY == 1)*/ + + #if ( ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) + +/** + * @brief Register a channel and fixed format string for use with the separate User Event Buffer functions + * + * @param[in] channel Channel name handle + * @param[in] formatStr Format string that will be used for all events on this channel + * + * @return traceUBChannel Channel handle + */ + traceUBChannel xTraceRegisterUBChannel( TraceStringHandle_t channel, + TraceStringHandle_t formatStr ); + +/** + * @brief Creates a User Event using the channel, previously set format string and data parameters + * + * @param[in] channel Channel + * @param[in] ... + */ + void vTraceUBData( traceUBChannel channel, + ... ); + +/** + * @brief Creates a User Event using the channel and previously set string + * + * @param[in] channel Channel + */ + void vTraceUBEvent( traceUBChannel channel ); + #else /* if ( ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) */ + #define xTraceRegisterChannelFormat( eventLabel, formatStr ) ( ( void ) ( eventLabel ), ( void ) ( formatStr ), 0 ) + #define vTraceUBData( label, ... ) ( void ) ( label ) + #endif /*(TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)*/ + + #define NEventCodes 0x100 + +/* Our local critical sections for the recorder */ + #define trcCRITICAL_SECTION_BEGIN() { TRACE_ENTER_CRITICAL_SECTION(); recorder_busy++; } + #define trcCRITICAL_SECTION_END() { recorder_busy--; TRACE_EXIT_CRITICAL_SECTION(); } + + #if ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M ) + #define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY TRACE_ALLOC_CRITICAL_SECTION + #define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_BEGIN + #define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_END + #else + #define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY() {} + #define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY() recorder_busy++; + #define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--; + #endif + +/** + * @brief Object handle stack struct. + * + * This data-structure is used to provide a mechanism for 1-byte trace object + * handles. This way, only 1 byte is necessary instead of 4 bytes (a pointer) + * when storing a reference to an object. This allows for up to 255 objects of + * each object class active at any given moment. There can be more "historic" + * objects, that have been deleted - that number is only limited by the size of + * the symbol table. + * + * Note that handle zero (0) is not used, it is a code for an invalid handle. + * + * This data structure keeps track of the FREE handles, not the handles in use. + * This data structure contains one stack per object class. When a handle is + * allocated to an object, the next free handle is popped from the stack. When + * a handle is released (on object delete), it is pushed back on the stack. + * Note that there is no initialization code that pushed the free handles + * initially, that is not necessary due to the following optimization: + * + * The stack of handles (objectHandles) is initially all zeros. Since zero + * is not a valid handle, that is a signal of additional handles needed. + * If a zero is received when popping a new handle, it is replaced by the + * index of the popped handle instead. + */ + typedef struct + { + uint16_t indexOfNextAvailableHandle[ TRACE_NCLASSES ]; /**< For each object class, the index of the next handle to allocate */ + uint16_t lowestIndexOfClass[ TRACE_NCLASSES ]; /**< The lowest index of this class (constant) */ + uint16_t highestIndexOfClass[ TRACE_NCLASSES ]; /**< The highest index of this class (constant) */ + uint16_t handleCountWaterMarksOfClass[ TRACE_NCLASSES ]; /**< The highest use count for this class (for statistics) */ + traceHandle objectHandles[ TRACE_KERNEL_OBJECT_COUNT ]; /**< The free object handles - a set of stacks within this array */ + } objectHandleStackType; + + extern objectHandleStackType objectHandleStacks; + +/** + * @brief Object property table struct + * + * The Object Table contains name and other properties of the objects (tasks, + * queues, mutexes, etc). The below data structures defines the properties of + * each object class and are used to cast the byte buffer into a cleaner format. + * + * The values in the object table are continuously overwritten and always + * represent the current state. If a property is changed during runtime, the OLD + * value should be stored in the trace buffer, not the new value (since the new + * value is found in the Object Property Table). + * + * For close events this mechanism is the old names are stored in the symbol + * table), for "priority set" (the old priority is stored in the event data) + * and for "isActive", where the value decides if the task switch event type + * should be "new" or "resume". + */ + typedef struct + { + /* = NCLASSES */ + uint32_t NumberOfObjectClasses; /**< */ + uint32_t ObjectPropertyTableSizeInBytes; /**< */ + + /* This is used to calculate the index in the dynamic object table + * (handle - 1 - nofStaticObjects = index)*/ + #if ( TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1 ) + traceHandle NumberOfObjectsPerClass[ 2 * ( ( TRACE_NCLASSES + 1 ) / 2 ) ]; /** */ + #else + traceHandle NumberOfObjectsPerClass[ 4 * ( ( TRACE_NCLASSES + 3 ) / 4 ) ]; /** */ + #endif + /* Allocation size rounded up to the closest multiple of 4 */ + uint8_t NameLengthPerClass[ 4 * ( ( TRACE_NCLASSES + 3 ) / 4 ) ]; /**< */ + + /* Allocation size rounded up to the closest multiple of 2 */ + uint8_t TotalPropertyBytesPerClass[ 4 * ( ( TRACE_NCLASSES + 3 ) / 4 ) ]; /**< */ + + /* */ + uint16_t StartIndexOfClass[ 2 * ( ( TRACE_NCLASSES + 1 ) / 2 ) ]; /**< */ + + /* The actual handles issued, should be Initiated to all zeros */ + uint8_t objbytes[ 4 * ( ( TRACE_OBJECT_TABLE_SIZE + 3 ) / 4 ) ]; /**< */ + } ObjectPropertyTableType; + +/** + * @brief Symbol table structure + */ + typedef struct + { + /* = SYMBOL_HISTORY_TABLE_SIZE_IN_BYTES */ + uint32_t symTableSize; /**< */ + + /* Entry 0 is reserved. Any reference to entry 0 implies NULL*/ + uint32_t nextFreeSymbolIndex; /**< */ + + /* Size rounded up to closest multiple of 4, to avoid alignment issues*/ + uint8_t symbytes[ 4 * ( ( ( TRC_CFG_SYMBOL_TABLE_SIZE ) + 3 ) / 4 ) ]; /**< */ + + /* Used for lookups - Up to 64 linked lists within the symbol table + * connecting all entries with the same 6 bit checksum. + * This field holds the current list heads. Should be initiated to zeros */ + uint16_t latestEntryOfChecksum[ 64 ]; /**< */ + } symbolTableType; + + +/******************************************************************************* + * The data structures of the different events, all 4 bytes long + ******************************************************************************/ + + typedef struct + { + uint8_t type; + uint8_t objHandle; + uint16_t dts; /* differential timestamp - time since last event */ + } TSEvent, TREvent; + + typedef struct + { + uint8_t type; + uint8_t dummy; + uint16_t dts; /* differential timestamp - time since last event */ + } LPEvent; + + typedef struct + { + uint8_t type; + uint8_t objHandle; + uint16_t dts; /* differential timestamp - time since last event */ + } KernelCall; + + typedef struct + { + uint8_t type; + uint8_t objHandle; + uint8_t param; + uint8_t dts; /* differential timestamp - time since last event */ + } KernelCallWithParamAndHandle; + + typedef struct + { + uint8_t type; + uint8_t dts; /* differential timestamp - time since last event */ + uint16_t param; + } KernelCallWithParam16; + + typedef struct + { + uint8_t type; + uint8_t objHandle; /* the handle of the closed object */ + uint16_t symbolIndex; /* the name of the closed object */ + } ObjCloseNameEvent; + + typedef struct + { + uint8_t type; + uint8_t arg1; + uint8_t arg2; + uint8_t arg3; + } ObjClosePropEvent; + + typedef struct + { + uint8_t type; + uint8_t unused1; + uint8_t unused2; + uint8_t dts; + } TaskInstanceStatusEvent; + + typedef struct + { + uint8_t type; + uint8_t dts; + uint16_t payload; /* the name of the user event */ + } UserEvent; + + typedef struct + { + uint8_t type; + + /* 8 bits extra for storing DTS, if it does not fit in ordinary event + * (this one is always MSB if used) */ + uint8_t xts_8; + + /* 16 bits extra for storing DTS, if it does not fit in ordinary event. */ + uint16_t xts_16; + } XTSEvent; + + typedef struct + { + uint8_t type; + + uint8_t xps_8; + uint16_t xps_16; + } XPSEvent; + + typedef struct + { + uint8_t type; + uint8_t dts; + uint16_t size; + } MemEventSize; + + typedef struct + { + uint8_t type; + uint8_t addr_high; + uint16_t addr_low; + } MemEventAddr; + +/******************************************************************************* + * The separate user event buffer structure. Can be enabled in trcConfig.h. + ******************************************************************************/ + + #if ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) + typedef struct + { + TraceStringHandle_t name; + TraceStringHandle_t defaultFormat; + } ChannelFormatPair; + + typedef struct + { + uint16_t bufferID; + uint16_t version; + uint32_t wraparoundCounter; + uint32_t numberOfSlots; + uint32_t nextSlotToWrite; + uint8_t numberOfChannels; + uint8_t padding1; + uint8_t padding2; + uint8_t padding3; + ChannelFormatPair channels[ ( TRC_CFG_UB_CHANNELS ) + 1 ]; + uint8_t channelBuffer[ ( ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) + 3 ) & 0xFFFFFFFC ]; /* 1 byte per slot, with padding for 4 byte alignment */ + uint8_t dataBuffer[ ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) * 4 ]; /* 4 bytes per slot */ + } UserEventBuffer; + #endif /* (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) */ + +/******************************************************************************* + * The main data structure, read by Tracealyzer from the RAM dump + ******************************************************************************/ + + typedef struct + { + volatile uint8_t startmarker0; /* Volatile is important, see init code. */ + volatile uint8_t startmarker1; + volatile uint8_t startmarker2; + volatile uint8_t startmarker3; + volatile uint8_t startmarker4; + volatile uint8_t startmarker5; + volatile uint8_t startmarker6; + volatile uint8_t startmarker7; + volatile uint8_t startmarker8; + volatile uint8_t startmarker9; + volatile uint8_t startmarker10; + volatile uint8_t startmarker11; + + /* Used to determine Kernel and Endianess */ + uint16_t version; + + /* Currently 7 */ + uint8_t minor_version; + + /* This should be 0 if lower IRQ priority values implies higher priority + * levels, such as on ARM Cortex M. If the opposite scheme is used, i.e., + * if higher IRQ priority values means higher priority, this should be 1. */ + uint8_t irq_priority_order; + + /* sizeof(RecorderDataType) - just for control */ + uint32_t filesize; + + /* Current number of events recorded */ + uint32_t numEvents; + + /* The buffer size, in number of event records */ + uint32_t maxEvents; + + /* The event buffer index, where to write the next event */ + uint32_t nextFreeIndex; + + /* 1 if the buffer is full, 0 otherwise */ + uint32_t bufferIsFull; + + /* The frequency of the clock/timer/counter used as time base */ + uint32_t frequency; + + /* The absolute timestamp of the last stored event, in the native + * timebase, modulo frequency! */ + uint32_t absTimeLastEvent; + + /* The number of seconds in total - lasts for 136 years */ + uint32_t absTimeLastEventSecond; + + /* 1 if the recorder has been started, 0 if not yet started or stopped. + * This is a 32 bit variable due to alignment issues. */ + uint32_t recorderActive; + + /* If > 0, tells the maximum time between two traced ISRs that execute + * back-to-back. If the time between vTraceStoreISREnd and a directly + * following vTraceISRBegin is above isrTailchainingThreshold, we assume a + * return to the previous context in between the ISRs, otherwise we assume + * the have executed back-to-back and don't show any fragment of the previous + * context in between. */ + uint32_t isrTailchainingThreshold; + + /* The maximum amount of heap memory that was allocated */ + uint32_t heapMemMaxUsage; + + /* The amount of heap memory used */ + uint32_t heapMemUsage; + + /* 0xF0F0F0F0 - for control only */ + int32_t debugMarker0; + + /* Set to value of TRC_CFG_USE_16BIT_OBJECT_HANDLES */ + uint32_t isUsing16bitHandles; + + /* The Object Property Table holds information about currently active + * tasks, queues, and other recorded objects. This is updated on each + * create call and includes object name and other properties. */ + ObjectPropertyTableType ObjectPropertyTable; + + /* 0xF1F1F1F1 - for control only */ + int32_t debugMarker1; + + /* The Symbol Table stores strings for User Events and is also used to + * store names of deleted objects, which still may be in the trace but no + * longer are available. */ + symbolTableType SymbolTable; + + /* For inclusion of float support, and for endian detection of floats. + * The value should be (float)1 or (uint32_t)0 */ + #if ( TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1 ) + float exampleFloatEncoding; + #else + uint32_t exampleFloatEncoding; + #endif + + /* This is non-zero if an internal error occurred in the recorder, e.g., if + * one of the Nxxx constants was too small. The systemInfo string will then + * contain an error message that is displayed when attempting to view the + * trace file. */ + uint32_t internalErrorOccurred; + + /* 0xF2F2F2F2 - for control only */ + int32_t debugMarker2; + + /* Error messages from the recorder. */ + char systemInfo[ 80 ]; + + /* 0xF3F3F3F3 - for control only */ + int32_t debugMarker3; + + /* The event data, in 4-byte records */ + uint8_t eventData[ ( TRC_CFG_EVENT_BUFFER_SIZE ) * 4 ]; + + #if ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) + UserEventBuffer userEventBuffer; + #endif + + /* This should always be 0 */ + uint32_t endOfSecondaryBlocks; + + uint8_t endmarker0; + uint8_t endmarker1; + uint8_t endmarker2; + uint8_t endmarker3; + uint8_t endmarker4; + uint8_t endmarker5; + uint8_t endmarker6; + uint8_t endmarker7; + uint8_t endmarker8; + uint8_t endmarker9; + uint8_t endmarker10; + uint8_t endmarker11; + } RecorderDataType; + + extern RecorderDataType * RecorderDataPtr; + +/* Internal functions */ + +/** + * @brief Signals a trace error + * + * @param[in] msg Message + */ + void prvTraceError( const char * msg ); + +/** + * @brief + * + * Returns the current time based on the HWTC macros which provide a hardware + * isolation layer towards the hardware timer/counter. + * + * The HWTC macros and prvTracePortGetTimeStamp is the main porting issue + * or the trace recorder library. Typically you should not need to change + * the code of prvTracePortGetTimeStamp if using the HWTC macros. + * + * @param[out] puiTimestamp Timestamp + */ + void prvTracePortGetTimeStamp( uint32_t * puiTimestamp ); + +/** + * @brief Reserve an object handle + * + * @param[in] objectclass Object class + * + * @return traceHandle + */ + traceHandle prvTraceGetObjectHandle( traceObjectClass objectclass ); + +/** + * @brief Free an object handle + * + * @param[in] objectclass Object class + * @param[in] handle Handle + */ + void prvTraceFreeObjectHandle( traceObjectClass objectclass, + traceHandle handle ); + +/* Private function. Use the public functions in trcKernelPort.h */ + +/** + * @brief Set the object name + * + * @param[in] objectclass Object class + * @param[in] handle Handle + * @param[in] name Name + */ + void prvTraceSetObjectName( traceObjectClass objectclass, + traceHandle handle, + const char * name ); + +/* Internal macros */ + + #define TRACE_PROPERTY_NAME_GET( objectclass, objecthandle ) \ + ( const char * ) ( &RecorderDataPtr->ObjectPropertyTable.objbytes \ + [ uiIndexOfObject( objecthandle, objectclass ) ] ) + + #define TRACE_PROPERTY_OBJECT_STATE( objectclass, handle ) \ + RecorderDataPtr->ObjectPropertyTable.objbytes[ uiIndexOfObject( handle, objectclass ) \ + + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ] ] + + #define TRACE_PROPERTY_ACTOR_PRIORITY( objectclass, handle ) \ + RecorderDataPtr->ObjectPropertyTable.objbytes[ uiIndexOfObject( handle, objectclass ) \ + + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ] + 1 ] + +/* DEBUG ASSERTS */ + #if defined TRC_CFG_USE_TRACE_ASSERT && TRC_CFG_USE_TRACE_ASSERT != 0 + #define TRACE_ASSERT( eval, msg, defRetVal ) \ + if( !( eval ) ) \ + { \ + prvTraceError( "TRACE_ASSERT: " msg ); \ + return defRetVal; \ + } + #else + #define TRACE_ASSERT( eval, msg, defRetVal ) + #endif + + typedef RecorderDataType TraceRecorderDataBuffer_t; + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/ + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #ifndef TRC_EXTERNAL_BUFFERS + #define TRC_EXTERNAL_BUFFERS 0 + #endif + + typedef struct TraceRecorderData + { + uint32_t uiSessionCounter; + uint32_t uiRecorderEnabled; + uint32_t uiTraceSystemState; + + TraceAssertBuffer_t xAssertBuffer; + #if ( TRC_EXTERNAL_BUFFERS == 0 ) + TraceHeaderBuffer_t xHeaderBuffer; + TraceEntryTableBuffer_t xEntryTableBuffer; + TraceTimestampBuffer_t xTimestampBuffer; + #endif + TraceStreamPortBuffer_t xStreamPortBuffer; + TraceStaticBufferBuffer_t xStaticBufferBuffer; + TraceEventDataBuffer_t xEventDataBuffer; + TracePrintBuffer_t xPrintBuffer; + TraceErrorBuffer_t xErrorBuffer; + TraceISRInfoBuffer_t xISRInfoBuffer; + TraceKernelPortDataBuffer_t xKernelPortBuffer; + TraceTaskInfoBuffer_t xTaskInfoBuffer; + TraceStackMonitorBuffer_t xStackMonitorBuffer; + TraceDiagnosticsBuffer_t xDiagnosticsBuffer; + } TraceRecorderData_t; + + extern TraceRecorderData_t * pxTraceRecorderData; + extern uint32_t RecorderInitialized; + + #define TRC_RECORDER_DATA_BUFFER_SIZE ( sizeof( TraceRecorderData_t ) ) + + typedef struct TraceRecorderDataBuffer + { + uint8_t buffer[ ( TRC_RECORDER_DATA_BUFFER_SIZE ) ]; + } TraceRecorderDataBuffer_t; + +/** + * @brief Initializes the header data + * + * @param[in] pxBuffer Pointer to header buffer + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceHeaderInitialize( TraceHeaderBuffer_t * pxBuffer ); + +/** + * @brief Query if recorder is enabled + * + * @retval 1 Recorder enabled + * @retval 0 Recorder not enabled + */ + #define xTraceIsRecorderEnabled() ( xTraceIsRecorderInitialized() & pxTraceRecorderData->uiRecorderEnabled ) + +/** + * @brief Query if recorder initialized + * + * @retval 1 Recorder initialized + * @retval 0 Recorder not initialized + */ + #define xTraceIsRecorderInitialized() xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_CORE ) + +/** + * @brief Flag component as initialized + * + * @param[in] uiComponentBit Component bit + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceSetComponentInitialized( uiComponentBit ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( RecorderInitialized |= ( uiComponentBit ), TRC_SUCCESS ) + +/** + * @brief Query if component is initialized + * + * @param[in] uiComponentBit Component bit + * + * @retval 1 Component initialized + * @retval 0 Component not initialized + */ + #define xTraceIsComponentInitialized( uiComponentBit ) ( ( RecorderInitialized & ( uiComponentBit ) ) ? 1 : 0 ) + +/** + * @brief Set the trace state + * + * @param[in] uiState State + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceStateSet( uiState ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( pxTraceRecorderData->uiTraceSystemState = ( uiState ), TRC_SUCCESS ) + +/** + * @brief Query the trace state + * + * @param[out] puiState State + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceStateGet( puiState ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( puiState ) = pxTraceRecorderData->uiTraceSystemState, TRC_SUCCESS ) + +/** + * @brief Call this function periodically + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTzCtrl( void ); + +/******************************************************************************/ +/*** INTERNAL STREAMING FUNCTIONS *********************************************/ +/******************************************************************************/ + +/** + * @brief Stores an event without parameters + * + * @param[in] _eventID Event id + */ + #define prvTraceStoreEvent_None( _eventID ) \ + { \ + TraceEventHandle_t _xEventHandle = 0; \ + if( xTraceEventBegin( _eventID, 0, &_xEventHandle ) == TRC_SUCCESS ) \ + { \ + xTraceEventEnd( _xEventHandle ); \ + } \ + } + +/** + * @brief Stores an event with a handle parameter + * + * @param[in] _eventID Event id + * @param[in] _handle Handle + */ + #define prvTraceStoreEvent_Handle( _eventID, _handle ) \ + { \ + TraceEventHandle_t _xEventHandle = 0; \ + if( xTraceEventBegin( _eventID, sizeof( void * ), &_xEventHandle ) == TRC_SUCCESS ) \ + { \ + xTraceEventAddPointer( _xEventHandle, ( void * ) ( _handle ) ); \ + xTraceEventEnd( _xEventHandle ); \ + } \ + } + +/** + * @brief Stores an event with one 32-bit parameter + * + * @param[in] _eventID Event id + * @param[in] _param1 Param + */ + #define prvTraceStoreEvent_Param( _eventID, _param1 ) \ + { \ + TraceEventHandle_t _xEventHandle = 0; \ + if( xTraceEventBegin( _eventID, sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \ + { \ + xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \ + xTraceEventEnd( _xEventHandle ); \ + } \ + } + +/** + * @brief Stores an event with a handle and one 32-bit parameter + * + * @param[in] _eventID Event id + * @param[in] _handle Handle + * @param[in] _param1 Param + */ + #define prvTraceStoreEvent_HandleParam( _eventID, _handle, _param1 ) \ + { \ + TraceEventHandle_t _xEventHandle = 0; \ + if( xTraceEventBegin( _eventID, sizeof( void * ) + sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \ + { \ + xTraceEventAddPointer( _xEventHandle, ( void * ) ( _handle ) ); \ + xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \ + xTraceEventEnd( _xEventHandle ); \ + } \ + } + +/** + * @brief Stores an event with two 32-bit parameters + * + * @param[in] _eventID Event id + * @param[in] _param1 Param 1 + * @param[in] _param2 Param 2 + */ + #define prvTraceStoreEvent_ParamParam( _eventID, _param1, _param2 ) \ + { \ + TraceEventHandle_t _xEventHandle = 0; \ + if( xTraceEventBegin( _eventID, sizeof( uint32_t ) + sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \ + { \ + xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \ + xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param2 ) ); \ + xTraceEventEnd( _xEventHandle ); \ + } \ + } + +/** + * @brief Stores an event with a handle and two 32-bit parameters + * + * @param[in] _eventID Event id + * @param[in] _handle Handle + * @param[in] _param1 Param 1 + * @param[in] _param2 Param 2 + */ + #define prvTraceStoreEvent_HandleParamParam( _eventID, _handle, _param1, _param2 ) \ + { \ + TraceEventHandle_t _xEventHandle = 0; \ + if( xTraceEventBegin( _eventID, sizeof( void * ) + sizeof( uint32_t ) + sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \ + { \ + xTraceEventAddPointer( _xEventHandle, ( void * ) ( _handle ) ); \ + xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \ + xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param2 ) ); \ + xTraceEventEnd( _xEventHandle ); \ + } \ + } + +/** + * @brief Stores an event with three 32-bit parameters + * + * @param[in] _eventID Event id + * @param[in] _param1 Param 1 + * @param[in] _param2 Param 2 + * @param[in] _param3 Param 3 + */ + #define prvTraceStoreEvent_ParamParamParam( _eventID, _param1, _param2, _param3 ) \ + { \ + TraceEventHandle_t _xEventHandle = 0; \ + if( xTraceEventBegin( _eventID, sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \ + { \ + xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \ + xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param2 ) ); \ + xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param3 ) ); \ + xTraceEventEnd( _xEventHandle ); \ + } \ + } + +/** + * @brief Snapshot mode only. Trace stop hook. + * + * @param[in] x + */ + #define vTraceSetStopHook( x ) ( void ) ( x ) + +/** + * @brief Snapshot mode only. Initialize timestamps. + */ + #define vTraceInitTimestamps() + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + + #if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM ) + +/** + * @brief Set the recorder data buffer + * + * @param[in] pxBuffer Pointer to the recorder data buffer + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceSetBuffer( TraceRecorderDataBuffer_t * pxBuffer ); + #else + #define xTraceSetBuffer( p ) ( TRC_SUCCESS ) + #endif + +/** + * @brief Retrieve the event buffer and event buffer size + * + * @param[out] ppvBuffer Pointer where event buffer pointer will be written + * @param[out] puiSize Event buffer size + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceGetEventBuffer( void ** ppvBuffer, + TraceUnsignedBaseType_t * puiSize ); + + #else /* when TRC_USE_TRACEALYZER_RECORDER == 0 */ + + #define xTraceInitialize() ( TRC_SUCCESS ) + #define xTraceEnable( x ) ( ( void ) ( x ), TRC_SUCCESS ) + #define xTraceDisable() ( TRC_SUCCESS ) + #define xTraceStringRegister( x, y ) ( ( void ) ( x ), ( void ) y, TRC_SUCCESS ) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */ + #define xTracePrint( chn, ... ) ( ( void ) ( chn ), TRC_SUCCESS ) + #define xTracePrintF( chn, fmt, ... ) ( ( void ) ( chn ), ( void ) ( fmt ), TRC_SUCCESS ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ + #define xTraceVPrintF( chn, formatStr, vl ) ( ( void ) ( chn ), ( void ) ( formatStr ), ( void ) ( vl ), TRC_SUCCESS ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */ + #define xTraceTaskInstanceFinishedNow() + #define xTraceTaskInstanceFinishedNext() + #define vTraceStoreISRBegin( x ) ( void ) ( x ) + #define vTraceStoreISREnd( x ) ( void ) ( x ) + #define xTraceSetISRProperties( a, b ) ( ( void ) ( a ), ( void ) ( b ), ( traceHandle ) 0 ) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */ + #define xTraceRegisterChannelFormat( eventLabel, formatStr ) ( ( void ) ( eventLabel ), ( void ) ( formatStr ), 0 ) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */ + #define vTraceUBData( label, ... ) ( void ) ( label ) + + #define vTraceSetFilterGroup( x ) ( void ) ( x ) + #define vTraceSetFilterMask( x ) ( void ) ( x ) + + #define prvTraceSetReadyEventsEnabled( status ) ( void ) ( status ) + + #define vTraceExcludeTask( handle ) ( void ) ( handle ) + + #define vTraceConsoleChannelPrintF( fmt, ... ) ( void ) ( fmt ) + + #ifndef TRC_ALLOC_CUSTOM_BUFFER + #define TRC_ALLOC_CUSTOM_BUFFER( bufname ) + #endif + + #define xTraceIsRecorderEnabled() ( 0 ) + #define xTraceIsRecorderInitialized() ( 0 ) + + #define xTraceSetBuffer( p ) ( TRC_SUCCESS ) + #define xTraceGetEventBuffer( p ) ( TRC_FAIL ) + + #define vTraceSetStopHook( x ) ( void ) ( x ) + + #define TraceRecorderDataBuffer_t uint32_t + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +/** + * @deprecated Backwards compatibility. Use xTraceInitialize instead. + */ + #define vTraceInitialize ( void ) xTraceInitialize + +/** + * @deprecated Backwards compatibility. Use xTraceEnable instead. + */ + #define vTraceEnable ( void ) xTraceEnable + +/** + * @deprecated Backwards compatibility. Use xTraceDisable instead. + */ + #define vTraceStop ( void ) xTraceDisable + +/** + * @deprecated Backwards compatibility. Use xTraceTaskInstanceFinishedNow instead. + */ + #define vTraceInstanceFinishedNow ( void ) xTraceTaskInstanceFinishedNow + +/** + * @deprecated Backwards compatibility. Use xTraceTaskInstanceFinishedNext instead. + */ + #define vTraceInstanceFinishedNext ( void ) xTraceTaskInstanceFinishedNext + +/** + * @deprecated Backwards compatibility. Use xTracePrintF instead. + */ + #define vTracePrintF ( void ) xTracePrintF + +/** + * @deprecated Backwards compatibility. Use xTraceVPrintF instead. + */ + #define vTraceVPrintF ( void ) xTraceVPrintF + +/** + * @deprecated Backwards compatibility. Use xTracePrint instead. + */ + #define vTracePrint ( void ) xTracePrint + +/** + * @deprecated Backwards compatibility. Use xTraceSetBuffer instead. + */ + #define vTraceSetRecorderDataBuffer( pxBuffer ) xTraceSetBuffer( ( TraceRecorderDataBuffer_t * ) ( pxBuffer ) ) + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_RECORDER_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStackMonitor.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStackMonitor.h index c5b9c5f6f..c8bc219bf 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStackMonitor.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStackMonitor.h @@ -1,135 +1,137 @@ -/* -* Percepio Trace Recorder SDK for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace stack monitor APIs. - */ - -#ifndef TRC_STACK_MONITOR_H -#define TRC_STACK_MONITOR_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_stack_monitor_apis Trace Stack Monitor APIs - * @ingroup trace_recorder_apis - * @{ - */ - -#if (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0)) - -#define TRACE_STACK_MONITOR_BUFFER_SIZE ((sizeof(void*) + sizeof(TraceUnsignedBaseType_t)) * (TRC_CFG_STACK_MONITOR_MAX_TASKS) + sizeof(uint32_t)) - -/** - * @internal Trace Stack Monitor Buffer Structure - */ -typedef struct TraceStackMonitorBuffer -{ - uint32_t buffer[(TRACE_STACK_MONITOR_BUFFER_SIZE) / sizeof(uint32_t)]; -} TraceStackMonitorBuffer_t; - -/** - * @internal Initialize trace stack monitor system. - * - * @param[in] pxBuffer Pointer to memory that will be used by the trace - * stack monitor system. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStackMonitorInitialize(TraceStackMonitorBuffer_t* pxBuffer); - -/** - * @brief Adds task/thread to trace stack monitor. - * - * @param[in] pvTask Task/Thread. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStackMonitorAdd(void* pvTask); - -/** - * @brief Removes task/thread from trace stack monitor. - * - * @param[in] pvTask Task/Thread. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStackMonitorRemove(void* pvTask); - -/** - * @brief Gets trace stack monitor tread/task at index. - * - * @param[in] uiIndex Index. - * @param[in] ppvTask Task/Thread. - * @param[out] puxLowWaterMark Low water mark. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStackMonitorGetAtIndex(uint32_t uiIndex, void** ppvTask, TraceUnsignedBaseType_t* puxLowWaterMark); - -/** - * @brief Performs trace stack monitor reporting. - * - * This routine performs a trace stack monitor check and report - * for TRC_CFG_STACK_MONITOR_MAX_REPORTS number of registered - * tasks/threads. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStackMonitorReport(void); - -#else /* (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0)) */ - -typedef struct TraceStackMonitorBuffer -{ - uint32_t buffer[1]; -} TraceStackMonitorBuffer_t; - -#define xTraceStackMonitorInitialize(pxBuffer) ((void)pxBuffer, TRC_SUCCESS) - -#define xTraceStackMonitorDiagnosticsGet(xType, puiValue) ((void)xType, puiValue != 0 ? *puiValue = 0 : 0, puiValue != 0 ? TRC_SUCCESS : TRC_FAIL) - -#define xTraceStackMonitorDiagnosticsSet(xType, uiValue) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3((void)xType, (void)uiValue, TRC_SUCCESS) - -#define xTraceStackMonitorAdd(pvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)pvTask, TRC_SUCCESS) - -#define xTraceStackMonitorRemove(pvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)pvTask, TRC_SUCCESS) - -#define xTraceStackMonitorGetAtIndex(uiIndex, ppvTask, puxLowWaterMark) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)uiIndex, (void)ppvTask, (void)puxLowWaterMark, TRC_SUCCESS) - -#define xTraceStackMonitorReport() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS) - -#endif /* (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0)) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_STACK_MONITOR_H */ +/* + * Percepio Trace Recorder SDK for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace stack monitor APIs. + */ + +#ifndef TRC_STACK_MONITOR_H + #define TRC_STACK_MONITOR_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_stack_monitor_apis Trace Stack Monitor APIs + * @ingroup trace_recorder_apis + * @{ + */ + + #if ( ( ( TRC_CFG_ENABLE_STACK_MONITOR ) == 1 ) && ( ( TRC_CFG_SCHEDULING_ONLY ) == 0 ) ) + + #define TRACE_STACK_MONITOR_BUFFER_SIZE ( ( sizeof( void * ) + sizeof( TraceUnsignedBaseType_t ) ) * ( TRC_CFG_STACK_MONITOR_MAX_TASKS ) + sizeof( uint32_t ) ) + +/** + * @internal Trace Stack Monitor Buffer Structure + */ + typedef struct TraceStackMonitorBuffer + { + uint32_t buffer[ ( TRACE_STACK_MONITOR_BUFFER_SIZE ) / sizeof( uint32_t ) ]; + } TraceStackMonitorBuffer_t; + +/** + * @internal Initialize trace stack monitor system. + * + * @param[in] pxBuffer Pointer to memory that will be used by the trace + * stack monitor system. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStackMonitorInitialize( TraceStackMonitorBuffer_t * pxBuffer ); + +/** + * @brief Adds task/thread to trace stack monitor. + * + * @param[in] pvTask Task/Thread. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStackMonitorAdd( void * pvTask ); + +/** + * @brief Removes task/thread from trace stack monitor. + * + * @param[in] pvTask Task/Thread. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStackMonitorRemove( void * pvTask ); + +/** + * @brief Gets trace stack monitor tread/task at index. + * + * @param[in] uiIndex Index. + * @param[in] ppvTask Task/Thread. + * @param[out] puxLowWaterMark Low water mark. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStackMonitorGetAtIndex( uint32_t uiIndex, + void ** ppvTask, + TraceUnsignedBaseType_t * puxLowWaterMark ); + +/** + * @brief Performs trace stack monitor reporting. + * + * This routine performs a trace stack monitor check and report + * for TRC_CFG_STACK_MONITOR_MAX_REPORTS number of registered + * tasks/threads. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStackMonitorReport( void ); + + #else /* (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0)) */ + + typedef struct TraceStackMonitorBuffer + { + uint32_t buffer[ 1 ]; + } TraceStackMonitorBuffer_t; + + #define xTraceStackMonitorInitialize( pxBuffer ) ( ( void ) pxBuffer, TRC_SUCCESS ) + + #define xTraceStackMonitorDiagnosticsGet( xType, puiValue ) ( ( void ) xType, puiValue != 0 ? *puiValue = 0 : 0, puiValue != 0 ? TRC_SUCCESS : TRC_FAIL ) + + #define xTraceStackMonitorDiagnosticsSet( xType, uiValue ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( ( void ) xType, ( void ) uiValue, TRC_SUCCESS ) + + #define xTraceStackMonitorAdd( pvTask ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( ( void ) pvTask, TRC_SUCCESS ) + + #define xTraceStackMonitorRemove( pvTask ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( ( void ) pvTask, TRC_SUCCESS ) + + #define xTraceStackMonitorGetAtIndex( uiIndex, ppvTask, puxLowWaterMark ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( ( void ) uiIndex, ( void ) ppvTask, ( void ) puxLowWaterMark, TRC_SUCCESS ) + + #define xTraceStackMonitorReport() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1( TRC_SUCCESS ) + + #endif /* (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0)) */ + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_STACK_MONITOR_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStateMachine.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStateMachine.h index f5f68400c..6beeb6ec5 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStateMachine.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStateMachine.h @@ -1,78 +1,82 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace state machine APIs. - */ - -#ifndef TRC_STATE_MACHINE_H -#define TRC_STATE_MACHINE_H - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_state_machine_apis Trace State Machine APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @brief Creates trace state machine. - * - * @param[in] szName Name. - * @param[out] pxStateMachineHandle Pointer to uninitialized trace state machine. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStateMachineCreate(const char *szName, TraceStateMachineHandle_t *pxStateMachineHandle); - -/** - * @brief Creates trace state machine state. - * - * @param[in] xStateMachineHandle Pointer to initialized trace state machine. - * @param[in] szName Name. - * @param[out] pxStateHandle Pointer to uninitialized trace state machine state. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStateMachineStateCreate(TraceStateMachineHandle_t xStateMachineHandle, const char *szName, TraceStateMachineStateHandle_t *pxStateHandle); - -/** - * @brief Sets trace state machine state. - * - * @param[in] xStateMachineHandle Pointer to initialized trace state machine. - * @param[in] xStateHandle Pointer to initialized trace state machine state. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStateMachineSetState(TraceStateMachineHandle_t xStateMachineHandle, TraceStateMachineStateHandle_t xStateHandle); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_STATE_MACHINE_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace state machine APIs. + */ + +#ifndef TRC_STATE_MACHINE_H + #define TRC_STATE_MACHINE_H + + #include + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_state_machine_apis Trace State Machine APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @brief Creates trace state machine. + * + * @param[in] szName Name. + * @param[out] pxStateMachineHandle Pointer to uninitialized trace state machine. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStateMachineCreate( const char * szName, + TraceStateMachineHandle_t * pxStateMachineHandle ); + +/** + * @brief Creates trace state machine state. + * + * @param[in] xStateMachineHandle Pointer to initialized trace state machine. + * @param[in] szName Name. + * @param[out] pxStateHandle Pointer to uninitialized trace state machine state. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStateMachineStateCreate( TraceStateMachineHandle_t xStateMachineHandle, + const char * szName, + TraceStateMachineStateHandle_t * pxStateHandle ); + +/** + * @brief Sets trace state machine state. + * + * @param[in] xStateMachineHandle Pointer to initialized trace state machine. + * @param[in] xStateHandle Pointer to initialized trace state machine state. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStateMachineSetState( TraceStateMachineHandle_t xStateMachineHandle, + TraceStateMachineStateHandle_t xStateHandle ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_STATE_MACHINE_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStaticBuffer.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStaticBuffer.h index 4a7fa72a7..ce9d441e7 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStaticBuffer.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcStaticBuffer.h @@ -1,112 +1,112 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace static buffer APIs. - */ - -#ifndef TRC_STATIC_BUFFER_H -#define TRC_STATIC_BUFFER_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_static_buffer_apis Trace Static Buffer APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/* A buffer type that is maximum size */ -typedef uint8_t TraceStaticBuffer_t[TRC_MAX_BLOB_SIZE]; - -/** - * @internal Trace Core Static Buffer Core Structure - */ -typedef struct TraceCoreStaticBufferCore -{ - TraceStaticBuffer_t dummyEvents[(TRC_CFG_MAX_ISR_NESTING)+1]; /**< */ -} TraceCoreStaticBuffer_t; - -/** - * @internal Trace Static Buffer Table Structure - */ -typedef struct TraceStaticBufferTable -{ - TraceCoreStaticBuffer_t coreDummyEvents[TRC_CFG_CORE_COUNT]; /**< Temporary buffers used for event or blob creation. */ -} TraceStaticBufferTable_t; - -#define TRC_STATIC_BUFFER_BUFFER_SIZE (sizeof(TraceStaticBufferTable_t)) - -/** - * @internal Trace Static Buffer Buffer Structure - */ -typedef struct TraceStaticBufferBuffer -{ - uint8_t buffer[TRC_STATIC_BUFFER_BUFFER_SIZE]; /**< */ -} TraceStaticBufferBuffer_t; - -extern TraceStaticBufferTable_t* pxTraceStaticBufferTable; - -/** - * @internal Initialize trace static buffer. - * - * @param[in] pxBuffer Pointer to memory that will be used by the - * trace static buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStaticBufferInitialize(TraceStaticBufferBuffer_t* pxBuffer); - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -/** - * @brief Gets trace static buffer. - * - * @param[out] ppvBuffer Buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStaticBufferGet(void **ppvBuffer); - -#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** - * @brief Gets trace static buffer. - * - * @param[out] ppvBuffer Buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceStaticBufferGet(ppvBuffer) (*ppvBuffer = (void*)&pxTraceStaticBufferTable->coreDummyEvents[TRC_CFG_GET_CURRENT_CORE()].dummyEvents[xTraceISRGetCurrentNestingReturned() + 1], TRC_SUCCESS) - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_STATIC_BUFFER_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace static buffer APIs. + */ + +#ifndef TRC_STATIC_BUFFER_H + #define TRC_STATIC_BUFFER_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_static_buffer_apis Trace Static Buffer APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/* A buffer type that is maximum size */ + typedef uint8_t TraceStaticBuffer_t[ TRC_MAX_BLOB_SIZE ]; + +/** + * @internal Trace Core Static Buffer Core Structure + */ + typedef struct TraceCoreStaticBufferCore + { + TraceStaticBuffer_t dummyEvents[ ( TRC_CFG_MAX_ISR_NESTING ) + 1 ]; /**< */ + } TraceCoreStaticBuffer_t; + +/** + * @internal Trace Static Buffer Table Structure + */ + typedef struct TraceStaticBufferTable + { + TraceCoreStaticBuffer_t coreDummyEvents[ TRC_CFG_CORE_COUNT ]; /**< Temporary buffers used for event or blob creation. */ + } TraceStaticBufferTable_t; + + #define TRC_STATIC_BUFFER_BUFFER_SIZE ( sizeof( TraceStaticBufferTable_t ) ) + +/** + * @internal Trace Static Buffer Buffer Structure + */ + typedef struct TraceStaticBufferBuffer + { + uint8_t buffer[ TRC_STATIC_BUFFER_BUFFER_SIZE ]; /**< */ + } TraceStaticBufferBuffer_t; + + extern TraceStaticBufferTable_t * pxTraceStaticBufferTable; + +/** + * @internal Initialize trace static buffer. + * + * @param[in] pxBuffer Pointer to memory that will be used by the + * trace static buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStaticBufferInitialize( TraceStaticBufferBuffer_t * pxBuffer ); + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + +/** + * @brief Gets trace static buffer. + * + * @param[out] ppvBuffer Buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStaticBufferGet( void ** ppvBuffer ); + + #else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** + * @brief Gets trace static buffer. + * + * @param[out] ppvBuffer Buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceStaticBufferGet( ppvBuffer ) ( *ppvBuffer = ( void * ) &pxTraceStaticBufferTable->coreDummyEvents[ TRC_CFG_GET_CURRENT_CORE() ].dummyEvents[ xTraceISRGetCurrentNestingReturned() + 1 ], TRC_SUCCESS ) + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_STATIC_BUFFER_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcString.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcString.h index 5f2ed6946..5d9d8d981 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcString.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcString.h @@ -1,76 +1,77 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace string APIs. - */ - -#ifndef TRC_STRING_H -#define TRC_STRING_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_string_apis Trace String APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @brief Registers a trace string. - * - * This routine registers a strings in the recorder, e.g. for names of user - * event channels. - * - * Example: - * TraceStringHandle_t myEventHandle; - * xTraceStringRegister("MyUserEvent", &myEventHandle); - * ... - * xTracePrintF(myEventHandle, "My value is: %d", myValue); - * - * @param[in] szString String. - * @param[out] pString Pointer to uninitialized trace string. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStringRegister(const char *szString, TraceStringHandle_t* pString); - -/** - * @brief Registers a trace string. - * - * @deprecated Remains for backward compability with pre v4.6 versions - * of the recorder. - * - * @param[in] name Name. - * - * @return TraceStringHandle_t - */ -TraceStringHandle_t xTraceRegisterString(const char *name); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_STRING_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace string APIs. + */ + +#ifndef TRC_STRING_H + #define TRC_STRING_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_string_apis Trace String APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @brief Registers a trace string. + * + * This routine registers a strings in the recorder, e.g. for names of user + * event channels. + * + * Example: + * TraceStringHandle_t myEventHandle; + * xTraceStringRegister("MyUserEvent", &myEventHandle); + * ... + * xTracePrintF(myEventHandle, "My value is: %d", myValue); + * + * @param[in] szString String. + * @param[out] pString Pointer to uninitialized trace string. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStringRegister( const char * szString, + TraceStringHandle_t * pString ); + +/** + * @brief Registers a trace string. + * + * @deprecated Remains for backward compability with pre v4.6 versions + * of the recorder. + * + * @param[in] name Name. + * + * @return TraceStringHandle_t + */ + TraceStringHandle_t xTraceRegisterString( const char * name ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_STRING_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTask.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTask.h index e063527dc..f3b9d13a7 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTask.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTask.h @@ -1,243 +1,248 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace task APIs. - */ - -#ifndef TRC_TASK_H -#define TRC_TASK_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_task_apis Trace Task APIs - * @ingroup trace_recorder_apis - * @{ - */ - -#ifndef TRC_CFG_ENABLE_STACK_MONITOR -#define TRC_CFG_ENABLE_STACK_MONITOR 0 -#endif - -/** - * @internal Trace Task Info Structure - */ -typedef struct TraceTaskInfo -{ - void* coreTasks[TRC_CFG_CORE_COUNT]; -} TraceTaskInfo_t; - -extern TraceTaskInfo_t* pxTraceTaskInfo; - -#define TRACE_TASK_INFO_BUFFER_SIZE (sizeof(TraceTaskInfo_t)) - -/** - * @internal Trace Task Info Buffer Structure - */ -typedef struct TraceTaskInfoBuffer -{ - uint8_t buffer[TRACE_TASK_INFO_BUFFER_SIZE]; -} TraceTaskInfoBuffer_t; - -/** - * @internal Initialize trace task system. - * - * @param[in] pxBuffer Pointer to memory that will be used by the - * trace task system. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskInitialize(TraceTaskInfoBuffer_t* pxBuffer); - -/** - * @brief Register trace task in the trace. - * - * @param[in] pvTask Task. - * @param[in] szName Name. - * @param[in] uxPriority Priority. - * @param[out] pxTaskHandle Pointer to uninitialized trace task. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTaskRegister(pvTask, szName, uxPriority, pxTaskHandle) ((((pvTask) != 0) && (xTraceObjectRegister(PSF_EVENT_TASK_CREATE, pvTask, szName, uxPriority, (TraceObjectHandle_t*)(pxTaskHandle)) == TRC_SUCCESS)) ? (xTraceStackMonitorAdd(pvTask), TRC_SUCCESS) : TRC_FAIL) - -/** - * @brief Unregister trace task from trace. - * - * @param[in] xTaskHandle Pointer to initialized trace task. - * @param[in] uxPriority Priority. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskUnregister(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority); - -/** - * @brief Sets trace task name. - * - * @param[in] pvTask Task. - * @param[in] szName Name. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTaskSetName xTraceObjectSetName - -/** - * @brief Sets trace task priority. - * - * @param[in] xTaskHandle Pointer to initialized trace task. - * @param[in] uxPriority Priority. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskSetPriority(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority); - -/** - * @brief Registers trace task without trace task handle. - * - * @param[in] pvTask Task. - * @param[in] szName Name. - * @param[in] uxPriority Priority. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTaskRegisterWithoutHandle(pvTask, szName, uxPriority) ((((pvTask) != 0) && (xTraceObjectRegisterWithoutHandle(PSF_EVENT_TASK_CREATE, pvTask, szName, uxPriority) == TRC_SUCCESS)) ? (xTraceStackMonitorAdd(pvTask), TRC_SUCCESS) : TRC_FAIL) - -/** - * @brief Unregisters trace task without trace task handle. - * - * @param[in] pvTask Task. - * @param[in] uxPriority Priority. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTaskUnregisterWithoutHandle(pvTask, uxPriority) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(xTraceStackMonitorRemove(pvTask), xTraceObjectUnregisterWithoutHandle(PSF_EVENT_TASK_DELETE, pvTask, uxPriority)) - -/** - * @brief Sets trace task name without trace task handle. - * - * @param[in] pvTask Task. - * @param[in] szName Name. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTaskSetNameWithoutHandle xTraceObjectSetNameWithoutHandle - -/** - * @brief Sets trace task priority without trace task handle. - * - * @param[in] pvTask Task. - * @param[in] uxPriority Priority. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskSetPriorityWithoutHandle(void* pvTask, TraceUnsignedBaseType_t uxPriority); - -/** - * @brief Registers trace task switch event. - * - * @param[in] pvTask Task. - * @param[in] uxPriority Priority. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskSwitch(void* pvTask, TraceUnsignedBaseType_t uxPriority); - -#if (TRC_CFG_INCLUDE_READY_EVENTS == 1) -/** - * @brief Registers trace task ready event. - * - * @param[in] pvTask Task. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskReady(void* pvTask); -#else -#define xTraceTaskReady(p) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)p, TRC_SUCCESS) -#endif - -/** - * @brief Sets current trace task. - * - * @param[in] pvTask Task. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTaskSetCurrent(pvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceTaskInfo->coreTasks[TRC_CFG_GET_CURRENT_CORE()] = (pvTask), TRC_SUCCESS) - -/** - * @brief Gets current trace task. - * - * @param[out] ppvTask Task. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTaskGetCurrent(ppvTask) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(ppvTask) = pxTraceTaskInfo->coreTasks[TRC_CFG_GET_CURRENT_CORE()], TRC_SUCCESS) - -/** - * @brief Registers trace task instance finished event. - * - * This routine creates a trace event that ends the current task instance at - * this very instant. This makes the viewer split the current fragment at - * this point and begin a new actor instance, even if no task-switch has - * occurred - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskInstanceFinishedNow(void); - -/** - * @brief Marks the current trace task instance as finished on the next - * kernel call. - * - * If that kernel call is blocking, the instance ends after the blocking event - * and the corresponding return event is then the start of the next instance. - * If the kernel call is not blocking, the viewer instead splits the current - * fragment right before the kernel call, which makes this call the first event - * of the next instance. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTaskInstanceFinishedNext(void); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_TASK_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace task APIs. + */ + +#ifndef TRC_TASK_H + #define TRC_TASK_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_task_apis Trace Task APIs + * @ingroup trace_recorder_apis + * @{ + */ + + #ifndef TRC_CFG_ENABLE_STACK_MONITOR + #define TRC_CFG_ENABLE_STACK_MONITOR 0 + #endif + +/** + * @internal Trace Task Info Structure + */ + typedef struct TraceTaskInfo + { + void * coreTasks[ TRC_CFG_CORE_COUNT ]; + } TraceTaskInfo_t; + + extern TraceTaskInfo_t * pxTraceTaskInfo; + + #define TRACE_TASK_INFO_BUFFER_SIZE ( sizeof( TraceTaskInfo_t ) ) + +/** + * @internal Trace Task Info Buffer Structure + */ + typedef struct TraceTaskInfoBuffer + { + uint8_t buffer[ TRACE_TASK_INFO_BUFFER_SIZE ]; + } TraceTaskInfoBuffer_t; + +/** + * @internal Initialize trace task system. + * + * @param[in] pxBuffer Pointer to memory that will be used by the + * trace task system. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskInitialize( TraceTaskInfoBuffer_t * pxBuffer ); + +/** + * @brief Register trace task in the trace. + * + * @param[in] pvTask Task. + * @param[in] szName Name. + * @param[in] uxPriority Priority. + * @param[out] pxTaskHandle Pointer to uninitialized trace task. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTaskRegister( pvTask, szName, uxPriority, pxTaskHandle ) ( ( ( ( pvTask ) != 0 ) && ( xTraceObjectRegister( PSF_EVENT_TASK_CREATE, pvTask, szName, uxPriority, ( TraceObjectHandle_t * ) ( pxTaskHandle ) ) == TRC_SUCCESS ) ) ? ( xTraceStackMonitorAdd( pvTask ), TRC_SUCCESS ) : TRC_FAIL ) + +/** + * @brief Unregister trace task from trace. + * + * @param[in] xTaskHandle Pointer to initialized trace task. + * @param[in] uxPriority Priority. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskUnregister( TraceTaskHandle_t xTaskHandle, + TraceUnsignedBaseType_t uxPriority ); + +/** + * @brief Sets trace task name. + * + * @param[in] pvTask Task. + * @param[in] szName Name. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTaskSetName xTraceObjectSetName + +/** + * @brief Sets trace task priority. + * + * @param[in] xTaskHandle Pointer to initialized trace task. + * @param[in] uxPriority Priority. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskSetPriority( TraceTaskHandle_t xTaskHandle, + TraceUnsignedBaseType_t uxPriority ); + +/** + * @brief Registers trace task without trace task handle. + * + * @param[in] pvTask Task. + * @param[in] szName Name. + * @param[in] uxPriority Priority. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTaskRegisterWithoutHandle( pvTask, szName, uxPriority ) ( ( ( ( pvTask ) != 0 ) && ( xTraceObjectRegisterWithoutHandle( PSF_EVENT_TASK_CREATE, pvTask, szName, uxPriority ) == TRC_SUCCESS ) ) ? ( xTraceStackMonitorAdd( pvTask ), TRC_SUCCESS ) : TRC_FAIL ) + +/** + * @brief Unregisters trace task without trace task handle. + * + * @param[in] pvTask Task. + * @param[in] uxPriority Priority. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTaskUnregisterWithoutHandle( pvTask, uxPriority ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( xTraceStackMonitorRemove( pvTask ), xTraceObjectUnregisterWithoutHandle( PSF_EVENT_TASK_DELETE, pvTask, uxPriority ) ) + +/** + * @brief Sets trace task name without trace task handle. + * + * @param[in] pvTask Task. + * @param[in] szName Name. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTaskSetNameWithoutHandle xTraceObjectSetNameWithoutHandle + +/** + * @brief Sets trace task priority without trace task handle. + * + * @param[in] pvTask Task. + * @param[in] uxPriority Priority. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskSetPriorityWithoutHandle( void * pvTask, + TraceUnsignedBaseType_t uxPriority ); + +/** + * @brief Registers trace task switch event. + * + * @param[in] pvTask Task. + * @param[in] uxPriority Priority. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskSwitch( void * pvTask, + TraceUnsignedBaseType_t uxPriority ); + + #if ( TRC_CFG_INCLUDE_READY_EVENTS == 1 ) + +/** + * @brief Registers trace task ready event. + * + * @param[in] pvTask Task. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskReady( void * pvTask ); + #else + #define xTraceTaskReady( p ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( ( void ) p, TRC_SUCCESS ) + #endif + +/** + * @brief Sets current trace task. + * + * @param[in] pvTask Task. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTaskSetCurrent( pvTask ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( pxTraceTaskInfo->coreTasks[ TRC_CFG_GET_CURRENT_CORE() ] = ( pvTask ), TRC_SUCCESS ) + +/** + * @brief Gets current trace task. + * + * @param[out] ppvTask Task. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTaskGetCurrent( ppvTask ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( ppvTask ) = pxTraceTaskInfo->coreTasks[ TRC_CFG_GET_CURRENT_CORE() ], TRC_SUCCESS ) + +/** + * @brief Registers trace task instance finished event. + * + * This routine creates a trace event that ends the current task instance at + * this very instant. This makes the viewer split the current fragment at + * this point and begin a new actor instance, even if no task-switch has + * occurred + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskInstanceFinishedNow( void ); + +/** + * @brief Marks the current trace task instance as finished on the next + * kernel call. + * + * If that kernel call is blocking, the instance ends after the blocking event + * and the corresponding return event is then the start of the next instance. + * If the kernel call is not blocking, the viewer instead splits the current + * fragment right before the kernel call, which makes this call the first event + * of the next instance. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTaskInstanceFinishedNext( void ); + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_TASK_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTimestamp.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTimestamp.h index 481d135d8..621c0c83a 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTimestamp.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTimestamp.h @@ -1,253 +1,253 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -/** - * @file - * - * @brief Public trace timestamp APIs. - */ - -#ifndef TRC_TIMESTAMP_H -#define TRC_TIMESTAMP_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup trace_timestamp_apis Trace Timestamp APIs - * @ingroup trace_recorder_apis - * @{ - */ - -/** - * @brief Trace Timestamp Structure - */ -typedef struct TraceTimestamp -{ - uint32_t type; /**< Timer type (direction) */ - TraceUnsignedBaseType_t frequency; /**< Timer Frequency */ - uint32_t period; /**< Timer Period */ - uint32_t wraparounds; /**< Nr of timer wraparounds */ - uint32_t osTickHz; /**< RTOS tick frequency */ - uint32_t latestTimestamp; /**< Latest timestamp */ - uint32_t osTickCount; /**< RTOS tick count */ -} TraceTimestamp_t; - -extern TraceTimestamp_t* pxTraceTimestamp; - -#define TRC_TIMESTAMP_RECORD_SIZE (sizeof(TraceTimestamp_t)) - -/** - * @internal Trace Timestamp Buffer Structure - */ -typedef struct TraceTimestampBuffer -{ - uint32_t buffer[(TRC_TIMESTAMP_RECORD_SIZE) / sizeof(uint32_t)]; -} TraceTimestampBuffer_t; - -/** - * @internal Initialize trace timestamp system. - * - * @param[in] pxBuffer Pointer to memory that will be used by the - * trace timestamp system. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTimestampInitialize(TraceTimestampBuffer_t *pxBuffer); - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -/** - * @brief Gets current trace timestamp. - * - * @param[out] puiTimestamp Timestamp. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTimestampGet(uint32_t* puiTimestamp); - -/** - * @brief Gets trace timestamp wraparounds. - * - * @param[out] puiTimerWraparounds Timer wraparounds. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTimestampGetWraparounds(uint32_t* puiTimerWraparounds); - -/** - * @brief Sets trace timestamp frequency. - * - * @param[in] uxFrequency Frequency. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTimestampSetFrequency(TraceUnsignedBaseType_t uxFrequency); - -/** - * @brief Gets trace timestamp frequency. - * - * @param[out] puxFrequency Frequency. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTimestampGetFrequency(TraceUnsignedBaseType_t* puxFrequency); - -/** - * @brief Sets trace timestamp period. - * - * @param[in] uiPeriod Period. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTimestampSetPeriod(uint32_t uiPeriod); - -/** - * @brief Gets trace timestamp period. - * - * @param[out] puiPeriod Period. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTimestampGetPeriod(uint32_t* puiPeriod); - -/** - * @brief Sets trace timestamp OS tick count. - * - * @param[in] uiOsTickCount OS tick count. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTimestampSetOsTickCount(uint32_t uiOsTickCount); - -/** - * @brief Gets trace timestamp OS tick count. - * - * @param[in] puiOsTickCount - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceTimestampGetOsTickCount(uint32_t *puiOsTickCount); - -#else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** - * @brief Gets current trace timestamp. - * - * @param[out] puiTimestamp Timestamp. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#if ((TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR)) -#define xTraceTimestampGet(puiTimestamp) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(*(puiTimestamp) = TRC_HWTC_COUNT, (*(puiTimestamp) < pxTraceTimestamp->latestTimestamp) ? pxTraceTimestamp->wraparounds++ : 0, pxTraceTimestamp->latestTimestamp = *(puiTimestamp), TRC_SUCCESS) -#elif ((TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR)) -#define xTraceTimestampGet(puiTimestamp) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(*(puiTimestamp) = TRC_HWTC_COUNT, (*(puiTimestamp) > pxTraceTimestamp->latestTimestamp) ? pxTraceTimestamp->wraparounds++ : 0, pxTraceTimestamp->latestTimestamp = *(puiTimestamp), TRC_SUCCESS) -#elif ((TRC_HWTC_TYPE == TRC_OS_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)) -#define xTraceTimestampGet(puiTimestamp) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(*(puiTimestamp) = ((TRC_HWTC_COUNT) & 0x00FFFFFFU) + ((pxTraceTimestamp->osTickCount & 0x000000FFU) << 24), pxTraceTimestamp->wraparounds = pxTraceTimestamp->osTickCount, pxTraceTimestamp->latestTimestamp = *(puiTimestamp), TRC_SUCCESS) -#endif - -/** - * @brief Gets trace timestamp wraparounds. - * - * @param[out] puiTimerWraparounds Timer wraparounds. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTimestampGetWraparounds(puiTimerWraparounds) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiTimerWraparounds) = pxTraceTimestamp->wraparounds, TRC_SUCCESS) - -/** - * @brief Sets trace timestamp frequency. - * - * @param[in] uxFrequency Frequency. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTimestampSetFrequency(uxFrequency) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceTimestamp->frequency = uxFrequency, TRC_SUCCESS) - -/** - * @brief Sets trace timestamp period. - * - * @param[in] uiPeriod Period. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTimestampSetPeriod(uiPeriod) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceTimestamp->period = uiPeriod, TRC_SUCCESS) - -/** - * @brief Sets trace timestamp OS tick count. - * - * @param[in] uiOsTickCount OS tick count. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTimestampSetOsTickCount(uiOsTickCount) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(pxTraceTimestamp->osTickCount = uiOsTickCount, TRC_SUCCESS) - -/** - * @brief Gets trace timestamp frequency. - * - * @param[out] puxFrequency Frequency. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTimestampGetFrequency(puxFrequency) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puxFrequency) = pxTraceTimestamp->frequency, TRC_SUCCESS) - -/** - * @brief Gets trace timestamp period. - * - * @param[out] puiPeriod Period. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTimestampGetPeriod(puiPeriod) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiPeriod) = pxTraceTimestamp->period, TRC_SUCCESS) - -/** - * @brief Gets trace timestamp OS tick count. - * - * @param[in] puiOsTickCount - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -#define xTraceTimestampGetOsTickCount(puiOsTickCount) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(puiOsTickCount) = pxTraceTimestamp->osTickCount, TRC_SUCCESS) - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /* TRC_TIMESTAMP_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Public trace timestamp APIs. + */ + +#ifndef TRC_TIMESTAMP_H + #define TRC_TIMESTAMP_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @defgroup trace_timestamp_apis Trace Timestamp APIs + * @ingroup trace_recorder_apis + * @{ + */ + +/** + * @brief Trace Timestamp Structure + */ + typedef struct TraceTimestamp + { + uint32_t type; /**< Timer type (direction) */ + TraceUnsignedBaseType_t frequency; /**< Timer Frequency */ + uint32_t period; /**< Timer Period */ + uint32_t wraparounds; /**< Nr of timer wraparounds */ + uint32_t osTickHz; /**< RTOS tick frequency */ + uint32_t latestTimestamp; /**< Latest timestamp */ + uint32_t osTickCount; /**< RTOS tick count */ + } TraceTimestamp_t; + + extern TraceTimestamp_t * pxTraceTimestamp; + + #define TRC_TIMESTAMP_RECORD_SIZE ( sizeof( TraceTimestamp_t ) ) + +/** + * @internal Trace Timestamp Buffer Structure + */ + typedef struct TraceTimestampBuffer + { + uint32_t buffer[ ( TRC_TIMESTAMP_RECORD_SIZE ) / sizeof( uint32_t ) ]; + } TraceTimestampBuffer_t; + +/** + * @internal Initialize trace timestamp system. + * + * @param[in] pxBuffer Pointer to memory that will be used by the + * trace timestamp system. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTimestampInitialize( TraceTimestampBuffer_t * pxBuffer ); + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + +/** + * @brief Gets current trace timestamp. + * + * @param[out] puiTimestamp Timestamp. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTimestampGet( uint32_t * puiTimestamp ); + +/** + * @brief Gets trace timestamp wraparounds. + * + * @param[out] puiTimerWraparounds Timer wraparounds. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTimestampGetWraparounds( uint32_t * puiTimerWraparounds ); + +/** + * @brief Sets trace timestamp frequency. + * + * @param[in] uxFrequency Frequency. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTimestampSetFrequency( TraceUnsignedBaseType_t uxFrequency ); + +/** + * @brief Gets trace timestamp frequency. + * + * @param[out] puxFrequency Frequency. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTimestampGetFrequency( TraceUnsignedBaseType_t * puxFrequency ); + +/** + * @brief Sets trace timestamp period. + * + * @param[in] uiPeriod Period. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTimestampSetPeriod( uint32_t uiPeriod ); + +/** + * @brief Gets trace timestamp period. + * + * @param[out] puiPeriod Period. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTimestampGetPeriod( uint32_t * puiPeriod ); + +/** + * @brief Sets trace timestamp OS tick count. + * + * @param[in] uiOsTickCount OS tick count. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTimestampSetOsTickCount( uint32_t uiOsTickCount ); + +/** + * @brief Gets trace timestamp OS tick count. + * + * @param[in] puiOsTickCount + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceTimestampGetOsTickCount( uint32_t * puiOsTickCount ); + + #else /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** + * @brief Gets current trace timestamp. + * + * @param[out] puiTimestamp Timestamp. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #if ( ( TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR ) || ( TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR ) ) + #define xTraceTimestampGet( puiTimestamp ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( *( puiTimestamp ) = TRC_HWTC_COUNT, ( *( puiTimestamp ) < pxTraceTimestamp->latestTimestamp ) ? pxTraceTimestamp->wraparounds++ : 0, pxTraceTimestamp->latestTimestamp = *( puiTimestamp ), TRC_SUCCESS ) + #elif ( ( TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR ) || ( TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR ) ) + #define xTraceTimestampGet( puiTimestamp ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( *( puiTimestamp ) = TRC_HWTC_COUNT, ( *( puiTimestamp ) > pxTraceTimestamp->latestTimestamp ) ? pxTraceTimestamp->wraparounds++ : 0, pxTraceTimestamp->latestTimestamp = *( puiTimestamp ), TRC_SUCCESS ) + #elif ( ( TRC_HWTC_TYPE == TRC_OS_TIMER_INCR ) || ( TRC_HWTC_TYPE == TRC_OS_TIMER_DECR ) ) + #define xTraceTimestampGet( puiTimestamp ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( *( puiTimestamp ) = ( ( TRC_HWTC_COUNT ) & 0x00FFFFFFU ) + ( ( pxTraceTimestamp->osTickCount & 0x000000FFU ) << 24 ), pxTraceTimestamp->wraparounds = pxTraceTimestamp->osTickCount, pxTraceTimestamp->latestTimestamp = *( puiTimestamp ), TRC_SUCCESS ) + #endif + +/** + * @brief Gets trace timestamp wraparounds. + * + * @param[out] puiTimerWraparounds Timer wraparounds. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTimestampGetWraparounds( puiTimerWraparounds ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( puiTimerWraparounds ) = pxTraceTimestamp->wraparounds, TRC_SUCCESS ) + +/** + * @brief Sets trace timestamp frequency. + * + * @param[in] uxFrequency Frequency. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTimestampSetFrequency( uxFrequency ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( pxTraceTimestamp->frequency = uxFrequency, TRC_SUCCESS ) + +/** + * @brief Sets trace timestamp period. + * + * @param[in] uiPeriod Period. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTimestampSetPeriod( uiPeriod ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( pxTraceTimestamp->period = uiPeriod, TRC_SUCCESS ) + +/** + * @brief Sets trace timestamp OS tick count. + * + * @param[in] uiOsTickCount OS tick count. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTimestampSetOsTickCount( uiOsTickCount ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( pxTraceTimestamp->osTickCount = uiOsTickCount, TRC_SUCCESS ) + +/** + * @brief Gets trace timestamp frequency. + * + * @param[out] puxFrequency Frequency. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTimestampGetFrequency( puxFrequency ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( puxFrequency ) = pxTraceTimestamp->frequency, TRC_SUCCESS ) + +/** + * @brief Gets trace timestamp period. + * + * @param[out] puiPeriod Period. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTimestampGetPeriod( puiPeriod ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( puiPeriod ) = pxTraceTimestamp->period, TRC_SUCCESS ) + +/** + * @brief Gets trace timestamp OS tick count. + * + * @param[in] puiOsTickCount + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + #define xTraceTimestampGetOsTickCount( puiOsTickCount ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( puiOsTickCount ) = pxTraceTimestamp->osTickCount, TRC_SUCCESS ) + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/** @} */ + + #ifdef __cplusplus +} + #endif + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /* TRC_TIMESTAMP_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTypes.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTypes.h index 98aee91ba..b2428a3a5 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTypes.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcTypes.h @@ -1,69 +1,69 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The common types. -*/ - -#ifndef TRC_TYPES_H -#define TRC_TYPES_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef TRC_BASE_TYPE -#define TRC_BASE_TYPE int32_t -#endif - -#ifndef TRC_UNSIGNED_BASE_TYPE -#define TRC_UNSIGNED_BASE_TYPE uint32_t -#endif - -typedef TRC_UNSIGNED_BASE_TYPE TraceUnsignedBaseType_t; - -typedef TRC_BASE_TYPE TraceBaseType_t; - -typedef TraceUnsignedBaseType_t traceResult; - -typedef TraceUnsignedBaseType_t TraceEventHandle_t; - -typedef TraceUnsignedBaseType_t TraceISRHandle_t; - -typedef TraceUnsignedBaseType_t TraceEntryHandle_t; - -typedef TraceUnsignedBaseType_t TraceTaskHandle_t; - -typedef TraceUnsignedBaseType_t TraceObjectHandle_t; - -typedef TraceUnsignedBaseType_t TraceExtensionHandle_t; - -typedef TraceUnsignedBaseType_t TraceHeapHandle_t; - -typedef TraceUnsignedBaseType_t TraceIntervalHandle_t; - -typedef TraceUnsignedBaseType_t TraceStateMachineHandle_t; - -typedef TraceUnsignedBaseType_t TraceStateMachineStateHandle_t; - -typedef TraceUnsignedBaseType_t TraceStringHandle_t; - -typedef TraceUnsignedBaseType_t TraceCounterHandle_t; - -typedef void (*TraceCounterCallback_t)(TraceCounterHandle_t xCounterHandle); - -/* DEPRECATED. Backwards compatibility */ -typedef TraceStringHandle_t traceString; - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_TYPES_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The common types. + */ + +#ifndef TRC_TYPES_H + #define TRC_TYPES_H + + #include + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + + #ifndef TRC_BASE_TYPE + #define TRC_BASE_TYPE int32_t + #endif + + #ifndef TRC_UNSIGNED_BASE_TYPE + #define TRC_UNSIGNED_BASE_TYPE uint32_t + #endif + + typedef TRC_UNSIGNED_BASE_TYPE TraceUnsignedBaseType_t; + + typedef TRC_BASE_TYPE TraceBaseType_t; + + typedef TraceUnsignedBaseType_t traceResult; + + typedef TraceUnsignedBaseType_t TraceEventHandle_t; + + typedef TraceUnsignedBaseType_t TraceISRHandle_t; + + typedef TraceUnsignedBaseType_t TraceEntryHandle_t; + + typedef TraceUnsignedBaseType_t TraceTaskHandle_t; + + typedef TraceUnsignedBaseType_t TraceObjectHandle_t; + + typedef TraceUnsignedBaseType_t TraceExtensionHandle_t; + + typedef TraceUnsignedBaseType_t TraceHeapHandle_t; + + typedef TraceUnsignedBaseType_t TraceIntervalHandle_t; + + typedef TraceUnsignedBaseType_t TraceStateMachineHandle_t; + + typedef TraceUnsignedBaseType_t TraceStateMachineStateHandle_t; + + typedef TraceUnsignedBaseType_t TraceStringHandle_t; + + typedef TraceUnsignedBaseType_t TraceCounterHandle_t; + + typedef void (* TraceCounterCallback_t)( TraceCounterHandle_t xCounterHandle ); + +/* DEPRECATED. Backwards compatibility */ + typedef TraceStringHandle_t traceString; + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_TYPES_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcUtility.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcUtility.h index 225b6ccf3..e05b26591 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcUtility.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcUtility.h @@ -1,51 +1,51 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The interface for trace utility functions. -*/ - -#ifndef TRC_UTILITY_H -#define TRC_UTILITY_H - -#ifndef TRC_MEMCPY -#define TRC_MEMCPY(dst, src, size) \ - { \ - uint32_t __i; \ - for (__i = 0; __i < size; __i++) { \ - ((uint8_t*)(dst))[__i] = ((uint8_t*)(src))[__i]; \ - } \ - } -#endif - -#define TRC_STRCAT(dst, dst_size, pDstLength, src) \ - { \ - TraceUnsignedBaseType_t uxTRC_STRCAT_INDEX = 0; \ - while (*(pDstLength) < (dst_size)) \ - { \ - dst[*(pDstLength)] = src[uxTRC_STRCAT_INDEX]; \ - if (dst[*(pDstLength)] == 0) \ - break; \ - (*(pDstLength))++; \ - uxTRC_STRCAT_INDEX++; \ - } \ - } - -#if (defined(TRC_CFG_USE_GCC_STATEMENT_EXPR) && TRC_CFG_USE_GCC_STATEMENT_EXPR == 1) || __GNUC__ - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(e1) ({e1;}) - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(e1, e2) ({e1; e2;}) - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3(e1, e2, e3) ({e1; e2; e3;}) - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(e1, e2, e3, e4) ({e1; e2; e3; e4;}) - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5(e1, e2, e3, e4, e5) ({e1; e2; e3; e4; e5;}) -#else - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(e1) (e1) - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(e1, e2) (e1, e2) - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3(e1, e2, e3) (e1, e2, e3) - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4(e1, e2, e3, e4) (e1, e2, e3, e4) - #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5(e1, e2, e3, e4, e5) (e1, e2, e3, e4, e5) -#endif - -#endif /* TRC_UTILITY_H */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface for trace utility functions. + */ + +#ifndef TRC_UTILITY_H +#define TRC_UTILITY_H + +#ifndef TRC_MEMCPY + #define TRC_MEMCPY( dst, src, size ) \ + { \ + uint32_t __i; \ + for( __i = 0; __i < size; __i++ ) { \ + ( ( uint8_t * ) ( dst ) )[ __i ] = ( ( uint8_t * ) ( src ) )[ __i ]; \ + } \ + } +#endif + +#define TRC_STRCAT( dst, dst_size, pDstLength, src ) \ + { \ + TraceUnsignedBaseType_t uxTRC_STRCAT_INDEX = 0; \ + while( *( pDstLength ) < ( dst_size ) ) \ + { \ + dst[ *( pDstLength ) ] = src[ uxTRC_STRCAT_INDEX ]; \ + if( dst[ *( pDstLength ) ] == 0 ) \ + break; \ + ( *( pDstLength ) ) ++; \ + uxTRC_STRCAT_INDEX++; \ + } \ + } + +#if ( defined( TRC_CFG_USE_GCC_STATEMENT_EXPR ) && TRC_CFG_USE_GCC_STATEMENT_EXPR == 1 ) || __GNUC__ + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1( e1 ) ( { e1; } ) + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( e1, e2 ) ( { e1; e2; } ) + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( e1, e2, e3 ) ( { e1; e2; e3; } ) + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( e1, e2, e3, e4 ) ( { e1; e2; e3; e4; } ) + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5( e1, e2, e3, e4, e5 ) ( { e1; e2; e3; e4; e5; } ) +#else + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1( e1 ) ( e1 ) + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( e1, e2 ) ( e1, e2 ) + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_3( e1, e2, e3 ) ( e1, e2, e3 ) + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( e1, e2, e3, e4 ) ( e1, e2, e3, e4 ) + #define TRC_COMMA_EXPR_TO_STATEMENT_EXPR_5( e1, e2, e3, e4, e5 ) ( e1, e2, e3, e4, e5 ) +#endif /* if ( defined( TRC_CFG_USE_GCC_STATEMENT_EXPR ) && TRC_CFG_USE_GCC_STATEMENT_EXPR == 1 ) || __GNUC__ */ + +#endif /* TRC_UTILITY_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/LICENSE.md b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/LICENSE.md index 29f81d812..261eeb9e9 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/LICENSE.md +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/LICENSE.md @@ -1,201 +1,201 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/LICENSE.spdx b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/LICENSE.spdx index c46cd90f9..0779f51a8 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/LICENSE.spdx +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/LICENSE.spdx @@ -1,10 +1,10 @@ -SPDXVersion: SPDX-2.2 -DataLicense: CC0-1.0 -Creator: Organization: Percepio AB () -PackageName: TraceRecorderSource -PackageOriginator: Percepio AB -PackageDownloadLocation: git+https://github.com/percepio/TraceRecorderSource.git -PackageLicenseDeclared: Apache-2.0 -PackageCopyrightText: Copyright 2021 Percepio AB -PackageSummary: Trace Recorder +SPDXVersion: SPDX-2.2 +DataLicense: CC0-1.0 +Creator: Organization: Percepio AB () +PackageName: TraceRecorderSource +PackageOriginator: Percepio AB +PackageDownloadLocation: git+https://github.com/percepio/TraceRecorderSource.git +PackageLicenseDeclared: Apache-2.0 +PackageCopyrightText: Copyright 2021 Percepio AB +PackageSummary: Trace Recorder PackageDescription: A generic software Trace Recorder that can generate trace events and transmit or store them. \ No newline at end of file diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/README.md b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/README.md index eaea65595..d9f9159d3 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/README.md +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/README.md @@ -1,5 +1,5 @@ -Trace Recorder source code for use with Percepio's Tracealyzer. - -Read more at https://percepio.com/tracealyzer/ and https://percepio.com/gettingstarted. - -Repository at https://github.com/percepio/TraceRecorderSource +Trace Recorder source code for use with Percepio's Tracealyzer. + +Read more at https://percepio.com/tracealyzer/ and https://percepio.com/gettingstarted. + +Repository at https://github.com/percepio/TraceRecorderSource diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/ReadMe.url b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/ReadMe.url index 251da66aa..d12e8899a 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/ReadMe.url +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/ReadMe.url @@ -1,5 +1,5 @@ -[InternetShortcut] -URL=http://www.freertos.org/trace -IDList= -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/trace +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h index 3e10709b4..032f84bca 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcConfig.h @@ -1,320 +1,320 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Main configuration parameters for the trace recorder library. - * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h. - */ - -#ifndef TRC_CONFIG_H -#define TRC_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/****************************************************************************** - * Include of processor header file - * - * Here you may need to include the header file for your processor. This is - * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API. - * Try that in case of build problems. Otherwise, remove the #error line below. - *****************************************************************************/ -#error "Trace Recorder: Please include your processor's header file here and remove this line." - -/** - * @def TRC_CFG_HARDWARE_PORT - * @brief Specify what hardware port to use (i.e., the "timestamping driver"). - * - * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M". - * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is - * available on most such devices. In case your device don't have DWT support, - * you will get an error message opening the trace. In that case, you may - * force the recorder to use SysTick timestamping instead, using this define: - * - * #define TRC_CFG_ARM_CM_USE_SYSTICK - * - * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically. - * - * See trcHardwarePort.h for available ports and information on how to - * define your own port, if not already present. - */ -#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET - -/** - * @def TRC_CFG_SCHEDULING_ONLY - * @brief Macro which should be defined as an integer value. - * - * If this setting is enabled (= 1), only scheduling events are recorded. - * If disabled (= 0), all events are recorded (unless filtered in other ways). - * - * Default value is 0 (= include additional events). - */ -#define TRC_CFG_SCHEDULING_ONLY 0 - -/** - * @def TRC_CFG_INCLUDE_MEMMANG_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * This controls if malloc and free calls should be traced. Set this to zero (0) - * to exclude malloc/free calls, or one (1) to include such events in the trace. - * - * Default value is 1. - */ -#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1 - -/** - * @def TRC_CFG_INCLUDE_USER_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), all code related to User Events is excluded in order - * to reduce code size. Any attempts of storing User Events are then silently - * ignored. - * - * User Events are application-generated events, like "printf" but for the - * trace log, generated using vTracePrint and vTracePrintF. - * The formatting is done on host-side, by Tracealyzer. User Events are - * therefore much faster than a console printf and can often be used - * in timing critical code without problems. - * - * Note: In streaming mode, User Events are used to provide error messages - * and warnings from the recorder (in case of incorrect configuration) for - * display in Tracealyzer. Disabling user events will also disable these - * warnings. You can however still catch them by calling xTraceErrorGetLast - * or by putting breakpoints in xTraceError and xTraceWarning. - * - * Default value is 1. - */ -#define TRC_CFG_INCLUDE_USER_EVENTS 1 - -/** - * @def TRC_CFG_INCLUDE_ISR_TRACING - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the code for recording Interrupt Service Routines is - * excluded, in order to reduce code size. This means that any calls to - * vTraceStoreISRBegin/vTraceStoreISREnd will be ignored. - * This does not completely disable ISR tracing, in cases where an ISR is - * calling a traced kernel service. These events will still be recorded and - * show up in anonymous ISR instances in Tracealyzer, with names such as - * "ISR sending to ". - * To disable such tracing, please refer to vTraceSetFilterGroup and - * vTraceSetFilterMask. - * - * Default value is 1. - * - * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin - * and vTraceStoreISREnd in your interrupt handlers. - */ -#define TRC_CFG_INCLUDE_ISR_TRACING 1 - -/** - * @def TRC_CFG_INCLUDE_READY_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If one (1), events are recorded when tasks enter scheduling state "ready". - * This allows Tracealyzer to show the initial pending time before tasks enter - * the execution state, and present accurate response times. - * If zero (0), "ready events" are not created, which allows for recording - * longer traces in the same amount of RAM. - * - * Default value is 1. - */ -#define TRC_CFG_INCLUDE_READY_EVENTS 1 - -/** - * @def TRC_CFG_INCLUDE_OSTICK_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is one (1), events will be generated whenever the OS clock is - * increased. If zero (0), OS tick events are not generated, which allows for - * recording longer traces in the same amount of RAM. - * - * Default value is 1. - */ -#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1 - -/** - * @def TRC_CFG_ENABLE_STACK_MONITOR - * @brief If enabled (1), the recorder periodically reports the unused stack space of - * all active tasks. - * The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task - * is always created by the recorder when in streaming mode. - * In snapshot mode, the TzCtrl task is only used for stack monitoring and is - * not created unless this is enabled. - */ -#define TRC_CFG_ENABLE_STACK_MONITOR 1 - -/** - * @def TRC_CFG_STACK_MONITOR_MAX_TASKS - * @brief Macro which should be defined as a non-zero integer value. - * - * This controls how many tasks that can be monitored by the stack monitor. - * If this is too small, some tasks will be excluded and a warning is shown. - * - * Default value is 10. - */ -#define TRC_CFG_STACK_MONITOR_MAX_TASKS 10 - -/** - * @def TRC_CFG_STACK_MONITOR_MAX_REPORTS - * @brief Macro which should be defined as a non-zero integer value. - * - * This defines how many tasks that will be subject to stack usage analysis for - * each execution of the Tracealyzer Control task (TzCtrl). Note that the stack - * monitoring cycles between the tasks, so this does not affect WHICH tasks that - * are monitored, but HOW OFTEN each task stack is analyzed. - * - * This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the - * frequency of the stack monitoring. This is motivated since the stack analysis - * can take some time to execute. - * However, note that the stack analysis runs in a separate task (TzCtrl) that - * can be executed on low priority. This way, you can avoid that the stack - * analysis disturbs any time-sensitive tasks. - * - * Default value is 1. - */ -#define TRC_CFG_STACK_MONITOR_MAX_REPORTS 1 - -/** - * @def TRC_CFG_CTRL_TASK_PRIORITY - * @brief The scheduling priority of the Tracealyzer Control (TzCtrl) task. - * - * In streaming mode, TzCtrl is used to receive start/stop commands from - * Tracealyzer and in some cases also to transmit the trace data (for stream - * ports that uses the internal buffer, like TCP/IP). For such stream ports, - * make sure the TzCtrl priority is high enough to ensure reliable periodic - * execution and transfer of the data, but low enough to avoid disturbing any - * time-sensitive functions. - * - * In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is - * not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should - * be low, to avoid disturbing any time-sensitive tasks. - */ -#define TRC_CFG_CTRL_TASK_PRIORITY 1 - -/** - * @def TRC_CFG_CTRL_TASK_DELAY - * @brief The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY), - * which affects the frequency of the stack monitoring. - * - * In streaming mode, this also affects the trace data transfer if you are using - * a stream port leveraging the internal buffer (like TCP/IP). A shorter delay - * increases the CPU load of TzCtrl somewhat, but may improve the performance of - * of the trace streaming, especially if the trace buffer is small. - */ -#define TRC_CFG_CTRL_TASK_DELAY 2 - -/** - * @def TRC_CFG_CTRL_TASK_STACK_SIZE - * @brief The stack size of the Tracealyzer Control (TzCtrl) task. - * See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl. - */ -#define TRC_CFG_CTRL_TASK_STACK_SIZE 1024 - -/** - * @def TRC_CFG_RECORDER_BUFFER_ALLOCATION - * @brief Specifies how the recorder buffer is allocated (also in case of streaming, in - * port using the recorder's internal temporary buffer) - * - * Values: - * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal) - * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable - * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer - * - * Static and dynamic mode does the allocation for you, either in compile time - * (static) or in runtime (malloc). - * The custom mode allows you to control how and where the allocation is made, - * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer(). - */ -#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC - -/** - * @def TRC_CFG_MAX_ISR_NESTING - * @brief Defines how many levels of interrupt nesting the recorder can handle, in - * case multiple ISRs are traced and ISR nesting is possible. If this - * is exceeded, the particular ISR will not be traced and the recorder then - * logs an error message. This setting is used to allocate an internal stack - * for keeping track of the previous execution context (4 byte per entry). - * - * This value must be a non-zero positive constant, at least 1. - * - * Default value: 8 - */ -#define TRC_CFG_MAX_ISR_NESTING 8 - -/** - * @def TRC_CFG_ISR_TAILCHAINING_THRESHOLD - * @brief Macro which should be defined as an integer value. - * - * If tracing multiple ISRs, this setting allows for accurate display of the - * context-switching also in cases when the ISRs execute in direct sequence. - * - * vTraceStoreISREnd normally assumes that the ISR returns to the previous - * context, i.e., a task or a preempted ISR. But if another traced ISR - * executes in direct sequence, Tracealyzer may incorrectly display a minimal - * fragment of the previous context in between the ISRs. - * - * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is - * however a threshold value that must be measured for your specific setup. - * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ - * - * The default setting is 0, meaning "disabled" and that you may get an - * extra fragments of the previous context in between tail-chained ISRs. - * - * Note: This setting has separate definitions in trcSnapshotConfig.h and - * trcStreamingConfig.h, since it is affected by the recorder mode. - */ -#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 - -/** - * @def TRC_CFG_RECORDER_DATA_INIT - * @brief Macro which states wether the recorder data should have an initial value. - * - * In very specific cases where traced objects are created before main(), - * the recorder will need to be started even before that. In these cases, - * the recorder data would be initialized by vTraceEnable(TRC_INIT) but could - * then later be overwritten by the initialization value. - * If this is an issue for you, set TRC_CFG_RECORDER_DATA_INIT to 0. - * The following code can then be used before any traced objects are created: - * - * extern uint32_t RecorderEnabled; - * RecorderEnabled = 0; - * xTraceInitialize(); - * - * After the clocks are properly initialized, use vTraceEnable(...) to start - * the tracing. - * - * Default value is 1. - */ -#define TRC_CFG_RECORDER_DATA_INIT 1 - -/** - * @def TRC_CFG_RECORDER_DATA_ATTRIBUTE - * @brief When setting TRC_CFG_RECORDER_DATA_INIT to 0, you might also need to make - * sure certain recorder data is placed in a specific RAM section to avoid being - * zeroed out after initialization. Define TRC_CFG_RECORDER_DATA_ATTRIBUTE as - * that attribute. - * - * Example: - * #define TRC_CFG_RECORDER_DATA_ATTRIBUTE __attribute__((section(".bss.trace_recorder_data"))) - * - * Default value is empty. - */ -#define TRC_CFG_RECORDER_DATA_ATTRIBUTE - -/** - * @def TRC_CFG_USE_TRACE_ASSERT - * @brief Enable or disable debug asserts. Information regarding any assert that is - * triggered will be in trcAssert.c. - */ -#define TRC_CFG_USE_TRACE_ASSERT 0 - -#ifdef __cplusplus -} -#endif - -#endif /* _TRC_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Main configuration parameters for the trace recorder library. + * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h. + */ + +#ifndef TRC_CONFIG_H + #define TRC_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/****************************************************************************** + * Include of processor header file + * + * Here you may need to include the header file for your processor. This is + * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API. + * Try that in case of build problems. Otherwise, remove the #error line below. + *****************************************************************************/ + #error "Trace Recorder: Please include your processor's header file here and remove this line." + +/** + * @def TRC_CFG_HARDWARE_PORT + * @brief Specify what hardware port to use (i.e., the "timestamping driver"). + * + * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M". + * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is + * available on most such devices. In case your device don't have DWT support, + * you will get an error message opening the trace. In that case, you may + * force the recorder to use SysTick timestamping instead, using this define: + * + * #define TRC_CFG_ARM_CM_USE_SYSTICK + * + * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically. + * + * See trcHardwarePort.h for available ports and information on how to + * define your own port, if not already present. + */ + #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET + +/** + * @def TRC_CFG_SCHEDULING_ONLY + * @brief Macro which should be defined as an integer value. + * + * If this setting is enabled (= 1), only scheduling events are recorded. + * If disabled (= 0), all events are recorded (unless filtered in other ways). + * + * Default value is 0 (= include additional events). + */ + #define TRC_CFG_SCHEDULING_ONLY 0 + +/** + * @def TRC_CFG_INCLUDE_MEMMANG_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * This controls if malloc and free calls should be traced. Set this to zero (0) + * to exclude malloc/free calls, or one (1) to include such events in the trace. + * + * Default value is 1. + */ + #define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1 + +/** + * @def TRC_CFG_INCLUDE_USER_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), all code related to User Events is excluded in order + * to reduce code size. Any attempts of storing User Events are then silently + * ignored. + * + * User Events are application-generated events, like "printf" but for the + * trace log, generated using vTracePrint and vTracePrintF. + * The formatting is done on host-side, by Tracealyzer. User Events are + * therefore much faster than a console printf and can often be used + * in timing critical code without problems. + * + * Note: In streaming mode, User Events are used to provide error messages + * and warnings from the recorder (in case of incorrect configuration) for + * display in Tracealyzer. Disabling user events will also disable these + * warnings. You can however still catch them by calling xTraceErrorGetLast + * or by putting breakpoints in xTraceError and xTraceWarning. + * + * Default value is 1. + */ + #define TRC_CFG_INCLUDE_USER_EVENTS 1 + +/** + * @def TRC_CFG_INCLUDE_ISR_TRACING + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the code for recording Interrupt Service Routines is + * excluded, in order to reduce code size. This means that any calls to + * vTraceStoreISRBegin/vTraceStoreISREnd will be ignored. + * This does not completely disable ISR tracing, in cases where an ISR is + * calling a traced kernel service. These events will still be recorded and + * show up in anonymous ISR instances in Tracealyzer, with names such as + * "ISR sending to ". + * To disable such tracing, please refer to vTraceSetFilterGroup and + * vTraceSetFilterMask. + * + * Default value is 1. + * + * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin + * and vTraceStoreISREnd in your interrupt handlers. + */ + #define TRC_CFG_INCLUDE_ISR_TRACING 1 + +/** + * @def TRC_CFG_INCLUDE_READY_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If one (1), events are recorded when tasks enter scheduling state "ready". + * This allows Tracealyzer to show the initial pending time before tasks enter + * the execution state, and present accurate response times. + * If zero (0), "ready events" are not created, which allows for recording + * longer traces in the same amount of RAM. + * + * Default value is 1. + */ + #define TRC_CFG_INCLUDE_READY_EVENTS 1 + +/** + * @def TRC_CFG_INCLUDE_OSTICK_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is one (1), events will be generated whenever the OS clock is + * increased. If zero (0), OS tick events are not generated, which allows for + * recording longer traces in the same amount of RAM. + * + * Default value is 1. + */ + #define TRC_CFG_INCLUDE_OSTICK_EVENTS 1 + +/** + * @def TRC_CFG_ENABLE_STACK_MONITOR + * @brief If enabled (1), the recorder periodically reports the unused stack space of + * all active tasks. + * The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task + * is always created by the recorder when in streaming mode. + * In snapshot mode, the TzCtrl task is only used for stack monitoring and is + * not created unless this is enabled. + */ + #define TRC_CFG_ENABLE_STACK_MONITOR 1 + +/** + * @def TRC_CFG_STACK_MONITOR_MAX_TASKS + * @brief Macro which should be defined as a non-zero integer value. + * + * This controls how many tasks that can be monitored by the stack monitor. + * If this is too small, some tasks will be excluded and a warning is shown. + * + * Default value is 10. + */ + #define TRC_CFG_STACK_MONITOR_MAX_TASKS 10 + +/** + * @def TRC_CFG_STACK_MONITOR_MAX_REPORTS + * @brief Macro which should be defined as a non-zero integer value. + * + * This defines how many tasks that will be subject to stack usage analysis for + * each execution of the Tracealyzer Control task (TzCtrl). Note that the stack + * monitoring cycles between the tasks, so this does not affect WHICH tasks that + * are monitored, but HOW OFTEN each task stack is analyzed. + * + * This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the + * frequency of the stack monitoring. This is motivated since the stack analysis + * can take some time to execute. + * However, note that the stack analysis runs in a separate task (TzCtrl) that + * can be executed on low priority. This way, you can avoid that the stack + * analysis disturbs any time-sensitive tasks. + * + * Default value is 1. + */ + #define TRC_CFG_STACK_MONITOR_MAX_REPORTS 1 + +/** + * @def TRC_CFG_CTRL_TASK_PRIORITY + * @brief The scheduling priority of the Tracealyzer Control (TzCtrl) task. + * + * In streaming mode, TzCtrl is used to receive start/stop commands from + * Tracealyzer and in some cases also to transmit the trace data (for stream + * ports that uses the internal buffer, like TCP/IP). For such stream ports, + * make sure the TzCtrl priority is high enough to ensure reliable periodic + * execution and transfer of the data, but low enough to avoid disturbing any + * time-sensitive functions. + * + * In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is + * not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should + * be low, to avoid disturbing any time-sensitive tasks. + */ + #define TRC_CFG_CTRL_TASK_PRIORITY 1 + +/** + * @def TRC_CFG_CTRL_TASK_DELAY + * @brief The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY), + * which affects the frequency of the stack monitoring. + * + * In streaming mode, this also affects the trace data transfer if you are using + * a stream port leveraging the internal buffer (like TCP/IP). A shorter delay + * increases the CPU load of TzCtrl somewhat, but may improve the performance of + * of the trace streaming, especially if the trace buffer is small. + */ + #define TRC_CFG_CTRL_TASK_DELAY 2 + +/** + * @def TRC_CFG_CTRL_TASK_STACK_SIZE + * @brief The stack size of the Tracealyzer Control (TzCtrl) task. + * See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl. + */ + #define TRC_CFG_CTRL_TASK_STACK_SIZE 1024 + +/** + * @def TRC_CFG_RECORDER_BUFFER_ALLOCATION + * @brief Specifies how the recorder buffer is allocated (also in case of streaming, in + * port using the recorder's internal temporary buffer) + * + * Values: + * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal) + * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable + * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer + * + * Static and dynamic mode does the allocation for you, either in compile time + * (static) or in runtime (malloc). + * The custom mode allows you to control how and where the allocation is made, + * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer(). + */ + #define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC + +/** + * @def TRC_CFG_MAX_ISR_NESTING + * @brief Defines how many levels of interrupt nesting the recorder can handle, in + * case multiple ISRs are traced and ISR nesting is possible. If this + * is exceeded, the particular ISR will not be traced and the recorder then + * logs an error message. This setting is used to allocate an internal stack + * for keeping track of the previous execution context (4 byte per entry). + * + * This value must be a non-zero positive constant, at least 1. + * + * Default value: 8 + */ + #define TRC_CFG_MAX_ISR_NESTING 8 + +/** + * @def TRC_CFG_ISR_TAILCHAINING_THRESHOLD + * @brief Macro which should be defined as an integer value. + * + * If tracing multiple ISRs, this setting allows for accurate display of the + * context-switching also in cases when the ISRs execute in direct sequence. + * + * vTraceStoreISREnd normally assumes that the ISR returns to the previous + * context, i.e., a task or a preempted ISR. But if another traced ISR + * executes in direct sequence, Tracealyzer may incorrectly display a minimal + * fragment of the previous context in between the ISRs. + * + * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is + * however a threshold value that must be measured for your specific setup. + * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ + * + * The default setting is 0, meaning "disabled" and that you may get an + * extra fragments of the previous context in between tail-chained ISRs. + * + * Note: This setting has separate definitions in trcSnapshotConfig.h and + * trcStreamingConfig.h, since it is affected by the recorder mode. + */ + #define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 + +/** + * @def TRC_CFG_RECORDER_DATA_INIT + * @brief Macro which states wether the recorder data should have an initial value. + * + * In very specific cases where traced objects are created before main(), + * the recorder will need to be started even before that. In these cases, + * the recorder data would be initialized by vTraceEnable(TRC_INIT) but could + * then later be overwritten by the initialization value. + * If this is an issue for you, set TRC_CFG_RECORDER_DATA_INIT to 0. + * The following code can then be used before any traced objects are created: + * + * extern uint32_t RecorderEnabled; + * RecorderEnabled = 0; + * xTraceInitialize(); + * + * After the clocks are properly initialized, use vTraceEnable(...) to start + * the tracing. + * + * Default value is 1. + */ + #define TRC_CFG_RECORDER_DATA_INIT 1 + +/** + * @def TRC_CFG_RECORDER_DATA_ATTRIBUTE + * @brief When setting TRC_CFG_RECORDER_DATA_INIT to 0, you might also need to make + * sure certain recorder data is placed in a specific RAM section to avoid being + * zeroed out after initialization. Define TRC_CFG_RECORDER_DATA_ATTRIBUTE as + * that attribute. + * + * Example: + * #define TRC_CFG_RECORDER_DATA_ATTRIBUTE __attribute__((section(".bss.trace_recorder_data"))) + * + * Default value is empty. + */ + #define TRC_CFG_RECORDER_DATA_ATTRIBUTE + +/** + * @def TRC_CFG_USE_TRACE_ASSERT + * @brief Enable or disable debug asserts. Information regarding any assert that is + * triggered will be in trcAssert.c. + */ + #define TRC_CFG_USE_TRACE_ASSERT 0 + + #ifdef __cplusplus +} + #endif + +#endif /* _TRC_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortConfig.h index 08443bf24..7f0369c98 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortConfig.h @@ -1,116 +1,116 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Configuration parameters for the kernel port. - * More settings can be found in trcKernelPortStreamingConfig.h and - * trcKernelPortSnapshotConfig.h. - */ - -#ifndef TRC_KERNEL_PORT_CONFIG_H -#define TRC_KERNEL_PORT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @def TRC_CFG_RECORDER_MODE - * @brief Specify what recording mode to use. Snapshot means that the data is saved in - * an internal RAM buffer, for later upload. Streaming means that the data is - * transferred continuously to the host PC. - * - * For more information, see http://percepio.com/2016/10/05/rtos-tracing/ - * and the Tracealyzer User Manual. - * - * Values: - * TRC_RECORDER_MODE_SNAPSHOT - * TRC_RECORDER_MODE_STREAMING - */ -#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_STREAMING - -/** - * @def TRC_CFG_FREERTOS_VERSION - * @brief Specify what version of FreeRTOS that is used (don't change unless using the - * trace recorder library with an older version of FreeRTOS). - * - * TRC_FREERTOS_VERSION_7_3_X If using FreeRTOS v7.3.X - * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X - * TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X - * TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X - * TRC_FREERTOS_VERSION_8_X_X If using FreeRTOS v8.X.X - * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0 - * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1 - * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2 - * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 - * TRC_FREERTOS_VERSION_10_0_1 If using FreeRTOS v10.0.1 - * TRC_FREERTOS_VERSION_10_1_0 If using FreeRTOS v10.1.0 - * TRC_FREERTOS_VERSION_10_1_1 If using FreeRTOS v10.1.1 - * TRC_FREERTOS_VERSION_10_2_0 If using FreeRTOS v10.2.0 - * TRC_FREERTOS_VERSION_10_2_1 If using FreeRTOS v10.2.1 - * TRC_FREERTOS_VERSION_10_3_0 If using FreeRTOS v10.3.0 - * TRC_FREERTOS_VERSION_10_3_1 If using FreeRTOS v10.3.1 - * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 - * TRC_FREERTOS_VERSION_10_4_1 If using FreeRTOS v10.4.1 or later - */ -#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_1 - -/** - * @def TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the trace will exclude any "event group" events. - * - * Default value is 0 (excluded) since dependent on event_groups.c - */ -#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 1 - -/** - * @def TRC_CFG_INCLUDE_TIMER_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the trace will exclude any Timer events. - * - * Default value is 0 since dependent on timers.c - */ -#define TRC_CFG_INCLUDE_TIMER_EVENTS 1 - -/** - * @def TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the trace will exclude any "pending function call" - * events, such as xTimerPendFunctionCall(). - * - * Default value is 0 since dependent on timers.c - */ -#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 - -/** - * @def TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the trace will exclude any stream buffer or message - * buffer events. - * - * Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10) - */ -#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 1 - -/** - * @def TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND - * @brief When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace - * point in prvNotifyQueueSetContainer() in queue.c is renamed from - * traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from - * other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED. - */ -#define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND 0 /* TRC_ACKNOWLEDGED */ - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_KERNEL_PORT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Configuration parameters for the kernel port. + * More settings can be found in trcKernelPortStreamingConfig.h and + * trcKernelPortSnapshotConfig.h. + */ + +#ifndef TRC_KERNEL_PORT_CONFIG_H + #define TRC_KERNEL_PORT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @def TRC_CFG_RECORDER_MODE + * @brief Specify what recording mode to use. Snapshot means that the data is saved in + * an internal RAM buffer, for later upload. Streaming means that the data is + * transferred continuously to the host PC. + * + * For more information, see http://percepio.com/2016/10/05/rtos-tracing/ + * and the Tracealyzer User Manual. + * + * Values: + * TRC_RECORDER_MODE_SNAPSHOT + * TRC_RECORDER_MODE_STREAMING + */ + #define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_STREAMING + +/** + * @def TRC_CFG_FREERTOS_VERSION + * @brief Specify what version of FreeRTOS that is used (don't change unless using the + * trace recorder library with an older version of FreeRTOS). + * + * TRC_FREERTOS_VERSION_7_3_X If using FreeRTOS v7.3.X + * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X + * TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X + * TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X + * TRC_FREERTOS_VERSION_8_X_X If using FreeRTOS v8.X.X + * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0 + * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1 + * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2 + * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 + * TRC_FREERTOS_VERSION_10_0_1 If using FreeRTOS v10.0.1 + * TRC_FREERTOS_VERSION_10_1_0 If using FreeRTOS v10.1.0 + * TRC_FREERTOS_VERSION_10_1_1 If using FreeRTOS v10.1.1 + * TRC_FREERTOS_VERSION_10_2_0 If using FreeRTOS v10.2.0 + * TRC_FREERTOS_VERSION_10_2_1 If using FreeRTOS v10.2.1 + * TRC_FREERTOS_VERSION_10_3_0 If using FreeRTOS v10.3.0 + * TRC_FREERTOS_VERSION_10_3_1 If using FreeRTOS v10.3.1 + * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 + * TRC_FREERTOS_VERSION_10_4_1 If using FreeRTOS v10.4.1 or later + */ + #define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_1 + +/** + * @def TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any "event group" events. + * + * Default value is 0 (excluded) since dependent on event_groups.c + */ + #define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 1 + +/** + * @def TRC_CFG_INCLUDE_TIMER_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any Timer events. + * + * Default value is 0 since dependent on timers.c + */ + #define TRC_CFG_INCLUDE_TIMER_EVENTS 1 + +/** + * @def TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any "pending function call" + * events, such as xTimerPendFunctionCall(). + * + * Default value is 0 since dependent on timers.c + */ + #define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 + +/** + * @def TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any stream buffer or message + * buffer events. + * + * Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10) + */ + #define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 1 + +/** + * @def TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND + * @brief When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace + * point in prvNotifyQueueSetContainer() in queue.c is renamed from + * traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from + * other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED. + */ + #define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND 0 /* TRC_ACKNOWLEDGED */ + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_KERNEL_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortSnapshotConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortSnapshotConfig.h index 9b1b1f411..1036e7237 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortSnapshotConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortSnapshotConfig.h @@ -1,69 +1,69 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Kernel port configuration parameters for snapshot mode. - */ - -#ifndef TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H -#define TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @def TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE... - * @brief A group of macros which should be defined as integer values, zero or larger. - * - * These define the capacity of the Object Property Table, i.e., the maximum - * number of objects active at any given point, within each object class (e.g., - * task, queue, semaphore, ...). - * - * If tasks or other objects are deleted in your system, this - * setting does not limit the total amount of objects created, only the number - * of objects that have been successfully created but not yet deleted. - * - * Using too small values will cause vTraceError to be called, which stores an - * error message in the trace that is shown when opening the trace file. The - * error message can also be retrieved using xTraceGetLastError. - * - * It can be wise to start with large values for these constants, - * unless you are very confident on these numbers. Then do a recording and - * check the actual usage by selecting View menu -> Trace Details -> - * Resource Usage -> Object Table. - */ -#define TRC_CFG_NTASK 15 -#define TRC_CFG_NISR 5 -#define TRC_CFG_NQUEUE 10 -#define TRC_CFG_NSEMAPHORE 10 -#define TRC_CFG_NMUTEX 10 -#define TRC_CFG_NTIMER 5 -#define TRC_CFG_NEVENTGROUP 5 -#define TRC_CFG_NSTREAMBUFFER 5 -#define TRC_CFG_NMESSAGEBUFFER 5 - -/** - * @def TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ... - * @brief Macros that specify the maximum lengths (number of characters) for names of - * kernel objects, such as tasks and queues. If longer names are used, they will - * be truncated when stored in the recorder. - */ -#define TRC_CFG_NAME_LEN_TASK 15 -#define TRC_CFG_NAME_LEN_ISR 15 -#define TRC_CFG_NAME_LEN_QUEUE 15 -#define TRC_CFG_NAME_LEN_SEMAPHORE 15 -#define TRC_CFG_NAME_LEN_MUTEX 15 -#define TRC_CFG_NAME_LEN_TIMER 15 -#define TRC_CFG_NAME_LEN_EVENTGROUP 15 -#define TRC_CFG_NAME_LEN_STREAMBUFFER 15 -#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Kernel port configuration parameters for snapshot mode. + */ + +#ifndef TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H + #define TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @def TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE... + * @brief A group of macros which should be defined as integer values, zero or larger. + * + * These define the capacity of the Object Property Table, i.e., the maximum + * number of objects active at any given point, within each object class (e.g., + * task, queue, semaphore, ...). + * + * If tasks or other objects are deleted in your system, this + * setting does not limit the total amount of objects created, only the number + * of objects that have been successfully created but not yet deleted. + * + * Using too small values will cause vTraceError to be called, which stores an + * error message in the trace that is shown when opening the trace file. The + * error message can also be retrieved using xTraceGetLastError. + * + * It can be wise to start with large values for these constants, + * unless you are very confident on these numbers. Then do a recording and + * check the actual usage by selecting View menu -> Trace Details -> + * Resource Usage -> Object Table. + */ + #define TRC_CFG_NTASK 15 + #define TRC_CFG_NISR 5 + #define TRC_CFG_NQUEUE 10 + #define TRC_CFG_NSEMAPHORE 10 + #define TRC_CFG_NMUTEX 10 + #define TRC_CFG_NTIMER 5 + #define TRC_CFG_NEVENTGROUP 5 + #define TRC_CFG_NSTREAMBUFFER 5 + #define TRC_CFG_NMESSAGEBUFFER 5 + +/** + * @def TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ... + * @brief Macros that specify the maximum lengths (number of characters) for names of + * kernel objects, such as tasks and queues. If longer names are used, they will + * be truncated when stored in the recorder. + */ + #define TRC_CFG_NAME_LEN_TASK 15 + #define TRC_CFG_NAME_LEN_ISR 15 + #define TRC_CFG_NAME_LEN_QUEUE 15 + #define TRC_CFG_NAME_LEN_SEMAPHORE 15 + #define TRC_CFG_NAME_LEN_MUTEX 15 + #define TRC_CFG_NAME_LEN_TIMER 15 + #define TRC_CFG_NAME_LEN_EVENTGROUP 15 + #define TRC_CFG_NAME_LEN_STREAMBUFFER 15 + #define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortStreamingConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortStreamingConfig.h index 4cbc5bfb8..39e5108af 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortStreamingConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcKernelPortStreamingConfig.h @@ -1,24 +1,24 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Kernel port configuration parameters for streaming mode. - */ - -#ifndef TRC_KERNEL_PORT_STREAMING_CONFIG_H -#define TRC_KERNEL_PORT_STREAMING_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Nothing yet */ - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_KERNEL_PORT_STREAMING_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Kernel port configuration parameters for streaming mode. + */ + +#ifndef TRC_KERNEL_PORT_STREAMING_CONFIG_H + #define TRC_KERNEL_PORT_STREAMING_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/* Nothing yet */ + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_KERNEL_PORT_STREAMING_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h index 888532ded..199409922 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcSnapshotConfig.h @@ -1,245 +1,245 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Configuration parameters for trace recorder library in snapshot mode. - * Read more at http://percepio.com/2016/10/05/rtos-tracing/ - */ - -#ifndef TRC_SNAPSHOT_CONFIG_H -#define TRC_SNAPSHOT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @def TRC_CFG_SNAPSHOT_MODE - * @brief Macro which should be defined as one of: - * - TRC_SNAPSHOT_MODE_RING_BUFFER - * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL - * Default is TRC_SNAPSHOT_MODE_RING_BUFFER. - * - * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the - * events are stored in a ring buffer, i.e., where the oldest events are - * overwritten when the buffer becomes full. This allows you to get the last - * events leading up to an interesting state, e.g., an error, without having - * to store the whole run since startup. - * - * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the - * recording is stopped when the buffer becomes full. This is useful for - * recording events following a specific state, e.g., the startup sequence. - */ -#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER - -/** - * @def TRC_CFG_EVENT_BUFFER_SIZE - * @brief Macro which should be defined as an integer value. - * - * This defines the capacity of the event buffer, i.e., the number of records - * it may store. Most events use one record (4 byte), although some events - * require multiple 4-byte records. You should adjust this to the amount of RAM - * available in the target system. - * - * Default value is 1000, which means that 4000 bytes is allocated for the - * event buffer. - */ -#define TRC_CFG_EVENT_BUFFER_SIZE 1000 - -/** - * @def TRC_CFG_INCLUDE_FLOAT_SUPPORT - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If this is zero (0), the support for logging floating point values in - * vTracePrintF is stripped out, in case floating point values are not used or - * supported by the platform used. - * - * Floating point values are only used in vTracePrintF and its subroutines, to - * allow for storing float (%f) or double (%lf) arguments. - * - * vTracePrintF can be used with integer and string arguments in either case. - * - * Default value is 0. - */ -#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 - -/** - * @def TRC_CFG_SYMBOL_TABLE_SIZE - * @brief Macro which should be defined as an integer value. - * - * This defines the capacity of the symbol table, in bytes. This symbol table - * stores User Events labels and names of deleted tasks, queues, or other kernel - * objects. If you don't use User Events or delete any kernel - * objects you set this to a very low value. The minimum recommended value is 4. - * A size of zero (0) is not allowed since a zero-sized array may result in a - * 32-bit pointer, i.e., using 4 bytes rather than 0. - * - * Default value is 800. - */ -#define TRC_CFG_SYMBOL_TABLE_SIZE 800 - -#if (TRC_CFG_SYMBOL_TABLE_SIZE == 0) -#error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!" -#endif - -/****************************************************************************** - *** ADVANCED SETTINGS ******************************************************** - ****************************************************************************** - * The remaining settings are not necessary to modify but allows for optimizing - * the recorder setup for your specific needs, e.g., to exclude events that you - * are not interested in, in order to get longer traces. - *****************************************************************************/ - -/** - * @def TRC_CFG_HEAP_SIZE_BELOW_16M - * @brief An integer constant that can be used to reduce the buffer usage of memory - * allocation events (malloc/free). This value should be 1 if the heap size is - * below 16 MB (2^24 byte), and you can live with reported addresses showing the - * lower 24 bits only. If 0, you get the full 32-bit addresses. - * - * Default value is 0. - */ -#define TRC_CFG_HEAP_SIZE_BELOW_16M 0 - -/** - * @def TRC_CFG_USE_IMPLICIT_IFE_RULES - * @brief Macro which should be defined as either zero (0) or one (1). - * Default is 1. - * - * Tracealyzer groups the events into "instances" based on Instance Finish - * Events (IFEs), produced either by default rules or calls to the recorder - * functions xTraceTaskInstanceFinishedNow and xTraceTaskInstanceFinishedNext. - * - * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is - * used, resulting in a "typical" grouping of events into instances. - * If these rules don't give appropriate instances in your case, you can - * override the default rules using xTraceTaskInstanceFinishedNow/Next for one - * or several tasks. The default IFE rules are then disabled for those tasks. - * - * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are - * disabled globally. You must then call xTraceTaskInstanceFinishedNow or - * xTraceTaskInstanceFinishedNext to manually group the events into instances, - * otherwise the tasks will appear a single long instance. - * - * The default IFE rules count the following events as "instance finished": - * - Task delay, delay until - * - Task suspend - * - Blocking on "input" operations, i.e., when the task is waiting for the - * next a message/signal/event. But only if this event is blocking. - */ -#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1 - -/** - * @def TRC_CFG_USE_16BIT_OBJECT_HANDLES - * @brief Macro which should be defined as either zero (0) or one (1). - * - * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel - * objects such as tasks and queues. This limits the supported number of - * concurrently active objects to 255 of each type (tasks, queues, mutexes, - * etc.) Note: 255, not 256, since handle 0 is reserved. - * - * If set to 1 (one), the recorder uses 16-bit handles to identify kernel - * objects such as tasks and queues. This limits the supported number of - * concurrent objects to 65535 of each type (object class). However, since the - * object property table is limited to 64 KB, the practical limit is about - * 3000 objects in total. - * - * Default is 0 (8-bit handles) - * - * NOTE: An object with handle above 255 will use an extra 4-byte record in - * the event buffer whenever the object is referenced. Moreover, some internal - * tables in the recorder gets slightly larger when using 16-bit handles. - */ -#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0 - -/** - * @def TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER - * @brief Macro which should be defined as an integer value. - * - * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the - * separate user event buffer (UB). - * In this mode, user events are stored separately from other events, - * e.g., RTOS events. Thereby you can get a much longer history of - * user events as they don't need to share the buffer space with more - * frequent events. - * - * The UB is typically used with the snapshot ring-buffer mode, so the - * recording can continue when the main buffer gets full. And since the - * main buffer then overwrites the earliest events, Tracealyzer displays - * "Unknown Actor" instead of task scheduling for periods with UB data only. - * - * In UB mode, user events are structured as UB channels, which contains - * a channel name and a default format string. Register a UB channel using - * xTraceRegisterUBChannel. - * - * Events and data arguments are written using vTraceUBEvent and - * vTraceUBData. They are designed to provide efficient logging of - * repeating events, using the same format string within each channel. - * - * Examples: - * TraceStringHandle_t chn1; - * TraceStringHandle_t fmt1; - * xTraceStringRegister("Channel 1", &chn1); - * xTraceStringRegister("Event!", &fmt1); - * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); - * - * TraceStringHandle_t chn2; - * TraceStringHandle_t fmt2; - * xTraceStringRegister("Channel 2", &chn2); - * xTraceStringRegister("X: %d, Y: %d", &fmt2); - * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); - * - * // Result in "[Channel 1] Event!" - * vTraceUBEvent(UBCh1); - * - * // Result in "[Channel 2] X: 23, Y: 19" - * vTraceUBData(UBCh2, 23, 19); - * - * You can also use the other user event functions, like xTracePrintF. - * as they are then rerouted to the UB instead of the main event buffer. - * vTracePrintF then looks up the correct UB channel based on the - * provided channel name and format string, or creates a new UB channel - * if no match is found. The format string should therefore not contain - * "random" messages but mainly format specifiers. Random strings should - * be stored using %s and with the string as an argument. - * - * // Creates a new UB channel ("Channel 2", "%Z: %d") - * xTracePrintF(chn2, "%Z: %d", value1); - * - * // Finds the existing UB channel - * xTracePrintF(chn2, "%Z: %d", value2); - */ -#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0 - -/** - * @def TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE - * @brief Macro which should be defined as an integer value. - * - * This defines the capacity of the user event buffer (UB), in number of slots. - * A single user event can use multiple slots, depending on the arguments. - * - * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. - */ -#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200 - -/** - * @def TRC_CFG_UB_CHANNELS - * @brief Macro which should be defined as an integer value. - * - * This defines the number of User Event Buffer Channels (UB channels). - * These are used to structure the events when using the separate user - * event buffer, and contains both a User Event Channel (the name) and - * a default format string for the channel. - * - * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. - */ -#define TRC_CFG_UB_CHANNELS 32 - -#ifdef __cplusplus -} -#endif - -#endif /*TRC_SNAPSHOT_CONFIG_H*/ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Configuration parameters for trace recorder library in snapshot mode. + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + */ + +#ifndef TRC_SNAPSHOT_CONFIG_H + #define TRC_SNAPSHOT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @def TRC_CFG_SNAPSHOT_MODE + * @brief Macro which should be defined as one of: + * - TRC_SNAPSHOT_MODE_RING_BUFFER + * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL + * Default is TRC_SNAPSHOT_MODE_RING_BUFFER. + * + * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the + * events are stored in a ring buffer, i.e., where the oldest events are + * overwritten when the buffer becomes full. This allows you to get the last + * events leading up to an interesting state, e.g., an error, without having + * to store the whole run since startup. + * + * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the + * recording is stopped when the buffer becomes full. This is useful for + * recording events following a specific state, e.g., the startup sequence. + */ + #define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER + +/** + * @def TRC_CFG_EVENT_BUFFER_SIZE + * @brief Macro which should be defined as an integer value. + * + * This defines the capacity of the event buffer, i.e., the number of records + * it may store. Most events use one record (4 byte), although some events + * require multiple 4-byte records. You should adjust this to the amount of RAM + * available in the target system. + * + * Default value is 1000, which means that 4000 bytes is allocated for the + * event buffer. + */ + #define TRC_CFG_EVENT_BUFFER_SIZE 1000 + +/** + * @def TRC_CFG_INCLUDE_FLOAT_SUPPORT + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the support for logging floating point values in + * vTracePrintF is stripped out, in case floating point values are not used or + * supported by the platform used. + * + * Floating point values are only used in vTracePrintF and its subroutines, to + * allow for storing float (%f) or double (%lf) arguments. + * + * vTracePrintF can be used with integer and string arguments in either case. + * + * Default value is 0. + */ + #define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 + +/** + * @def TRC_CFG_SYMBOL_TABLE_SIZE + * @brief Macro which should be defined as an integer value. + * + * This defines the capacity of the symbol table, in bytes. This symbol table + * stores User Events labels and names of deleted tasks, queues, or other kernel + * objects. If you don't use User Events or delete any kernel + * objects you set this to a very low value. The minimum recommended value is 4. + * A size of zero (0) is not allowed since a zero-sized array may result in a + * 32-bit pointer, i.e., using 4 bytes rather than 0. + * + * Default value is 800. + */ + #define TRC_CFG_SYMBOL_TABLE_SIZE 800 + + #if ( TRC_CFG_SYMBOL_TABLE_SIZE == 0 ) + #error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!" + #endif + +/****************************************************************************** + *** ADVANCED SETTINGS ******************************************************** + ****************************************************************************** + * The remaining settings are not necessary to modify but allows for optimizing + * the recorder setup for your specific needs, e.g., to exclude events that you + * are not interested in, in order to get longer traces. + *****************************************************************************/ + +/** + * @def TRC_CFG_HEAP_SIZE_BELOW_16M + * @brief An integer constant that can be used to reduce the buffer usage of memory + * allocation events (malloc/free). This value should be 1 if the heap size is + * below 16 MB (2^24 byte), and you can live with reported addresses showing the + * lower 24 bits only. If 0, you get the full 32-bit addresses. + * + * Default value is 0. + */ + #define TRC_CFG_HEAP_SIZE_BELOW_16M 0 + +/** + * @def TRC_CFG_USE_IMPLICIT_IFE_RULES + * @brief Macro which should be defined as either zero (0) or one (1). + * Default is 1. + * + * Tracealyzer groups the events into "instances" based on Instance Finish + * Events (IFEs), produced either by default rules or calls to the recorder + * functions xTraceTaskInstanceFinishedNow and xTraceTaskInstanceFinishedNext. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is + * used, resulting in a "typical" grouping of events into instances. + * If these rules don't give appropriate instances in your case, you can + * override the default rules using xTraceTaskInstanceFinishedNow/Next for one + * or several tasks. The default IFE rules are then disabled for those tasks. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are + * disabled globally. You must then call xTraceTaskInstanceFinishedNow or + * xTraceTaskInstanceFinishedNext to manually group the events into instances, + * otherwise the tasks will appear a single long instance. + * + * The default IFE rules count the following events as "instance finished": + * - Task delay, delay until + * - Task suspend + * - Blocking on "input" operations, i.e., when the task is waiting for the + * next a message/signal/event. But only if this event is blocking. + */ + #define TRC_CFG_USE_IMPLICIT_IFE_RULES 1 + +/** + * @def TRC_CFG_USE_16BIT_OBJECT_HANDLES + * @brief Macro which should be defined as either zero (0) or one (1). + * + * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrently active objects to 255 of each type (tasks, queues, mutexes, + * etc.) Note: 255, not 256, since handle 0 is reserved. + * + * If set to 1 (one), the recorder uses 16-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrent objects to 65535 of each type (object class). However, since the + * object property table is limited to 64 KB, the practical limit is about + * 3000 objects in total. + * + * Default is 0 (8-bit handles) + * + * NOTE: An object with handle above 255 will use an extra 4-byte record in + * the event buffer whenever the object is referenced. Moreover, some internal + * tables in the recorder gets slightly larger when using 16-bit handles. + */ + #define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0 + +/** + * @def TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER + * @brief Macro which should be defined as an integer value. + * + * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the + * separate user event buffer (UB). + * In this mode, user events are stored separately from other events, + * e.g., RTOS events. Thereby you can get a much longer history of + * user events as they don't need to share the buffer space with more + * frequent events. + * + * The UB is typically used with the snapshot ring-buffer mode, so the + * recording can continue when the main buffer gets full. And since the + * main buffer then overwrites the earliest events, Tracealyzer displays + * "Unknown Actor" instead of task scheduling for periods with UB data only. + * + * In UB mode, user events are structured as UB channels, which contains + * a channel name and a default format string. Register a UB channel using + * xTraceRegisterUBChannel. + * + * Events and data arguments are written using vTraceUBEvent and + * vTraceUBData. They are designed to provide efficient logging of + * repeating events, using the same format string within each channel. + * + * Examples: + * TraceStringHandle_t chn1; + * TraceStringHandle_t fmt1; + * xTraceStringRegister("Channel 1", &chn1); + * xTraceStringRegister("Event!", &fmt1); + * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); + * + * TraceStringHandle_t chn2; + * TraceStringHandle_t fmt2; + * xTraceStringRegister("Channel 2", &chn2); + * xTraceStringRegister("X: %d, Y: %d", &fmt2); + * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); + * + * // Result in "[Channel 1] Event!" + * vTraceUBEvent(UBCh1); + * + * // Result in "[Channel 2] X: 23, Y: 19" + * vTraceUBData(UBCh2, 23, 19); + * + * You can also use the other user event functions, like xTracePrintF. + * as they are then rerouted to the UB instead of the main event buffer. + * vTracePrintF then looks up the correct UB channel based on the + * provided channel name and format string, or creates a new UB channel + * if no match is found. The format string should therefore not contain + * "random" messages but mainly format specifiers. Random strings should + * be stored using %s and with the string as an argument. + * + * // Creates a new UB channel ("Channel 2", "%Z: %d") + * xTracePrintF(chn2, "%Z: %d", value1); + * + * // Finds the existing UB channel + * xTracePrintF(chn2, "%Z: %d", value2); + */ + #define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0 + +/** + * @def TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE + * @brief Macro which should be defined as an integer value. + * + * This defines the capacity of the user event buffer (UB), in number of slots. + * A single user event can use multiple slots, depending on the arguments. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + */ + #define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200 + +/** + * @def TRC_CFG_UB_CHANNELS + * @brief Macro which should be defined as an integer value. + * + * This defines the number of User Event Buffer Channels (UB channels). + * These are used to structure the events when using the separate user + * event buffer, and contains both a User Event Channel (the name) and + * a default format string for the channel. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + */ + #define TRC_CFG_UB_CHANNELS 32 + + #ifdef __cplusplus +} + #endif + +#endif /*TRC_SNAPSHOT_CONFIG_H*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h index 3e0cc3c7e..2e5facc56 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/config/trcStreamingConfig.h @@ -1,51 +1,51 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Configuration parameters for the trace recorder library in streaming mode. - * Read more at http://percepio.com/2016/10/05/rtos-tracing/ - */ - -#ifndef TRC_STREAMING_CONFIG_H -#define TRC_STREAMING_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @def TRC_CFG_ENTRY_SLOTS - * @brief The maximum number of objects and symbols that can be stored. This includes: - * - Task names - * - Named ISRs (vTraceSetISRProperties) - * - Named kernel objects (vTraceStoreKernelObjectName) - * - User event channels (xTraceStringRegister) - * - * If this value is too small, not all symbol names will be stored and the - * trace display will be affected. In that case, there will be warnings - * (as User Events) from TzCtrl task, that monitors this. - */ -#define TRC_CFG_ENTRY_SLOTS 50 - -/** - * @def TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH - * @brief The maximum length of symbol names, including: - * - Task names - * - Named ISRs (vTraceSetISRProperties) - * - Named kernel objects (vTraceStoreKernelObjectName) - * - User event channel names (xTraceStringRegister) - * - * If longer symbol names are used, they will be truncated by the recorder, - * which will affect the trace display. In that case, there will be warnings - * (as User Events) from TzCtrl task, that monitors this. - */ -#define TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH 32 - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAMING_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Configuration parameters for the trace recorder library in streaming mode. + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + */ + +#ifndef TRC_STREAMING_CONFIG_H + #define TRC_STREAMING_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @def TRC_CFG_ENTRY_SLOTS + * @brief The maximum number of objects and symbols that can be stored. This includes: + * - Task names + * - Named ISRs (vTraceSetISRProperties) + * - Named kernel objects (vTraceStoreKernelObjectName) + * - User event channels (xTraceStringRegister) + * + * If this value is too small, not all symbol names will be stored and the + * trace display will be affected. In that case, there will be warnings + * (as User Events) from TzCtrl task, that monitors this. + */ + #define TRC_CFG_ENTRY_SLOTS 50 + +/** + * @def TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH + * @brief The maximum length of symbol names, including: + * - Task names + * - Named ISRs (vTraceSetISRProperties) + * - Named kernel objects (vTraceStoreKernelObjectName) + * - User event channel names (xTraceStringRegister) + * + * If longer symbol names are used, they will be truncated by the recorder, + * which will affect the trace display. In that case, there will be warnings + * (as User Events) from TzCtrl task, that monitors this. + */ + #define TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH 32 + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAMING_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/TraceRecorderInit.cpp b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/TraceRecorderInit.cpp index 148ffc4b9..69eed36ce 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/TraceRecorderInit.cpp +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/TraceRecorderInit.cpp @@ -1,55 +1,55 @@ -/* - * Percepio Trace Recorder Initialization v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * This file should only be included in a project if there is a need to - * initialize the Trace Recorder before main() has been called. - * An example of this scenario is if you have a global object instance that has - * a constructor that creates an object that should be traced. - * This file will make it easier to initiate the recorder correctly. - * - * Usage: - * Add a call to TraceRecorderInit::Initialize() wherever a traced object is - * created before the Trace Recorder is normally initialized. This will ensure - * the Trace Recorder is initialized only once. - * - * Set TRC_CFG_RECORDER_DATA_PTR_INIT to 0 in trcSnapshotConfig.h to ensure - * RecorderInitialized isn't initialized to 0 after the recorder has been - * already initialized. - * - * Finally, call vTraceEnable(TRC_START) after hardware is initialized to - * start gathering trace events. - */ - -#include -#include - -extern "C" uint32_t RecorderInitialized; - -/* Public */ -bool TraceRecorderInit::Initialize() -{ - /* Lazy initialization, and constructor is only run once ensuring that we only initialize the recorder once */ - static TraceRecorderInit instance; - - return instance.IsInitialized(); -} - -/* Private */ -TraceRecorderInit::TraceRecorderInit() -{ - RecorderInitialized = 0; - xTraceInitialize(); -} - -TraceRecorderInit::~TraceRecorderInit() -{ -} - -bool TraceRecorderInit::IsInitialized() -{ - return RecorderInitialized != 0; -} +/* + * Percepio Trace Recorder Initialization v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * This file should only be included in a project if there is a need to + * initialize the Trace Recorder before main() has been called. + * An example of this scenario is if you have a global object instance that has + * a constructor that creates an object that should be traced. + * This file will make it easier to initiate the recorder correctly. + * + * Usage: + * Add a call to TraceRecorderInit::Initialize() wherever a traced object is + * created before the Trace Recorder is normally initialized. This will ensure + * the Trace Recorder is initialized only once. + * + * Set TRC_CFG_RECORDER_DATA_PTR_INIT to 0 in trcSnapshotConfig.h to ensure + * RecorderInitialized isn't initialized to 0 after the recorder has been + * already initialized. + * + * Finally, call vTraceEnable(TRC_START) after hardware is initialized to + * start gathering trace events. + */ + +#include +#include + +extern "C" uint32_t RecorderInitialized; + +/* Public */ +bool TraceRecorderInit::Initialize() +{ + /* Lazy initialization, and constructor is only run once ensuring that we only initialize the recorder once */ + static TraceRecorderInit instance; + + return instance.IsInitialized(); +} + +/* Private */ +TraceRecorderInit::TraceRecorderInit() +{ + RecorderInitialized = 0; + xTraceInitialize(); +} + +TraceRecorderInit::~TraceRecorderInit() +{ +} + +bool TraceRecorderInit::IsInitialized() +{ + return RecorderInitialized != 0; +} diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/include/TraceRecorderInit.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/include/TraceRecorderInit.h index 18c6efd4f..3c9d63dd1 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/include/TraceRecorderInit.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/include/TraceRecorderInit.h @@ -1,38 +1,38 @@ -/* - * Percepio Trace Recorder Initialization v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * This file should only be included in a project if there is a need to - * initialize the Trace Recorder before main() has been called. - * An example of this scenario is if you have a global object instance that has - * a constructor that creates an object that should be traced. - * This file will make it easier to initiate the recorder correctly. - * - * Usage: - * Add a call to TraceRecorderInit::Initialize() wherever a traced object is - * created before the Trace Recorder is normally initialized. This will ensure - * the Trace Recorder is initialized only once. - * - * Set TRC_CFG_RECORDER_DATA_PTR_INIT to 0 in trcSnapshotConfig.h to ensure - * RecorderInitialized isn't initialized to 0 after the recorder has been - * already initialized. - * - * Finally, call vTraceEnable(TRC_START) after hardware is initialized to - * start gathering trace events. - */ - -#pragma once - -class TraceRecorderInit -{ -public: - static bool Initialize(); -private: - TraceRecorderInit(); - ~TraceRecorderInit(); - - bool IsInitialized(); -}; +/* + * Percepio Trace Recorder Initialization v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * This file should only be included in a project if there is a need to + * initialize the Trace Recorder before main() has been called. + * An example of this scenario is if you have a global object instance that has + * a constructor that creates an object that should be traced. + * This file will make it easier to initiate the recorder correctly. + * + * Usage: + * Add a call to TraceRecorderInit::Initialize() wherever a traced object is + * created before the Trace Recorder is normally initialized. This will ensure + * the Trace Recorder is initialized only once. + * + * Set TRC_CFG_RECORDER_DATA_PTR_INIT to 0 in trcSnapshotConfig.h to ensure + * RecorderInitialized isn't initialized to 0 after the recorder has been + * already initialized. + * + * Finally, call vTraceEnable(TRC_START) after hardware is initialized to + * start gathering trace events. + */ + +#pragma once + +class TraceRecorderInit +{ +public: + static bool Initialize(); +private: + TraceRecorderInit(); + ~TraceRecorderInit(); + + bool IsInitialized(); +}; diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/readme.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/readme.txt index 4a565b53f..b227c27b7 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/readme.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/extras/TraceRecorderInit/readme.txt @@ -1,30 +1,30 @@ -Percepio Trace Recorder Initialization v4.6.0 -Copyright 2021 Percepio AB -www.percepio.com - -This folder contains files that should only be included in a project -if there is a need to initialize the Trace Recorder before main() -has been called. - -An example of this scenario is if you have a global object instance that has -a constructor that creates an object that should be traced. -TraceRecorderInit will make it easier to initiate the recorder correctly. - -Usage: -Add a call to TraceRecorderInit::Initialize() wherever a traced object -is created before the Trace Recorder is normally initialized, or simply -as early as absloutely possible. This will ensure the Trace Recorder is -initialized only once. - -Set TRC_CFG_RECORDER_DATA_INIT to 0 in trcConfig.h to ensure -recorder data isn't initialized cleared after the recorder has been -already initialized. - -It is possible that you also need to make sure certain recorder data isn't -cleared when RAM sections are initialized. Create a RAM section that isn't -cleared, then set the appropriate attribute in TRC_CFG_RECORDER_DATA_ATTRIBUTE. -This attribute will then be set for all necessary recorder data that should -not be cleared. - -After the hardware and clocks are properly initialized, use -vTraceEnable(TRC_START) to start the tracing. +Percepio Trace Recorder Initialization v4.6.0 +Copyright 2021 Percepio AB +www.percepio.com + +This folder contains files that should only be included in a project +if there is a need to initialize the Trace Recorder before main() +has been called. + +An example of this scenario is if you have a global object instance that has +a constructor that creates an object that should be traced. +TraceRecorderInit will make it easier to initiate the recorder correctly. + +Usage: +Add a call to TraceRecorderInit::Initialize() wherever a traced object +is created before the Trace Recorder is normally initialized, or simply +as early as absloutely possible. This will ensure the Trace Recorder is +initialized only once. + +Set TRC_CFG_RECORDER_DATA_INIT to 0 in trcConfig.h to ensure +recorder data isn't initialized cleared after the recorder has been +already initialized. + +It is possible that you also need to make sure certain recorder data isn't +cleared when RAM sections are initialized. Create a RAM section that isn't +cleared, then set the appropriate attribute in TRC_CFG_RECORDER_DATA_ATTRIBUTE. +This attribute will then be set for all necessary recorder data that should +not be cleared. + +After the hardware and clocks are properly initialized, use +vTraceEnable(TRC_START) to start the tracing. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/Readme-Streamport.txt index c59413e4c..4e29e0109 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/Readme-Streamport.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/Readme-Streamport.txt @@ -1,21 +1,21 @@ -Tracealyzer Stream Port for Amazon FreeRTOS TCP/WIFI -Percepio AB -www.percepio.com ----------------------------------------------------- - -This directory contains a "stream port" for the Tracealyzer recorder library, -i.e., the specific code needed to use a particular interface for streaming a -Tracealyzer RTOS trace. The stream port is defined by a set of macros in -trcStreamPort.h, found in the "include" directory. - -This particular stream port is for streaming via a TCP socket in Amazon -FreeRTOS (AFR) directly to a host computer on the local network, typically -using Wifi. Read more in trcStreamPort.h. - -To use this stream port, make sure that include/trcStreamPort.h is found -by the compiler (i.e., add this folder to your project's include paths) and -add all included source files to your build. Make sure no other versions of -trcStreamPort.h are included by mistake! - -See also http://percepio.com/2016/10/05/rtos-tracing -and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ +Tracealyzer Stream Port for Amazon FreeRTOS TCP/WIFI +Percepio AB +www.percepio.com +---------------------------------------------------- + +This directory contains a "stream port" for the Tracealyzer recorder library, +i.e., the specific code needed to use a particular interface for streaming a +Tracealyzer RTOS trace. The stream port is defined by a set of macros in +trcStreamPort.h, found in the "include" directory. + +This particular stream port is for streaming via a TCP socket in Amazon +FreeRTOS (AFR) directly to a host computer on the local network, typically +using Wifi. Read more in trcStreamPort.h. + +To use this stream port, make sure that include/trcStreamPort.h is found +by the compiler (i.e., add this folder to your project's include paths) and +add all included source files to your build. Make sure no other versions of +trcStreamPort.h are included by mistake! + +See also http://percepio.com/2016/10/05/rtos-tracing +and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/include/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/include/trcStreamPort.h index ddf6f6d95..2e833f921 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/include/trcStreamPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/include/trcStreamPort.h @@ -1,127 +1,131 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * This stream port provides trace streaming using the Amazon FreeRTOS sockets - * layer and is intended for streaming over Wifi directly to a computer on the - * local Wifi network. - * - * Note that this does NOT use the TLS encryption available in Amazon - * FreeRTOS, due to performance and memory usage concerns. However, it does not - * use any AWS services either, and is intended for your local network only. - * - * This should be started using vTraceEnable(TRC_START) and this call should be - * made AFTER the kernel has started and the Wifi interface is ready. - * - * In the Tracealyzer setting -> "PSF Streaming Settings" make sure that the - * "Target Connection" setting is "TCP (Target Initiated)". - * - * To use this, make sure to start the trace recording in Tracealyzer before - * you start your target system. This ensures that Tracealyzer is ready when - * the target system connects. - * - * And don't forget to enter the IP address of the Tracealyzer host computer - * in trcStreamPort.h. - * - * NOTES: - * - * 1: The tracing will increase the stack usage of you application, so you - * may want to increase configMINIMAL_STACK_SIZE in your FreeRTOSConfig.h. - * - * 2: To reduce the amount of trace data, we recommend disabling the tracing - * of OS Ticks and memory allocation events. - * See TRC_CFG_INCLUDE_OSTICK_EVENTS in trcConfig.h. - * - * 3: The transmission of trace data is done in the TzCtrl task. To avoid that - * the trace streaming is blocked during the (long) MQTT connection phase, - * make sure the scheduling priority of TzCtrl is higher than the MQTT task. - * Otherwise, if you prefer to run the TzCtrl task at lower priority to avoid - * interfering with your application, wait with the vTraceEnable call until - * after the MQTT connection is established. - * See TRC_CFG_CTRL_TASK_PRIORITY in trcStreamingConfig.h. - * - * 4: The Wifi transmission of trace data often uses FreeRTOS functions, that - * are traced and thus produce additional trace data. This may cause a fast - * increase in trace data rate, that may saturate the trace buffer and cause - * data loss (i.e. incomplete traces). - * To eliminate this effect and reduce the amount of trace data produced, we - * recommend excluding all FreeRTOS objects that are used by Wifi stack. - * This is done using vTraceSetFilterGroup and vTraceSetFilterMask: - * - * // Just before wifi initialization: - * - * // All objects created after this point are assigned to group 15. - * vTraceSetFilterGroup(FilterGroup15); - * - * // Only trace objects assigned to group 0 (the default group). - * vTraceSetFilterMask(FilterGroup0); - * - * // The wifi stack initialization... (creates semaphores etc.) - * if ( eWifi_Connected == prvWifiConnect() ) - * { - * yMainState = eMain_StartApplication; - * - * // When connected, restore the FilterGroup setting to Group 0, so - * // that later created objects are included, like the TzCtrl task - * // created in vTraceEnable. Excluding tasks is not recommended! - * vTraceSetFilterGroup(FilterGroup0); - * - * // Then call vTraceEnable to start the tracing. - * vTraceEnable(TRC_START); - * } - * - * 5: If you still get "red sections" in Tracealyzer (lost data), you need - * to adjust the other settings in trcStreamingConfig.h. - * - * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT - * Increase this, as long as you have memory to spare. - * - * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE - * Increase this, as long as you have memory to spare. - * But don't exceed the maximum payload size of the Wifi chip, which - * is often limited to 1000-1500 bytes. Some chips crash if you try to - * send to large chunks... - * - * - TRC_CFG_CTRL_TASK_DELAY - * Decrease this to flush the trace buffer more frequently. - * - * See also http://percepio.com/2016/10/05/rtos-tracing - * and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ - */ - -#ifndef TRC_STREAM_PORT_H -#define TRC_STREAM_PORT_H - -#ifdef __cplusplus -extern "C" { -#endif - - -#define HOST_IPADDRESS_0 192 -#define HOST_IPADDRESS_1 168 -#define HOST_IPADDRESS_2 10 -#define HOST_IPADDRESS_3 116 -#define HOST_PORT 12000 - -void prvInitSocket(void); -int32_t prvReadFromSocket(void* ptrData, uint32_t size, int32_t* ptrBytesRead); -int32_t prvWriteToSocket(void* ptrData, uint32_t size, int32_t* ptrBytesWritten); - -#define TRC_STREAM_PORT_INIT() \ - TRC_STREAM_PORT_MALLOC(); \ - prvInitSocket(); - -#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1 - -#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) prvWriteToSocket(_ptrData, _size, _ptrBytesWritten) - -#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) prvReadFromSocket(_ptrData, _size, _ptrBytesRead) - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * This stream port provides trace streaming using the Amazon FreeRTOS sockets + * layer and is intended for streaming over Wifi directly to a computer on the + * local Wifi network. + * + * Note that this does NOT use the TLS encryption available in Amazon + * FreeRTOS, due to performance and memory usage concerns. However, it does not + * use any AWS services either, and is intended for your local network only. + * + * This should be started using vTraceEnable(TRC_START) and this call should be + * made AFTER the kernel has started and the Wifi interface is ready. + * + * In the Tracealyzer setting -> "PSF Streaming Settings" make sure that the + * "Target Connection" setting is "TCP (Target Initiated)". + * + * To use this, make sure to start the trace recording in Tracealyzer before + * you start your target system. This ensures that Tracealyzer is ready when + * the target system connects. + * + * And don't forget to enter the IP address of the Tracealyzer host computer + * in trcStreamPort.h. + * + * NOTES: + * + * 1: The tracing will increase the stack usage of you application, so you + * may want to increase configMINIMAL_STACK_SIZE in your FreeRTOSConfig.h. + * + * 2: To reduce the amount of trace data, we recommend disabling the tracing + * of OS Ticks and memory allocation events. + * See TRC_CFG_INCLUDE_OSTICK_EVENTS in trcConfig.h. + * + * 3: The transmission of trace data is done in the TzCtrl task. To avoid that + * the trace streaming is blocked during the (long) MQTT connection phase, + * make sure the scheduling priority of TzCtrl is higher than the MQTT task. + * Otherwise, if you prefer to run the TzCtrl task at lower priority to avoid + * interfering with your application, wait with the vTraceEnable call until + * after the MQTT connection is established. + * See TRC_CFG_CTRL_TASK_PRIORITY in trcStreamingConfig.h. + * + * 4: The Wifi transmission of trace data often uses FreeRTOS functions, that + * are traced and thus produce additional trace data. This may cause a fast + * increase in trace data rate, that may saturate the trace buffer and cause + * data loss (i.e. incomplete traces). + * To eliminate this effect and reduce the amount of trace data produced, we + * recommend excluding all FreeRTOS objects that are used by Wifi stack. + * This is done using vTraceSetFilterGroup and vTraceSetFilterMask: + * + * // Just before wifi initialization: + * + * // All objects created after this point are assigned to group 15. + * vTraceSetFilterGroup(FilterGroup15); + * + * // Only trace objects assigned to group 0 (the default group). + * vTraceSetFilterMask(FilterGroup0); + * + * // The wifi stack initialization... (creates semaphores etc.) + * if ( eWifi_Connected == prvWifiConnect() ) + * { + * yMainState = eMain_StartApplication; + * + * // When connected, restore the FilterGroup setting to Group 0, so + * // that later created objects are included, like the TzCtrl task + * // created in vTraceEnable. Excluding tasks is not recommended! + * vTraceSetFilterGroup(FilterGroup0); + * + * // Then call vTraceEnable to start the tracing. + * vTraceEnable(TRC_START); + * } + * + * 5: If you still get "red sections" in Tracealyzer (lost data), you need + * to adjust the other settings in trcStreamingConfig.h. + * + * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT + * Increase this, as long as you have memory to spare. + * + * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE + * Increase this, as long as you have memory to spare. + * But don't exceed the maximum payload size of the Wifi chip, which + * is often limited to 1000-1500 bytes. Some chips crash if you try to + * send to large chunks... + * + * - TRC_CFG_CTRL_TASK_DELAY + * Decrease this to flush the trace buffer more frequently. + * + * See also http://percepio.com/2016/10/05/rtos-tracing + * and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ + */ + +#ifndef TRC_STREAM_PORT_H + #define TRC_STREAM_PORT_H + + #ifdef __cplusplus + extern "C" { + #endif + + + #define HOST_IPADDRESS_0 192 + #define HOST_IPADDRESS_1 168 + #define HOST_IPADDRESS_2 10 + #define HOST_IPADDRESS_3 116 + #define HOST_PORT 12000 + + void prvInitSocket( void ); + int32_t prvReadFromSocket( void * ptrData, + uint32_t size, + int32_t * ptrBytesRead ); + int32_t prvWriteToSocket( void * ptrData, + uint32_t size, + int32_t * ptrBytesWritten ); + + #define TRC_STREAM_PORT_INIT() \ + TRC_STREAM_PORT_MALLOC(); \ + prvInitSocket(); + + #define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1 + + #define TRC_STREAM_PORT_WRITE_DATA( _ptrData, _size, _ptrBytesWritten ) prvWriteToSocket( _ptrData, _size, _ptrBytesWritten ) + + #define TRC_STREAM_PORT_READ_DATA( _ptrData, _size, _ptrBytesRead ) prvReadFromSocket( _ptrData, _size, _ptrBytesRead ) + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/trcStreamPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/trcStreamPort.c index 1f05fe366..51155b441 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/trcStreamPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/AFR_WIFI_LOCAL/trcStreamPort.c @@ -1,157 +1,163 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * This stream port provides trace streaming using the Amazon FreeRTOS sockets - * layer and is intended for streaming over Wifi directly to a computer on the - * local Wifi network. - * - * Note that this does NOT use the TLS encryption available in Amazon - * FreeRTOS, due to performance and memory usage concerns. However, it does not - * use any AWS services either, and is intended for your local network only. - * - * This should be started using vTraceEnable(TRC_START) and this call should be - * made AFTER the kernel has started and the Wifi interface is ready. - * - * In the Tracealyzer setting -> "PSF Streaming Settings" make sure that the - * "Target Connection" setting is "TCP (Target Initiated)". - * - * To use this, make sure to start the trace recording in Tracealyzer before - * you start your target system. This ensures that Tracealyzer is ready when - * the target system connects. - * - * And don't forget to enter the IP address of the Tracealyzer host computer - * in trcStreamPort.h. - * - * NOTES: - * - * 1: The tracing will increase the stack usage of you application, so you - * may want to increase configMINIMAL_STACK_SIZE in your FreeRTOSConfig.h. - * - * 2: To reduce the amount of trace data, we recommend disabling the tracing - * of OS Ticks and memory allocation events. - * See TRC_CFG_INCLUDE_OSTICK_EVENTS in trcConfig.h. - * - * 3: The transmission of trace data is done in the TzCtrl task. To avoid that - * the trace streaming is blocked during the (long) MQTT connection phase, - * make sure the scheduling priority of TzCtrl is higher than the MQTT task. - * Otherwise, if you prefer to run the TzCtrl task at lower priority to avoid - * interfering with your application, wait with the vTraceEnable call until - * after the MQTT connection is established. - * See TRC_CFG_CTRL_TASK_PRIORITY in trcStreamingConfig.h. - * - * 4: The Wifi transmission of trace data often uses FreeRTOS functions, that - * are traced and thus produce additional trace data. This may cause a fast - * increase in trace data rate, that may saturate the trace buffer and cause - * data loss (i.e. incomplete traces). - * To eliminate this effect and reduce the amount of trace data produced, we - * recommend excluding all FreeRTOS objects that are used by Wifi stack. - * This is done using vTraceSetFilterGroup and vTraceSetFilterMask: - * - * // Just before wifi initialization: - * - * // All objects created after this point are assigned to group 15. - * vTraceSetFilterGroup(FilterGroup15); - * - * // Only trace objects assigned to group 0 (the default group). - * vTraceSetFilterMask(FilterGroup0); - * - * // The wifi stack initialization... (creates semaphores etc.) - * if ( eWifi_Connected == prvWifiConnect() ) - * { - * yMainState = eMain_StartApplication; - * - * // When connected, restore the FilterGroup setting to Group 0, so - * // that later created objects are included, like the TzCtrl task - * // created in vTraceEnable. Excluding tasks is not recommended! - * vTraceSetFilterGroup(FilterGroup0); - * - * // Then call vTraceEnable to start the tracing. - * vTraceEnable(TRC_START); - * } - * - * 5: If you still get "red sections" in Tracealyzer (lost data), you need - * to adjust the other settings in trcStreamingConfig.h. - * - * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT - * Increase this, as long as you have memory to spare. - * - * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE - * Increase this, as long as you have memory to spare. - * But don't exceed the maximum payload size of the Wifi chip, which - * is often limited to 1000-1500 bytes. Some chips crash if you try to - * send to large chunks... - * - * - TRC_CFG_CTRL_TASK_DELAY - * Decrease this to flush the trace buffer more frequently. - * - * See also http://percepio.com/2016/10/05/rtos-tracing - * and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ - */ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -SocketsSockaddr_t addr = {sizeof(SocketsSockaddr_t), SOCKETS_AF_INET, 0, 0}; - -#define IPv4(a,b,c,d) (uint32_t)((d << 24) + (c << 16) + (b << 8) + a) - -Socket_t sock = 0; - -void prvInitSocket(void) -{ - int32_t status; - - SOCKETS_Init(); - - sock = SOCKETS_Socket(SOCKETS_AF_INET, SOCKETS_SOCK_STREAM, SOCKETS_IPPROTO_TCP); - - configPRINTF( ( "Connecting to %d.%d.%d.%d, port %d\r\n", HOST_IPADDRESS_0, HOST_IPADDRESS_1, HOST_IPADDRESS_2, HOST_IPADDRESS_3, HOST_PORT) ); - - addr.ulAddress = IPv4(HOST_IPADDRESS_0, HOST_IPADDRESS_1, HOST_IPADDRESS_2, HOST_IPADDRESS_3); - addr.usPort = SOCKETS_htons(HOST_PORT); - - status = SOCKETS_Connect(sock, &addr, sizeof( SocketsSockaddr_t ) ); - - if (status != SOCKETS_ERROR_NONE) - { - //prvTraceError(PSF_ERROR_STREAM_PORT_FAIL); - configPRINTF( ( "Failed to connect, status: %d\r\n", status) ); - } - else - { - configPRINTF( ( "Connected.\r\n") ); - } -} - - -int32_t prvWriteToSocket(void* ptrData, uint32_t size, int32_t* ptrBytesWritten) -{ - uint32_t bytesWritten = SOCKETS_Send(sock, ptrData, size, 0); - - if (ptrBytesWritten != 0) - *ptrBytesWritten = (int32_t)bytesWritten; - - if (bytesWritten != size) - { - return -1; - } - - return 0; -} - -int32_t prvReadFromSocket(void* ptrData, uint32_t size, int32_t* ptrBytesRead) -{ - // Not yet implemented, since not necessary. - return 0; -} - -#endif -#endif +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * This stream port provides trace streaming using the Amazon FreeRTOS sockets + * layer and is intended for streaming over Wifi directly to a computer on the + * local Wifi network. + * + * Note that this does NOT use the TLS encryption available in Amazon + * FreeRTOS, due to performance and memory usage concerns. However, it does not + * use any AWS services either, and is intended for your local network only. + * + * This should be started using vTraceEnable(TRC_START) and this call should be + * made AFTER the kernel has started and the Wifi interface is ready. + * + * In the Tracealyzer setting -> "PSF Streaming Settings" make sure that the + * "Target Connection" setting is "TCP (Target Initiated)". + * + * To use this, make sure to start the trace recording in Tracealyzer before + * you start your target system. This ensures that Tracealyzer is ready when + * the target system connects. + * + * And don't forget to enter the IP address of the Tracealyzer host computer + * in trcStreamPort.h. + * + * NOTES: + * + * 1: The tracing will increase the stack usage of you application, so you + * may want to increase configMINIMAL_STACK_SIZE in your FreeRTOSConfig.h. + * + * 2: To reduce the amount of trace data, we recommend disabling the tracing + * of OS Ticks and memory allocation events. + * See TRC_CFG_INCLUDE_OSTICK_EVENTS in trcConfig.h. + * + * 3: The transmission of trace data is done in the TzCtrl task. To avoid that + * the trace streaming is blocked during the (long) MQTT connection phase, + * make sure the scheduling priority of TzCtrl is higher than the MQTT task. + * Otherwise, if you prefer to run the TzCtrl task at lower priority to avoid + * interfering with your application, wait with the vTraceEnable call until + * after the MQTT connection is established. + * See TRC_CFG_CTRL_TASK_PRIORITY in trcStreamingConfig.h. + * + * 4: The Wifi transmission of trace data often uses FreeRTOS functions, that + * are traced and thus produce additional trace data. This may cause a fast + * increase in trace data rate, that may saturate the trace buffer and cause + * data loss (i.e. incomplete traces). + * To eliminate this effect and reduce the amount of trace data produced, we + * recommend excluding all FreeRTOS objects that are used by Wifi stack. + * This is done using vTraceSetFilterGroup and vTraceSetFilterMask: + * + * // Just before wifi initialization: + * + * // All objects created after this point are assigned to group 15. + * vTraceSetFilterGroup(FilterGroup15); + * + * // Only trace objects assigned to group 0 (the default group). + * vTraceSetFilterMask(FilterGroup0); + * + * // The wifi stack initialization... (creates semaphores etc.) + * if ( eWifi_Connected == prvWifiConnect() ) + * { + * yMainState = eMain_StartApplication; + * + * // When connected, restore the FilterGroup setting to Group 0, so + * // that later created objects are included, like the TzCtrl task + * // created in vTraceEnable. Excluding tasks is not recommended! + * vTraceSetFilterGroup(FilterGroup0); + * + * // Then call vTraceEnable to start the tracing. + * vTraceEnable(TRC_START); + * } + * + * 5: If you still get "red sections" in Tracealyzer (lost data), you need + * to adjust the other settings in trcStreamingConfig.h. + * + * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT + * Increase this, as long as you have memory to spare. + * + * - TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE + * Increase this, as long as you have memory to spare. + * But don't exceed the maximum payload size of the Wifi chip, which + * is often limited to 1000-1500 bytes. Some chips crash if you try to + * send to large chunks... + * + * - TRC_CFG_CTRL_TASK_DELAY + * Decrease this to flush the trace buffer more frequently. + * + * See also http://percepio.com/2016/10/05/rtos-tracing + * and https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + SocketsSockaddr_t addr = { sizeof( SocketsSockaddr_t ), SOCKETS_AF_INET, 0, 0 }; + + #define IPv4( a, b, c, d ) ( uint32_t ) ( ( d << 24 ) + ( c << 16 ) + ( b << 8 ) + a ) + + Socket_t sock = 0; + + void prvInitSocket( void ) + { + int32_t status; + + SOCKETS_Init(); + + sock = SOCKETS_Socket( SOCKETS_AF_INET, SOCKETS_SOCK_STREAM, SOCKETS_IPPROTO_TCP ); + + configPRINTF( ( "Connecting to %d.%d.%d.%d, port %d\r\n", HOST_IPADDRESS_0, HOST_IPADDRESS_1, HOST_IPADDRESS_2, HOST_IPADDRESS_3, HOST_PORT ) ); + + addr.ulAddress = IPv4( HOST_IPADDRESS_0, HOST_IPADDRESS_1, HOST_IPADDRESS_2, HOST_IPADDRESS_3 ); + addr.usPort = SOCKETS_htons( HOST_PORT ); + + status = SOCKETS_Connect( sock, &addr, sizeof( SocketsSockaddr_t ) ); + + if( status != SOCKETS_ERROR_NONE ) + { + /*prvTraceError(PSF_ERROR_STREAM_PORT_FAIL); */ + configPRINTF( ( "Failed to connect, status: %d\r\n", status ) ); + } + else + { + configPRINTF( ( "Connected.\r\n" ) ); + } + } + + + int32_t prvWriteToSocket( void * ptrData, + uint32_t size, + int32_t * ptrBytesWritten ) + { + uint32_t bytesWritten = SOCKETS_Send( sock, ptrData, size, 0 ); + + if( ptrBytesWritten != 0 ) + { + *ptrBytesWritten = ( int32_t ) bytesWritten; + } + + if( bytesWritten != size ) + { + return -1; + } + + return 0; + } + + int32_t prvReadFromSocket( void * ptrData, + uint32_t size, + int32_t * ptrBytesRead ) + { + /* Not yet implemented, since not necessary. */ + return 0; + } + + #endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) */ +#endif /* if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Keil-uVision-Tracealyzer-ITM-Exporter.ini b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Keil-uVision-Tracealyzer-ITM-Exporter.ini index 45d015e12..92cc3e065 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Keil-uVision-Tracealyzer-ITM-Exporter.ini +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Keil-uVision-Tracealyzer-ITM-Exporter.ini @@ -1,55 +1,55 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -FUNC void tzSetEnable(int enable) -{ - if (enable == 1) - { - printf("Starting Tracealyzer recorder\n"); - - // Forward the ITM data to file - exec("ITMLOG 1 > .\\tracealyzer.psf"); - - // Send start command to Tracealyzer (not required if using vTraceEnable(TRC_START)) - exec("E CHAR tz_host_command_data = 1, 1, 0, 0, 0, 0, 0xFD, 0xFF"); - exec("tz_host_command_bytes_to_read = 8"); - } - else if (enable == 0) - { - printf("Stopping Tracealyzer recorder...\n"); - - // Send stop command to Tracealyzer, to stop writing ITM data. - exec("E CHAR tz_host_command_data = 1, 0, 0, 0, 0, 0, 0xFE, 0xFF"); - exec("tz_host_command_bytes_to_read = 8"); - - _sleep_(2000); // Wait a while to let all data be written the host file. - - // Stop forwarding the ITM data to file and close the file. - exec("ITMLOG 1 OFF"); - - printf("Tracealyzer recorder stopped.\n"); - - } - else printf("Usage: tzSetEnable(0 or 1), where 0 is disable (stops recorder) and 1 enable (starts recording)"); - -} - - -// The Tracealyzer ITM stream port for Keil µVision can be used in two ways. -// -// 1. Start tracing directly from startup. -// Make sure tzSetEnable(1) is called below and vTraceEnable(TRC_START) in your target startup. -// -// 2. Start the trace manually, using the "Start Recording" button in Keil µVision. -// In this case, comment out the below call to tzSetEnable and make sure you call vTraceEnable(TRC_INIT) in your target startup (not TRC_START). - -tzSetEnable(1); - -DEFINE BUTTON "Start Recording", "tzSetEnable(1)"; -DEFINE BUTTON "Stop Recording", "tzSetEnable(0)"; +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +FUNC void tzSetEnable(int enable) +{ + if (enable == 1) + { + printf("Starting Tracealyzer recorder\n"); + + // Forward the ITM data to file + exec("ITMLOG 1 > .\\tracealyzer.psf"); + + // Send start command to Tracealyzer (not required if using vTraceEnable(TRC_START)) + exec("E CHAR tz_host_command_data = 1, 1, 0, 0, 0, 0, 0xFD, 0xFF"); + exec("tz_host_command_bytes_to_read = 8"); + } + else if (enable == 0) + { + printf("Stopping Tracealyzer recorder...\n"); + + // Send stop command to Tracealyzer, to stop writing ITM data. + exec("E CHAR tz_host_command_data = 1, 0, 0, 0, 0, 0, 0xFE, 0xFF"); + exec("tz_host_command_bytes_to_read = 8"); + + _sleep_(2000); // Wait a while to let all data be written the host file. + + // Stop forwarding the ITM data to file and close the file. + exec("ITMLOG 1 OFF"); + + printf("Tracealyzer recorder stopped.\n"); + + } + else printf("Usage: tzSetEnable(0 or 1), where 0 is disable (stops recorder) and 1 enable (starts recording)"); + +} + + +// The Tracealyzer ITM stream port for Keil µVision can be used in two ways. +// +// 1. Start tracing directly from startup. +// Make sure tzSetEnable(1) is called below and vTraceEnable(TRC_START) in your target startup. +// +// 2. Start the trace manually, using the "Start Recording" button in Keil µVision. +// In this case, comment out the below call to tzSetEnable and make sure you call vTraceEnable(TRC_INIT) in your target startup (not TRC_START). + +tzSetEnable(1); + +DEFINE BUTTON "Start Recording", "tzSetEnable(1)"; +DEFINE BUTTON "Stop Recording", "tzSetEnable(0)"; diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt index e98d14637..fff7ec41c 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/Readme-ARM_ITM.txt @@ -1,34 +1,34 @@ -Tracealyzer Stream Port for ARM Cortex-M ITM -Percepio AB -www.percepio.com --------------------------------------------- - -This directory contains a "stream port" for the Tracealyzer recorder library, -i.e., the specific code needed to use a particular interface for streaming a -Tracealyzer RTOS trace. The stream port is defined by a set of macros in -trcStreamPort.h, found in the "include" directory. - -This particular stream port targets ARM's ITM interface, which together with -a fast debug probe such as a Keil ULINKpro or ULINKplus provides excellent -performance. This stream port does not use any RAM buffer for the trace, but -writes the data directly to the ITM registers. This is very fast. - -To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus), -see Percepio Application Note PA-021, https://percepio.com/2018/05/04/keil-itm-support/ - -To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet, -see Percepio Application Note PA-023, https://percepio.com/iar - -To setup Lauterbach TRACE32 for ITM tracing with a uTrace, -see Percepio Application Note PA-033, https://percepio.com/apn/PA033-TRACE32%20ITM%20Streaming.pdf - -Learn more: - - Tracealyzer User Manual (Help -> User Manual) - - https://percepio.com/gettingstarted - - Percepio Application Note PA-021 (Keil), https://percepio.com/2018/05/04/keil-itm-support/ - - Percepio Application Note PA-023 (IAR), https://percepio.com/iar - - Percepio Application Note PA-033 (Lauterbach), https://percepio.com/apn/PA033-TRACE32%20ITM%20Streaming.pdf - - About ITM trace, https://percepio.com/2016/06/09/arm-itm/ - - About the recorder and custom streaming, http://percepio.com/2016/10/05/rtos-tracing - -For questions, please contact support@percepio.com +Tracealyzer Stream Port for ARM Cortex-M ITM +Percepio AB +www.percepio.com +-------------------------------------------- + +This directory contains a "stream port" for the Tracealyzer recorder library, +i.e., the specific code needed to use a particular interface for streaming a +Tracealyzer RTOS trace. The stream port is defined by a set of macros in +trcStreamPort.h, found in the "include" directory. + +This particular stream port targets ARM's ITM interface, which together with +a fast debug probe such as a Keil ULINKpro or ULINKplus provides excellent +performance. This stream port does not use any RAM buffer for the trace, but +writes the data directly to the ITM registers. This is very fast. + +To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus), +see Percepio Application Note PA-021, https://percepio.com/2018/05/04/keil-itm-support/ + +To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet, +see Percepio Application Note PA-023, https://percepio.com/iar + +To setup Lauterbach TRACE32 for ITM tracing with a uTrace, +see Percepio Application Note PA-033, https://percepio.com/apn/PA033-TRACE32%20ITM%20Streaming.pdf + +Learn more: + - Tracealyzer User Manual (Help -> User Manual) + - https://percepio.com/gettingstarted + - Percepio Application Note PA-021 (Keil), https://percepio.com/2018/05/04/keil-itm-support/ + - Percepio Application Note PA-023 (IAR), https://percepio.com/iar + - Percepio Application Note PA-033 (Lauterbach), https://percepio.com/apn/PA033-TRACE32%20ITM%20Streaming.pdf + - About ITM trace, https://percepio.com/2016/06/09/arm-itm/ + - About the recorder and custom streaming, http://percepio.com/2016/10/05/rtos-tracing + +For questions, please contact support@percepio.com diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/config/trcStreamPortConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/config/trcStreamPortConfig.h index 3218b896f..01352d22c 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/config/trcStreamPortConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/config/trcStreamPortConfig.h @@ -1,35 +1,35 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The configuration for trace streaming ("stream ports"). - */ - -#ifndef TRC_STREAM_PORT_CONFIG_H -#define TRC_STREAM_PORT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/******************************************************************************* - * TRC_CFG_STREAM_PORT_ITM_PORT - * - * Valid values: 0 - 31 - * - * What ITM port to use for the ITM software events. Make sure the IDE is - * configured for the same channel. - * - * Default: 1 (0 is typically terminal output and 31 is used by Keil) - * - ******************************************************************************/ -#define TRC_CFG_STREAM_PORT_ITM_PORT 1 - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The configuration for trace streaming ("stream ports"). + */ + +#ifndef TRC_STREAM_PORT_CONFIG_H + #define TRC_STREAM_PORT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/******************************************************************************* + * TRC_CFG_STREAM_PORT_ITM_PORT + * + * Valid values: 0 - 31 + * + * What ITM port to use for the ITM software events. Make sure the IDE is + * configured for the same channel. + * + * Default: 1 (0 is typically terminal output and 31 is used by Keil) + * + ******************************************************************************/ + #define TRC_CFG_STREAM_PORT_ITM_PORT 1 + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamPort.h index 0ca76adf1..98b6bef85 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/include/trcStreamPort.h @@ -1,113 +1,117 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The interface definitions for trace streaming ("stream ports"). - * This "stream port" sets up the recorder to use ARM ITM as streaming channel. - * - * To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus), - * see Percepio Application Note PA-021, available at - * https://percepio.com/2018/05/04/keil-itm-support/ - * - * To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet, - * see Percepio Application Note PA-023, https://percepio.com/iar - * - * NOTE: This stream port may block the application in case the ITM port - * is not ready for more data (the TPIU FIFO has become full). This is - * necessary to avoid data loss, as the TPIU FIFO is often quite small. - * - * --- Direct vs. Indirect ITM streaming --- - * Direct streaming: By default, this stream port writes directly to the ITM - * register mode without any RAM buffer. This assumes you have a fast debug - * probe, like aKeil ULINKpro or IAR I-Jet, to avoid excessive blocking. - * In case the ITM blocking appears to disturb your application, make sure your - * debugger is configured for maximum performance, as described in the above - * Application Nodes. - * - * Indirect streaming: If direct streaming gives too much overhead, you may - * instead try indirect ITM streaming. This is done by enabling the internal - * RAM buffer, like below. This reconfigures the recorder to store the events - * in the internal RAM buffer instead of writing them directly to the ITM port. - * - * Set TRC_STREAM_PORT_USE_INTERNAL_BUFFER to 1 to use the indirect mode. - * - * This increases RAM usage but eliminates peaks in the trace data rate. - * Moreover, the ITM writes are then performed in a separate task (TzCtrl). - * You find relevant settings (buffer size etc.) in trcStreamingConfig.h. - * - * See also https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming - * - * --- One-way vs. Two-way Communication --- - * The ITM port only provides one-way communication, from target to host. - * This is sufficient if you start the tracing from the target application, - * using vTraceEnable(TRC_START). Just make sure to start the Tracealyzer - * recording before you start the target system. - * - * In case you prefer to interactively start and stop the tracing from the host - * computer, you need two-way communication to send commands to the recorder. - * This is possible by writing such "start" and "stop" commands to a special - * buffer, monitored by the recorder library, using the debugger IDE. - * See trcStreamingPort.c and also the example macro for Keil uVision - * (Keil-uVision-Tracealyzer-ITM-Exporter.ini). - */ - -#ifndef TRC_STREAM_PORT_H -#define TRC_STREAM_PORT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if (!defined(TRC_CFG_STREAM_PORT_ITM_PORT) || (TRC_CFG_STREAM_PORT_ITM_PORT) < 0) || ((TRC_CFG_STREAM_PORT_ITM_PORT) > 31) -#error "Invalid ITM port defined in trcStreamPortConfig.h." -#endif - -/* Important for the ITM port - no RAM buffer, direct writes. In most other ports this can be skipped (default is 1) */ -#define TRC_USE_INTERNAL_BUFFER 0 - -typedef struct TraceStreamPortBuffer -{ - uint8_t buffer[sizeof(TraceUnsignedBaseType_t)]; -} TraceStreamPortBuffer_t; - -traceResult prvTraceItmWrite(void* ptrData, uint32_t size, int32_t* ptrBytesWritten); -traceResult prvTraceItmRead(void* ptrData, uint32_t uiSize, int32_t* piBytesRead); - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer); - -#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)uiSize, xTraceStaticBufferGet(ppvData)) - -#define xTraceStreamPortCommit(pvData, uiSize, piBytesCommitted) prvTraceItmWrite(pvData, uiSize, piBytesCommitted) - -#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)pvData, (void)uiSize, (void)piBytesWritten, TRC_SUCCESS) - -#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) prvTraceItmRead(pvData, uiSize, piBytesRead) - -#define xTraceStreamPortOnEnable(uiStartOption) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(uiStartOption), TRC_SUCCESS) - -#define xTraceStreamPortOnDisable() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS) - -#define xTraceStreamPortOnTraceBegin() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS) - -#define xTraceStreamPortOnTraceEnd() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS) - -#ifdef __cplusplus -} -#endif - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ - -#endif /* TRC_STREAM_PORT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface definitions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to use ARM ITM as streaming channel. + * + * To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus), + * see Percepio Application Note PA-021, available at + * https://percepio.com/2018/05/04/keil-itm-support/ + * + * To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet, + * see Percepio Application Note PA-023, https://percepio.com/iar + * + * NOTE: This stream port may block the application in case the ITM port + * is not ready for more data (the TPIU FIFO has become full). This is + * necessary to avoid data loss, as the TPIU FIFO is often quite small. + * + * --- Direct vs. Indirect ITM streaming --- + * Direct streaming: By default, this stream port writes directly to the ITM + * register mode without any RAM buffer. This assumes you have a fast debug + * probe, like aKeil ULINKpro or IAR I-Jet, to avoid excessive blocking. + * In case the ITM blocking appears to disturb your application, make sure your + * debugger is configured for maximum performance, as described in the above + * Application Nodes. + * + * Indirect streaming: If direct streaming gives too much overhead, you may + * instead try indirect ITM streaming. This is done by enabling the internal + * RAM buffer, like below. This reconfigures the recorder to store the events + * in the internal RAM buffer instead of writing them directly to the ITM port. + * + * Set TRC_STREAM_PORT_USE_INTERNAL_BUFFER to 1 to use the indirect mode. + * + * This increases RAM usage but eliminates peaks in the trace data rate. + * Moreover, the ITM writes are then performed in a separate task (TzCtrl). + * You find relevant settings (buffer size etc.) in trcStreamingConfig.h. + * + * See also https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming + * + * --- One-way vs. Two-way Communication --- + * The ITM port only provides one-way communication, from target to host. + * This is sufficient if you start the tracing from the target application, + * using vTraceEnable(TRC_START). Just make sure to start the Tracealyzer + * recording before you start the target system. + * + * In case you prefer to interactively start and stop the tracing from the host + * computer, you need two-way communication to send commands to the recorder. + * This is possible by writing such "start" and "stop" commands to a special + * buffer, monitored by the recorder library, using the debugger IDE. + * See trcStreamingPort.c and also the example macro for Keil uVision + * (Keil-uVision-Tracealyzer-ITM-Exporter.ini). + */ + +#ifndef TRC_STREAM_PORT_H + #define TRC_STREAM_PORT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + + #if ( !defined( TRC_CFG_STREAM_PORT_ITM_PORT ) || ( TRC_CFG_STREAM_PORT_ITM_PORT ) < 0 ) || ( ( TRC_CFG_STREAM_PORT_ITM_PORT ) > 31 ) + #error "Invalid ITM port defined in trcStreamPortConfig.h." + #endif + +/* Important for the ITM port - no RAM buffer, direct writes. In most other ports this can be skipped (default is 1) */ + #define TRC_USE_INTERNAL_BUFFER 0 + + typedef struct TraceStreamPortBuffer + { + uint8_t buffer[ sizeof( TraceUnsignedBaseType_t ) ]; + } TraceStreamPortBuffer_t; + + traceResult prvTraceItmWrite( void * ptrData, + uint32_t size, + int32_t * ptrBytesWritten ); + traceResult prvTraceItmRead( void * ptrData, + uint32_t uiSize, + int32_t * piBytesRead ); + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ); + + #define xTraceStreamPortAllocate( uiSize, ppvData ) ( ( void ) uiSize, xTraceStaticBufferGet( ppvData ) ) + + #define xTraceStreamPortCommit( pvData, uiSize, piBytesCommitted ) prvTraceItmWrite( pvData, uiSize, piBytesCommitted ) + + #define xTraceStreamPortWriteData( pvData, uiSize, piBytesWritten ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( ( void ) pvData, ( void ) uiSize, ( void ) piBytesWritten, TRC_SUCCESS ) + + #define xTraceStreamPortReadData( pvData, uiSize, piBytesRead ) prvTraceItmRead( pvData, uiSize, piBytesRead ) + + #define xTraceStreamPortOnEnable( uiStartOption ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( ( void ) ( uiStartOption ), TRC_SUCCESS ) + + #define xTraceStreamPortOnDisable() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1( TRC_SUCCESS ) + + #define xTraceStreamPortOnTraceBegin() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1( TRC_SUCCESS ) + + #define xTraceStreamPortOnTraceEnd() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1( TRC_SUCCESS ) + + #ifdef __cplusplus +} + #endif + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + + #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#endif /* TRC_STREAM_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamPort.c index 43c8787d9..0f57aadce 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/ARM_ITM/trcStreamPort.c @@ -1,161 +1,165 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Supporting functions for trace streaming, used by the "stream ports" - * for reading and writing data to the interface. - * Existing ports can easily be modified to fit another setup, e.g., a - * different TCP/IP stack, or to define your own stream port. - * - * This stream port is for ITM streaming on Arm Cortex-M devices. - * - * To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus), - * see Percepio Application Note PA-021, available at - * https://percepio.com/2018/05/04/keil-itm-support/ - * - * To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet, - * see Percepio Application Note PA-023, https://percepio.com/iar - * - * NOTE: This stream port may block the application in case the ITM port - * is not ready for more data (the TPIU FIFO has become full). This is - * necessary to avoid data loss, as the TPIU FIFO is often quite small. - * - * --- Direct vs. Indirect ITM streaming --- - * Direct streaming: By default, this stream port writes directly to the ITM - * register mode without any RAM buffer. This assumes you have a fast debug - * probe, like aKeil ULINKpro or IAR I-Jet, to avoid excessive blocking. - * In case the ITM blocking appears to disturb your application, make sure your - * debugger is configured for maximum performance, as described in the above - * Application Nodes. - * - * Indirect streaming: If direct streaming gives too much overhead, you may - * instead try indirect ITM streaming. This is done by enabling the internal - * RAM buffer, like below. This reconfigures the recorder to store the events - * in the internal RAM buffer instead of writing them directly to the ITM port. - * - * Set TRC_STREAM_PORT_USE_INTERNAL_BUFFER to 1 to use the indirect mode. - * - * This increases RAM usage but eliminates peaks in the trace data rate. - * Moreover, the ITM writes are then performed in a separate task (TzCtrl). - * You find relevant settings (buffer size etc.) in trcStreamingConfig.h. - * - * See also https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming - * - * --- One-way vs. Two-way Communication --- - * The ITM port only provides one-way communication, from target to host. - * This is sufficient if you start the tracing from the target application, - * using vTraceEnable(TRC_START). Just make sure to start the Tracealyzer - * recording before you start the target system. - * - * In case you prefer to interactively start and stop the tracing from the host - * computer, you need two-way communication to send commands to the recorder. - * This is possible by writing such "start" and "stop" commands to a special - * buffer, monitored by the recorder library, using the debugger IDE. - * See trcStreamingPort.c and also the example macro for Keil uVision - * (Keil-uVision-Tracealyzer-ITM-Exporter.ini). - */ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -typedef struct TraceStreamPortFile -{ - uint8_t buffer[sizeof(TraceUnsignedBaseType_t)]; -} TraceStreamPortFile_t; - -static TraceStreamPortFile_t* pxStreamPortFile; - -/* This will be set by the debugger when there is data to be read */ -volatile int32_t tz_host_command_bytes_to_read = 0; - -/* This will be filled with data from the debugger */ -volatile char tz_host_command_data[32]; - -/* These variables are used for reading commands from the host, using read_from_host(). - * This is not required if using vTraceEnable(TRC_START). - * A debugger IDE may write to these functions using a macro. - * An example for Keil is included (Keil-uVision-Tracealyzer-ITM-Exporter.ini). */ - -#define itm_write_32(__data) \ -{\ - if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled? */ \ - (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled? */ \ - (ITM->TER & (1UL << (TRC_CFG_STREAM_PORT_ITM_PORT)))) /* ITM port enabled? */ \ - { \ - while (ITM->PORT[TRC_CFG_STREAM_PORT_ITM_PORT].u32 == 0) { /* Do nothing */ } /* Block until room in ITM FIFO - This stream port is always in "blocking mode", since intended for high-speed ITM! */ \ - ITM->PORT[TRC_CFG_STREAM_PORT_ITM_PORT].u32 = __data; /* Write the data */ \ - } \ -} - -/* This is assumed to execute from within the recorder, with interrupts disabled */ -traceResult prvTraceItmWrite(void* ptrData, uint32_t size, int32_t* ptrBytesWritten) -{ - uint32_t* ptr32 = (uint32_t*)ptrData; - - TRC_ASSERT(size % 4 == 0); - TRC_ASSERT(ptrBytesWritten != 0); - - *ptrBytesWritten = 0; - - while (*ptrBytesWritten < (int32_t)size) - { - itm_write_32(*ptr32); - ptr32++; - *ptrBytesWritten += 4; - } - - return TRC_SUCCESS; -} - -/* This reads "command" data from a RAM buffer, written by a host macro in the debugger */ -traceResult prvTraceItmRead(void* ptrData, uint32_t uiSize, int32_t* piBytesRead) -{ - int32_t i; - uint8_t* bytesBuffer = (uint8_t*)ptrData; - - TRC_ASSERT(piBytesRead != 0); - - /* Check if the debugger has updated tz_host_command_bytes_to_read */ - if (tz_host_command_bytes_to_read > 0) - { - if (tz_host_command_bytes_to_read != (int32_t)uiSize) - { - /* Sanity check. */ - return TRC_FAIL; - } - - *piBytesRead = (int32_t)tz_host_command_bytes_to_read; - - /* Read the bytes */ - for (i = 0; i < tz_host_command_bytes_to_read; i++) - { - bytesBuffer[i] = tz_host_command_data[i]; - } - - /* Reset */ - tz_host_command_bytes_to_read = 0; - } - - return TRC_SUCCESS; -} - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortFile_t); - - TRC_ASSERT(pxBuffer != 0); - - pxStreamPortFile = (TraceStreamPortFile_t*)pxBuffer; - - return TRC_SUCCESS; -} - -#endif - -#endif +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Supporting functions for trace streaming, used by the "stream ports" + * for reading and writing data to the interface. + * Existing ports can easily be modified to fit another setup, e.g., a + * different TCP/IP stack, or to define your own stream port. + * + * This stream port is for ITM streaming on Arm Cortex-M devices. + * + * To setup Keil uVision for ITM tracing with a Keil ULINKpro (or ULINKplus), + * see Percepio Application Note PA-021, available at + * https://percepio.com/2018/05/04/keil-itm-support/ + * + * To setup IAR Embedded Workbench for ITM tracing with an IAR I-Jet, + * see Percepio Application Note PA-023, https://percepio.com/iar + * + * NOTE: This stream port may block the application in case the ITM port + * is not ready for more data (the TPIU FIFO has become full). This is + * necessary to avoid data loss, as the TPIU FIFO is often quite small. + * + * --- Direct vs. Indirect ITM streaming --- + * Direct streaming: By default, this stream port writes directly to the ITM + * register mode without any RAM buffer. This assumes you have a fast debug + * probe, like aKeil ULINKpro or IAR I-Jet, to avoid excessive blocking. + * In case the ITM blocking appears to disturb your application, make sure your + * debugger is configured for maximum performance, as described in the above + * Application Nodes. + * + * Indirect streaming: If direct streaming gives too much overhead, you may + * instead try indirect ITM streaming. This is done by enabling the internal + * RAM buffer, like below. This reconfigures the recorder to store the events + * in the internal RAM buffer instead of writing them directly to the ITM port. + * + * Set TRC_STREAM_PORT_USE_INTERNAL_BUFFER to 1 to use the indirect mode. + * + * This increases RAM usage but eliminates peaks in the trace data rate. + * Moreover, the ITM writes are then performed in a separate task (TzCtrl). + * You find relevant settings (buffer size etc.) in trcStreamingConfig.h. + * + * See also https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming + * + * --- One-way vs. Two-way Communication --- + * The ITM port only provides one-way communication, from target to host. + * This is sufficient if you start the tracing from the target application, + * using vTraceEnable(TRC_START). Just make sure to start the Tracealyzer + * recording before you start the target system. + * + * In case you prefer to interactively start and stop the tracing from the host + * computer, you need two-way communication to send commands to the recorder. + * This is possible by writing such "start" and "stop" commands to a special + * buffer, monitored by the recorder library, using the debugger IDE. + * See trcStreamingPort.c and also the example macro for Keil uVision + * (Keil-uVision-Tracealyzer-ITM-Exporter.ini). + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + typedef struct TraceStreamPortFile + { + uint8_t buffer[ sizeof( TraceUnsignedBaseType_t ) ]; + } TraceStreamPortFile_t; + + static TraceStreamPortFile_t * pxStreamPortFile; + +/* This will be set by the debugger when there is data to be read */ + volatile int32_t tz_host_command_bytes_to_read = 0; + +/* This will be filled with data from the debugger */ + volatile char tz_host_command_data[ 32 ]; + +/* These variables are used for reading commands from the host, using read_from_host(). + * This is not required if using vTraceEnable(TRC_START). + * A debugger IDE may write to these functions using a macro. + * An example for Keil is included (Keil-uVision-Tracealyzer-ITM-Exporter.ini). */ + + #define itm_write_32( __data ) \ + { \ + if( ( CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk ) && /* Trace enabled? */ \ + ( ITM->TCR & ITM_TCR_ITMENA_Msk ) && /* ITM enabled? */ \ + ( ITM->TER & ( 1UL << ( TRC_CFG_STREAM_PORT_ITM_PORT ) ) ) ) /* ITM port enabled? */ \ + { \ + while( ITM->PORT[ TRC_CFG_STREAM_PORT_ITM_PORT ].u32 == 0 ) { /* Do nothing */ } /* Block until room in ITM FIFO - This stream port is always in "blocking mode", since intended for high-speed ITM! */ \ + ITM->PORT[ TRC_CFG_STREAM_PORT_ITM_PORT ].u32 = __data; /* Write the data */ \ + } \ + } + +/* This is assumed to execute from within the recorder, with interrupts disabled */ + traceResult prvTraceItmWrite( void * ptrData, + uint32_t size, + int32_t * ptrBytesWritten ) + { + uint32_t * ptr32 = ( uint32_t * ) ptrData; + + TRC_ASSERT( size % 4 == 0 ); + TRC_ASSERT( ptrBytesWritten != 0 ); + + *ptrBytesWritten = 0; + + while( *ptrBytesWritten < ( int32_t ) size ) + { + itm_write_32( *ptr32 ); + ptr32++; + *ptrBytesWritten += 4; + } + + return TRC_SUCCESS; + } + +/* This reads "command" data from a RAM buffer, written by a host macro in the debugger */ + traceResult prvTraceItmRead( void * ptrData, + uint32_t uiSize, + int32_t * piBytesRead ) + { + int32_t i; + uint8_t * bytesBuffer = ( uint8_t * ) ptrData; + + TRC_ASSERT( piBytesRead != 0 ); + + /* Check if the debugger has updated tz_host_command_bytes_to_read */ + if( tz_host_command_bytes_to_read > 0 ) + { + if( tz_host_command_bytes_to_read != ( int32_t ) uiSize ) + { + /* Sanity check. */ + return TRC_FAIL; + } + + *piBytesRead = ( int32_t ) tz_host_command_bytes_to_read; + + /* Read the bytes */ + for( i = 0; i < tz_host_command_bytes_to_read; i++ ) + { + bytesBuffer[ i ] = tz_host_command_data[ i ]; + } + + /* Reset */ + tz_host_command_bytes_to_read = 0; + } + + return TRC_SUCCESS; + } + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceStreamPortBuffer_t, TraceStreamPortFile_t ); + + TRC_ASSERT( pxBuffer != 0 ); + + pxStreamPortFile = ( TraceStreamPortFile_t * ) pxBuffer; + + return TRC_SUCCESS; + } + + #endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) */ + +#endif /* if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt index f66208518..000a9737f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/Readme-Streamport.txt @@ -1,18 +1,18 @@ -Tracealyzer Stream Port for Files -Percepio AB -www.percepio.com -------------------------------------------------- - -This directory contains a "stream port" for the Tracealyzer recorder library, -i.e., the specific code needed to use a particular interface for streaming a -Tracealyzer RTOS trace. The stream port is defined by a set of macros in -trcStreamPort.h, found in the "include" directory. - -This particular stream port is for streaming to a file via stdio.h (fwrite). - -To use this stream port, make sure that include/trcStreamPort.h is found -by the compiler (i.e., add this folder to your project's include paths) and -add all included source files to your build. Make sure no other versions of -trcStreamPort.h are included by mistake! - -See also http://percepio.com/2016/10/05/rtos-tracing. +Tracealyzer Stream Port for Files +Percepio AB +www.percepio.com +------------------------------------------------- + +This directory contains a "stream port" for the Tracealyzer recorder library, +i.e., the specific code needed to use a particular interface for streaming a +Tracealyzer RTOS trace. The stream port is defined by a set of macros in +trcStreamPort.h, found in the "include" directory. + +This particular stream port is for streaming to a file via stdio.h (fwrite). + +To use this stream port, make sure that include/trcStreamPort.h is found +by the compiler (i.e., add this folder to your project's include paths) and +add all included source files to your build. Make sure no other versions of +trcStreamPort.h are included by mistake! + +See also http://percepio.com/2016/10/05/rtos-tracing. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/config/trcStreamPortConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/config/trcStreamPortConfig.h index 2f95a1652..21a253428 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/config/trcStreamPortConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/config/trcStreamPortConfig.h @@ -1,39 +1,39 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The configuration for trace streaming ("stream ports"). - */ - -#ifndef TRC_STREAM_PORT_CONFIG_H -#define TRC_STREAM_PORT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Default file name */ -#ifndef TRC_CFG_STREAM_PORT_TRACE_FILE -#define TRC_CFG_STREAM_PORT_TRACE_FILE "trace.psf" -#endif - -/* This define will determine whether to use the internal buffer or not. -If file writing creates additional trace events (i.e. it uses semaphores or mutexes), -then the internal buffer must be enabled to avoid infinite recursion. */ -#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0 - -/******************************************************************************* -* Configuration Macro: TRC_CFG_STREAM_PORT_BUFFER_SIZE -* -* Specifies the size of the internal buffer, if one is used. -******************************************************************************/ -#define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000 - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The configuration for trace streaming ("stream ports"). + */ + +#ifndef TRC_STREAM_PORT_CONFIG_H + #define TRC_STREAM_PORT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/* Default file name */ + #ifndef TRC_CFG_STREAM_PORT_TRACE_FILE + #define TRC_CFG_STREAM_PORT_TRACE_FILE "trace.psf" + #endif + +/* This define will determine whether to use the internal buffer or not. + * If file writing creates additional trace events (i.e. it uses semaphores or mutexes), + * then the internal buffer must be enabled to avoid infinite recursion. */ + #define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_STREAM_PORT_BUFFER_SIZE + * + * Specifies the size of the internal buffer, if one is used. + ******************************************************************************/ + #define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000 + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamPort.h index 3e4734774..ab501d493 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/include/trcStreamPort.h @@ -1,84 +1,84 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The interface definitions for trace streaming ("stream ports"). - * This "stream port" sets up the recorder to stream the trace to file. - */ - -#ifndef TRC_STREAM_PORT_H -#define TRC_STREAM_PORT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER) - -/* Default file name */ -#ifndef TRC_CFG_STREAM_PORT_TRACE_FILE -#define TRC_CFG_STREAM_PORT_TRACE_FILE "trace.psf" -#endif - -typedef struct TraceStreamPortFile -{ - FILE* pxFile; -#if (TRC_USE_INTERNAL_BUFFER) - uint8_t buffer[TRC_STREAM_PORT_BUFFER_SIZE]; -#endif -} TraceStreamPortFile_t; - -extern TraceStreamPortFile_t* pxStreamPortFile; - -#define TRC_STREAM_PORT_BUFFER_SIZE (sizeof(TraceStreamPortFile_t)) - -typedef struct TraceStreamPortBuffer -{ - uint8_t buffer[TRC_STREAM_PORT_BUFFER_SIZE]; -} TraceStreamPortBuffer_t; - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer); - -#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData)) - -#if (TRC_USE_INTERNAL_BUFFER == 1) -/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */ -#define xTraceStreamPortCommit(pvData, uiSize, piBytesCommitted) xTraceInternalEventBufferPush(pvData, uiSize, piBytesCommitted) -#else -/* Write directly to file */ -#define xTraceStreamPortCommit(pvData, uiSize, piBytesCommitted) xTraceStreamPortWriteData(pvData, uiSize, piBytesCommitted) -#endif - -#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) (*(piBytesWritten) = fwrite(pvData, 1, uiSize, pxStreamPortFile->pxFile), TRC_SUCCESS) - -#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) ((void)(pvData), (void)(uiSize), (void)(piBytesRead), TRC_SUCCESS) - -#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS) - -#define xTraceStreamPortOnDisable() (TRC_SUCCESS) - -traceResult xTraceStreamPortOnTraceBegin(void); - -traceResult xTraceStreamPortOnTraceEnd(void); - -#ifdef __cplusplus -} -#endif - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ - -#endif /* TRC_STREAM_PORT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface definitions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to stream the trace to file. + */ + +#ifndef TRC_STREAM_PORT_H + #define TRC_STREAM_PORT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + #include + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + + #define TRC_USE_INTERNAL_BUFFER ( TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER ) + +/* Default file name */ + #ifndef TRC_CFG_STREAM_PORT_TRACE_FILE + #define TRC_CFG_STREAM_PORT_TRACE_FILE "trace.psf" + #endif + + typedef struct TraceStreamPortFile + { + FILE * pxFile; + #if ( TRC_USE_INTERNAL_BUFFER ) + uint8_t buffer[ TRC_STREAM_PORT_BUFFER_SIZE ]; + #endif + } TraceStreamPortFile_t; + + extern TraceStreamPortFile_t * pxStreamPortFile; + + #define TRC_STREAM_PORT_BUFFER_SIZE ( sizeof( TraceStreamPortFile_t ) ) + + typedef struct TraceStreamPortBuffer + { + uint8_t buffer[ TRC_STREAM_PORT_BUFFER_SIZE ]; + } TraceStreamPortBuffer_t; + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ); + + #define xTraceStreamPortAllocate( uiSize, ppvData ) ( ( void ) ( uiSize ), xTraceStaticBufferGet( ppvData ) ) + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) +/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */ + #define xTraceStreamPortCommit( pvData, uiSize, piBytesCommitted ) xTraceInternalEventBufferPush( pvData, uiSize, piBytesCommitted ) + #else +/* Write directly to file */ + #define xTraceStreamPortCommit( pvData, uiSize, piBytesCommitted ) xTraceStreamPortWriteData( pvData, uiSize, piBytesCommitted ) + #endif + + #define xTraceStreamPortWriteData( pvData, uiSize, piBytesWritten ) ( *( piBytesWritten ) = fwrite( pvData, 1, uiSize, pxStreamPortFile->pxFile ), TRC_SUCCESS ) + + #define xTraceStreamPortReadData( pvData, uiSize, piBytesRead ) ( ( void ) ( pvData ), ( void ) ( uiSize ), ( void ) ( piBytesRead ), TRC_SUCCESS ) + + #define xTraceStreamPortOnEnable( uiStartOption ) ( ( void ) ( uiStartOption ), TRC_SUCCESS ) + + #define xTraceStreamPortOnDisable() ( TRC_SUCCESS ) + + traceResult xTraceStreamPortOnTraceBegin( void ); + + traceResult xTraceStreamPortOnTraceEnd( void ); + + #ifdef __cplusplus +} + #endif + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + + #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#endif /* TRC_STREAM_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamPort.c index 1786026cd..d9b32943e 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamPort.c @@ -1,82 +1,83 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Supporting functions for trace streaming, used by the "stream ports" - * for reading and writing data to the interface. - * Existing ports can easily be modified to fit another setup, e.g., a - * different TCP/IP stack, or to define your own stream port. - */ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -TraceStreamPortFile_t* pxStreamPortFile; - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortFile_t); - - TRC_ASSERT(pxBuffer != 0); - - pxStreamPortFile = (TraceStreamPortFile_t*)pxBuffer; - pxStreamPortFile->pxFile = 0; - -#if (TRC_USE_INTERNAL_BUFFER == 1) - return xTraceInternalEventBufferInitialize(pxStreamPortFile->buffer, sizeof(pxStreamPortFile->buffer)); -#else - return TRC_SUCCESS; -#endif -} - -traceResult xTraceStreamPortOnTraceBegin(void) -{ - if (pxStreamPortFile == 0) - { - return TRC_FAIL; - } - - if (pxStreamPortFile->pxFile == 0) - { - errno_t err = fopen_s(&pxStreamPortFile->pxFile, TRC_CFG_STREAM_PORT_TRACE_FILE, "wb"); - if (err != 0) - { - printf("Could not open trace file, error code %d.\n", err); - - return TRC_FAIL; - } - else - { - printf("Trace file created.\n"); - } - } - - return TRC_SUCCESS; -} - -traceResult xTraceStreamPortOnTraceEnd(void) -{ - if (pxStreamPortFile == 0) - { - return TRC_FAIL; - } - - if (pxStreamPortFile->pxFile != 0) - { - fclose(pxStreamPortFile->pxFile); - pxStreamPortFile->pxFile = 0; - printf("Trace file closed.\n"); - } - - return TRC_SUCCESS; -} - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Supporting functions for trace streaming, used by the "stream ports" + * for reading and writing data to the interface. + * Existing ports can easily be modified to fit another setup, e.g., a + * different TCP/IP stack, or to define your own stream port. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + TraceStreamPortFile_t * pxStreamPortFile; + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceStreamPortBuffer_t, TraceStreamPortFile_t ); + + TRC_ASSERT( pxBuffer != 0 ); + + pxStreamPortFile = ( TraceStreamPortFile_t * ) pxBuffer; + pxStreamPortFile->pxFile = 0; + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + return xTraceInternalEventBufferInitialize( pxStreamPortFile->buffer, sizeof( pxStreamPortFile->buffer ) ); + #else + return TRC_SUCCESS; + #endif + } + + traceResult xTraceStreamPortOnTraceBegin( void ) + { + if( pxStreamPortFile == 0 ) + { + return TRC_FAIL; + } + + if( pxStreamPortFile->pxFile == 0 ) + { + errno_t err = fopen_s( &pxStreamPortFile->pxFile, TRC_CFG_STREAM_PORT_TRACE_FILE, "wb" ); + + if( err != 0 ) + { + printf( "Could not open trace file, error code %d.\n", err ); + + return TRC_FAIL; + } + else + { + printf( "Trace file created.\n" ); + } + } + + return TRC_SUCCESS; + } + + traceResult xTraceStreamPortOnTraceEnd( void ) + { + if( pxStreamPortFile == 0 ) + { + return TRC_FAIL; + } + + if( pxStreamPortFile->pxFile != 0 ) + { + fclose( pxStreamPortFile->pxFile ); + pxStreamPortFile->pxFile = 0; + printf( "Trace file closed.\n" ); + } + + return TRC_SUCCESS; + } + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + +#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/Readme-Streamport.txt index 5c35ed83e..a28d4dcda 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/Readme-Streamport.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/Readme-Streamport.txt @@ -1,21 +1,21 @@ -Tracealyzer Stream Port for SEGGER J-Link -Percepio AB -www.percepio.com ------------------------------------------ - -This directory contains a "stream port" for the Tracealyzer recorder library, -i.e., the specific code needed to use a particular interface for streaming a -Tracealyzer RTOS trace. The stream port is defined by a set of macros in -trcStreamPort.h, found in the "include" directory. - -This particular stream port targets SEGGER J-Link debug probes, using the RTT -interface provided by SEGGER. - -To use this stream port, make sure that include/trcStreamPort.h is found -by the compiler (i.e., add this folder to your project's include paths) and -add all included source files to your build. Make sure no other versions of -trcStreamPort.h are included by mistake! - -Note that this stream port also contains SEGGER's RTT driver. - -See also http://percepio.com/2016/10/05/rtos-tracing. +Tracealyzer Stream Port for SEGGER J-Link +Percepio AB +www.percepio.com +----------------------------------------- + +This directory contains a "stream port" for the Tracealyzer recorder library, +i.e., the specific code needed to use a particular interface for streaming a +Tracealyzer RTOS trace. The stream port is defined by a set of macros in +trcStreamPort.h, found in the "include" directory. + +This particular stream port targets SEGGER J-Link debug probes, using the RTT +interface provided by SEGGER. + +To use this stream port, make sure that include/trcStreamPort.h is found +by the compiler (i.e., add this folder to your project's include paths) and +add all included source files to your build. Make sure no other versions of +trcStreamPort.h are included by mistake! + +Note that this stream port also contains SEGGER's RTT driver. + +See also http://percepio.com/2016/10/05/rtos-tracing. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/SEGGER_RTT.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/SEGGER_RTT.c index 3ff3ba9ae..10118bdcc 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/SEGGER_RTT.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/SEGGER_RTT.c @@ -1,1447 +1,1702 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* SEGGER RTT * Real Time Transfer for embedded targets * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source, linkable, or executable form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source, executable, or * -* linkable form may not be distributed without prior consent of * -* SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** -* * -* RTT version: 6.00e * -* * -********************************************************************** ----------------------------END-OF-HEADER------------------------------ -File : SEGGER_RTT.c -Purpose : Implementation of SEGGER real-time transfer (RTT) which - allows real-time communication on targets which support - debugger memory accesses while the CPU is running. -Revision: $Rev: 4079 $ - -Additional information: - Type "int" is assumed to be 32-bits in size - H->T Host to target communication - T->H Target to host communication - - RTT channel 0 is always present and reserved for Terminal usage. - Name is fixed to "Terminal" - - Effective buffer size: SizeOfBuffer - 1 - - WrOff == RdOff: Buffer is empty - WrOff == (RdOff - 1): Buffer is full - WrOff > RdOff: Free space includes wrap-around - WrOff < RdOff: Used space includes wrap-around - (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): - Buffer full and wrap-around after next byte - - ----------------------------------------------------------------------- -*/ - -#include "SEGGER_RTT.h" - -#include // for memcpy - -/********************************************************************* -* -* Configuration, default values -* -********************************************************************** -*/ - -#ifndef BUFFER_SIZE_UP - #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host -#endif - -#ifndef BUFFER_SIZE_DOWN - #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) -#endif - -#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS - #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target -#endif - -#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS - #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target -#endif - -#ifndef SEGGER_RTT_BUFFER_SECTION - #if defined(SEGGER_RTT_SECTION) - #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION - #endif -#endif - -#ifndef SEGGER_RTT_ALIGNMENT - #define SEGGER_RTT_ALIGNMENT 0 -#endif - -#ifndef SEGGER_RTT_BUFFER_ALIGNMENT - #define SEGGER_RTT_BUFFER_ALIGNMENT 0 -#endif - -#ifndef SEGGER_RTT_MODE_DEFAULT - #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP -#endif - -#ifndef SEGGER_RTT_LOCK - #define SEGGER_RTT_LOCK() -#endif - -#ifndef SEGGER_RTT_UNLOCK - #define SEGGER_RTT_UNLOCK() -#endif - -#ifndef STRLEN - #define STRLEN(a) strlen((a)) -#endif - -#ifndef MEMCPY - #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) -#endif - -#ifndef MIN - #define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef MAX - #define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif -// -// For some environments, NULL may not be defined until certain headers are included -// -#ifndef NULL - #define NULL 0 -#endif - -/********************************************************************* -* -* Defines, fixed -* -********************************************************************** -*/ -#if (defined __ICCARM__) || (defined __ICCRX__) - #define RTT_PRAGMA(P) _Pragma(#P) -#endif - -#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT - #if (defined __GNUC__) - #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) - #elif (defined __ICCARM__) || (defined __ICCRX__) - #define PRAGMA(A) _Pragma(#A) -#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ - Var - #elif (defined __CC_ARM__) - #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) - #else - #error "Alignment not supported for this compiler." - #endif -#else - #define SEGGER_RTT_ALIGN(Var, Alignment) Var -#endif - -#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) - #if (defined __GNUC__) - #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var - #elif (defined __ICCARM__) || (defined __ICCRX__) -#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ - Var - #elif (defined __CC_ARM__) - #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var - #else - #error "Section placement not supported for this compiler." - #endif -#else - #define SEGGER_RTT_PUT_SECTION(Var, Section) Var -#endif - - -#if SEGGER_RTT_ALIGNMENT - #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) -#else - #define SEGGER_RTT_CB_ALIGN(Var) Var -#endif - -#if SEGGER_RTT_BUFFER_ALIGNMENT - #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) -#else - #define SEGGER_RTT_BUFFER_ALIGN(Var) Var -#endif - - -#if defined(SEGGER_RTT_SECTION) - #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) -#else - #define SEGGER_RTT_PUT_CB_SECTION(Var) Var -#endif - -#if defined(SEGGER_RTT_BUFFER_SECTION) - #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) -#else - #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var -#endif - -/********************************************************************* -* -* Static const data -* -********************************************************************** -*/ - -static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - -/********************************************************************* -* -* Static data -* -********************************************************************** -*/ -// -// RTT Control Block and allocate buffers for channel 0 -// -SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); - -SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP])); -SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN])); - -static char _ActiveTerminal; - -/********************************************************************* -* -* Static functions -* -********************************************************************** -*/ - -/********************************************************************* -* -* _DoInit() -* -* Function description -* Initializes the control block an buffers. -* May only be called via INIT() to avoid overriding settings. -* -*/ -#define INIT() do { \ - if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ - } while (0) -static void _DoInit(void) { - SEGGER_RTT_CB* p; - // - // Initialize control block - // - p = &_SEGGER_RTT; - p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; - p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; - // - // Initialize up buffer 0 - // - p->aUp[0].sName = "Terminal"; - p->aUp[0].pBuffer = _acUpBuffer; - p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); - p->aUp[0].RdOff = 0u; - p->aUp[0].WrOff = 0u; - p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; - // - // Initialize down buffer 0 - // - p->aDown[0].sName = "Terminal"; - p->aDown[0].pBuffer = _acDownBuffer; - p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); - p->aDown[0].RdOff = 0u; - p->aDown[0].WrOff = 0u; - p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; - // - // Finish initialization of the control block. - // Copy Id string in three steps to make sure "SEGGER RTT" is not found - // in initializer memory (usually flash) by J-Link - // - strcpy(&p->acID[7], "RTT"); - strcpy(&p->acID[0], "SEGGER"); - p->acID[6] = ' '; -} - -/********************************************************************* -* -* _WriteBlocking() -* -* Function description -* Stores a specified number of characters in SEGGER RTT ring buffer -* and updates the associated write pointer which is periodically -* read by the host. -* The caller is responsible for managing the write chunk sizes as -* _WriteBlocking() will block until all data has been posted successfully. -* -* Parameters -* pRing Ring buffer to post to. -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* >= 0 - Number of bytes written into buffer. -*/ -static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { - unsigned NumBytesToWrite; - unsigned NumBytesWritten; - unsigned RdOff; - unsigned WrOff; - // - // Write data to buffer and handle wrap-around if necessary - // - NumBytesWritten = 0u; - WrOff = pRing->WrOff; - do { - RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime - if (RdOff > WrOff) { - NumBytesToWrite = RdOff - WrOff - 1u; - } else { - NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); - } - NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around - NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); - memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); - NumBytesWritten += NumBytesToWrite; - pBuffer += NumBytesToWrite; - NumBytes -= NumBytesToWrite; - WrOff += NumBytesToWrite; - if (WrOff == pRing->SizeOfBuffer) { - WrOff = 0u; - } - pRing->WrOff = WrOff; - } while (NumBytes); - // - return NumBytesWritten; -} - -/********************************************************************* -* -* _WriteNoCheck() -* -* Function description -* Stores a specified number of characters in SEGGER RTT ring buffer -* and updates the associated write pointer which is periodically -* read by the host. -* It is callers responsibility to make sure data actually fits in buffer. -* -* Parameters -* pRing Ring buffer to post to. -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Notes -* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking -*/ -static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { - unsigned NumBytesAtOnce; - unsigned WrOff; - unsigned Rem; - - WrOff = pRing->WrOff; - Rem = pRing->SizeOfBuffer - WrOff; - if (Rem > NumBytes) { - // - // All data fits before wrap around - // - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; - } else { - // - // We reach the end of the buffer, so need to wrap around - // - NumBytesAtOnce = Rem; - memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); - NumBytesAtOnce = NumBytes - Rem; - memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce); - pRing->WrOff = NumBytesAtOnce; - } -} - -/********************************************************************* -* -* _PostTerminalSwitch() -* -* Function description -* Switch terminal to the given terminal ID. It is the caller's -* responsibility to ensure the terminal ID is correct and there is -* enough space in the buffer for this to complete successfully. -* -* Parameters -* pRing Ring buffer to post to. -* TerminalId Terminal ID to switch to. -*/ -static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { - char ac[2]; - - ac[0] = 0xFFu; - ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit - _WriteBlocking(pRing, ac, 2u); -} - -/********************************************************************* -* -* _GetAvailWriteSpace() -* -* Function description -* Returns the number of bytes that can be written to the ring -* buffer without blocking. -* -* Parameters -* pRing Ring buffer to check. -* -* Return value -* Number of bytes that are free in the buffer. -*/ -static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { - unsigned RdOff; - unsigned WrOff; - unsigned r; - // - // Avoid warnings regarding volatile access order. It's not a problem - // in this case, but dampen compiler enthusiasm. - // - RdOff = pRing->RdOff; - WrOff = pRing->WrOff; - if (RdOff <= WrOff) { - r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; - } else { - r = RdOff - WrOff - 1u; - } - return r; -} - -/********************************************************************* -* -* Public code -* -********************************************************************** -*/ -/********************************************************************* -* -* SEGGER_RTT_ReadNoLock() -* -* Function description -* Reads characters from SEGGER real-time-terminal control block -* which have been previously stored by the host. -* Do not lock against interrupts and multiple access. -* -* Parameters -* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. -* BufferSize Size of the target application buffer. -* -* Return value -* Number of bytes that have been read. -*/ -unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { - unsigned NumBytesRem; - unsigned NumBytesRead; - unsigned RdOff; - unsigned WrOff; - unsigned char* pBuffer; - SEGGER_RTT_BUFFER_DOWN* pRing; - // - INIT(); - pRing = &_SEGGER_RTT.aDown[BufferIndex]; - pBuffer = (unsigned char*)pData; - RdOff = pRing->RdOff; - WrOff = pRing->WrOff; - NumBytesRead = 0u; - // - // Read from current read position to wrap-around of buffer, first - // - if (RdOff > WrOff) { - NumBytesRem = pRing->SizeOfBuffer - RdOff; - NumBytesRem = MIN(NumBytesRem, BufferSize); - memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); - NumBytesRead += NumBytesRem; - pBuffer += NumBytesRem; - BufferSize -= NumBytesRem; - RdOff += NumBytesRem; - // - // Handle wrap-around of buffer - // - if (RdOff == pRing->SizeOfBuffer) { - RdOff = 0u; - } - } - // - // Read remaining items of buffer - // - NumBytesRem = WrOff - RdOff; - NumBytesRem = MIN(NumBytesRem, BufferSize); - if (NumBytesRem > 0u) { - memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); - NumBytesRead += NumBytesRem; - pBuffer += NumBytesRem; - BufferSize -= NumBytesRem; - RdOff += NumBytesRem; - } - if (NumBytesRead) { - pRing->RdOff = RdOff; - } - // - return NumBytesRead; -} - -/********************************************************************* -* -* SEGGER_RTT_Read -* -* Function description -* Reads characters from SEGGER real-time-terminal control block -* which have been previously stored by the host. -* -* Parameters -* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. -* BufferSize Size of the target application buffer. -* -* Return value -* Number of bytes that have been read. -*/ -unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { - unsigned NumBytesRead; - // - SEGGER_RTT_LOCK(); - // - // Call the non-locking read function - // - NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); - // - // Finish up. - // - SEGGER_RTT_UNLOCK(); - // - return NumBytesRead; -} - -/********************************************************************* -* -* SEGGER_RTT_WriteWithOverwriteNoLock -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block. -* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application -* and overwrites data if the data does not fit into the buffer. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, data is overwritten. -* (2) For performance reasons this function does not call Init() -* and may only be called after RTT has been initialized. -* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. -* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link -* connection reads RTT data. -*/ -void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - const char* pData; - SEGGER_RTT_BUFFER_UP* pRing; - unsigned Avail; - - pData = (const char *)pBuffer; - // - // Get "to-host" ring buffer and copy some elements into local variables. - // - pRing = &_SEGGER_RTT.aUp[BufferIndex]; - // - // Check if we will overwrite data and need to adjust the RdOff. - // - if (pRing->WrOff == pRing->RdOff) { - Avail = pRing->SizeOfBuffer - 1u; - } else if ( pRing->WrOff < pRing->RdOff) { - Avail = pRing->RdOff - pRing->WrOff - 1u; - } else { - Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; - } - if (NumBytes > Avail) { - pRing->RdOff += (NumBytes - Avail); - while (pRing->RdOff >= pRing->SizeOfBuffer) { - pRing->RdOff -= pRing->SizeOfBuffer; - } - } - // - // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds - // - Avail = pRing->SizeOfBuffer - pRing->WrOff; - do { - if (Avail > NumBytes) { - // - // Last round - // -#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. - char* pDst; - pDst = pRing->pBuffer + pRing->WrOff; - pRing->WrOff += NumBytes; - do { - *pDst++ = *pData++; - } while (--NumBytes); -#else - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff += NumBytes; -#endif - break; //Alternatively: NumBytes = 0; - } else { - // - // Wrap-around necessary, write until wrap-around and reset WrOff - // - memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail); - pData += Avail; - pRing->WrOff = 0; - NumBytes -= Avail; - Avail = (pRing->SizeOfBuffer - 1); - } - } while (NumBytes); -} - -/********************************************************************* -* -* SEGGER_RTT_WriteSkipNoLock -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block which is then read by the host. -* SEGGER_RTT_WriteSkipNoLock does not lock the application and -* skips all data, if the data does not fit into the buffer. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, all data is dropped. -* (2) For performance reasons this function does not call Init() -* and may only be called after RTT has been initialized. -* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. -*/ -unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - const char* pData; - SEGGER_RTT_BUFFER_UP* pRing; - unsigned Avail; - unsigned RdOff; - unsigned WrOff; - unsigned Rem; - - pData = (const char *)pBuffer; - // - // Get "to-host" ring buffer and copy some elements into local variables. - // - pRing = &_SEGGER_RTT.aUp[BufferIndex]; - RdOff = pRing->RdOff; - WrOff = pRing->WrOff; - // - // Handle the most common cases fastest. - // Which is: - // RdOff <= WrOff -> Space until wrap around is free. - // AND - // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. - // - // OR - // - // RdOff > WrOff -> Space until RdOff - 1 is free. - // AND - // WrOff + NumBytes < RdOff -> Data fits into buffer - // - if (RdOff <= WrOff) { - // - // Get space until WrOff will be at wrap around. - // - Avail = pRing->SizeOfBuffer - 1u - WrOff ; - if (Avail >= NumBytes) { -#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. - char* pDst; - pDst = pRing->pBuffer + WrOff; - WrOff += NumBytes; - do { - *pDst++ = *pData++; - } while (--NumBytes); - pRing->WrOff = WrOff + NumBytes; -#else - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; -#endif - return 1; - } - // - // If data did not fit into space until wrap around calculate complete space in buffer. - // - Avail += RdOff; - // - // If there is still no space for the whole of this output, don't bother. - // - if (Avail >= NumBytes) { - // - // OK, we have enough space in buffer. Copy in one or 2 chunks - // - Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer - if (Rem > NumBytes) { - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; - } else { - // - // We reach the end of the buffer, so need to wrap around - // - memcpy(pRing->pBuffer + WrOff, pData, Rem); - memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem); - pRing->WrOff = NumBytes - Rem; - } - return 1; - } - } else { - Avail = RdOff - WrOff - 1u; - if (Avail >= NumBytes) { - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; - return 1; - } - } - // - // If we reach this point no data has been written - // - return 0; -} - -/********************************************************************* -* -* SEGGER_RTT_WriteNoLock -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block which is then read by the host. -* SEGGER_RTT_WriteNoLock does not lock the application. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. -* (2) For performance reasons this function does not call Init() -* and may only be called after RTT has been initialized. -* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. -*/ -unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - unsigned Status; - unsigned Avail; - const char* pData; - SEGGER_RTT_BUFFER_UP* pRing; - - pData = (const char *)pBuffer; - // - // Get "to-host" ring buffer. - // - pRing = &_SEGGER_RTT.aUp[BufferIndex]; - // - // How we output depends upon the mode... - // - switch (pRing->Flags) { - case SEGGER_RTT_MODE_NO_BLOCK_SKIP: - // - // If we are in skip mode and there is no space for the whole - // of this output, don't bother. - // - Avail = _GetAvailWriteSpace(pRing); - if (Avail < NumBytes) { - Status = 0u; - } else { - Status = NumBytes; - _WriteNoCheck(pRing, pData, NumBytes); - } - break; - case SEGGER_RTT_MODE_NO_BLOCK_TRIM: - // - // If we are in trim mode, trim to what we can output without blocking. - // - Avail = _GetAvailWriteSpace(pRing); - Status = Avail < NumBytes ? Avail : NumBytes; - _WriteNoCheck(pRing, pData, Status); - break; - case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: - // - // If we are in blocking mode, output everything. - // - Status = _WriteBlocking(pRing, pData, NumBytes); - break; - default: - Status = 0u; - break; - } - // - // Finish up. - // - return Status; -} - -/********************************************************************* -* -* SEGGER_RTT_Write -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block which is then read by the host. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. -*/ -unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - unsigned Status; - // - INIT(); - SEGGER_RTT_LOCK(); - // - // Call the non-locking write function - // - Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); - // - // Finish up. - // - SEGGER_RTT_UNLOCK(); - // - return Status; -} - -/********************************************************************* -* -* SEGGER_RTT_WriteString -* -* Function description -* Stores string in SEGGER RTT control block. -* This data is read by the host. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* s Pointer to string. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, depending on configuration, -* remaining characters may be dropped or RTT module waits until there is more space in the buffer. -* (2) String passed to this function has to be \0 terminated -* (3) \0 termination character is *not* stored in RTT buffer -*/ -unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { - unsigned Len; - - Len = STRLEN(s); - return SEGGER_RTT_Write(BufferIndex, s, Len); -} - -/********************************************************************* -* -* SEGGER_RTT_GetKey -* -* Function description -* Reads one character from the SEGGER RTT buffer. -* Host has previously stored data there. -* -* Return value -* < 0 - No character available (buffer empty). -* >= 0 - Character which has been read. (Possible values: 0 - 255) -* -* Notes -* (1) This function is only specified for accesses to RTT buffer 0. -*/ -int SEGGER_RTT_GetKey(void) { - char c; - int r; - - r = (int)SEGGER_RTT_Read(0u, &c, 1u); - if (r == 1) { - r = (int)(unsigned char)c; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_WaitKey -* -* Function description -* Waits until at least one character is avaible in the SEGGER RTT buffer. -* Once a character is available, it is read and this function returns. -* -* Return value -* >=0 - Character which has been read. -* -* Notes -* (1) This function is only specified for accesses to RTT buffer 0 -* (2) This function is blocking if no character is present in RTT buffer -*/ -int SEGGER_RTT_WaitKey(void) { - int r; - - do { - r = SEGGER_RTT_GetKey(); - } while (r < 0); - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_HasKey -* -* Function description -* Checks if at least one character for reading is available in the SEGGER RTT buffer. -* -* Return value -* == 0 - No characters are available to read. -* == 1 - At least one character is available. -* -* Notes -* (1) This function is only specified for accesses to RTT buffer 0 -*/ -int SEGGER_RTT_HasKey(void) { - unsigned RdOff; - int r; - - INIT(); - RdOff = _SEGGER_RTT.aDown[0].RdOff; - if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { - r = 1; - } else { - r = 0; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_HasData -* -* Function description -* Check if there is data from the host in the given buffer. -* -* Return value: -* ==0: No data -* !=0: Data in buffer -* -*/ -unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { - SEGGER_RTT_BUFFER_DOWN* pRing; - unsigned v; - - pRing = &_SEGGER_RTT.aDown[BufferIndex]; - v = pRing->WrOff; - return v - pRing->RdOff; -} - -/********************************************************************* -* -* SEGGER_RTT_AllocDownBuffer -* -* Function description -* Run-time configuration of the next down-buffer (H->T). -* The next buffer, which is not used yet is configured. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 - O.K. Buffer Index -* < 0 - Error -*/ -int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int BufferIndex; - - INIT(); - SEGGER_RTT_LOCK(); - BufferIndex = 0; - do { - if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { - break; - } - BufferIndex++; - } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); - if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { - _SEGGER_RTT.aDown[BufferIndex].sName = sName; - _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; - _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; - _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; - } else { - BufferIndex = -1; - } - SEGGER_RTT_UNLOCK(); - return BufferIndex; -} - -/********************************************************************* -* -* SEGGER_RTT_AllocUpBuffer -* -* Function description -* Run-time configuration of the next up-buffer (T->H). -* The next buffer, which is not used yet is configured. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 - O.K. Buffer Index -* < 0 - Error -*/ -int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int BufferIndex; - - INIT(); - SEGGER_RTT_LOCK(); - BufferIndex = 0; - do { - if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { - break; - } - BufferIndex++; - } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); - if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { - _SEGGER_RTT.aUp[BufferIndex].sName = sName; - _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; - _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; - _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; - } else { - BufferIndex = -1; - } - SEGGER_RTT_UNLOCK(); - return BufferIndex; -} - -/********************************************************************* -* -* SEGGER_RTT_ConfigUpBuffer -* -* Function description -* Run-time configuration of a specific up-buffer (T->H). -* Buffer to be configured is specified by index. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* BufferIndex Index of the buffer to configure. -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 - O.K. -* < 0 - Error -* -* Additional information -* Buffer 0 is configured on compile-time. -* May only be called once per buffer. -* Buffer name and flags can be reconfigured using the appropriate functions. -*/ -int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { - SEGGER_RTT_LOCK(); - if (BufferIndex > 0u) { - _SEGGER_RTT.aUp[BufferIndex].sName = sName; - _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; - _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; - } - _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_ConfigDownBuffer -* -* Function description -* Run-time configuration of a specific down-buffer (H->T). -* Buffer to be configured is specified by index. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* BufferIndex Index of the buffer to configure. -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 O.K. -* < 0 Error -* -* Additional information -* Buffer 0 is configured on compile-time. -* May only be called once per buffer. -* Buffer name and flags can be reconfigured using the appropriate functions. -*/ -int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { - SEGGER_RTT_LOCK(); - if (BufferIndex > 0u) { - _SEGGER_RTT.aDown[BufferIndex].sName = sName; - _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; - _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; - } - _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_SetNameUpBuffer -* -* Function description -* Run-time configuration of a specific up-buffer name (T->H). -* Buffer to be configured is specified by index. -* -* Parameters -* BufferIndex Index of the buffer to renamed. -* sName Pointer to a constant name string. -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { - SEGGER_RTT_LOCK(); - _SEGGER_RTT.aUp[BufferIndex].sName = sName; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_SetNameDownBuffer -* -* Function description -* Run-time configuration of a specific Down-buffer name (T->H). -* Buffer to be configured is specified by index. -* -* Parameters -* BufferIndex Index of the buffer to renamed. -* sName Pointer to a constant name string. -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { - SEGGER_RTT_LOCK(); - _SEGGER_RTT.aDown[BufferIndex].sName = sName; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_SetFlagsUpBuffer -* -* Function description -* Run-time configuration of specific up-buffer flags (T->H). -* Buffer to be configured is specified by index. -* -* Parameters -* BufferIndex Index of the buffer. -* Flags Flags to set for the buffer. -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { - SEGGER_RTT_LOCK(); - _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_SetFlagsDownBuffer -* -* Function description -* Run-time configuration of specific Down-buffer flags (T->H). -* Buffer to be configured is specified by index. -* -* Parameters -* BufferIndex Index of the buffer to renamed. -* Flags Flags to set for the buffer. -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { - SEGGER_RTT_LOCK(); - _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_Init -* -* Function description -* Initializes the RTT Control Block. -* Should be used in RAM targets, at start of the application. -* -*/ -void SEGGER_RTT_Init (void) { - _DoInit(); -} - -/********************************************************************* -* -* SEGGER_RTT_SetTerminal -* -* Function description -* Sets the terminal to be used for output on channel 0. -* -* Parameters -* TerminalId Index of the terminal. -* -* Return value -* >= 0 O.K. -* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) -*/ -int SEGGER_RTT_SetTerminal (char TerminalId) { - char ac[2]; - SEGGER_RTT_BUFFER_UP* pRing; - unsigned Avail; - int r; - // - INIT(); - // - r = 0; - ac[0] = 0xFFU; - if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels - ac[1] = _aTerminalId[(unsigned char)TerminalId]; - pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed - SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing - if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { - _ActiveTerminal = TerminalId; - _WriteBlocking(pRing, ac, 2u); - } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes - Avail = _GetAvailWriteSpace(pRing); - if (Avail >= 2) { - _ActiveTerminal = TerminalId; // Only change active terminal in case of success - _WriteNoCheck(pRing, ac, 2u); - } else { - r = -1; - } - } - SEGGER_RTT_UNLOCK(); - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_TerminalOut -* -* Function description -* Writes a string to the given terminal -* without changing the terminal for channel 0. -* -* Parameters -* TerminalId Index of the terminal. -* s String to be printed on the terminal. -* -* Return value -* >= 0 - Number of bytes written. -* < 0 - Error. -* -*/ -int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { - int Status; - unsigned FragLen; - unsigned Avail; - SEGGER_RTT_BUFFER_UP* pRing; - // - INIT(); - // - // Validate terminal ID. - // - if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels - // - // Get "to-host" ring buffer. - // - pRing = &_SEGGER_RTT.aUp[0]; - // - // Need to be able to change terminal, write data, change back. - // Compute the fixed and variable sizes. - // - FragLen = strlen(s); - // - // How we output depends upon the mode... - // - SEGGER_RTT_LOCK(); - Avail = _GetAvailWriteSpace(pRing); - switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { - case SEGGER_RTT_MODE_NO_BLOCK_SKIP: - // - // If we are in skip mode and there is no space for the whole - // of this output, don't bother switching terminals at all. - // - if (Avail < (FragLen + 4u)) { - Status = 0; - } else { - _PostTerminalSwitch(pRing, TerminalId); - Status = (int)_WriteBlocking(pRing, s, FragLen); - _PostTerminalSwitch(pRing, _ActiveTerminal); - } - break; - case SEGGER_RTT_MODE_NO_BLOCK_TRIM: - // - // If we are in trim mode and there is not enough space for everything, - // trim the output but always include the terminal switch. If no room - // for terminal switch, skip that totally. - // - if (Avail < 4u) { - Status = -1; - } else { - _PostTerminalSwitch(pRing, TerminalId); - Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); - _PostTerminalSwitch(pRing, _ActiveTerminal); - } - break; - case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: - // - // If we are in blocking mode, output everything. - // - _PostTerminalSwitch(pRing, TerminalId); - Status = (int)_WriteBlocking(pRing, s, FragLen); - _PostTerminalSwitch(pRing, _ActiveTerminal); - break; - default: - Status = -1; - break; - } - // - // Finish up. - // - SEGGER_RTT_UNLOCK(); - } else { - Status = -1; - } - return Status; -} - - -/*************************** End of file ****************************/ +/********************************************************************* + * SEGGER MICROCONTROLLER GmbH & Co. KG * + * Solutions for real time microcontroller applications * + ********************************************************************** + * * + * (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * + * * + * www.segger.com Support: support@segger.com * + * * + ********************************************************************** + * * + * SEGGER RTT * Real Time Transfer for embedded targets * + * * + ********************************************************************** + * * + * All rights reserved. * + * * + * * This software may in its unmodified form be freely redistributed * + * in source, linkable, or executable form. * + * * The source code may be modified, provided the source code * + * retains the above copyright notice, this list of conditions and * + * the following disclaimer. * + * * Modified versions of this software in source, executable, or * + * linkable form may not be distributed without prior consent of * + * SEGGER. * + * * This software may only be used for communication with SEGGER * + * J-Link debug probes. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * + * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * + * DAMAGE. * + * * + ********************************************************************** + * * + * RTT version: 6.00e * + * * + ********************************************************************** + * ---------------------------END-OF-HEADER------------------------------ + * File : SEGGER_RTT.c + * Purpose : Implementation of SEGGER real-time transfer (RTT) which + * allows real-time communication on targets which support + * debugger memory accesses while the CPU is running. + * Revision: $Rev: 4079 $ + * + * Additional information: + * Type "int" is assumed to be 32-bits in size + * H->T Host to target communication + * T->H Target to host communication + * + * RTT channel 0 is always present and reserved for Terminal usage. + * Name is fixed to "Terminal" + * + * Effective buffer size: SizeOfBuffer - 1 + * + * WrOff == RdOff: Buffer is empty + * WrOff == (RdOff - 1): Buffer is full + * WrOff > RdOff: Free space includes wrap-around + * WrOff < RdOff: Used space includes wrap-around + * (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + * Buffer full and wrap-around after next byte + * + * + * ---------------------------------------------------------------------- + */ + +#include "SEGGER_RTT.h" + +#include /* for memcpy */ + +/********************************************************************* + * + * Configuration, default values + * + ********************************************************************** + */ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 /* Size of the buffer for terminal output of target, up to host */ +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 /* Size of the buffer for terminal input to target from host (Usually keyboard input) */ +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 /* Number of up-buffers (T->H) available on this target */ +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 /* Number of down-buffers (H->T) available on this target */ +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined( SEGGER_RTT_SECTION ) + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN( a ) strlen( ( a ) ) +#endif + +#ifndef MEMCPY + #define MEMCPY( pDest, pSrc, NumBytes ) memcpy( ( pDest ), ( pSrc ), ( NumBytes ) ) +#endif + +#ifndef MIN + #define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#endif + +#ifndef MAX + #define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) +#endif +/* */ +/* For some environments, NULL may not be defined until certain headers are included */ +/* */ +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* + * + * Defines, fixed + * + ********************************************************************** + */ +#if ( defined __ICCARM__ ) || ( defined __ICCRX__ ) + #define RTT_PRAGMA( P ) _Pragma(#P) +#endif + +#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT + #if ( defined __GNUC__ ) + #define SEGGER_RTT_ALIGN( Var, Alignment ) Var __attribute__( ( aligned( Alignment ) ) ) + #elif ( defined __ICCARM__ ) || ( defined __ICCRX__ ) + #define PRAGMA( A ) _Pragma(#A) + #define SEGGER_RTT_ALIGN( Var, Alignment ) \ + RTT_PRAGMA( data_alignment = Alignment ) \ + Var + #elif ( defined __CC_ARM__ ) + #define SEGGER_RTT_ALIGN( Var, Alignment ) Var __attribute__( ( aligned( Alignment ) ) ) + #else + #error "Alignment not supported for this compiler." + #endif +#else /* if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT */ + #define SEGGER_RTT_ALIGN( Var, Alignment ) Var +#endif /* if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT */ + +#if defined( SEGGER_RTT_SECTION ) || defined( SEGGER_RTT_BUFFER_SECTION ) + #if ( defined __GNUC__ ) + #define SEGGER_RTT_PUT_SECTION( Var, Section ) __attribute__( ( section( Section ) ) ) Var + #elif ( defined __ICCARM__ ) || ( defined __ICCRX__ ) + #define SEGGER_RTT_PUT_SECTION( Var, Section ) \ + RTT_PRAGMA( location = Section ) \ + Var + #elif ( defined __CC_ARM__ ) + #define SEGGER_RTT_PUT_SECTION( Var, Section ) __attribute__( ( section( Section ), zero_init ) ) Var + #else + #error "Section placement not supported for this compiler." + #endif +#else /* if defined( SEGGER_RTT_SECTION ) || defined( SEGGER_RTT_BUFFER_SECTION ) */ + #define SEGGER_RTT_PUT_SECTION( Var, Section ) Var +#endif /* if defined( SEGGER_RTT_SECTION ) || defined( SEGGER_RTT_BUFFER_SECTION ) */ + + +#if SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_CB_ALIGN( Var ) SEGGER_RTT_ALIGN( Var, SEGGER_RTT_ALIGNMENT ) +#else + #define SEGGER_RTT_CB_ALIGN( Var ) Var +#endif + +#if SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGN( Var ) SEGGER_RTT_ALIGN( Var, SEGGER_RTT_BUFFER_ALIGNMENT ) +#else + #define SEGGER_RTT_BUFFER_ALIGN( Var ) Var +#endif + + +#if defined( SEGGER_RTT_SECTION ) + #define SEGGER_RTT_PUT_CB_SECTION( Var ) SEGGER_RTT_PUT_SECTION( Var, SEGGER_RTT_SECTION ) +#else + #define SEGGER_RTT_PUT_CB_SECTION( Var ) Var +#endif + +#if defined( SEGGER_RTT_BUFFER_SECTION ) + #define SEGGER_RTT_PUT_BUFFER_SECTION( Var ) SEGGER_RTT_PUT_SECTION( Var, SEGGER_RTT_BUFFER_SECTION ) +#else + #define SEGGER_RTT_PUT_BUFFER_SECTION( Var ) Var +#endif + +/********************************************************************* + * + * Static const data + * + ********************************************************************** + */ + +static unsigned char _aTerminalId[ 16 ] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* + * + * Static data + * + ********************************************************************** + */ +/* */ +/* RTT Control Block and allocate buffers for channel 0 */ +/* */ +SEGGER_RTT_PUT_CB_SECTION( SEGGER_RTT_CB_ALIGN( SEGGER_RTT_CB _SEGGER_RTT ) ); + +SEGGER_RTT_PUT_BUFFER_SECTION( SEGGER_RTT_BUFFER_ALIGN( static char _acUpBuffer[ BUFFER_SIZE_UP ] ) ); +SEGGER_RTT_PUT_BUFFER_SECTION( SEGGER_RTT_BUFFER_ALIGN( static char _acDownBuffer[ BUFFER_SIZE_DOWN ] ) ); + +static char _ActiveTerminal; + +/********************************************************************* + * + * Static functions + * + ********************************************************************** + */ + +/********************************************************************* + * + * _DoInit() + * + * Function description + * Initializes the control block an buffers. + * May only be called via INIT() to avoid overriding settings. + * + */ +#define INIT() \ + do { \ + if( _SEGGER_RTT.acID[ 0 ] == '\0' ) { _DoInit(); } \ + } while( 0 ) +static void _DoInit( void ) +{ + SEGGER_RTT_CB * p; + + /* */ + /* Initialize control block */ + /* */ + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + /* */ + /* Initialize up buffer 0 */ + /* */ + p->aUp[ 0 ].sName = "Terminal"; + p->aUp[ 0 ].pBuffer = _acUpBuffer; + p->aUp[ 0 ].SizeOfBuffer = sizeof( _acUpBuffer ); + p->aUp[ 0 ].RdOff = 0u; + p->aUp[ 0 ].WrOff = 0u; + p->aUp[ 0 ].Flags = SEGGER_RTT_MODE_DEFAULT; + /* */ + /* Initialize down buffer 0 */ + /* */ + p->aDown[ 0 ].sName = "Terminal"; + p->aDown[ 0 ].pBuffer = _acDownBuffer; + p->aDown[ 0 ].SizeOfBuffer = sizeof( _acDownBuffer ); + p->aDown[ 0 ].RdOff = 0u; + p->aDown[ 0 ].WrOff = 0u; + p->aDown[ 0 ].Flags = SEGGER_RTT_MODE_DEFAULT; + /* */ + /* Finish initialization of the control block. */ + /* Copy Id string in three steps to make sure "SEGGER RTT" is not found */ + /* in initializer memory (usually flash) by J-Link */ + /* */ + strcpy( &p->acID[ 7 ], "RTT" ); + strcpy( &p->acID[ 0 ], "SEGGER" ); + p->acID[ 6 ] = ' '; +} + +/********************************************************************* + * + * _WriteBlocking() + * + * Function description + * Stores a specified number of characters in SEGGER RTT ring buffer + * and updates the associated write pointer which is periodically + * read by the host. + * The caller is responsible for managing the write chunk sizes as + * _WriteBlocking() will block until all data has been posted successfully. + * + * Parameters + * pRing Ring buffer to post to. + * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. + * NumBytes Number of bytes to be stored in the SEGGER RTT control block. + * + * Return value + * >= 0 - Number of bytes written into buffer. + */ +static unsigned _WriteBlocking( SEGGER_RTT_BUFFER_UP * pRing, + const char * pBuffer, + unsigned NumBytes ) +{ + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; + + /* */ + /* Write data to buffer and handle wrap-around if necessary */ + /* */ + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + + do + { + RdOff = pRing->RdOff; /* May be changed by host (debug probe) in the meantime */ + + if( RdOff > WrOff ) + { + NumBytesToWrite = RdOff - WrOff - 1u; + } + else + { + NumBytesToWrite = pRing->SizeOfBuffer - ( WrOff - RdOff + 1u ); + } + + NumBytesToWrite = MIN( NumBytesToWrite, ( pRing->SizeOfBuffer - WrOff ) ); /* Number of bytes that can be written until buffer wrap-around */ + NumBytesToWrite = MIN( NumBytesToWrite, NumBytes ); + memcpy( pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite ); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + + if( WrOff == pRing->SizeOfBuffer ) + { + WrOff = 0u; + } + + pRing->WrOff = WrOff; + } while( NumBytes ); + + /* */ + return NumBytesWritten; +} + +/********************************************************************* + * + * _WriteNoCheck() + * + * Function description + * Stores a specified number of characters in SEGGER RTT ring buffer + * and updates the associated write pointer which is periodically + * read by the host. + * It is callers responsibility to make sure data actually fits in buffer. + * + * Parameters + * pRing Ring buffer to post to. + * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. + * NumBytes Number of bytes to be stored in the SEGGER RTT control block. + * + * Notes + * (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking + */ +static void _WriteNoCheck( SEGGER_RTT_BUFFER_UP * pRing, + const char * pData, + unsigned NumBytes ) +{ + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + + if( Rem > NumBytes ) + { + /* */ + /* All data fits before wrap around */ + /* */ + memcpy( pRing->pBuffer + WrOff, pData, NumBytes ); + pRing->WrOff = WrOff + NumBytes; + } + else + { + /* */ + /* We reach the end of the buffer, so need to wrap around */ + /* */ + NumBytesAtOnce = Rem; + memcpy( pRing->pBuffer + WrOff, pData, NumBytesAtOnce ); + NumBytesAtOnce = NumBytes - Rem; + memcpy( pRing->pBuffer, pData + Rem, NumBytesAtOnce ); + pRing->WrOff = NumBytesAtOnce; + } +} + +/********************************************************************* + * + * _PostTerminalSwitch() + * + * Function description + * Switch terminal to the given terminal ID. It is the caller's + * responsibility to ensure the terminal ID is correct and there is + * enough space in the buffer for this to complete successfully. + * + * Parameters + * pRing Ring buffer to post to. + * TerminalId Terminal ID to switch to. + */ +static void _PostTerminalSwitch( SEGGER_RTT_BUFFER_UP * pRing, + unsigned char TerminalId ) +{ + char ac[ 2 ]; + + ac[ 0 ] = 0xFFu; + ac[ 1 ] = _aTerminalId[ TerminalId ]; /* Caller made already sure that TerminalId does not exceed our terminal limit */ + _WriteBlocking( pRing, ac, 2u ); +} + +/********************************************************************* + * + * _GetAvailWriteSpace() + * + * Function description + * Returns the number of bytes that can be written to the ring + * buffer without blocking. + * + * Parameters + * pRing Ring buffer to check. + * + * Return value + * Number of bytes that are free in the buffer. + */ +static unsigned _GetAvailWriteSpace( SEGGER_RTT_BUFFER_UP * pRing ) +{ + unsigned RdOff; + unsigned WrOff; + unsigned r; + + /* */ + /* Avoid warnings regarding volatile access order. It's not a problem */ + /* in this case, but dampen compiler enthusiasm. */ + /* */ + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + + if( RdOff <= WrOff ) + { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } + else + { + r = RdOff - WrOff - 1u; + } + + return r; +} + +/********************************************************************* + * + * Public code + * + ********************************************************************** + */ + +/********************************************************************* + * + * SEGGER_RTT_ReadNoLock() + * + * Function description + * Reads characters from SEGGER real-time-terminal control block + * which have been previously stored by the host. + * Do not lock against interrupts and multiple access. + * + * Parameters + * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). + * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. + * BufferSize Size of the target application buffer. + * + * Return value + * Number of bytes that have been read. + */ +unsigned SEGGER_RTT_ReadNoLock( unsigned BufferIndex, + void * pData, + unsigned BufferSize ) +{ + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char * pBuffer; + SEGGER_RTT_BUFFER_DOWN * pRing; + + /* */ + INIT(); + pRing = &_SEGGER_RTT.aDown[ BufferIndex ]; + pBuffer = ( unsigned char * ) pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + + /* */ + /* Read from current read position to wrap-around of buffer, first */ + /* */ + if( RdOff > WrOff ) + { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN( NumBytesRem, BufferSize ); + memcpy( pBuffer, pRing->pBuffer + RdOff, NumBytesRem ); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + + /* */ + /* Handle wrap-around of buffer */ + /* */ + if( RdOff == pRing->SizeOfBuffer ) + { + RdOff = 0u; + } + } + + /* */ + /* Read remaining items of buffer */ + /* */ + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN( NumBytesRem, BufferSize ); + + if( NumBytesRem > 0u ) + { + memcpy( pBuffer, pRing->pBuffer + RdOff, NumBytesRem ); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + } + + if( NumBytesRead ) + { + pRing->RdOff = RdOff; + } + + /* */ + return NumBytesRead; +} + +/********************************************************************* + * + * SEGGER_RTT_Read + * + * Function description + * Reads characters from SEGGER real-time-terminal control block + * which have been previously stored by the host. + * + * Parameters + * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). + * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. + * BufferSize Size of the target application buffer. + * + * Return value + * Number of bytes that have been read. + */ +unsigned SEGGER_RTT_Read( unsigned BufferIndex, + void * pBuffer, + unsigned BufferSize ) +{ + unsigned NumBytesRead; + + /* */ + SEGGER_RTT_LOCK(); + /* */ + /* Call the non-locking read function */ + /* */ + NumBytesRead = SEGGER_RTT_ReadNoLock( BufferIndex, pBuffer, BufferSize ); + /* */ + /* Finish up. */ + /* */ + SEGGER_RTT_UNLOCK(); + /* */ + return NumBytesRead; +} + +/********************************************************************* + * + * SEGGER_RTT_WriteWithOverwriteNoLock + * + * Function description + * Stores a specified number of characters in SEGGER RTT + * control block. + * SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application + * and overwrites data if the data does not fit into the buffer. + * + * Parameters + * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). + * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. + * NumBytes Number of bytes to be stored in the SEGGER RTT control block. + * + * Notes + * (1) If there is not enough space in the "Up"-buffer, data is overwritten. + * (2) For performance reasons this function does not call Init() + * and may only be called after RTT has been initialized. + * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. + * (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link + * connection reads RTT data. + */ +void SEGGER_RTT_WriteWithOverwriteNoLock( unsigned BufferIndex, + const void * pBuffer, + unsigned NumBytes ) +{ + const char * pData; + SEGGER_RTT_BUFFER_UP * pRing; + unsigned Avail; + + pData = ( const char * ) pBuffer; + /* */ + /* Get "to-host" ring buffer and copy some elements into local variables. */ + /* */ + pRing = &_SEGGER_RTT.aUp[ BufferIndex ]; + + /* */ + /* Check if we will overwrite data and need to adjust the RdOff. */ + /* */ + if( pRing->WrOff == pRing->RdOff ) + { + Avail = pRing->SizeOfBuffer - 1u; + } + else if( pRing->WrOff < pRing->RdOff ) + { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } + else + { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + + if( NumBytes > Avail ) + { + pRing->RdOff += ( NumBytes - Avail ); + + while( pRing->RdOff >= pRing->SizeOfBuffer ) + { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + + /* */ + /* Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds */ + /* */ + Avail = pRing->SizeOfBuffer - pRing->WrOff; + + do + { + if( Avail > NumBytes ) + { + /* */ + /* Last round */ + /* */ + #if 1 /* memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. */ + char * pDst; + pDst = pRing->pBuffer + pRing->WrOff; + pRing->WrOff += NumBytes; + + do + { + *pDst++ = *pData++; + } while( --NumBytes ); + #else + memcpy( pRing->pBuffer + WrOff, pData, NumBytes ); + pRing->WrOff += NumBytes; + #endif /* if 1 */ + break; /*Alternatively: NumBytes = 0; */ + } + else + { + /* */ + /* Wrap-around necessary, write until wrap-around and reset WrOff */ + /* */ + memcpy( pRing->pBuffer + pRing->WrOff, pData, Avail ); + pData += Avail; + pRing->WrOff = 0; + NumBytes -= Avail; + Avail = ( pRing->SizeOfBuffer - 1 ); + } + } while( NumBytes ); +} + +/********************************************************************* + * + * SEGGER_RTT_WriteSkipNoLock + * + * Function description + * Stores a specified number of characters in SEGGER RTT + * control block which is then read by the host. + * SEGGER_RTT_WriteSkipNoLock does not lock the application and + * skips all data, if the data does not fit into the buffer. + * + * Parameters + * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). + * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. + * NumBytes Number of bytes to be stored in the SEGGER RTT control block. + * + * Return value + * Number of bytes which have been stored in the "Up"-buffer. + * + * Notes + * (1) If there is not enough space in the "Up"-buffer, all data is dropped. + * (2) For performance reasons this function does not call Init() + * and may only be called after RTT has been initialized. + * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. + */ +unsigned SEGGER_RTT_WriteSkipNoLock( unsigned BufferIndex, + const void * pBuffer, + unsigned NumBytes ) +{ + const char * pData; + SEGGER_RTT_BUFFER_UP * pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; + + pData = ( const char * ) pBuffer; + /* */ + /* Get "to-host" ring buffer and copy some elements into local variables. */ + /* */ + pRing = &_SEGGER_RTT.aUp[ BufferIndex ]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + + /* */ + /* Handle the most common cases fastest. */ + /* Which is: */ + /* RdOff <= WrOff -> Space until wrap around is free. */ + /* AND */ + /* WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. */ + /* */ + /* OR */ + /* */ + /* RdOff > WrOff -> Space until RdOff - 1 is free. */ + /* AND */ + /* WrOff + NumBytes < RdOff -> Data fits into buffer */ + /* */ + if( RdOff <= WrOff ) + { + /* */ + /* Get space until WrOff will be at wrap around. */ + /* */ + Avail = pRing->SizeOfBuffer - 1u - WrOff; + + if( Avail >= NumBytes ) + { + #if 1 /* memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. */ + char * pDst; + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + + do + { + *pDst++ = *pData++; + } while( --NumBytes ); + + pRing->WrOff = WrOff + NumBytes; + #else /* if 1 */ + memcpy( pRing->pBuffer + WrOff, pData, NumBytes ); + pRing->WrOff = WrOff + NumBytes; + #endif /* if 1 */ + return 1; + } + + /* */ + /* If data did not fit into space until wrap around calculate complete space in buffer. */ + /* */ + Avail += RdOff; + + /* */ + /* If there is still no space for the whole of this output, don't bother. */ + /* */ + if( Avail >= NumBytes ) + { + /* */ + /* OK, we have enough space in buffer. Copy in one or 2 chunks */ + /* */ + Rem = pRing->SizeOfBuffer - WrOff; /* Space until end of buffer */ + + if( Rem > NumBytes ) + { + memcpy( pRing->pBuffer + WrOff, pData, NumBytes ); + pRing->WrOff = WrOff + NumBytes; + } + else + { + /* */ + /* We reach the end of the buffer, so need to wrap around */ + /* */ + memcpy( pRing->pBuffer + WrOff, pData, Rem ); + memcpy( pRing->pBuffer, pData + Rem, NumBytes - Rem ); + pRing->WrOff = NumBytes - Rem; + } + + return 1; + } + } + else + { + Avail = RdOff - WrOff - 1u; + + if( Avail >= NumBytes ) + { + memcpy( pRing->pBuffer + WrOff, pData, NumBytes ); + pRing->WrOff = WrOff + NumBytes; + return 1; + } + } + + /* */ + /* If we reach this point no data has been written */ + /* */ + return 0; +} + +/********************************************************************* + * + * SEGGER_RTT_WriteNoLock + * + * Function description + * Stores a specified number of characters in SEGGER RTT + * control block which is then read by the host. + * SEGGER_RTT_WriteNoLock does not lock the application. + * + * Parameters + * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). + * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. + * NumBytes Number of bytes to be stored in the SEGGER RTT control block. + * + * Return value + * Number of bytes which have been stored in the "Up"-buffer. + * + * Notes + * (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. + * (2) For performance reasons this function does not call Init() + * and may only be called after RTT has been initialized. + * Either by calling SEGGER_RTT_Init() or calling another RTT API function first. + */ +unsigned SEGGER_RTT_WriteNoLock( unsigned BufferIndex, + const void * pBuffer, + unsigned NumBytes ) +{ + unsigned Status; + unsigned Avail; + const char * pData; + SEGGER_RTT_BUFFER_UP * pRing; + + pData = ( const char * ) pBuffer; + /* */ + /* Get "to-host" ring buffer. */ + /* */ + pRing = &_SEGGER_RTT.aUp[ BufferIndex ]; + + /* */ + /* How we output depends upon the mode... */ + /* */ + switch( pRing->Flags ) + { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + /* */ + /* If we are in skip mode and there is no space for the whole */ + /* of this output, don't bother. */ + /* */ + Avail = _GetAvailWriteSpace( pRing ); + + if( Avail < NumBytes ) + { + Status = 0u; + } + else + { + Status = NumBytes; + _WriteNoCheck( pRing, pData, NumBytes ); + } + + break; + + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + /* */ + /* If we are in trim mode, trim to what we can output without blocking. */ + /* */ + Avail = _GetAvailWriteSpace( pRing ); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck( pRing, pData, Status ); + break; + + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + /* */ + /* If we are in blocking mode, output everything. */ + /* */ + Status = _WriteBlocking( pRing, pData, NumBytes ); + break; + + default: + Status = 0u; + break; + } + + /* */ + /* Finish up. */ + /* */ + return Status; +} + +/********************************************************************* + * + * SEGGER_RTT_Write + * + * Function description + * Stores a specified number of characters in SEGGER RTT + * control block which is then read by the host. + * + * Parameters + * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). + * pBuffer Pointer to character array. Does not need to point to a \0 terminated string. + * NumBytes Number of bytes to be stored in the SEGGER RTT control block. + * + * Return value + * Number of bytes which have been stored in the "Up"-buffer. + * + * Notes + * (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. + */ +unsigned SEGGER_RTT_Write( unsigned BufferIndex, + const void * pBuffer, + unsigned NumBytes ) +{ + unsigned Status; + + /* */ + INIT(); + SEGGER_RTT_LOCK(); + /* */ + /* Call the non-locking write function */ + /* */ + Status = SEGGER_RTT_WriteNoLock( BufferIndex, pBuffer, NumBytes ); + /* */ + /* Finish up. */ + /* */ + SEGGER_RTT_UNLOCK(); + /* */ + return Status; +} + +/********************************************************************* + * + * SEGGER_RTT_WriteString + * + * Function description + * Stores string in SEGGER RTT control block. + * This data is read by the host. + * + * Parameters + * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). + * s Pointer to string. + * + * Return value + * Number of bytes which have been stored in the "Up"-buffer. + * + * Notes + * (1) If there is not enough space in the "Up"-buffer, depending on configuration, + * remaining characters may be dropped or RTT module waits until there is more space in the buffer. + * (2) String passed to this function has to be \0 terminated + * (3) \0 termination character is *not* stored in RTT buffer + */ +unsigned SEGGER_RTT_WriteString( unsigned BufferIndex, + const char * s ) +{ + unsigned Len; + + Len = STRLEN( s ); + return SEGGER_RTT_Write( BufferIndex, s, Len ); +} + +/********************************************************************* + * + * SEGGER_RTT_GetKey + * + * Function description + * Reads one character from the SEGGER RTT buffer. + * Host has previously stored data there. + * + * Return value + * < 0 - No character available (buffer empty). + * >= 0 - Character which has been read. (Possible values: 0 - 255) + * + * Notes + * (1) This function is only specified for accesses to RTT buffer 0. + */ +int SEGGER_RTT_GetKey( void ) +{ + char c; + int r; + + r = ( int ) SEGGER_RTT_Read( 0u, &c, 1u ); + + if( r == 1 ) + { + r = ( int ) ( unsigned char ) c; + } + else + { + r = -1; + } + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_WaitKey + * + * Function description + * Waits until at least one character is available in the SEGGER RTT buffer. + * Once a character is available, it is read and this function returns. + * + * Return value + * >=0 - Character which has been read. + * + * Notes + * (1) This function is only specified for accesses to RTT buffer 0 + * (2) This function is blocking if no character is present in RTT buffer + */ +int SEGGER_RTT_WaitKey( void ) +{ + int r; + + do + { + r = SEGGER_RTT_GetKey(); + } while( r < 0 ); + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_HasKey + * + * Function description + * Checks if at least one character for reading is available in the SEGGER RTT buffer. + * + * Return value + * == 0 - No characters are available to read. + * == 1 - At least one character is available. + * + * Notes + * (1) This function is only specified for accesses to RTT buffer 0 + */ +int SEGGER_RTT_HasKey( void ) +{ + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[ 0 ].RdOff; + + if( RdOff != _SEGGER_RTT.aDown[ 0 ].WrOff ) + { + r = 1; + } + else + { + r = 0; + } + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_HasData + * + * Function description + * Check if there is data from the host in the given buffer. + * + * Return value: + * ==0: No data + * !=0: Data in buffer + * + */ +unsigned SEGGER_RTT_HasData( unsigned BufferIndex ) +{ + SEGGER_RTT_BUFFER_DOWN * pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[ BufferIndex ]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* + * + * SEGGER_RTT_AllocDownBuffer + * + * Function description + * Run-time configuration of the next down-buffer (H->T). + * The next buffer, which is not used yet is configured. + * This includes: Buffer address, size, name, flags, ... + * + * Parameters + * sName Pointer to a constant name string. + * pBuffer Pointer to a buffer to be used. + * BufferSize Size of the buffer. + * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). + * + * Return value + * >= 0 - O.K. Buffer Index + * < 0 - Error + */ +int SEGGER_RTT_AllocDownBuffer( const char * sName, + void * pBuffer, + unsigned BufferSize, + unsigned Flags ) +{ + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + + do + { + if( _SEGGER_RTT.aDown[ BufferIndex ].pBuffer == NULL ) + { + break; + } + + BufferIndex++; + } while( BufferIndex < _SEGGER_RTT.MaxNumDownBuffers ); + + if( BufferIndex < _SEGGER_RTT.MaxNumDownBuffers ) + { + _SEGGER_RTT.aDown[ BufferIndex ].sName = sName; + _SEGGER_RTT.aDown[ BufferIndex ].pBuffer = ( char * ) pBuffer; + _SEGGER_RTT.aDown[ BufferIndex ].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[ BufferIndex ].RdOff = 0u; + _SEGGER_RTT.aDown[ BufferIndex ].WrOff = 0u; + _SEGGER_RTT.aDown[ BufferIndex ].Flags = Flags; + } + else + { + BufferIndex = -1; + } + + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* + * + * SEGGER_RTT_AllocUpBuffer + * + * Function description + * Run-time configuration of the next up-buffer (T->H). + * The next buffer, which is not used yet is configured. + * This includes: Buffer address, size, name, flags, ... + * + * Parameters + * sName Pointer to a constant name string. + * pBuffer Pointer to a buffer to be used. + * BufferSize Size of the buffer. + * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). + * + * Return value + * >= 0 - O.K. Buffer Index + * < 0 - Error + */ +int SEGGER_RTT_AllocUpBuffer( const char * sName, + void * pBuffer, + unsigned BufferSize, + unsigned Flags ) +{ + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + + do + { + if( _SEGGER_RTT.aUp[ BufferIndex ].pBuffer == NULL ) + { + break; + } + + BufferIndex++; + } while( BufferIndex < _SEGGER_RTT.MaxNumUpBuffers ); + + if( BufferIndex < _SEGGER_RTT.MaxNumUpBuffers ) + { + _SEGGER_RTT.aUp[ BufferIndex ].sName = sName; + _SEGGER_RTT.aUp[ BufferIndex ].pBuffer = ( char * ) pBuffer; + _SEGGER_RTT.aUp[ BufferIndex ].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[ BufferIndex ].RdOff = 0u; + _SEGGER_RTT.aUp[ BufferIndex ].WrOff = 0u; + _SEGGER_RTT.aUp[ BufferIndex ].Flags = Flags; + } + else + { + BufferIndex = -1; + } + + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* + * + * SEGGER_RTT_ConfigUpBuffer + * + * Function description + * Run-time configuration of a specific up-buffer (T->H). + * Buffer to be configured is specified by index. + * This includes: Buffer address, size, name, flags, ... + * + * Parameters + * BufferIndex Index of the buffer to configure. + * sName Pointer to a constant name string. + * pBuffer Pointer to a buffer to be used. + * BufferSize Size of the buffer. + * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). + * + * Return value + * >= 0 - O.K. + * < 0 - Error + * + * Additional information + * Buffer 0 is configured on compile-time. + * May only be called once per buffer. + * Buffer name and flags can be reconfigured using the appropriate functions. + */ +int SEGGER_RTT_ConfigUpBuffer( unsigned BufferIndex, + const char * sName, + void * pBuffer, + unsigned BufferSize, + unsigned Flags ) +{ + int r; + + INIT(); + + if( BufferIndex < ( unsigned ) _SEGGER_RTT.MaxNumUpBuffers ) + { + SEGGER_RTT_LOCK(); + + if( BufferIndex > 0u ) + { + _SEGGER_RTT.aUp[ BufferIndex ].sName = sName; + _SEGGER_RTT.aUp[ BufferIndex ].pBuffer = ( char * ) pBuffer; + _SEGGER_RTT.aUp[ BufferIndex ].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[ BufferIndex ].RdOff = 0u; + _SEGGER_RTT.aUp[ BufferIndex ].WrOff = 0u; + } + + _SEGGER_RTT.aUp[ BufferIndex ].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } + else + { + r = -1; + } + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_ConfigDownBuffer + * + * Function description + * Run-time configuration of a specific down-buffer (H->T). + * Buffer to be configured is specified by index. + * This includes: Buffer address, size, name, flags, ... + * + * Parameters + * BufferIndex Index of the buffer to configure. + * sName Pointer to a constant name string. + * pBuffer Pointer to a buffer to be used. + * BufferSize Size of the buffer. + * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). + * + * Return value + * >= 0 O.K. + * < 0 Error + * + * Additional information + * Buffer 0 is configured on compile-time. + * May only be called once per buffer. + * Buffer name and flags can be reconfigured using the appropriate functions. + */ +int SEGGER_RTT_ConfigDownBuffer( unsigned BufferIndex, + const char * sName, + void * pBuffer, + unsigned BufferSize, + unsigned Flags ) +{ + int r; + + INIT(); + + if( BufferIndex < ( unsigned ) _SEGGER_RTT.MaxNumDownBuffers ) + { + SEGGER_RTT_LOCK(); + + if( BufferIndex > 0u ) + { + _SEGGER_RTT.aDown[ BufferIndex ].sName = sName; + _SEGGER_RTT.aDown[ BufferIndex ].pBuffer = ( char * ) pBuffer; + _SEGGER_RTT.aDown[ BufferIndex ].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[ BufferIndex ].RdOff = 0u; + _SEGGER_RTT.aDown[ BufferIndex ].WrOff = 0u; + } + + _SEGGER_RTT.aDown[ BufferIndex ].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } + else + { + r = -1; + } + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_SetNameUpBuffer + * + * Function description + * Run-time configuration of a specific up-buffer name (T->H). + * Buffer to be configured is specified by index. + * + * Parameters + * BufferIndex Index of the buffer to renamed. + * sName Pointer to a constant name string. + * + * Return value + * >= 0 O.K. + * < 0 Error + */ +int SEGGER_RTT_SetNameUpBuffer( unsigned BufferIndex, + const char * sName ) +{ + int r; + + INIT(); + + if( BufferIndex < ( unsigned ) _SEGGER_RTT.MaxNumUpBuffers ) + { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[ BufferIndex ].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } + else + { + r = -1; + } + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_SetNameDownBuffer + * + * Function description + * Run-time configuration of a specific Down-buffer name (T->H). + * Buffer to be configured is specified by index. + * + * Parameters + * BufferIndex Index of the buffer to renamed. + * sName Pointer to a constant name string. + * + * Return value + * >= 0 O.K. + * < 0 Error + */ +int SEGGER_RTT_SetNameDownBuffer( unsigned BufferIndex, + const char * sName ) +{ + int r; + + INIT(); + + if( BufferIndex < ( unsigned ) _SEGGER_RTT.MaxNumDownBuffers ) + { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[ BufferIndex ].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } + else + { + r = -1; + } + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_SetFlagsUpBuffer + * + * Function description + * Run-time configuration of specific up-buffer flags (T->H). + * Buffer to be configured is specified by index. + * + * Parameters + * BufferIndex Index of the buffer. + * Flags Flags to set for the buffer. + * + * Return value + * >= 0 O.K. + * < 0 Error + */ +int SEGGER_RTT_SetFlagsUpBuffer( unsigned BufferIndex, + unsigned Flags ) +{ + int r; + + INIT(); + + if( BufferIndex < ( unsigned ) _SEGGER_RTT.MaxNumUpBuffers ) + { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[ BufferIndex ].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } + else + { + r = -1; + } + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_SetFlagsDownBuffer + * + * Function description + * Run-time configuration of specific Down-buffer flags (T->H). + * Buffer to be configured is specified by index. + * + * Parameters + * BufferIndex Index of the buffer to renamed. + * Flags Flags to set for the buffer. + * + * Return value + * >= 0 O.K. + * < 0 Error + */ +int SEGGER_RTT_SetFlagsDownBuffer( unsigned BufferIndex, + unsigned Flags ) +{ + int r; + + INIT(); + + if( BufferIndex < ( unsigned ) _SEGGER_RTT.MaxNumDownBuffers ) + { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[ BufferIndex ].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } + else + { + r = -1; + } + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_Init + * + * Function description + * Initializes the RTT Control Block. + * Should be used in RAM targets, at start of the application. + * + */ +void SEGGER_RTT_Init( void ) +{ + _DoInit(); +} + +/********************************************************************* + * + * SEGGER_RTT_SetTerminal + * + * Function description + * Sets the terminal to be used for output on channel 0. + * + * Parameters + * TerminalId Index of the terminal. + * + * Return value + * >= 0 O.K. + * < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) + */ +int SEGGER_RTT_SetTerminal( char TerminalId ) +{ + char ac[ 2 ]; + SEGGER_RTT_BUFFER_UP * pRing; + unsigned Avail; + int r; + + /* */ + INIT(); + /* */ + r = 0; + ac[ 0 ] = 0xFFU; + + if( ( unsigned char ) TerminalId < ( unsigned char ) sizeof( _aTerminalId ) ) /* We only support a certain number of channels */ + { + ac[ 1 ] = _aTerminalId[ ( unsigned char ) TerminalId ]; + pRing = &_SEGGER_RTT.aUp[ 0 ]; /* Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed */ + SEGGER_RTT_LOCK(); /* Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing */ + + if( ( pRing->Flags & SEGGER_RTT_MODE_MASK ) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ) + { + _ActiveTerminal = TerminalId; + _WriteBlocking( pRing, ac, 2u ); + } + else /* Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes */ + { + Avail = _GetAvailWriteSpace( pRing ); + + if( Avail >= 2 ) + { + _ActiveTerminal = TerminalId; /* Only change active terminal in case of success */ + _WriteNoCheck( pRing, ac, 2u ); + } + else + { + r = -1; + } + } + + SEGGER_RTT_UNLOCK(); + } + else + { + r = -1; + } + + return r; +} + +/********************************************************************* + * + * SEGGER_RTT_TerminalOut + * + * Function description + * Writes a string to the given terminal + * without changing the terminal for channel 0. + * + * Parameters + * TerminalId Index of the terminal. + * s String to be printed on the terminal. + * + * Return value + * >= 0 - Number of bytes written. + * < 0 - Error. + * + */ +int SEGGER_RTT_TerminalOut( char TerminalId, + const char * s ) +{ + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP * pRing; + + /* */ + INIT(); + + /* */ + /* Validate terminal ID. */ + /* */ + if( TerminalId < ( char ) sizeof( _aTerminalId ) ) /* We only support a certain number of channels */ + { /* */ + /* Get "to-host" ring buffer. */ + /* */ + pRing = &_SEGGER_RTT.aUp[ 0 ]; + /* */ + /* Need to be able to change terminal, write data, change back. */ + /* Compute the fixed and variable sizes. */ + /* */ + FragLen = strlen( s ); + /* */ + /* How we output depends upon the mode... */ + /* */ + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace( pRing ); + + switch( pRing->Flags & SEGGER_RTT_MODE_MASK ) + { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + + /* */ + /* If we are in skip mode and there is no space for the whole */ + /* of this output, don't bother switching terminals at all. */ + /* */ + if( Avail < ( FragLen + 4u ) ) + { + Status = 0; + } + else + { + _PostTerminalSwitch( pRing, TerminalId ); + Status = ( int ) _WriteBlocking( pRing, s, FragLen ); + _PostTerminalSwitch( pRing, _ActiveTerminal ); + } + + break; + + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + + /* */ + /* If we are in trim mode and there is not enough space for everything, */ + /* trim the output but always include the terminal switch. If no room */ + /* for terminal switch, skip that totally. */ + /* */ + if( Avail < 4u ) + { + Status = -1; + } + else + { + _PostTerminalSwitch( pRing, TerminalId ); + Status = ( int ) _WriteBlocking( pRing, s, ( FragLen < ( Avail - 4u ) ) ? FragLen : ( Avail - 4u ) ); + _PostTerminalSwitch( pRing, _ActiveTerminal ); + } + + break; + + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + /* */ + /* If we are in blocking mode, output everything. */ + /* */ + _PostTerminalSwitch( pRing, TerminalId ); + Status = ( int ) _WriteBlocking( pRing, s, FragLen ); + _PostTerminalSwitch( pRing, _ActiveTerminal ); + break; + + default: + Status = -1; + break; + } + + /* */ + /* Finish up. */ + /* */ + SEGGER_RTT_UNLOCK(); + } + else + { + Status = -1; + } + + return Status; +} + + +/*************************** End of file ****************************/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/config/trcStreamPortConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/config/trcStreamPortConfig.h index 29c7b9156..0086a8105 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/config/trcStreamPortConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/config/trcStreamPortConfig.h @@ -1,123 +1,123 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The configuration for trace streaming ("stream ports"). - */ - -#ifndef TRC_STREAM_PORT_CONFIG_H -#define TRC_STREAM_PORT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* This define will determine whether to use the internal buffer or not. -If file writing creates additional trace events (i.e. it uses semaphores or mutexes), -then the internal buffer must be enabled to avoid infinite recursion. */ -#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0 - -/** -* @def TRC_CFG_INTERNAL_BUFFER_SIZE -* -* @brief Configures the size of the internal buffer if used. -* is enabled. -*/ -#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 5000 - -/** -* @def TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE -* -* @brief Defines the size of the "up" RTT buffer (target -> host) to use for writing -* the trace data, for RTT buffer 1 or higher. -* -* This setting is ignored for RTT buffer 0, which can't be reconfigured -* in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h. -* -* Default buffer size for Tracealyzer is 5000 bytes. -* -* If you have a stand-alone J-Link probe, the can be decreased to around 1 KB. -* But integrated J-Link OB interfaces are slower and needs about 5-10 KB, -* depending on the amount of data produced. -*/ -#define TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE 5000 - -/** -* @def TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE -* -* @brief Defines the size of the "down" RTT buffer (host -> target) to use for reading -* commands from Tracealyzer, for RTT buffer 1 or higher. -* -* Default buffer size for Tracealyzer is 32 bytes. -* -* This setting is ignored for RTT buffer 0, which can't be reconfigured -* in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h. -*/ -#define TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE 32 - -/** -* @def TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX -* -* @brief Defines the RTT buffer to use for writing the trace data. Make sure that -* the PC application has the same setting (File->Settings). -* -* Default: 1 -* -* We don't recommend using RTT buffer 0, since mainly intended for terminals. -* If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h. -*/ -#define TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX 1 - -/** -* @def TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX -* -* @brief Defines the RTT buffer to use for reading the trace data. Make sure that -* the PC application has the same setting (File->Settings). -* -* Default: 1 -* -* We don't recommend using RTT buffer 0, since mainly intended for terminals. -* If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h. -*/ -#define TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX 1 - -/** -* @def TRC_CFG_STREAM_PORT_RTT_MODE -* -* @brief This stream port for J-Link streaming relies on SEGGER RTT, that contains an -* internal RAM buffer read by the J-Link probes during execution. -* -* Possible values: -* - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL -* - SEGGER_RTT_MODE_NO_BLOCK_SKIP (default) -* -* Using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ensure that you get a -* complete and valid trace. This may however cause blocking if your streaming -* interface isn't fast enough, which may disturb the real-time behavior. -* -* We therefore recommend SEGGER_RTT_MODE_NO_BLOCK_SKIP. In this mode, -* Tracealyzer will report lost events if the transfer is not -* fast enough. In that case, try increasing the size of the "up buffer". -*/ -#define TRC_CFG_STREAM_PORT_RTT_MODE SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL - -/** - * @def TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE - * - * @brief Sets if RTT should write without locking or not when writing - * RTT data. This should normally be disabled with an exception being - * Zephyr, where the SEGGER RTT locks aren't necessary and causes - * problems if enabled. - * - * Default: 0 - */ -#define TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE 0 - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The configuration for trace streaming ("stream ports"). + */ + +#ifndef TRC_STREAM_PORT_CONFIG_H + #define TRC_STREAM_PORT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/* This define will determine whether to use the internal buffer or not. + * If file writing creates additional trace events (i.e. it uses semaphores or mutexes), + * then the internal buffer must be enabled to avoid infinite recursion. */ + #define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0 + +/** + * @def TRC_CFG_INTERNAL_BUFFER_SIZE + * + * @brief Configures the size of the internal buffer if used. + * is enabled. + */ + #define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 5000 + +/** + * @def TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE + * + * @brief Defines the size of the "up" RTT buffer (target -> host) to use for writing + * the trace data, for RTT buffer 1 or higher. + * + * This setting is ignored for RTT buffer 0, which can't be reconfigured + * in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h. + * + * Default buffer size for Tracealyzer is 5000 bytes. + * + * If you have a stand-alone J-Link probe, the can be decreased to around 1 KB. + * But integrated J-Link OB interfaces are slower and needs about 5-10 KB, + * depending on the amount of data produced. + */ + #define TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE 5000 + +/** + * @def TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE + * + * @brief Defines the size of the "down" RTT buffer (host -> target) to use for reading + * commands from Tracealyzer, for RTT buffer 1 or higher. + * + * Default buffer size for Tracealyzer is 32 bytes. + * + * This setting is ignored for RTT buffer 0, which can't be reconfigured + * in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h. + */ + #define TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE 32 + +/** + * @def TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX + * + * @brief Defines the RTT buffer to use for writing the trace data. Make sure that + * the PC application has the same setting (File->Settings). + * + * Default: 1 + * + * We don't recommend using RTT buffer 0, since mainly intended for terminals. + * If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h. + */ + #define TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX 1 + +/** + * @def TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX + * + * @brief Defines the RTT buffer to use for reading the trace data. Make sure that + * the PC application has the same setting (File->Settings). + * + * Default: 1 + * + * We don't recommend using RTT buffer 0, since mainly intended for terminals. + * If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h. + */ + #define TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX 1 + +/** + * @def TRC_CFG_STREAM_PORT_RTT_MODE + * + * @brief This stream port for J-Link streaming relies on SEGGER RTT, that contains an + * internal RAM buffer read by the J-Link probes during execution. + * + * Possible values: + * - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL + * - SEGGER_RTT_MODE_NO_BLOCK_SKIP (default) + * + * Using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ensure that you get a + * complete and valid trace. This may however cause blocking if your streaming + * interface isn't fast enough, which may disturb the real-time behavior. + * + * We therefore recommend SEGGER_RTT_MODE_NO_BLOCK_SKIP. In this mode, + * Tracealyzer will report lost events if the transfer is not + * fast enough. In that case, try increasing the size of the "up buffer". + */ + #define TRC_CFG_STREAM_PORT_RTT_MODE SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL + +/** + * @def TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE + * + * @brief Sets if RTT should write without locking or not when writing + * RTT data. This should normally be disabled with an exception being + * Zephyr, where the SEGGER RTT locks aren't necessary and causes + * problems if enabled. + * + * Default: 0 + */ + #define TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE 0 + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT.h index cdd6270d5..a4efc0c25 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT.h @@ -1,238 +1,275 @@ /********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* SEGGER RTT * Real Time Transfer for embedded targets * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source, linkable, or executable form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source, executable, or * -* linkable form may not be distributed without prior consent of * -* SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** -* * -* RTT version: 6.00e * -* * -********************************************************************** ----------------------------END-OF-HEADER------------------------------ -File : SEGGER_RTT.h -Purpose : Implementation of SEGGER real-time transfer which allows - real-time communication on targets which support debugger - memory accesses while the CPU is running. -Revision: $Rev: 4079 $ ----------------------------------------------------------------------- -*/ + * SEGGER MICROCONTROLLER GmbH & Co. KG * + * Solutions for real time microcontroller applications * + ********************************************************************** + * * + * (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * + * * + * www.segger.com Support: support@segger.com * + * * + ********************************************************************** + * * + * SEGGER RTT * Real Time Transfer for embedded targets * + * * + ********************************************************************** + * * + * All rights reserved. * + * * + * * This software may in its unmodified form be freely redistributed * + * in source, linkable, or executable form. * + * * The source code may be modified, provided the source code * + * retains the above copyright notice, this list of conditions and * + * the following disclaimer. * + * * Modified versions of this software in source, executable, or * + * linkable form may not be distributed without prior consent of * + * SEGGER. * + * * This software may only be used for communication with SEGGER * + * J-Link debug probes. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * + * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * + * DAMAGE. * + * * + ********************************************************************** + * * + * RTT version: 6.00e * + * * + ********************************************************************** + * ---------------------------END-OF-HEADER------------------------------ + * File : SEGGER_RTT.h + * Purpose : Implementation of SEGGER real-time transfer which allows + * real-time communication on targets which support debugger + * memory accesses while the CPU is running. + * Revision: $Rev: 4079 $ + * ---------------------------------------------------------------------- + */ #ifndef SEGGER_RTT_H -#define SEGGER_RTT_H + #define SEGGER_RTT_H -#include "SEGGER_RTT_Conf.h" + #include "SEGGER_RTT_Conf.h" /********************************************************************* -* -* Defines, fixed -* -********************************************************************** -*/ + * + * Defines, fixed + * + ********************************************************************** + */ /********************************************************************* -* -* Types -* -********************************************************************** -*/ + * + * Types + * + ********************************************************************** + */ -// -// Description for a circular buffer (also called "ring buffer") -// which is used as up-buffer (T->H) -// -typedef struct { - const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" - char* pBuffer; // Pointer to start of buffer - unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. - unsigned WrOff; // Position of next item to be written by either target. - volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. - unsigned Flags; // Contains configuration flags -} SEGGER_RTT_BUFFER_UP; +/* */ +/* Description for a circular buffer (also called "ring buffer") */ +/* which is used as up-buffer (T->H) */ +/* */ + typedef struct + { + const char * sName; /* Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" */ + char * pBuffer; /* Pointer to start of buffer */ + unsigned SizeOfBuffer; /* Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. */ + unsigned WrOff; /* Position of next item to be written by either target. */ + volatile unsigned RdOff; /* Position of next item to be read by host. Must be volatile since it may be modified by host. */ + unsigned Flags; /* Contains configuration flags */ + } SEGGER_RTT_BUFFER_UP; -// -// Description for a circular buffer (also called "ring buffer") -// which is used as down-buffer (H->T) -// -typedef struct { - const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" - char* pBuffer; // Pointer to start of buffer - unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. - volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. - unsigned RdOff; // Position of next item to be read by target (down-buffer). - unsigned Flags; // Contains configuration flags -} SEGGER_RTT_BUFFER_DOWN; +/* */ +/* Description for a circular buffer (also called "ring buffer") */ +/* which is used as down-buffer (H->T) */ +/* */ + typedef struct + { + const char * sName; /* Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" */ + char * pBuffer; /* Pointer to start of buffer */ + unsigned SizeOfBuffer; /* Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. */ + volatile unsigned WrOff; /* Position of next item to be written by host. Must be volatile since it may be modified by host. */ + unsigned RdOff; /* Position of next item to be read by target (down-buffer). */ + unsigned Flags; /* Contains configuration flags */ + } SEGGER_RTT_BUFFER_DOWN; -// -// RTT control block which describes the number of buffers available -// as well as the configuration for each buffer -// -// -typedef struct { - char acID[16]; // Initialized to "SEGGER RTT" - int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) - int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) - SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host - SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target -} SEGGER_RTT_CB; +/* */ +/* RTT control block which describes the number of buffers available */ +/* as well as the configuration for each buffer */ +/* */ +/* */ + typedef struct + { + char acID[ 16 ]; /* Initialized to "SEGGER RTT" */ + int MaxNumUpBuffers; /* Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) */ + int MaxNumDownBuffers; /* Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) */ + SEGGER_RTT_BUFFER_UP aUp[ SEGGER_RTT_MAX_NUM_UP_BUFFERS ]; /* Up buffers, transferring information up from target via debug probe to host */ + SEGGER_RTT_BUFFER_DOWN aDown[ SEGGER_RTT_MAX_NUM_DOWN_BUFFERS ]; /* Down buffers, transferring information down from host via debug probe to target */ + } SEGGER_RTT_CB; /********************************************************************* -* -* Global data -* -********************************************************************** -*/ -extern SEGGER_RTT_CB _SEGGER_RTT; + * + * Global data + * + ********************************************************************** + */ + extern SEGGER_RTT_CB _SEGGER_RTT; /********************************************************************* -* -* RTT API functions -* -********************************************************************** -*/ -#ifdef __cplusplus - extern "C" { -#endif -int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_GetKey (void); -unsigned SEGGER_RTT_HasData (unsigned BufferIndex); -int SEGGER_RTT_HasKey (void); -void SEGGER_RTT_Init (void); -unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); -unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); -int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName); -int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); -int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags); -int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags); -int SEGGER_RTT_WaitKey (void); -unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); -void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -// -// Function macro for performance optimization -// -#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + * + * RTT API functions + * + ********************************************************************** + */ + #ifdef __cplusplus + extern "C" { + #endif + int SEGGER_RTT_AllocDownBuffer( const char * sName, + void * pBuffer, + unsigned BufferSize, + unsigned Flags ); + int SEGGER_RTT_AllocUpBuffer( const char * sName, + void * pBuffer, + unsigned BufferSize, + unsigned Flags ); + int SEGGER_RTT_ConfigUpBuffer( unsigned BufferIndex, + const char * sName, + void * pBuffer, + unsigned BufferSize, + unsigned Flags ); + int SEGGER_RTT_ConfigDownBuffer( unsigned BufferIndex, + const char * sName, + void * pBuffer, + unsigned BufferSize, + unsigned Flags ); + int SEGGER_RTT_GetKey( void ); + unsigned SEGGER_RTT_HasData( unsigned BufferIndex ); + int SEGGER_RTT_HasKey( void ); + void SEGGER_RTT_Init( void ); + unsigned SEGGER_RTT_Read( unsigned BufferIndex, + void * pBuffer, + unsigned BufferSize ); + unsigned SEGGER_RTT_ReadNoLock( unsigned BufferIndex, + void * pData, + unsigned BufferSize ); + int SEGGER_RTT_SetNameDownBuffer( unsigned BufferIndex, + const char * sName ); + int SEGGER_RTT_SetNameUpBuffer( unsigned BufferIndex, + const char * sName ); + int SEGGER_RTT_SetFlagsDownBuffer( unsigned BufferIndex, + unsigned Flags ); + int SEGGER_RTT_SetFlagsUpBuffer( unsigned BufferIndex, + unsigned Flags ); + int SEGGER_RTT_WaitKey( void ); + unsigned SEGGER_RTT_Write( unsigned BufferIndex, + const void * pBuffer, + unsigned NumBytes ); + unsigned SEGGER_RTT_WriteNoLock( unsigned BufferIndex, + const void * pBuffer, + unsigned NumBytes ); + unsigned SEGGER_RTT_WriteSkipNoLock( unsigned BufferIndex, + const void * pBuffer, + unsigned NumBytes ); + unsigned SEGGER_RTT_WriteString( unsigned BufferIndex, + const char * s ); + void SEGGER_RTT_WriteWithOverwriteNoLock( unsigned BufferIndex, + const void * pBuffer, + unsigned NumBytes ); +/* */ +/* Function macro for performance optimization */ +/* */ + #define SEGGER_RTT_HASDATA( n ) ( _SEGGER_RTT.aDown[ n ].WrOff - _SEGGER_RTT.aDown[ n ].RdOff ) /********************************************************************* -* -* RTT "Terminal" API functions -* -********************************************************************** -*/ -int SEGGER_RTT_SetTerminal (char TerminalId); -int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); + * + * RTT "Terminal" API functions + * + ********************************************************************** + */ + int SEGGER_RTT_SetTerminal( char TerminalId ); + int SEGGER_RTT_TerminalOut( char TerminalId, + const char * s ); /********************************************************************* -* -* RTT printf functions (require SEGGER_RTT_printf.c) -* -********************************************************************** -*/ -int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); -#ifdef __cplusplus - } -#endif + * + * RTT printf functions (require SEGGER_RTT_printf.c) + * + ********************************************************************** + */ + int SEGGER_RTT_printf( unsigned BufferIndex, + const char * sFormat, + ... ); + #ifdef __cplusplus +} + #endif /********************************************************************* -* -* Defines -* -********************************************************************** -*/ + * + * Defines + * + ********************************************************************** + */ -// -// Operating modes. Define behavior if buffer is full (not enough space for entire message) -// -#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) -#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. -#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. -#define SEGGER_RTT_MODE_MASK (3U) +/* */ +/* Operating modes. Define behavior if buffer is full (not enough space for entire message) */ +/* */ + #define SEGGER_RTT_MODE_NO_BLOCK_SKIP ( 0U ) /* Skip. Do not block, output nothing. (Default) */ + #define SEGGER_RTT_MODE_NO_BLOCK_TRIM ( 1U ) /* Trim: Do not block, output as much as fits. */ + #define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ( 2U ) /* Block: Wait until there is space in the buffer. */ + #define SEGGER_RTT_MODE_MASK ( 3U ) -// -// Control sequences, based on ANSI. -// Can be used to control color, and clear the screen -// -#define RTT_CTRL_RESET "" // Reset to default colors -#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left +/* */ +/* Control sequences, based on ANSI. */ +/* Can be used to control color, and clear the screen */ +/* */ + #define RTT_CTRL_RESET "" /* Reset to default colors */ + #define RTT_CTRL_CLEAR "" /* Clear screen, reposition cursor to top left */ -#define RTT_CTRL_TEXT_BLACK "" -#define RTT_CTRL_TEXT_RED "" -#define RTT_CTRL_TEXT_GREEN "" -#define RTT_CTRL_TEXT_YELLOW "" -#define RTT_CTRL_TEXT_BLUE "" -#define RTT_CTRL_TEXT_MAGENTA "" -#define RTT_CTRL_TEXT_CYAN "" -#define RTT_CTRL_TEXT_WHITE "" + #define RTT_CTRL_TEXT_BLACK "" + #define RTT_CTRL_TEXT_RED "" + #define RTT_CTRL_TEXT_GREEN "" + #define RTT_CTRL_TEXT_YELLOW "" + #define RTT_CTRL_TEXT_BLUE "" + #define RTT_CTRL_TEXT_MAGENTA "" + #define RTT_CTRL_TEXT_CYAN "" + #define RTT_CTRL_TEXT_WHITE "" -#define RTT_CTRL_TEXT_BRIGHT_BLACK "" -#define RTT_CTRL_TEXT_BRIGHT_RED "" -#define RTT_CTRL_TEXT_BRIGHT_GREEN "" -#define RTT_CTRL_TEXT_BRIGHT_YELLOW "" -#define RTT_CTRL_TEXT_BRIGHT_BLUE "" -#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" -#define RTT_CTRL_TEXT_BRIGHT_CYAN "" -#define RTT_CTRL_TEXT_BRIGHT_WHITE "" + #define RTT_CTRL_TEXT_BRIGHT_BLACK "" + #define RTT_CTRL_TEXT_BRIGHT_RED "" + #define RTT_CTRL_TEXT_BRIGHT_GREEN "" + #define RTT_CTRL_TEXT_BRIGHT_YELLOW "" + #define RTT_CTRL_TEXT_BRIGHT_BLUE "" + #define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" + #define RTT_CTRL_TEXT_BRIGHT_CYAN "" + #define RTT_CTRL_TEXT_BRIGHT_WHITE "" -#define RTT_CTRL_BG_BLACK "" -#define RTT_CTRL_BG_RED "" -#define RTT_CTRL_BG_GREEN "" -#define RTT_CTRL_BG_YELLOW "" -#define RTT_CTRL_BG_BLUE "" -#define RTT_CTRL_BG_MAGENTA "" -#define RTT_CTRL_BG_CYAN "" -#define RTT_CTRL_BG_WHITE "" + #define RTT_CTRL_BG_BLACK "" + #define RTT_CTRL_BG_RED "" + #define RTT_CTRL_BG_GREEN "" + #define RTT_CTRL_BG_YELLOW "" + #define RTT_CTRL_BG_BLUE "" + #define RTT_CTRL_BG_MAGENTA "" + #define RTT_CTRL_BG_CYAN "" + #define RTT_CTRL_BG_WHITE "" -#define RTT_CTRL_BG_BRIGHT_BLACK "" -#define RTT_CTRL_BG_BRIGHT_RED "" -#define RTT_CTRL_BG_BRIGHT_GREEN "" -#define RTT_CTRL_BG_BRIGHT_YELLOW "" -#define RTT_CTRL_BG_BRIGHT_BLUE "" -#define RTT_CTRL_BG_BRIGHT_MAGENTA "" -#define RTT_CTRL_BG_BRIGHT_CYAN "" -#define RTT_CTRL_BG_BRIGHT_WHITE "" + #define RTT_CTRL_BG_BRIGHT_BLACK "" + #define RTT_CTRL_BG_BRIGHT_RED "" + #define RTT_CTRL_BG_BRIGHT_GREEN "" + #define RTT_CTRL_BG_BRIGHT_YELLOW "" + #define RTT_CTRL_BG_BRIGHT_BLUE "" + #define RTT_CTRL_BG_BRIGHT_MAGENTA "" + #define RTT_CTRL_BG_BRIGHT_CYAN "" + #define RTT_CTRL_BG_BRIGHT_WHITE "" -#endif +#endif /* ifndef SEGGER_RTT_H */ /*************************** End of file ****************************/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT_Conf.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT_Conf.h index 4bb1fdb5a..95ab5d116 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT_Conf.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/SEGGER_RTT_Conf.h @@ -1,263 +1,279 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* SEGGER RTT * Real Time Transfer for embedded targets * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source, linkable, or executable form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source, executable, or * -* linkable form may not be distributed without prior consent of * -* SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** -* * -* RTT version: 6.00e * -* * -********************************************************************** ----------------------------------------------------------------------- -File : SEGGER_RTT_Conf.h -Purpose : Implementation of SEGGER real-time transfer (RTT) which - allows real-time communication on targets which support - debugger memory accesses while the CPU is running. -Revision: $Rev: 3892 $ ----------------------------END-OF-HEADER------------------------------ -*/ - -#ifndef SEGGER_RTT_CONF_H -#define SEGGER_RTT_CONF_H - -#ifdef __IAR_SYSTEMS_ICC__ - #include -#endif - -/********************************************************************* -* -* Defines, configurable -* -********************************************************************** -*/ - -#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3) -#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3) - -#define BUFFER_SIZE_UP (64) // Size of the buffer for terminal output of target, up to host (Default: 1k) -#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) - -#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) - -#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) - -// This can be used to place the RTT control block in the right memory range, if no found automatically. -// This example is for NXP LPC54018, needs to be adapted for each MCU family. -//#define SEGGER_RTT_SECTION ".data.$RAM2" - -// -// Target is not allowed to perform other RTT operations while string still has not been stored completely. -// Otherwise we would probably end up with a mixed string in the buffer. -// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. -// -// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. -// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. -// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. -// (Higher priority = lower priority number) -// Default value for embOS: 128u -// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) -// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC -// or define SEGGER_RTT_LOCK() to completely disable interrupts. -// - -#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) - -/********************************************************************* -* -* RTT lock configuration for SEGGER Embedded Studio, -* Rowley CrossStudio and GCC -*/ -#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) - #ifdef __ARM_ARCH_6M__ - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - __asm volatile ("mrs %0, primask \n\t" \ - "mov r1, $1 \n\t" \ - "msr primask, r1 \n\t" \ - : "=r" (LockState) \ - : \ - : "r1" \ - ); - - #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ - : \ - : "r" (LockState) \ - : \ - ); \ - } - - #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) - #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY - #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) - #endif - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - __asm volatile ("mrs %0, basepri \n\t" \ - "mov r1, %1 \n\t" \ - "msr basepri, r1 \n\t" \ - : "=r" (LockState) \ - : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ - : "r1" \ - ); - - #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ - : \ - : "r" (LockState) \ - : \ - ); \ - } - - #elif defined(__ARM_ARCH_7A__) - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - __asm volatile ("mrs r1, CPSR \n\t" \ - "mov %0, r1 \n\t" \ - "orr r1, r1, #0xC0 \n\t" \ - "msr CPSR_c, r1 \n\t" \ - : "=r" (LockState) \ - : \ - : "r1" \ - ); - - #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ - "mrs r1, CPSR \n\t" \ - "bic r1, r1, #0xC0 \n\t" \ - "and r0, r0, #0xC0 \n\t" \ - "orr r1, r1, r0 \n\t" \ - "msr CPSR_c, r1 \n\t" \ - : \ - : "r" (LockState) \ - : "r0", "r1" \ - ); \ - } -#else - #define SEGGER_RTT_LOCK() - #define SEGGER_RTT_UNLOCK() - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration for IAR EWARM -*/ -#ifdef __ICCARM__ - #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - LockState = __get_PRIMASK(); \ - __set_PRIMASK(1); - - #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ - } - #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) - #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY - #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) - #endif - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - LockState = __get_BASEPRI(); \ - __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); - - #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ - } - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration for IAR RX -*/ -#ifdef __ICCRX__ - #define SEGGER_RTT_LOCK() { \ - unsigned long LockState; \ - LockState = __get_interrupt_state(); \ - __disable_interrupt(); - - #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ - } -#endif - -/********************************************************************* -* -* RTT lock configuration for KEIL ARM -*/ -#ifdef __CC_ARM - #if (defined __TARGET_ARCH_6S_M) - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - register unsigned char PRIMASK __asm( "primask"); \ - LockState = PRIMASK; \ - PRIMASK = 1u; \ - __schedule_barrier(); - - #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ - __schedule_barrier(); \ - } - #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) - #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY - #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) - #endif - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - register unsigned char BASEPRI __asm( "basepri"); \ - LockState = BASEPRI; \ - BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ - __schedule_barrier(); - - #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ - __schedule_barrier(); \ - } - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration fallback -*/ -#ifndef SEGGER_RTT_LOCK - #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) -#endif - -#ifndef SEGGER_RTT_UNLOCK - #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) -#endif - -#endif -/*************************** End of file ****************************/ +/********************************************************************* + * SEGGER MICROCONTROLLER GmbH & Co. KG * + * Solutions for real time microcontroller applications * + ********************************************************************** + * * + * (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * + * * + * www.segger.com Support: support@segger.com * + * * + ********************************************************************** + * * + * SEGGER RTT * Real Time Transfer for embedded targets * + * * + ********************************************************************** + * * + * All rights reserved. * + * * + * * This software may in its unmodified form be freely redistributed * + * in source, linkable, or executable form. * + * * The source code may be modified, provided the source code * + * retains the above copyright notice, this list of conditions and * + * the following disclaimer. * + * * Modified versions of this software in source, executable, or * + * linkable form may not be distributed without prior consent of * + * SEGGER. * + * * This software may only be used for communication with SEGGER * + * J-Link debug probes. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * + * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * + * DAMAGE. * + * * + ********************************************************************** + * * + * RTT version: 6.00e * + * * + ********************************************************************** + * ---------------------------------------------------------------------- + * File : SEGGER_RTT_Conf.h + * Purpose : Implementation of SEGGER real-time transfer (RTT) which + * allows real-time communication on targets which support + * debugger memory accesses while the CPU is running. + * Revision: $Rev: 3892 $ + * ---------------------------END-OF-HEADER------------------------------ + */ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __IAR_SYSTEMS_ICC__ + #include +#endif + +/********************************************************************* + * + * Defines, configurable + * + ********************************************************************** + */ + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS ( 3 ) /* Max. number of up-buffers (T->H) available on this target (Default: 3) */ +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS ( 3 ) /* Max. number of down-buffers (H->T) available on this target (Default: 3) */ + +#define BUFFER_SIZE_UP ( 64 ) /* Size of the buffer for terminal output of target, up to host (Default: 1k) */ +#define BUFFER_SIZE_DOWN ( 16 ) /* Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) */ + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE ( 64u ) /* Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) */ + +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP /* Mode for pre-initialized terminal channel (buffer 0) */ + +/* This can be used to place the RTT control block in the right memory range, if no found automatically. */ +/* This example is for NXP LPC54018, needs to be adapted for each MCU family. */ +/*#define SEGGER_RTT_SECTION ".data.$RAM2" */ + +/* */ +/* Target is not allowed to perform other RTT operations while string still has not been stored completely. */ +/* Otherwise we would probably end up with a mixed string in the buffer. */ +/* If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. */ +/* */ +/* SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. */ +/* Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. */ +/* When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. */ +/* (Higher priority = lower priority number) */ +/* Default value for embOS: 128u */ +/* Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) */ +/* In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC */ +/* or define SEGGER_RTT_LOCK() to completely disable interrupts. */ +/* */ + +#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY ( 0x20 ) /* Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) */ + +/********************************************************************* + * + * RTT lock configuration for SEGGER Embedded Studio, + * Rowley CrossStudio and GCC + */ +#if ( defined __SES_ARM ) || ( defined __CROSSWORKS_ARM ) || ( defined __GNUC__ ) + #ifdef __ARM_ARCH_6M__ + #define SEGGER_RTT_LOCK() \ + { \ + unsigned int LockState; \ + __asm volatile ( "mrs %0, primask \n\t" \ + "mov r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" ( LockState ) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() \ + __asm volatile ( "msr primask, %0 \n\t" \ + : \ + : "r" ( LockState ) \ + : \ + ); \ +} + + #elif ( defined( __ARM_ARCH_7M__ ) || defined( __ARM_ARCH_7EM__ ) ) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY ( 0x20 ) + #endif + #define SEGGER_RTT_LOCK() \ + { \ + unsigned int LockState; \ + __asm volatile ( "mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" ( LockState ) \ + : "i" ( SEGGER_RTT_MAX_INTERRUPT_PRIORITY ) \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() \ + __asm volatile ( "msr basepri, %0 \n\t" \ + : \ + : "r" ( LockState ) \ + : \ + ); \ +} + + #elif defined( __ARM_ARCH_7A__ ) + #define SEGGER_RTT_LOCK() \ + { \ + unsigned int LockState; \ + __asm volatile ( "mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" ( LockState ) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() \ + __asm volatile ( "mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" ( LockState ) \ + : "r0", "r1" \ + ); \ +} + #else /* ifdef __ARM_ARCH_6M__ */ + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif /* ifdef __ARM_ARCH_6M__ */ +#endif /* if ( defined __SES_ARM ) || ( defined __CROSSWORKS_ARM ) || ( defined __GNUC__ ) */ + +/********************************************************************* + * + * RTT lock configuration for IAR EWARM + */ +#ifdef __ICCARM__ + #if ( defined( __ARM6M__ ) && ( __CORE__ == __ARM6M__ ) ) + #define SEGGER_RTT_LOCK() \ + { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK( 1 ); + + #define SEGGER_RTT_UNLOCK() \ + __set_PRIMASK( LockState ); \ +} + #elif ( ( defined( __ARM7EM__ ) && ( __CORE__ == __ARM7EM__ ) ) || ( defined( __ARM7M__ ) && ( __CORE__ == __ARM7M__ ) ) ) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY ( 0x20 ) + #endif + #define SEGGER_RTT_LOCK() \ + { \ + unsigned int LockState; \ + LockState = __get_BASEPRI(); \ + __set_BASEPRI( SEGGER_RTT_MAX_INTERRUPT_PRIORITY ); + + #define SEGGER_RTT_UNLOCK() \ + __set_BASEPRI( LockState ); \ +} + #endif /* if ( defined( __ARM6M__ ) && ( __CORE__ == __ARM6M__ ) ) */ +#endif /* ifdef __ICCARM__ */ + +/********************************************************************* + * + * RTT lock configuration for IAR RX + */ +#ifdef __ICCRX__ + #define SEGGER_RTT_LOCK() \ + { \ + unsigned long LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() \ + __set_interrupt_state( LockState ); \ +} +#endif + +/********************************************************************* + * + * RTT lock configuration for KEIL ARM + */ +#ifdef __CC_ARM + #if ( defined __TARGET_ARCH_6S_M ) + #define SEGGER_RTT_LOCK() \ + { \ + unsigned int LockState; \ + register unsigned char PRIMASK __asm( "primask" ); \ + LockState = PRIMASK; \ + PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() \ + PRIMASK = LockState; \ + __schedule_barrier(); \ +} + #elif ( defined( __TARGET_ARCH_7_M ) || defined( __TARGET_ARCH_7E_M ) ) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY ( 0x20 ) + #endif + #define SEGGER_RTT_LOCK() \ + { \ + unsigned int LockState; \ + register unsigned char BASEPRI __asm( "basepri" ); \ + LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() \ + BASEPRI = LockState; \ + __schedule_barrier(); \ +} + #endif /* if ( defined __TARGET_ARCH_6S_M ) */ +#endif /* ifdef __CC_ARM */ + +/********************************************************************* + * + * RTT lock configuration fallback + */ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() /* Lock RTT (nestable) (i.e. disable interrupts) */ +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() /* Unlock RTT (nestable) (i.e. enable previous interrupt lock state) */ +#endif + +#endif /* ifndef SEGGER_RTT_CONF_H */ +/*************************** End of file ****************************/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamPort.h index 65075f9c4..8e0692cba 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/include/trcStreamPort.h @@ -1,143 +1,143 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The interface definitions for trace streaming ("stream ports"). - * This "stream port" sets up the recorder to use SEGGER RTT as streaming channel. - * - * Note that this stream port is more complex than the typical case, since - * the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead - * of the default buffer included in the recorder core. The other stream ports - * offer more typical examples of how to define a custom streaming interface. - */ - -#ifndef TRC_STREAM_PORT_H -#define TRC_STREAM_PORT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include -#include - -#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER) - -/* Aligned */ -#define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) - -/* Aligned */ -#define TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) - -/* Aligned */ -#define TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) - - -/** - * @brief A structure representing the trace stream port buffer. - */ -typedef struct TraceStreamPortBuffer -{ -#if (TRC_USE_INTERNAL_BUFFER == 1) - uint8_t bufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE]; -#endif - uint8_t bufferUp[TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE]; - uint8_t bufferDown[TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE]; -} TraceStreamPortBuffer_t; - -/** - * @internal Stream port initialize callback. - * - * This function is called by the recorder as part of its initialization phase. - * - * @param[in] pxBuffer Buffer - * - * @retval TRC_FAIL Initialization failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer); - -/** - * @brief Allocates data from the stream port. - * - * @param[in] uiSize Allocation size - * @param[out] ppvData Allocation data pointer - * - * @retval TRC_FAIL Allocate failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData)) - -/** - * @brief Commits data to the stream port, depending on the implementation/configuration of the - * stream port this data might be directly written to the stream port interface, buffered, or - * something else. - * - * @param[in] pvData Data to commit - * @param[in] uiSize Data to commit size - * @param[out] piBytesCommitted Bytes committed - * - * @retval TRC_FAIL Commit failed - * @retval TRC_SUCCESS Success - */ -#if (TRC_USE_INTERNAL_BUFFER == 1) -#define xTraceStreamPortCommit xTraceInternalEventBufferPush -#else -#define xTraceStreamPortCommit xTraceStreamPortWriteData -#endif - -/** - * @brief Writes data through the stream port interface. - * - * @param[in] pvData Data to write - * @param[in] uiSize Data to write size - * @param[out] piBytesWritten Bytes written - * - * @retval TRC_FAIL Write failed - * @retval TRC_SUCCESS Success - */ -#if (defined(TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE) && TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE == 1) -#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(piBytesWritten) = (int32_t)SEGGER_RTT_WriteNoLock((TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX), (const char*)pvData, uiSize), TRC_SUCCESS) -#else -#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2(*(piBytesWritten) = (int32_t)SEGGER_RTT_Write((TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX), (const char*)pvData, uiSize), TRC_SUCCESS) -#endif - -/** - * @brief Reads data through the stream port interface. - * - * @param[in] pvData Destination data buffer - * @param[in] uiSize Destination data buffer size - * @param[out] piBytesRead Bytes read - * - * @retval TRC_FAIL Read failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) ((SEGGER_RTT_HASDATA(TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX)) ? (*(piBytesRead) = (int32_t)SEGGER_RTT_Read((TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX), (char*)(pvData), uiSize), TRC_SUCCESS) : TRC_SUCCESS) - -traceResult xTraceStreamPortOnEnable(uint32_t uiStartOption); - -#define xTraceStreamPortOnDisable() (void)(TRC_SUCCESS) - -#define xTraceStreamPortOnTraceBegin() (void)(TRC_SUCCESS) - -#define xTraceStreamPortOnTraceEnd() (void)(TRC_SUCCESS) - -#ifdef __cplusplus -} -#endif - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ - -#endif /* TRC_STREAM_PORT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface definitions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to use SEGGER RTT as streaming channel. + * + * Note that this stream port is more complex than the typical case, since + * the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead + * of the default buffer included in the recorder core. The other stream ports + * offer more typical examples of how to define a custom streaming interface. + */ + +#ifndef TRC_STREAM_PORT_H + #define TRC_STREAM_PORT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #ifdef __cplusplus + extern "C" { + #endif + + #include + #include + + #include + #include + + #define TRC_USE_INTERNAL_BUFFER ( TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER ) + +/* Aligned */ + #define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ( ( ( ( TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE ) + sizeof( TraceUnsignedBaseType_t ) - 1 ) / sizeof( TraceUnsignedBaseType_t ) ) * sizeof( TraceUnsignedBaseType_t ) ) + +/* Aligned */ + #define TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE ( ( ( ( TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_SIZE ) + sizeof( TraceUnsignedBaseType_t ) - 1 ) / sizeof( TraceUnsignedBaseType_t ) ) * sizeof( TraceUnsignedBaseType_t ) ) + +/* Aligned */ + #define TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE ( ( ( ( TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_SIZE ) + sizeof( TraceUnsignedBaseType_t ) - 1 ) / sizeof( TraceUnsignedBaseType_t ) ) * sizeof( TraceUnsignedBaseType_t ) ) + + +/** + * @brief A structure representing the trace stream port buffer. + */ + typedef struct TraceStreamPortBuffer + { + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + uint8_t bufferInternal[ TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ]; + #endif + uint8_t bufferUp[ TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE ]; + uint8_t bufferDown[ TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE ]; + } TraceStreamPortBuffer_t; + +/** + * @internal Stream port initialize callback. + * + * This function is called by the recorder as part of its initialization phase. + * + * @param[in] pxBuffer Buffer + * + * @retval TRC_FAIL Initialization failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ); + +/** + * @brief Allocates data from the stream port. + * + * @param[in] uiSize Allocation size + * @param[out] ppvData Allocation data pointer + * + * @retval TRC_FAIL Allocate failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortAllocate( uiSize, ppvData ) ( ( void ) ( uiSize ), xTraceStaticBufferGet( ppvData ) ) + +/** + * @brief Commits data to the stream port, depending on the implementation/configuration of the + * stream port this data might be directly written to the stream port interface, buffered, or + * something else. + * + * @param[in] pvData Data to commit + * @param[in] uiSize Data to commit size + * @param[out] piBytesCommitted Bytes committed + * + * @retval TRC_FAIL Commit failed + * @retval TRC_SUCCESS Success + */ + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + #define xTraceStreamPortCommit xTraceInternalEventBufferPush + #else + #define xTraceStreamPortCommit xTraceStreamPortWriteData + #endif + +/** + * @brief Writes data through the stream port interface. + * + * @param[in] pvData Data to write + * @param[in] uiSize Data to write size + * @param[out] piBytesWritten Bytes written + * + * @retval TRC_FAIL Write failed + * @retval TRC_SUCCESS Success + */ + #if ( defined( TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE ) && TRC_CFG_STREAM_PORT_RTT_NO_LOCK_WRITE == 1 ) + #define xTraceStreamPortWriteData( pvData, uiSize, piBytesWritten ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( piBytesWritten ) = ( int32_t ) SEGGER_RTT_WriteNoLock( ( TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX ), ( const char * ) pvData, uiSize ), TRC_SUCCESS ) + #else + #define xTraceStreamPortWriteData( pvData, uiSize, piBytesWritten ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( piBytesWritten ) = ( int32_t ) SEGGER_RTT_Write( ( TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX ), ( const char * ) pvData, uiSize ), TRC_SUCCESS ) + #endif + +/** + * @brief Reads data through the stream port interface. + * + * @param[in] pvData Destination data buffer + * @param[in] uiSize Destination data buffer size + * @param[out] piBytesRead Bytes read + * + * @retval TRC_FAIL Read failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortReadData( pvData, uiSize, piBytesRead ) ( ( SEGGER_RTT_HASDATA( TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX ) ) ? ( *( piBytesRead ) = ( int32_t ) SEGGER_RTT_Read( ( TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX ), ( char * ) ( pvData ), uiSize ), TRC_SUCCESS ) : TRC_SUCCESS ) + + traceResult xTraceStreamPortOnEnable( uint32_t uiStartOption ); + + #define xTraceStreamPortOnDisable() ( void ) ( TRC_SUCCESS ) + + #define xTraceStreamPortOnTraceBegin() ( void ) ( TRC_SUCCESS ) + + #define xTraceStreamPortOnTraceEnd() ( void ) ( TRC_SUCCESS ) + + #ifdef __cplusplus +} + #endif + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + + #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#endif /* TRC_STREAM_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamPort.c index 4bd7837a0..189838365 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/Jlink_RTT/trcStreamPort.c @@ -1,64 +1,65 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Supporting functions for trace streaming, used by the "stream ports" - * for reading and writing data to the interface. - * - * Note that this stream port is more complex than the typical case, since - * the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead - * of the default buffer included in the recorder core. The other stream ports - * offer more typical examples of how to define a custom streaming interface. - */ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -typedef struct TraceStreamPortRTT { -#if (TRC_USE_INTERNAL_BUFFER == 1) - uint8_t bufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE]; -#endif - uint8_t bufferUp[TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE]; - uint8_t bufferDown[TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE]; -} TraceStreamPortRTT_t; - -static TraceStreamPortRTT_t* pxStreamPortRTT; - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortRTT_t); - - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - pxStreamPortRTT = (TraceStreamPortRTT_t*)pxBuffer; - -#if (TRC_USE_INTERNAL_BUFFER == 1) - return xTraceInternalEventBufferInitialize(pxStreamPortRTT->bufferInternal, sizeof(pxStreamPortRTT->bufferInternal)); -#else - return TRC_SUCCESS; -#endif -} - -traceResult xTraceStreamPortOnEnable(uint32_t uiStartOption) -{ - (void)uiStartOption; - - /* Configure the RTT buffers */ - SEGGER_RTT_ConfigUpBuffer(TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX, "TzData", pxStreamPortRTT->bufferUp, sizeof(pxStreamPortRTT->bufferUp), TRC_CFG_STREAM_PORT_RTT_MODE); - SEGGER_RTT_ConfigDownBuffer(TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX, "TzCtrl", pxStreamPortRTT->bufferDown, sizeof(pxStreamPortRTT->bufferDown), TRC_CFG_STREAM_PORT_RTT_MODE); - - return TRC_SUCCESS; -} - -#endif - -#endif +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Supporting functions for trace streaming, used by the "stream ports" + * for reading and writing data to the interface. + * + * Note that this stream port is more complex than the typical case, since + * the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead + * of the default buffer included in the recorder core. The other stream ports + * offer more typical examples of how to define a custom streaming interface. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + typedef struct TraceStreamPortRTT + { + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + uint8_t bufferInternal[ TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ]; + #endif + uint8_t bufferUp[ TRC_STREAM_PORT_RTT_UP_BUFFER_SIZE ]; + uint8_t bufferDown[ TRC_STREAM_PORT_RTT_DOWN_BUFFER_SIZE ]; + } TraceStreamPortRTT_t; + + static TraceStreamPortRTT_t * pxStreamPortRTT; + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceStreamPortBuffer_t, TraceStreamPortRTT_t ); + + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + pxStreamPortRTT = ( TraceStreamPortRTT_t * ) pxBuffer; + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + return xTraceInternalEventBufferInitialize( pxStreamPortRTT->bufferInternal, sizeof( pxStreamPortRTT->bufferInternal ) ); + #else + return TRC_SUCCESS; + #endif + } + + traceResult xTraceStreamPortOnEnable( uint32_t uiStartOption ) + { + ( void ) uiStartOption; + + /* Configure the RTT buffers */ + SEGGER_RTT_ConfigUpBuffer( TRC_CFG_STREAM_PORT_RTT_UP_BUFFER_INDEX, "TzData", pxStreamPortRTT->bufferUp, sizeof( pxStreamPortRTT->bufferUp ), TRC_CFG_STREAM_PORT_RTT_MODE ); + SEGGER_RTT_ConfigDownBuffer( TRC_CFG_STREAM_PORT_RTT_DOWN_BUFFER_INDEX, "TzCtrl", pxStreamPortRTT->bufferDown, sizeof( pxStreamPortRTT->bufferDown ), TRC_CFG_STREAM_PORT_RTT_MODE ); + + return TRC_SUCCESS; + } + + #endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) */ + +#endif /* if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/Readme-Streamport.txt index 8434b90e1..98d8f8f2a 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/Readme-Streamport.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/Readme-Streamport.txt @@ -1,19 +1,19 @@ -Tracealyzer Stream Port for Ring Buffer -------------------------------------------------- - -This directory contains a "stream port" for the Tracealyzer recorder library, -i.e., the specific code needed to use a particular interface for streaming a -Tracealyzer RTOS trace. The stream port is defined by a set of macros in -trcStreamPort.h, found in the "include" directory. - -This particular stream port is for streaming to a ring buffer. - -To use this stream port, make sure that include/trcStreamPort.h is found -by the compiler (i.e., add this folder to your project's include paths) and -add all included source files to your build. Make sure no other versions of -trcStreamPort.h are included by mistake! - -See also http://percepio.com/2016/10/05/rtos-tracing. - -Percepio AB +Tracealyzer Stream Port for Ring Buffer +------------------------------------------------- + +This directory contains a "stream port" for the Tracealyzer recorder library, +i.e., the specific code needed to use a particular interface for streaming a +Tracealyzer RTOS trace. The stream port is defined by a set of macros in +trcStreamPort.h, found in the "include" directory. + +This particular stream port is for streaming to a ring buffer. + +To use this stream port, make sure that include/trcStreamPort.h is found +by the compiler (i.e., add this folder to your project's include paths) and +add all included source files to your build. Make sure no other versions of +trcStreamPort.h are included by mistake! + +See also http://percepio.com/2016/10/05/rtos-tracing. + +Percepio AB www.percepio.com \ No newline at end of file diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/config/trcStreamPortConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/config/trcStreamPortConfig.h index 0b970b724..3c095953d 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/config/trcStreamPortConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/config/trcStreamPortConfig.h @@ -1,60 +1,60 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* - * The configuration for trace streaming ("stream ports"). -*/ - -#ifndef TRC_STREAM_PORT_CONFIG_H -#define TRC_STREAM_PORT_CONFIG_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Type flags */ -#define TRC_STREAM_PORT_RINGBUFFER_MODE_STOP_WHEN_FULL (0U) -#define TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL (1U) - -/** - * @def TRC_CFG_STREAM_PORT_BUFFER_SIZE - * - * @brief Defines the size of the ring buffer use for storing trace events. - */ -#define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000 - -/** - * @def TRC_CFG_STREAM_PORT_BUFFER_MODE - * - * @brief Configures the behavior of the ring buffer when full. - * - * With TRC_CFG_STREAM_PORT_MODE set to TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL, the - * events are stored in a ring buffer, i.e., where the oldest events are - * overwritten when the buffer becomes full. This allows you to get the last - * events leading up to an interesting state, e.g., an error, without having - * to store the whole run since startup. - * - * When TRC_CFG_STREAM_PORT_MODE is TRC_STREAM_PORT_RINGBUFFER_MODE_STOP_WHEN_FULL, the - * recording is stopped when the buffer becomes full. This is useful for - * recording events following a specific state, e.g., the startup sequence. - */ -#define TRC_CFG_STREAM_PORT_RINGBUFFER_MODE TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL - -#ifdef __cplusplus -} -#endif - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ - -#endif /* TRC_STREAM_PORT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The configuration for trace streaming ("stream ports"). + */ + +#ifndef TRC_STREAM_PORT_CONFIG_H + #define TRC_STREAM_PORT_CONFIG_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/* Type flags */ + #define TRC_STREAM_PORT_RINGBUFFER_MODE_STOP_WHEN_FULL ( 0U ) + #define TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL ( 1U ) + +/** + * @def TRC_CFG_STREAM_PORT_BUFFER_SIZE + * + * @brief Defines the size of the ring buffer use for storing trace events. + */ + #define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000 + +/** + * @def TRC_CFG_STREAM_PORT_BUFFER_MODE + * + * @brief Configures the behavior of the ring buffer when full. + * + * With TRC_CFG_STREAM_PORT_MODE set to TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL, the + * events are stored in a ring buffer, i.e., where the oldest events are + * overwritten when the buffer becomes full. This allows you to get the last + * events leading up to an interesting state, e.g., an error, without having + * to store the whole run since startup. + * + * When TRC_CFG_STREAM_PORT_MODE is TRC_STREAM_PORT_RINGBUFFER_MODE_STOP_WHEN_FULL, the + * recording is stopped when the buffer becomes full. This is useful for + * recording events following a specific state, e.g., the startup sequence. + */ + #define TRC_CFG_STREAM_PORT_RINGBUFFER_MODE TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL + + #ifdef __cplusplus +} + #endif + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + + #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#endif /* TRC_STREAM_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/include/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/include/trcStreamPort.h index afa8ff524..c8b2c1349 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/include/trcStreamPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/include/trcStreamPort.h @@ -1,201 +1,203 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The interface definitions for trace streaming ("stream ports"). -* This "stream port" sets up the recorder to stream to a Ring Buffer. -*/ - -#ifndef TRC_STREAM_PORT_H -#define TRC_STREAM_PORT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @def TRC_EXTERNAL_BUFFERS - * - * @brief This Stream Port houses the EntryTable and Timestamp buffers - */ -#define TRC_EXTERNAL_BUFFERS 1 - -/** - * @def TRC_SEND_NAME_ONLY_ON_DELETE - * - * @brief This Stream Port requires additional information to be sent when objects are deleted - */ -#define TRC_SEND_NAME_ONLY_ON_DELETE 1 - -/** - * @def TRC_USE_INTERNAL_BUFFER - * - * @brief This Stream Port uses the Multi Core Buffer directly. - */ - -#define TRC_USE_INTERNAL_BUFFER 0 - -#define TRC_STREAM_PORT_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_BUFFER_SIZE) + sizeof(uint32_t) - 1) / sizeof(uint32_t)) * sizeof(uint32_t)) - -/** -* @brief -*/ -typedef struct TraceMultiCoreBuffer -{ - uint32_t uiSize; - uint8_t uiBuffer[TRC_STREAM_PORT_BUFFER_SIZE]; -} TraceMultiCoreBuffer_t; - -/** - * @brief - */ -typedef struct TraceRingBuffer -{ - volatile uint8_t START_MARKERS[12]; - TraceHeaderBuffer_t xHeaderBuffer; - TraceTimestampBuffer_t xTimestampInfo; - TraceEntryTableBuffer_t xEntryTableBuffer; - TraceMultiCoreBuffer_t xEventBuffer; - volatile uint8_t END_MARKERS[12]; -} TraceRingBuffer_t; - -/** - * @brief - */ -typedef struct TraceStreamPortData -{ - TraceMultiCoreEventBuffer_t xMultiCoreEventBuffer; - TraceRingBuffer_t xRingBuffer; -} TraceStreamPortData_t; - -extern TraceStreamPortData_t* pxStreamPortData; - -/** -* @def TRC_STREAM_PORT_BUFFER_SIZE -* @brief The buffer size, aligned to base type. -*/ -#define TRC_STREAM_PORT_DATA_BUFFER_SIZE (sizeof(TraceStreamPortData_t)) - -/** - * @brief A structure representing the trace stream port buffer. - */ -typedef struct TraceStreamPortBuffer -{ - uint8_t buffer[(TRC_STREAM_PORT_DATA_BUFFER_SIZE)]; -} TraceStreamPortBuffer_t; - -/** - * @internal Stream port initialize callback. - * - * This function is called by the recorder as part of its initialization phase. - * - * @param[in] pxBuffer Buffer - * - * @retval TRC_FAIL Initialization failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer); - -/** - * @brief Allocates data from the stream port. - * - * @param[in] uiSize Allocation size - * @param[out] ppvData Allocation data pointer - * - * @retval TRC_FAIL Allocate failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)uiSize, xTraceStaticBufferGet(ppvData)) - -/** - * @brief Commits data to the stream port, depending on the implementation/configuration of the - * stream port this data might be directly written to the stream port interface, buffered, or - * something else. - * - * @param[in] pvData Data to commit - * @param[in] uiSize Data to commit size - * @param[out] piBytesCommitted Bytes commited - * - * @retval TRC_FAIL Commit failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortCommit(void* pvData, uint32_t uiSize, int32_t* piBytesCommitted); - -/** - * @brief Writes data through the stream port interface. - * - * @param[in] pvData Data to write - * @param[in] uiSize Data to write size - * @param[out] piBytesWritten Bytes written - * - * @retval TRC_FAIL Write failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)pvData, (void)uiSize, (void)piBytesWritten, TRC_SUCCESS) - -/** - * @brief Reads data through the stream port interface. - * - * @param[in] pvData Destination data buffer - * @param[in] uiSize Destination data buffer size - * @param[out] piBytesRead Bytes read - * - * @retval TRC_FAIL Read failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4((void)pvData, (void)uiSize, (void)piBytesRead, TRC_SUCCESS) - -/** - * @brief Callback for when recorder is enabled - * - * @param[in] uiStartOption Start option used when enabling trace recorder - * - * @retval TRC_FAIL Read failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortOnEnable(uiStartOption) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2((void)(uiStartOption), TRC_SUCCESS) - -/** - * @brief Callback for when recorder is disabled - * - * @retval TRC_FAIL Read failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortOnDisable() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS) - -/** - * @brief Callback for when tracing begins - * - * @retval TRC_FAIL Read failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortOnTraceBegin(); - -/** - * @brief Callback for when tracing ends - * - * @retval TRC_FAIL Read failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortOnTraceEnd() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1(TRC_SUCCESS) - -#ifdef __cplusplus -} -#endif - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ - -#endif /* TRC_STREAM_PORT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface definitions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to stream to a Ring Buffer. + */ + +#ifndef TRC_STREAM_PORT_H + #define TRC_STREAM_PORT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + +/** + * @def TRC_EXTERNAL_BUFFERS + * + * @brief This Stream Port houses the EntryTable and Timestamp buffers + */ + #define TRC_EXTERNAL_BUFFERS 1 + +/** + * @def TRC_SEND_NAME_ONLY_ON_DELETE + * + * @brief This Stream Port requires additional information to be sent when objects are deleted + */ + #define TRC_SEND_NAME_ONLY_ON_DELETE 1 + +/** + * @def TRC_USE_INTERNAL_BUFFER + * + * @brief This Stream Port uses the Multi Core Buffer directly. + */ + + #define TRC_USE_INTERNAL_BUFFER 0 + + #define TRC_STREAM_PORT_BUFFER_SIZE ( ( ( ( TRC_CFG_STREAM_PORT_BUFFER_SIZE ) + sizeof( uint32_t ) - 1 ) / sizeof( uint32_t ) ) * sizeof( uint32_t ) ) + +/** + * @brief + */ + typedef struct TraceMultiCoreBuffer + { + uint32_t uiSize; + uint8_t uiBuffer[ TRC_STREAM_PORT_BUFFER_SIZE ]; + } TraceMultiCoreBuffer_t; + +/** + * @brief + */ + typedef struct TraceRingBuffer + { + volatile uint8_t START_MARKERS[ 12 ]; + TraceHeaderBuffer_t xHeaderBuffer; + TraceTimestampBuffer_t xTimestampInfo; + TraceEntryTableBuffer_t xEntryTableBuffer; + TraceMultiCoreBuffer_t xEventBuffer; + volatile uint8_t END_MARKERS[ 12 ]; + } TraceRingBuffer_t; + +/** + * @brief + */ + typedef struct TraceStreamPortData + { + TraceMultiCoreEventBuffer_t xMultiCoreEventBuffer; + TraceRingBuffer_t xRingBuffer; + } TraceStreamPortData_t; + + extern TraceStreamPortData_t * pxStreamPortData; + +/** + * @def TRC_STREAM_PORT_BUFFER_SIZE + * @brief The buffer size, aligned to base type. + */ + #define TRC_STREAM_PORT_DATA_BUFFER_SIZE ( sizeof( TraceStreamPortData_t ) ) + +/** + * @brief A structure representing the trace stream port buffer. + */ + typedef struct TraceStreamPortBuffer + { + uint8_t buffer[ ( TRC_STREAM_PORT_DATA_BUFFER_SIZE ) ]; + } TraceStreamPortBuffer_t; + +/** + * @internal Stream port initialize callback. + * + * This function is called by the recorder as part of its initialization phase. + * + * @param[in] pxBuffer Buffer + * + * @retval TRC_FAIL Initialization failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ); + +/** + * @brief Allocates data from the stream port. + * + * @param[in] uiSize Allocation size + * @param[out] ppvData Allocation data pointer + * + * @retval TRC_FAIL Allocate failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortAllocate( uiSize, ppvData ) ( ( void ) uiSize, xTraceStaticBufferGet( ppvData ) ) + +/** + * @brief Commits data to the stream port, depending on the implementation/configuration of the + * stream port this data might be directly written to the stream port interface, buffered, or + * something else. + * + * @param[in] pvData Data to commit + * @param[in] uiSize Data to commit size + * @param[out] piBytesCommitted Bytes commited + * + * @retval TRC_FAIL Commit failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortCommit( void * pvData, + uint32_t uiSize, + int32_t * piBytesCommitted ); + +/** + * @brief Writes data through the stream port interface. + * + * @param[in] pvData Data to write + * @param[in] uiSize Data to write size + * @param[out] piBytesWritten Bytes written + * + * @retval TRC_FAIL Write failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortWriteData( pvData, uiSize, piBytesWritten ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( ( void ) pvData, ( void ) uiSize, ( void ) piBytesWritten, TRC_SUCCESS ) + +/** + * @brief Reads data through the stream port interface. + * + * @param[in] pvData Destination data buffer + * @param[in] uiSize Destination data buffer size + * @param[out] piBytesRead Bytes read + * + * @retval TRC_FAIL Read failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortReadData( pvData, uiSize, piBytesRead ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_4( ( void ) pvData, ( void ) uiSize, ( void ) piBytesRead, TRC_SUCCESS ) + +/** + * @brief Callback for when recorder is enabled + * + * @param[in] uiStartOption Start option used when enabling trace recorder + * + * @retval TRC_FAIL Read failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortOnEnable( uiStartOption ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( ( void ) ( uiStartOption ), TRC_SUCCESS ) + +/** + * @brief Callback for when recorder is disabled + * + * @retval TRC_FAIL Read failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortOnDisable() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1( TRC_SUCCESS ) + +/** + * @brief Callback for when tracing begins + * + * @retval TRC_FAIL Read failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortOnTraceBegin(); + +/** + * @brief Callback for when tracing ends + * + * @retval TRC_FAIL Read failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortOnTraceEnd() TRC_COMMA_EXPR_TO_STATEMENT_EXPR_1( TRC_SUCCESS ) + + #ifdef __cplusplus +} + #endif + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + + #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#endif /* TRC_STREAM_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/trcStreamPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/trcStreamPort.c index 5c0484d7b..237202d8c 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/trcStreamPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/RingBuffer/trcStreamPort.c @@ -1,130 +1,134 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* Supporting functions for trace streaming, used by the "stream ports" -* for reading and writing data to the interface. -* This "stream port" sets up the recorder to stream to a Ring Buffer. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -/* Backwards compatibility with plugins */ -typedef TraceRingBuffer_t RecorderData; -RecorderData* RecorderDataPtr = 0; - -TraceStreamPortData_t* pxStreamPortData; - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer) -{ - TraceRingBuffer_t* pxRingBuffer; - - TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortData_t); - - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - pxStreamPortData = (TraceStreamPortData_t*)pxBuffer; - RecorderDataPtr = pxRingBuffer = &pxStreamPortData->xRingBuffer; - - pxRingBuffer->xEventBuffer.uiSize = sizeof(pxRingBuffer->xEventBuffer.uiBuffer); - -#if (TRC_CFG_STREAM_PORT_RINGBUFFER_MODE == TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL) - if (xTraceMultiCoreEventBufferInitialize(&pxStreamPortData->xMultiCoreEventBuffer, TRC_EVENT_BUFFER_OPTION_OVERWRITE, pxRingBuffer->xEventBuffer.uiBuffer, sizeof(pxRingBuffer->xEventBuffer.uiBuffer)) == TRC_FAIL) - { - return TRC_FAIL; - } -#else - if (xTraceMultiCoreEventBufferInitialize(&pxStreamPortData->xMultiCoreEventBuffer, TRC_EVENT_BUFFER_OPTION_SKIP, pxRingBuffer->xEventBuffer.uiBuffer, sizeof(pxRingBuffer->xEventBuffer.uiBuffer)) == TRC_FAIL) - { - return TRC_FAIL; - } -#endif - - if (xTraceHeaderInitialize(&pxRingBuffer->xHeaderBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceEntryTableInitialize(&pxRingBuffer->xEntryTableBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceTimestampInitialize(&pxRingBuffer->xTimestampInfo) == TRC_FAIL) - { - return TRC_FAIL; - } - - pxRingBuffer->END_MARKERS[0] = 0x0A; - pxRingBuffer->END_MARKERS[1] = 0x0B; - pxRingBuffer->END_MARKERS[2] = 0x0C; - pxRingBuffer->END_MARKERS[3] = 0x0D; - - pxRingBuffer->END_MARKERS[4] = 0x71; - pxRingBuffer->END_MARKERS[5] = 0x72; - pxRingBuffer->END_MARKERS[6] = 0x73; - pxRingBuffer->END_MARKERS[7] = 0x74; - - pxRingBuffer->END_MARKERS[8] = 0xF1; - pxRingBuffer->END_MARKERS[9] = 0xF2; - pxRingBuffer->END_MARKERS[10] = 0xF3; - pxRingBuffer->END_MARKERS[11] = 0xF4; - - pxRingBuffer->START_MARKERS[0] = 0x05; - pxRingBuffer->START_MARKERS[1] = 0x06; - pxRingBuffer->START_MARKERS[2] = 0x07; - pxRingBuffer->START_MARKERS[3] = 0x08; - - pxRingBuffer->START_MARKERS[4] = 0x75; - pxRingBuffer->START_MARKERS[5] = 0x76; - pxRingBuffer->START_MARKERS[6] = 0x77; - pxRingBuffer->START_MARKERS[7] = 0x78; - - pxRingBuffer->START_MARKERS[8] = 0xF5; - pxRingBuffer->START_MARKERS[9] = 0xF6; - pxRingBuffer->START_MARKERS[10] = 0xF7; - pxRingBuffer->START_MARKERS[11] = 0xF8; - - return TRC_SUCCESS; -} - -traceResult xTraceStreamPortCommit(void* pvData, uint32_t uiSize, int32_t* piBytesCommitted) -{ - if (pvData == 0) - { - return TRC_FAIL; - } - - xTraceMultiCoreEventBufferPush(&pxStreamPortData->xMultiCoreEventBuffer, pvData, uiSize, piBytesCommitted); - -#if (TRC_CFG_STREAM_PORT_RINGBUFFER_MODE == TRC_STREAM_PORT_RINGBUFFER_MODE_STOP_WHEN_FULL) - /* If no bytes was written it means that the buffer is full and we should stop - * tracing. - */ - if (uiSize > 0 && *piBytesCommitted == 0) { - xTraceDisable(); - return TRC_FAIL; - } -#endif - - return TRC_SUCCESS; -} - -traceResult xTraceStreamPortOnTraceBegin() -{ - return xTraceMultiCoreEventBufferClear(&pxStreamPortData->xMultiCoreEventBuffer); -} - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Supporting functions for trace streaming, used by the "stream ports" + * for reading and writing data to the interface. + * This "stream port" sets up the recorder to stream to a Ring Buffer. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + +/* Backwards compatibility with plugins */ + typedef TraceRingBuffer_t RecorderData; + RecorderData * RecorderDataPtr = 0; + + TraceStreamPortData_t * pxStreamPortData; + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ) + { + TraceRingBuffer_t * pxRingBuffer; + + TRC_ASSERT_EQUAL_SIZE( TraceStreamPortBuffer_t, TraceStreamPortData_t ); + + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + pxStreamPortData = ( TraceStreamPortData_t * ) pxBuffer; + RecorderDataPtr = pxRingBuffer = &pxStreamPortData->xRingBuffer; + + pxRingBuffer->xEventBuffer.uiSize = sizeof( pxRingBuffer->xEventBuffer.uiBuffer ); + + #if ( TRC_CFG_STREAM_PORT_RINGBUFFER_MODE == TRC_STREAM_PORT_RINGBUFFER_MODE_OVERWRITE_WHEN_FULL ) + if( xTraceMultiCoreEventBufferInitialize( &pxStreamPortData->xMultiCoreEventBuffer, TRC_EVENT_BUFFER_OPTION_OVERWRITE, pxRingBuffer->xEventBuffer.uiBuffer, sizeof( pxRingBuffer->xEventBuffer.uiBuffer ) ) == TRC_FAIL ) + { + return TRC_FAIL; + } + #else + if( xTraceMultiCoreEventBufferInitialize( &pxStreamPortData->xMultiCoreEventBuffer, TRC_EVENT_BUFFER_OPTION_SKIP, pxRingBuffer->xEventBuffer.uiBuffer, sizeof( pxRingBuffer->xEventBuffer.uiBuffer ) ) == TRC_FAIL ) + { + return TRC_FAIL; + } + #endif + + if( xTraceHeaderInitialize( &pxRingBuffer->xHeaderBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceEntryTableInitialize( &pxRingBuffer->xEntryTableBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceTimestampInitialize( &pxRingBuffer->xTimestampInfo ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + pxRingBuffer->END_MARKERS[ 0 ] = 0x0A; + pxRingBuffer->END_MARKERS[ 1 ] = 0x0B; + pxRingBuffer->END_MARKERS[ 2 ] = 0x0C; + pxRingBuffer->END_MARKERS[ 3 ] = 0x0D; + + pxRingBuffer->END_MARKERS[ 4 ] = 0x71; + pxRingBuffer->END_MARKERS[ 5 ] = 0x72; + pxRingBuffer->END_MARKERS[ 6 ] = 0x73; + pxRingBuffer->END_MARKERS[ 7 ] = 0x74; + + pxRingBuffer->END_MARKERS[ 8 ] = 0xF1; + pxRingBuffer->END_MARKERS[ 9 ] = 0xF2; + pxRingBuffer->END_MARKERS[ 10 ] = 0xF3; + pxRingBuffer->END_MARKERS[ 11 ] = 0xF4; + + pxRingBuffer->START_MARKERS[ 0 ] = 0x05; + pxRingBuffer->START_MARKERS[ 1 ] = 0x06; + pxRingBuffer->START_MARKERS[ 2 ] = 0x07; + pxRingBuffer->START_MARKERS[ 3 ] = 0x08; + + pxRingBuffer->START_MARKERS[ 4 ] = 0x75; + pxRingBuffer->START_MARKERS[ 5 ] = 0x76; + pxRingBuffer->START_MARKERS[ 6 ] = 0x77; + pxRingBuffer->START_MARKERS[ 7 ] = 0x78; + + pxRingBuffer->START_MARKERS[ 8 ] = 0xF5; + pxRingBuffer->START_MARKERS[ 9 ] = 0xF6; + pxRingBuffer->START_MARKERS[ 10 ] = 0xF7; + pxRingBuffer->START_MARKERS[ 11 ] = 0xF8; + + return TRC_SUCCESS; + } + + traceResult xTraceStreamPortCommit( void * pvData, + uint32_t uiSize, + int32_t * piBytesCommitted ) + { + if( pvData == 0 ) + { + return TRC_FAIL; + } + + xTraceMultiCoreEventBufferPush( &pxStreamPortData->xMultiCoreEventBuffer, pvData, uiSize, piBytesCommitted ); + + #if ( TRC_CFG_STREAM_PORT_RINGBUFFER_MODE == TRC_STREAM_PORT_RINGBUFFER_MODE_STOP_WHEN_FULL ) + + /* If no bytes was written it means that the buffer is full and we should stop + * tracing. + */ + if( ( uiSize > 0 ) && ( *piBytesCommitted == 0 ) ) + { + xTraceDisable(); + return TRC_FAIL; + } + #endif + + return TRC_SUCCESS; + } + + traceResult xTraceStreamPortOnTraceBegin() + { + return xTraceMultiCoreEventBufferClear( &pxStreamPortData->xMultiCoreEventBuffer ); + } + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + +#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/Readme-Streamport.txt index 35986a3ac..fb36bff29 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/Readme-Streamport.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/Readme-Streamport.txt @@ -1,93 +1,93 @@ -Tracealyzer Stream Port for STM32 USB CDC (Virtual COM Port) -Percepio AB -https://percepio.com ------------------------------------------------------------- - -This directory contains a "stream port" for the Tracealyzer recorder library, -allowing for streaming the trace data over a USB connection. The stream port is defined by a set of macros in -trcStreamPort.h, found in the "include" directory, that relies on functions in trcStreamingPort.c. - -This particular stream port targets STM32 devices using USB CDC (virtual COM port). -It was been tested with STM32F767 and STM32L475. - ---- Prerequisites --- - -- An STM32 device with a USB connector for application use. - -- Tracealyzer 4 with a license for FreeRTOS, SafeRTOS or Micrium µC/OS-III. - -- STM32CubeIDE or the stand-alone STM32CubeMX configuration tool. - ---- Instructions --- - -1. Follow the general instructions (Section 1) at https://percepio.com/gettingstarted-freertos/ -and verify that Snapshot mode works. The basic integration of the recorder library is the same. - -2. Open the Device Configuration Tool (STM32CubeMX), e.g. by double-clicking on the .ioc file in your STM32CubeIDE project. - -2.1. Under "Middleware", enable "USB_DEVICE" and... -- In "USB_DEVICE Mode and Configuration", set the "Class for FS IP" to "Communication Device Class (Virtual Com Port)". -- Under Configuration -> Parameter Settings, set the TX and RX buffer sizes to a small value (e.g. 1). -The default TX and RX buffers are not used by the trace recorder library, so this avoids wasting RAM. - -2.2. Under "Connectivity", open "USB_OTG_FS" and... -- In "USB_OTG_FS Mode and Configuration", make sure "Mode" is set to "Device_Only" -- Under "Configuration", open "NVIC Settings" and make sure "USB OTG FS global interrupt" is enabled. - -3. Open trcConfig.h and set TRC_CFG_RECORDER_MODE to TRC_RECORDER_MODE_STREAMING. - -4. Copy trcStreamingPort.c and include/trcStreamPort.h into your project. - -5. Make sure you have "vTraceEnable(TRC_INIT);" in main.c (not TRC_START or so). -This should be placed after the HW setup but before making any RTOS calls. - -6. Plug in a USB cable to the connector labeled "USB OTG" or similar (i.e. for application use). - -7. Build the project and start it. Check that your computer finds a new USB device (there should be a notification). - -8. Check the number of the new COM port, that should have appeared. This is NOT "STLink Virtual COM port". - -9. Start Tracealyzer and open Recording Settings and select Target Connection: SerialPort. -You can also access these settings via File -> Settings -> PSF Streaming Settings. - -10. Enter the number of the COM port in the "Device" field. The settings (data -bits, data rate etc.) are irrelevant for USB serial connections and not used. - -11. While the target is running, select Record Streaming Trace in Tracealyzer. -You should now see a live display of the trace, while it is being received. -Make sure there are no warnings about "Dropped Events" (in that case, see Troubleshooting, below). - -Note that you can still debug and use breakpoints while streaming the trace. - ---- Further reading --- - -- http://percepio.com/2017/02/03/usb-trace-streaming-st-nucleo-f767zi-board -- http://percepio.com/2016/10/05/rtos-tracing -- https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ - ---- Troubleshooting --- - -A. If you get an error about "multiple definition of SysTick_Handler", open -FreeRTOSConfig.h (found in Core/Inc) and add this line in the bottom, -after the definition of xPortSysTickHandler. - -#undef xPortSysTickHandler - -B. If you get "Missed Events" in the Live Stream window, it is typically because -your application produces more trace data than can be transferred, so the trace -buffer overflows. -You may try the following to start with: -- Increase TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT and/or TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE in trcStreamingConfig.h -- Decrease TRC_CFG_CTRL_TASK_DELAY in trcConfig.h -- Increase TRC_CFG_CTRL_TASK_PRIORITY in trcConfig.h - -Also see the "tuning" guide at https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ - -Also note that this USB stream port has a diagnostics option that might come handy. -Enable USB_PERF_DIAGNOSTICS in trcStreamPort.h. This will save additional "user events" -each time a buffer page is transmitted, showing the number of bytes sent and the -remaining capacity in the trace buffer (if this goes down to zero, data is lost). - -#define USB_PERF_DIAGNOSTICS 1 - -If you need assistence, feel free to contact support@percepio.com. +Tracealyzer Stream Port for STM32 USB CDC (Virtual COM Port) +Percepio AB +https://percepio.com +------------------------------------------------------------ + +This directory contains a "stream port" for the Tracealyzer recorder library, +allowing for streaming the trace data over a USB connection. The stream port is defined by a set of macros in +trcStreamPort.h, found in the "include" directory, that relies on functions in trcStreamingPort.c. + +This particular stream port targets STM32 devices using USB CDC (virtual COM port). +It was been tested with STM32F767 and STM32L475. + +--- Prerequisites --- + +- An STM32 device with a USB connector for application use. + +- Tracealyzer 4 with a license for FreeRTOS, SafeRTOS or Micrium µC/OS-III. + +- STM32CubeIDE or the stand-alone STM32CubeMX configuration tool. + +--- Instructions --- + +1. Follow the general instructions (Section 1) at https://percepio.com/gettingstarted-freertos/ +and verify that Snapshot mode works. The basic integration of the recorder library is the same. + +2. Open the Device Configuration Tool (STM32CubeMX), e.g. by double-clicking on the .ioc file in your STM32CubeIDE project. + +2.1. Under "Middleware", enable "USB_DEVICE" and... +- In "USB_DEVICE Mode and Configuration", set the "Class for FS IP" to "Communication Device Class (Virtual Com Port)". +- Under Configuration -> Parameter Settings, set the TX and RX buffer sizes to a small value (e.g. 1). +The default TX and RX buffers are not used by the trace recorder library, so this avoids wasting RAM. + +2.2. Under "Connectivity", open "USB_OTG_FS" and... +- In "USB_OTG_FS Mode and Configuration", make sure "Mode" is set to "Device_Only" +- Under "Configuration", open "NVIC Settings" and make sure "USB OTG FS global interrupt" is enabled. + +3. Open trcConfig.h and set TRC_CFG_RECORDER_MODE to TRC_RECORDER_MODE_STREAMING. + +4. Copy trcStreamingPort.c and include/trcStreamPort.h into your project. + +5. Make sure you have "vTraceEnable(TRC_INIT);" in main.c (not TRC_START or so). +This should be placed after the HW setup but before making any RTOS calls. + +6. Plug in a USB cable to the connector labeled "USB OTG" or similar (i.e. for application use). + +7. Build the project and start it. Check that your computer finds a new USB device (there should be a notification). + +8. Check the number of the new COM port, that should have appeared. This is NOT "STLink Virtual COM port". + +9. Start Tracealyzer and open Recording Settings and select Target Connection: SerialPort. +You can also access these settings via File -> Settings -> PSF Streaming Settings. + +10. Enter the number of the COM port in the "Device" field. The settings (data +bits, data rate etc.) are irrelevant for USB serial connections and not used. + +11. While the target is running, select Record Streaming Trace in Tracealyzer. +You should now see a live display of the trace, while it is being received. +Make sure there are no warnings about "Dropped Events" (in that case, see Troubleshooting, below). + +Note that you can still debug and use breakpoints while streaming the trace. + +--- Further reading --- + +- http://percepio.com/2017/02/03/usb-trace-streaming-st-nucleo-f767zi-board +- http://percepio.com/2016/10/05/rtos-tracing +- https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ + +--- Troubleshooting --- + +A. If you get an error about "multiple definition of SysTick_Handler", open +FreeRTOSConfig.h (found in Core/Inc) and add this line in the bottom, +after the definition of xPortSysTickHandler. + +#undef xPortSysTickHandler + +B. If you get "Missed Events" in the Live Stream window, it is typically because +your application produces more trace data than can be transferred, so the trace +buffer overflows. +You may try the following to start with: +- Increase TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT and/or TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE in trcStreamingConfig.h +- Decrease TRC_CFG_CTRL_TASK_DELAY in trcConfig.h +- Increase TRC_CFG_CTRL_TASK_PRIORITY in trcConfig.h + +Also see the "tuning" guide at https://percepio.com/2018/10/11/tuning-your-custom-trace-streaming/ + +Also note that this USB stream port has a diagnostics option that might come handy. +Enable USB_PERF_DIAGNOSTICS in trcStreamPort.h. This will save additional "user events" +each time a buffer page is transmitted, showing the number of bytes sent and the +remaining capacity in the trace buffer (if this goes down to zero, data is lost). + +#define USB_PERF_DIAGNOSTICS 1 + +If you need assistance, feel free to contact support@percepio.com. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/config/trcStreamPortConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/config/trcStreamPortConfig.h index 7130bf362..9aebbd616 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/config/trcStreamPortConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/config/trcStreamPortConfig.h @@ -1,39 +1,39 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The configuration for trace streaming ("stream ports"). - */ - -#ifndef TRC_STREAM_PORT_CONFIG_H -#define TRC_STREAM_PORT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* The time to wait if the USB interface is busy. */ -#define TRC_CFG_STREAM_PORT_DELAY_ON_BUSY 3 - -/******************************************************************************* -* Configuration Macro: TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE -* -* Specifies the size of the usb buffer. -******************************************************************************/ -#define TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE 64 - -/******************************************************************************* -* Configuration Macro: TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE -* -* Specifies the size of the internal buffer. -******************************************************************************/ -#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 10000 - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The configuration for trace streaming ("stream ports"). + */ + +#ifndef TRC_STREAM_PORT_CONFIG_H + #define TRC_STREAM_PORT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/* The time to wait if the USB interface is busy. */ + #define TRC_CFG_STREAM_PORT_DELAY_ON_BUSY 3 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE + * + * Specifies the size of the usb buffer. + ******************************************************************************/ + #define TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE 64 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE + * + * Specifies the size of the internal buffer. + ******************************************************************************/ + #define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 10000 + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/include/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/include/trcStreamPort.h index 5b053fd01..f42c0cc83 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/include/trcStreamPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/include/trcStreamPort.h @@ -1,110 +1,114 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The interface definitions for trace streaming ("stream ports"). - * This "stream port" sets up the recorder to use USB CDC as streaming channel. - * The example is for STM32 using STM32Cube. - */ - -#ifndef TRC_STREAM_PORT_H -#define TRC_STREAM_PORT_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define TRC_USE_INTERNAL_BUFFER 1 - -#define TRC_STREAM_PORT_USB_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) -#define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) - -typedef struct TraceStreamPortBuffer -{ - uint8_t buffer[(TRC_STREAM_PORT_USB_BUFFER_SIZE) + (TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t)]; -} TraceStreamPortBuffer_t; - -traceResult prvTraceCDCReceive(void* data, uint32_t uiSize, int32_t* piBytesReceived); - -traceResult prvTraceCDCTransmit(void* pvData, uint32_t uiSize, int32_t* piBytesSent); - -/** - * @internal Stream port initialize callback. - * - * This function is called by the recorder as part of its initialization phase. - * - * @param[in] pxBuffer Buffer - * - * @retval TRC_FAIL Initialization failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer); - -/** - * @brief Allocates data from the stream port. - * - * @param[in] uiSize Allocation size - * @param[out] ppvData Allocation data pointer - * - * @retval TRC_FAIL Allocate failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)uiSize, xTraceStaticBufferGet(ppvData)) - -/** - * @brief Commits data to the stream port, depending on the implementation/configuration of the - * stream port this data might be directly written to the stream port interface, buffered, or - * something else. - * - * @param[in] pvData Data to commit - * @param[in] uiSize Data to commit size - * @param[out] piBytesCommitted Bytes committed - * - * @retval TRC_FAIL Commit failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortCommit xTraceInternalEventBufferPush - -/** - * @brief Writes data through the stream port interface. - * - * @param[in] pvData Data to write - * @param[in] uiSize Data to write size - * @param[out] piBytesWritten Bytes written - * - * @retval TRC_FAIL Write failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortWriteData prvTraceCDCTransmit - -/** - * @brief Reads data through the stream port interface. - * - * @param[in] pvData Destination data buffer - * @param[in] uiSize Destination data buffer size - * @param[out] piBytesRead Bytes read - * - * @retval TRC_FAIL Read failed - * @retval TRC_SUCCESS Success - */ -#define xTraceStreamPortReadData prvTraceCDCReceive - -#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS) - -#define xTraceStreamPortOnDisable() (TRC_SUCCESS) - -#define xTraceStreamPortOnTraceBegin() (TRC_SUCCESS) - -#define xTraceStreamPortOnTraceEnd() (TRC_SUCCESS) - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface definitions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to use USB CDC as streaming channel. + * The example is for STM32 using STM32Cube. + */ + +#ifndef TRC_STREAM_PORT_H + #define TRC_STREAM_PORT_H + + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + + #define TRC_USE_INTERNAL_BUFFER 1 + + #define TRC_STREAM_PORT_USB_BUFFER_SIZE ( ( ( ( TRC_CFG_STREAM_PORT_USB_BUFFER_SIZE ) + sizeof( TraceUnsignedBaseType_t ) - 1 ) / sizeof( TraceUnsignedBaseType_t ) ) * sizeof( TraceUnsignedBaseType_t ) ) + #define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ( ( ( ( TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE ) + sizeof( TraceUnsignedBaseType_t ) - 1 ) / sizeof( TraceUnsignedBaseType_t ) ) * sizeof( TraceUnsignedBaseType_t ) ) + + typedef struct TraceStreamPortBuffer + { + uint8_t buffer[ ( TRC_STREAM_PORT_USB_BUFFER_SIZE ) + ( TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ) + sizeof( TraceUnsignedBaseType_t ) ]; + } TraceStreamPortBuffer_t; + + traceResult prvTraceCDCReceive( void * data, + uint32_t uiSize, + int32_t * piBytesReceived ); + + traceResult prvTraceCDCTransmit( void * pvData, + uint32_t uiSize, + int32_t * piBytesSent ); + +/** + * @internal Stream port initialize callback. + * + * This function is called by the recorder as part of its initialization phase. + * + * @param[in] pxBuffer Buffer + * + * @retval TRC_FAIL Initialization failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ); + +/** + * @brief Allocates data from the stream port. + * + * @param[in] uiSize Allocation size + * @param[out] ppvData Allocation data pointer + * + * @retval TRC_FAIL Allocate failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortAllocate( uiSize, ppvData ) ( ( void ) uiSize, xTraceStaticBufferGet( ppvData ) ) + +/** + * @brief Commits data to the stream port, depending on the implementation/configuration of the + * stream port this data might be directly written to the stream port interface, buffered, or + * something else. + * + * @param[in] pvData Data to commit + * @param[in] uiSize Data to commit size + * @param[out] piBytesCommitted Bytes committed + * + * @retval TRC_FAIL Commit failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortCommit xTraceInternalEventBufferPush + +/** + * @brief Writes data through the stream port interface. + * + * @param[in] pvData Data to write + * @param[in] uiSize Data to write size + * @param[out] piBytesWritten Bytes written + * + * @retval TRC_FAIL Write failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortWriteData prvTraceCDCTransmit + +/** + * @brief Reads data through the stream port interface. + * + * @param[in] pvData Destination data buffer + * @param[in] uiSize Destination data buffer size + * @param[out] piBytesRead Bytes read + * + * @retval TRC_FAIL Read failed + * @retval TRC_SUCCESS Success + */ + #define xTraceStreamPortReadData prvTraceCDCReceive + + #define xTraceStreamPortOnEnable( uiStartOption ) ( ( void ) ( uiStartOption ), TRC_SUCCESS ) + + #define xTraceStreamPortOnDisable() ( TRC_SUCCESS ) + + #define xTraceStreamPortOnTraceBegin() ( TRC_SUCCESS ) + + #define xTraceStreamPortOnTraceEnd() ( TRC_SUCCESS ) + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/trcStreamPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/trcStreamPort.c index b89144e02..c28bc48b4 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/trcStreamPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/STM32_USB_CDC/trcStreamPort.c @@ -1,151 +1,158 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Supporting functions for trace streaming ("stream ports"). - * This "stream port" sets up the recorder to use USB CDC as streaming channel. - * The example is for STM32 using STM32Cube. - */ - -#include - -#include -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -static void prvCDCInit(void); - -static int8_t CDC_Receive_FS_modified(uint8_t* pbuf, uint32_t *puiLength); - -extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; - -static int8_t(*CDC_Receive_FS)(uint8_t* Buf, uint32_t* Len); - -typedef struct TraceStreamPortUSBCommandBuffer { - TraceUnsignedBaseType_t idx; - uint8_t bufferUSB[TRC_STREAM_PORT_USB_BUFFER_SIZE]; - uint8_t bufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE]; -} TraceStreamPortUSBBuffers_t; - -TraceStreamPortUSBBuffers_t* pxUSBBuffers; - -static int8_t CDC_Receive_FS_modified(uint8_t* pBuffer, uint32_t *puiLength) -{ - for(uint32_t i = 0; i < *puiLength; i++) - { - pxUSBBuffers->bufferUSB[pxUSBBuffers->idx] = pBuffer[i]; - pxUSBBuffers->idx++; - } - - CDC_Receive_FS(pBuffer, puiLength); - - return (USBD_OK); -} - -static void prvCDCInit(void) -{ - /* Store the original "Receive" function, from the static initialization */ - CDC_Receive_FS = USBD_Interface_fops_FS.Receive; - - /* Update the function pointer with our modified variant */ - USBD_Interface_fops_FS.Receive = CDC_Receive_FS_modified; - - pxUSBBuffers->idx = 0; - - MX_USB_DEVICE_Init(); -} - -/* The READ function, used in trcStreamPort.h */ -traceResult prvTraceCDCReceive(void *data, uint32_t uiSize, int32_t* piBytesReceived) -{ - uint32_t i, uiDiff; - - if(pxUSBBuffers->idx > 0) - { - if ((TraceUnsignedBaseType_t)uiSize >= pxUSBBuffers->idx) // More than what is stored, number of bytes will be .idx - { - TRC_MEMCPY(data, pxUSBBuffers->bufferUSB, pxUSBBuffers->idx); - *piBytesReceived = (int32_t)pxUSBBuffers->idx; - pxUSBBuffers->idx = 0; // Make the buffer ready for a new command - } - else // If some data in the buffer is not read - { - uiDiff = pxUSBBuffers->idx - uiSize; - TRC_MEMCPY(data, pxUSBBuffers->bufferUSB, uiSize); - - for(i = 0; i < uiDiff; i++) - { - pxUSBBuffers->bufferUSB[i] = pxUSBBuffers->bufferUSB[i + uiSize]; - } - - *piBytesReceived = uiSize; - - pxUSBBuffers->idx = uiDiff; - } - } - else - { - *piBytesReceived = 0; - } - - return TRC_SUCCESS; -} - -/* The WRITE function, used in trcStreamPort.h */ -traceResult prvTraceCDCTransmit(void* pvData, uint32_t uiSize, int32_t * piBytesSent ) -{ - static int fail_counter = 0; - - int32_t result; - - *piBytesSent = 0; - - result = CDC_Transmit_FS(pvData, uiSize); - - if (result == USBD_OK) - { - fail_counter = 0; - *piBytesSent = uiSize; - return TRC_SUCCESS; - } - else - { - fail_counter++; - - /* We keep trying to send more pvData. If busy, we delay for a while. This function will be called again afterwards. */ - xTraceKernelPortDelay(TRC_CFG_STREAM_PORT_DELAY_ON_BUSY); - - if (fail_counter >= 100) - { - /* If many unsuccessful attempts in a row, something is very wrong. Returning -1 will stop the recorder. */ - return TRC_FAIL; - } - } - - return TRC_SUCCESS; -} - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortUSBBuffers_t); - - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - pxUSBBuffers = (TraceStreamPortUSBBuffers_t*)pxBuffer; - - prvCDCInit(); - - return xTraceInternalEventBufferInitialize(pxUSBBuffers->bufferInternal, sizeof(pxUSBBuffers->bufferInternal)); -} - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ - +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Supporting functions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to use USB CDC as streaming channel. + * The example is for STM32 using STM32Cube. + */ + +#include + +#include +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + static void prvCDCInit( void ); + + static int8_t CDC_Receive_FS_modified( uint8_t * pbuf, + uint32_t * puiLength ); + + extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; + + static int8_t (* CDC_Receive_FS)( uint8_t * Buf, + uint32_t * Len ); + + typedef struct TraceStreamPortUSBCommandBuffer + { + TraceUnsignedBaseType_t idx; + uint8_t bufferUSB[ TRC_STREAM_PORT_USB_BUFFER_SIZE ]; + uint8_t bufferInternal[ TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ]; + } TraceStreamPortUSBBuffers_t; + + TraceStreamPortUSBBuffers_t * pxUSBBuffers; + + static int8_t CDC_Receive_FS_modified( uint8_t * pBuffer, + uint32_t * puiLength ) + { + for( uint32_t i = 0; i < *puiLength; i++ ) + { + pxUSBBuffers->bufferUSB[ pxUSBBuffers->idx ] = pBuffer[ i ]; + pxUSBBuffers->idx++; + } + + CDC_Receive_FS( pBuffer, puiLength ); + + return( USBD_OK ); + } + + static void prvCDCInit( void ) + { + /* Store the original "Receive" function, from the static initialization */ + CDC_Receive_FS = USBD_Interface_fops_FS.Receive; + + /* Update the function pointer with our modified variant */ + USBD_Interface_fops_FS.Receive = CDC_Receive_FS_modified; + + pxUSBBuffers->idx = 0; + + MX_USB_DEVICE_Init(); + } + +/* The READ function, used in trcStreamPort.h */ + traceResult prvTraceCDCReceive( void * data, + uint32_t uiSize, + int32_t * piBytesReceived ) + { + uint32_t i, uiDiff; + + if( pxUSBBuffers->idx > 0 ) + { + if( ( TraceUnsignedBaseType_t ) uiSize >= pxUSBBuffers->idx ) /* More than what is stored, number of bytes will be .idx */ + { + TRC_MEMCPY( data, pxUSBBuffers->bufferUSB, pxUSBBuffers->idx ); + *piBytesReceived = ( int32_t ) pxUSBBuffers->idx; + pxUSBBuffers->idx = 0; /* Make the buffer ready for a new command */ + } + else /* If some data in the buffer is not read */ + { + uiDiff = pxUSBBuffers->idx - uiSize; + TRC_MEMCPY( data, pxUSBBuffers->bufferUSB, uiSize ); + + for( i = 0; i < uiDiff; i++ ) + { + pxUSBBuffers->bufferUSB[ i ] = pxUSBBuffers->bufferUSB[ i + uiSize ]; + } + + *piBytesReceived = uiSize; + + pxUSBBuffers->idx = uiDiff; + } + } + else + { + *piBytesReceived = 0; + } + + return TRC_SUCCESS; + } + +/* The WRITE function, used in trcStreamPort.h */ + traceResult prvTraceCDCTransmit( void * pvData, + uint32_t uiSize, + int32_t * piBytesSent ) + { + static int fail_counter = 0; + + int32_t result; + + *piBytesSent = 0; + + result = CDC_Transmit_FS( pvData, uiSize ); + + if( result == USBD_OK ) + { + fail_counter = 0; + *piBytesSent = uiSize; + return TRC_SUCCESS; + } + else + { + fail_counter++; + + /* We keep trying to send more pvData. If busy, we delay for a while. This function will be called again afterwards. */ + xTraceKernelPortDelay( TRC_CFG_STREAM_PORT_DELAY_ON_BUSY ); + + if( fail_counter >= 100 ) + { + /* If many unsuccessful attempts in a row, something is very wrong. Returning -1 will stop the recorder. */ + return TRC_FAIL; + } + } + + return TRC_SUCCESS; + } + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceStreamPortBuffer_t, TraceStreamPortUSBBuffers_t ); + + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + pxUSBBuffers = ( TraceStreamPortUSBBuffers_t * ) pxBuffer; + + prvCDCInit(); + + return xTraceInternalEventBufferInitialize( pxUSBBuffers->bufferInternal, sizeof( pxUSBBuffers->bufferInternal ) ); + } + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ +#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/Readme-Streamport.txt index 1ec032660..0e285f058 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/Readme-Streamport.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/Readme-Streamport.txt @@ -1,49 +1,49 @@ -Tracealyzer Stream Port for TCP/IP (lwIP example) -Percepio AB -www.percepio.com -------------------------------------------------- - -This directory contains a "stream port" for the Tracealyzer recorder library, -i.e., the specific code needed to use a particular interface for streaming a -Tracealyzer RTOS trace. The stream port is defined by a set of macros in -trcStreamPort.h, found in the "include" directory. - -This particular stream port targets TCP/IP. This example assumes lwIP but is -easy to modify for other TCP/IP stacks. - -Instructions: - -1. Integrate the trace recorder and configure it for streaming, as described - in the Tracealyzer User Manual. For FreeRTOS this is found at: - https://percepio.com/docs/FreeRTOS/manual/index.html#Creating_and_Loading_Traces___Introduction - -2. Make sure all .c and .h files from this stream port folder is included in - your build, and that no other variant of trcStreamPort.h is included. - -3. In lwipopts.h, make sure you have this line: - - #define LWIP_SOCKET 1 - -4. Make sure that vTraceEnable(TRC_INIT) is called during the startup, before - any RTOS calls are made. - -5. In Tracealyzer, open File -> Settings -> PSF Streaming Settings and - select Target Connection: TCP. Enter the IP address of the target system - and the port number (by default 12000). - -6. Start your target system, wait a few seconds to ensure that the lwIP is operational, - then select Start Recording in Tracealyzer. - -Troubleshooting: - -- If the tracing suddenly stops, check the "errno" value in trcSocketSend (trcStreamingPort.c). -You can see the error code definitions in lwip/errno.h. If errno is ENOMEM, may you need to -increase MEM_SIZE in lwipopts.h. - -- Since lwIP performs a lot of semaphore and mutex operations, we recommend filtering out -such events from the trace, at least those caused by the transmission of trace data in the -TzCtrl task. This can be done using vTraceSetFilterGroup() and vTraceSetFilterMask(). - -Note that lwIP is not included in the stream port, but assumed to exist in the project already. - -See also http://percepio.com/2016/10/05/rtos-tracing. +Tracealyzer Stream Port for TCP/IP (lwIP example) +Percepio AB +www.percepio.com +------------------------------------------------- + +This directory contains a "stream port" for the Tracealyzer recorder library, +i.e., the specific code needed to use a particular interface for streaming a +Tracealyzer RTOS trace. The stream port is defined by a set of macros in +trcStreamPort.h, found in the "include" directory. + +This particular stream port targets TCP/IP. This example assumes lwIP but is +easy to modify for other TCP/IP stacks. + +Instructions: + +1. Integrate the trace recorder and configure it for streaming, as described + in the Tracealyzer User Manual. For FreeRTOS this is found at: + https://percepio.com/docs/FreeRTOS/manual/index.html#Creating_and_Loading_Traces___Introduction + +2. Make sure all .c and .h files from this stream port folder is included in + your build, and that no other variant of trcStreamPort.h is included. + +3. In lwipopts.h, make sure you have this line: + + #define LWIP_SOCKET 1 + +4. Make sure that vTraceEnable(TRC_INIT) is called during the startup, before + any RTOS calls are made. + +5. In Tracealyzer, open File -> Settings -> PSF Streaming Settings and + select Target Connection: TCP. Enter the IP address of the target system + and the port number (by default 12000). + +6. Start your target system, wait a few seconds to ensure that the lwIP is operational, + then select Start Recording in Tracealyzer. + +Troubleshooting: + +- If the tracing suddenly stops, check the "errno" value in trcSocketSend (trcStreamingPort.c). +You can see the error code definitions in lwip/errno.h. If errno is ENOMEM, may you need to +increase MEM_SIZE in lwipopts.h. + +- Since lwIP performs a lot of semaphore and mutex operations, we recommend filtering out +such events from the trace, at least those caused by the transmission of trace data in the +TzCtrl task. This can be done using vTraceSetFilterGroup() and vTraceSetFilterMask(). + +Note that lwIP is not included in the stream port, but assumed to exist in the project already. + +See also http://percepio.com/2016/10/05/rtos-tracing. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/config/trcStreamPortConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/config/trcStreamPortConfig.h index 76ad0744e..58e04bf84 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/config/trcStreamPortConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/config/trcStreamPortConfig.h @@ -1,41 +1,41 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The configuration for trace streaming ("stream ports"). - */ - -#ifndef TRC_STREAM_PORT_CONFIG_H -#define TRC_STREAM_PORT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* This define will determine whether to use the internal buffer or not. -If file writing creates additional trace events (i.e. it uses semaphores or mutexes), -then the internal buffer must be enabled to avoid infinite recursion. */ -#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0 - -/******************************************************************************* -* Configuration Macro: TRC_CFG_STREAM_PORT_TCPIP_PORT -* -* Specifies the TCP/IP port. -******************************************************************************/ -#define TRC_CFG_STREAM_PORT_TCPIP_PORT 8888 - -/******************************************************************************* -* Configuration Macro: TRC_CFG_STREAM_PORT_BUFFER_SIZE -* -* Specifies the size of the internal buffer, if one is used. -******************************************************************************/ -#define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000 - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The configuration for trace streaming ("stream ports"). + */ + +#ifndef TRC_STREAM_PORT_CONFIG_H + #define TRC_STREAM_PORT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/* This define will determine whether to use the internal buffer or not. + * If file writing creates additional trace events (i.e. it uses semaphores or mutexes), + * then the internal buffer must be enabled to avoid infinite recursion. */ + #define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_STREAM_PORT_TCPIP_PORT + * + * Specifies the TCP/IP port. + ******************************************************************************/ + #define TRC_CFG_STREAM_PORT_TCPIP_PORT 8888 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_STREAM_PORT_BUFFER_SIZE + * + * Specifies the size of the internal buffer, if one is used. + ******************************************************************************/ + #define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000 + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamPort.h index 7dc0ceb3c..e93505b8a 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/include/trcStreamPort.h @@ -1,75 +1,78 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The interface definitions for trace streaming ("stream ports"). - * This "stream port" sets up the recorder to use TCP/IP as streaming channel. - * The example is for lwIP. - */ - -#ifndef TRC_STREAM_PORT_H -#define TRC_STREAM_PORT_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER) - -/** - * @def TRC_STREAM_PORT_BUFFER_SIZE - * - * @brief The buffer size, aligned to base type. - */ -#define TRC_STREAM_PORT_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) - -typedef struct TraceStreamPortBuffer -{ -#if (TRC_USE_INTERNAL_BUFFER) - uint8_t buffer[(TRC_STREAM_PORT_BUFFER_SIZE)]; -#else - TraceUnsignedBaseType_t buffer[1]; -#endif -} TraceStreamPortBuffer_t; - -int32_t prvTraceTcpWrite(void* pvData, uint32_t uiSize, int32_t* piBytesWritten); - -int32_t prvTraceTcpRead(void* pvData, uint32_t uiSize, int32_t* piBytesRead); - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer); - -#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData)) - -#if (TRC_USE_INTERNAL_BUFFER == 1) -/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */ -#define xTraceStreamPortCommit xTraceInternalEventBufferPush -#else -/* Write directly */ -#define xTraceStreamPortCommit xTraceStreamPortWriteData -#endif - -#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) (prvTraceTcpWrite(pvData, uiSize, piBytesWritten) == 0 ? TRC_SUCCESS : TRC_FAIL) - -#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) (prvTraceTcpRead(pvData, uiSize, piBytesRead) == 0 ? TRC_SUCCESS : TRC_FAIL) - -#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS) - -#define xTraceStreamPortOnDisable() (TRC_SUCCESS) - -#define xTraceStreamPortOnTraceBegin() (TRC_SUCCESS) - -traceResult xTraceStreamPortOnTraceEnd(void); - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_H */ - +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface definitions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to use TCP/IP as streaming channel. + * The example is for lwIP. + */ + +#ifndef TRC_STREAM_PORT_H + #define TRC_STREAM_PORT_H + + #include + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + + #define TRC_USE_INTERNAL_BUFFER ( TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER ) + +/** + * @def TRC_STREAM_PORT_BUFFER_SIZE + * + * @brief The buffer size, aligned to base type. + */ + #define TRC_STREAM_PORT_BUFFER_SIZE ( ( ( ( TRC_CFG_STREAM_PORT_BUFFER_SIZE ) + sizeof( TraceUnsignedBaseType_t ) - 1 ) / sizeof( TraceUnsignedBaseType_t ) ) * sizeof( TraceUnsignedBaseType_t ) ) + + typedef struct TraceStreamPortBuffer + { + #if ( TRC_USE_INTERNAL_BUFFER ) + uint8_t buffer[ ( TRC_STREAM_PORT_BUFFER_SIZE ) ]; + #else + TraceUnsignedBaseType_t buffer[ 1 ]; + #endif + } TraceStreamPortBuffer_t; + + int32_t prvTraceTcpWrite( void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ); + + int32_t prvTraceTcpRead( void * pvData, + uint32_t uiSize, + int32_t * piBytesRead ); + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ); + + #define xTraceStreamPortAllocate( uiSize, ppvData ) ( ( void ) ( uiSize ), xTraceStaticBufferGet( ppvData ) ) + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) +/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */ + #define xTraceStreamPortCommit xTraceInternalEventBufferPush + #else +/* Write directly */ + #define xTraceStreamPortCommit xTraceStreamPortWriteData + #endif + + #define xTraceStreamPortWriteData( pvData, uiSize, piBytesWritten ) ( prvTraceTcpWrite( pvData, uiSize, piBytesWritten ) == 0 ? TRC_SUCCESS : TRC_FAIL ) + + #define xTraceStreamPortReadData( pvData, uiSize, piBytesRead ) ( prvTraceTcpRead( pvData, uiSize, piBytesRead ) == 0 ? TRC_SUCCESS : TRC_FAIL ) + + #define xTraceStreamPortOnEnable( uiStartOption ) ( ( void ) ( uiStartOption ), TRC_SUCCESS ) + + #define xTraceStreamPortOnDisable() ( TRC_SUCCESS ) + + #define xTraceStreamPortOnTraceBegin() ( TRC_SUCCESS ) + + traceResult xTraceStreamPortOnTraceEnd( void ); + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamPort.c index 9ff82d1f2..0e8e67164 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP/trcStreamPort.c @@ -1,205 +1,235 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Supporting functions for trace streaming, used by the "stream ports" - * for reading and writing data to the interface. - * Existing ports can easily be modified to fit another setup, e.g., a - * different TCP/IP stack, or to define your own stream port. - */ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -/* TCP/IP includes - for lwIP in this case */ -#include -#include -#include - -int sock = -1, new_sd = -1; -int flags = 0; -int remoteSize; -struct sockaddr_in address, remote; - -typedef struct TraceStreamPortTCPIP -{ -#if (TRC_USE_INTERNAL_BUFFER) - uint8_t buffer[(TRC_STREAM_PORT_BUFFER_SIZE)]; -#else - TraceUnsignedBaseType_t buffer[1]; -#endif -} TraceStreamPortTCPIP_t; - -static TraceStreamPortTCPIP_t* pxStreamPortFile; - -static int32_t prvSocketSend(void* pvData, uint32_t uiSize, int32_t* piBytesWritten); -static int32_t prvSocketReceive(void* pvData, uint32_t uiSize, int32_t* bytesRead); -static int32_t prvSocketInitializeListener(); -static int32_t prvSocketAccept(); -static void prvCloseAllSockets(); - -static int32_t prvSocketSend( void* pvData, uint32_t uiSize, int32_t* piBytesWritten ) -{ - if (new_sd < 0) - return -1; - - if (piBytesWritten == 0) - return -1; - - *piBytesWritten = send( new_sd, pvData, uiSize, 0 ); - if (*piBytesWritten < 0) - { - /* EWOULDBLOCK may be expected when buffers are full */ - if ((errno != 0) && (errno != EWOULDBLOCK)) - { - closesocket(new_sd); - new_sd = -1; - return -1; - } - else - *piBytesWritten = 0; - } - - return 0; -} - -static int32_t prvSocketReceive( void* pvData, uint32_t uiSize, int32_t* bytesRead ) -{ - if (new_sd < 0) - return -1; - - *bytesRead = recv( new_sd, pvData, uiSize, 0 ); - /* EWOULDBLOCK may be expected when there is no pvData to receive */ - if (errno != 0 && errno != EWOULDBLOCK) - { - closesocket(new_sd); - new_sd = -1; - return -1; - } - - return 0; -} - -static int32_t prvSocketInitializeListener() -{ - if (sock >= 0) - return 0; - - sock = lwip_socket(AF_INET, SOCK_STREAM, 0); - - if (sock < 0) - return -1; - - address.sin_family = AF_INET; - address.sin_port = htons(TRC_CFG_STREAM_PORT_TCPIP_PORT); - address.sin_addr.s_addr = INADDR_ANY; - - if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0) - { - closesocket(sock); - sock = -1; - return -1; - } - - if (lwip_listen(sock, 5) < 0) - { - closesocket(sock); - sock = -1; - return -1; - } - - return 0; -} - -static int32_t prvSocketAccept() -{ - if (sock < 0) - return -1; - - if (new_sd >= 0) - return 0; - - remoteSize = sizeof( remote ); - new_sd = accept( sock, (struct sockaddr *)&remote, (socklen_t*)&remoteSize ); - - if( new_sd < 0 ) - { - closesocket(new_sd); - new_sd = -1; - closesocket(sock); - sock = -1; - return -1; - } - - flags = fcntl( new_sd, F_GETFL, 0 ); - fcntl( new_sd, F_SETFL, flags | O_NONBLOCK ); - - return 0; -} - -static void prvCloseAllSockets() -{ - if (new_sd > 0) - { - closesocket(new_sd); - } - - if (sock > 0) - { - closesocket(sock); - } -} -/************** MODIFY THE ABOVE PART TO USE YOUR TPC/IP STACK ****************/ - -int32_t prvTraceTcpWrite(void* pvData, uint32_t uiSize, int32_t *piBytesWritten) -{ - prvSocketInitializeListener(); - - prvSocketAccept(); - - return prvSocketSend(pvData, uiSize, piBytesWritten); -} - -int32_t prvTraceTcpRead(void* pvData, uint32_t uiSize, int32_t *piBytesRead) -{ - prvSocketInitializeListener(); - - prvSocketAccept(); - - return prvSocketReceive(pvData, uiSize, piBytesRead); -} - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortTCPIP_t); - - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - pxStreamPortFile = (TraceStreamPortTCPIP_t*)pxBuffer; - -#if (TRC_USE_INTERNAL_BUFFER == 1) - return xTraceInternalEventBufferInitialize(pxStreamPortFile->buffer, sizeof(pxStreamPortFile->buffer)); -#else - return TRC_SUCCESS; -#endif -} - -traceResult xTraceStreamPortOnTraceEnd(void) -{ - prvCloseAllSockets(); - - return TRC_SUCCESS; -} - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Supporting functions for trace streaming, used by the "stream ports" + * for reading and writing data to the interface. + * Existing ports can easily be modified to fit another setup, e.g., a + * different TCP/IP stack, or to define your own stream port. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + +/* TCP/IP includes - for lwIP in this case */ + #include + #include + #include + + int sock = -1, new_sd = -1; + int flags = 0; + int remoteSize; + struct sockaddr_in address, remote; + + typedef struct TraceStreamPortTCPIP + { + #if ( TRC_USE_INTERNAL_BUFFER ) + uint8_t buffer[ ( TRC_STREAM_PORT_BUFFER_SIZE ) ]; + #else + TraceUnsignedBaseType_t buffer[ 1 ]; + #endif + } TraceStreamPortTCPIP_t; + + static TraceStreamPortTCPIP_t * pxStreamPortFile; + + static int32_t prvSocketSend( void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ); + static int32_t prvSocketReceive( void * pvData, + uint32_t uiSize, + int32_t * bytesRead ); + static int32_t prvSocketInitializeListener(); + static int32_t prvSocketAccept(); + static void prvCloseAllSockets(); + + static int32_t prvSocketSend( void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ) + { + if( new_sd < 0 ) + { + return -1; + } + + if( piBytesWritten == 0 ) + { + return -1; + } + + *piBytesWritten = send( new_sd, pvData, uiSize, 0 ); + + if( *piBytesWritten < 0 ) + { + /* EWOULDBLOCK may be expected when buffers are full */ + if( ( errno != 0 ) && ( errno != EWOULDBLOCK ) ) + { + closesocket( new_sd ); + new_sd = -1; + return -1; + } + else + { + *piBytesWritten = 0; + } + } + + return 0; + } + + static int32_t prvSocketReceive( void * pvData, + uint32_t uiSize, + int32_t * bytesRead ) + { + if( new_sd < 0 ) + { + return -1; + } + + *bytesRead = recv( new_sd, pvData, uiSize, 0 ); + + /* EWOULDBLOCK may be expected when there is no pvData to receive */ + if( ( errno != 0 ) && ( errno != EWOULDBLOCK ) ) + { + closesocket( new_sd ); + new_sd = -1; + return -1; + } + + return 0; + } + + static int32_t prvSocketInitializeListener() + { + if( sock >= 0 ) + { + return 0; + } + + sock = lwip_socket( AF_INET, SOCK_STREAM, 0 ); + + if( sock < 0 ) + { + return -1; + } + + address.sin_family = AF_INET; + address.sin_port = htons( TRC_CFG_STREAM_PORT_TCPIP_PORT ); + address.sin_addr.s_addr = INADDR_ANY; + + if( bind( sock, ( struct sockaddr * ) &address, sizeof( address ) ) < 0 ) + { + closesocket( sock ); + sock = -1; + return -1; + } + + if( lwip_listen( sock, 5 ) < 0 ) + { + closesocket( sock ); + sock = -1; + return -1; + } + + return 0; + } + + static int32_t prvSocketAccept() + { + if( sock < 0 ) + { + return -1; + } + + if( new_sd >= 0 ) + { + return 0; + } + + remoteSize = sizeof( remote ); + new_sd = accept( sock, ( struct sockaddr * ) &remote, ( socklen_t * ) &remoteSize ); + + if( new_sd < 0 ) + { + closesocket( new_sd ); + new_sd = -1; + closesocket( sock ); + sock = -1; + return -1; + } + + flags = fcntl( new_sd, F_GETFL, 0 ); + fcntl( new_sd, F_SETFL, flags | O_NONBLOCK ); + + return 0; + } + + static void prvCloseAllSockets() + { + if( new_sd > 0 ) + { + closesocket( new_sd ); + } + + if( sock > 0 ) + { + closesocket( sock ); + } + } +/************** MODIFY THE ABOVE PART TO USE YOUR TPC/IP STACK ****************/ + + int32_t prvTraceTcpWrite( void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ) + { + prvSocketInitializeListener(); + + prvSocketAccept(); + + return prvSocketSend( pvData, uiSize, piBytesWritten ); + } + + int32_t prvTraceTcpRead( void * pvData, + uint32_t uiSize, + int32_t * piBytesRead ) + { + prvSocketInitializeListener(); + + prvSocketAccept(); + + return prvSocketReceive( pvData, uiSize, piBytesRead ); + } + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceStreamPortBuffer_t, TraceStreamPortTCPIP_t ); + + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + pxStreamPortFile = ( TraceStreamPortTCPIP_t * ) pxBuffer; + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + return xTraceInternalEventBufferInitialize( pxStreamPortFile->buffer, sizeof( pxStreamPortFile->buffer ) ); + #else + return TRC_SUCCESS; + #endif + } + + traceResult xTraceStreamPortOnTraceEnd( void ) + { + prvCloseAllSockets(); + + return TRC_SUCCESS; + } + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + +#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/Readme-Streamport.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/Readme-Streamport.txt index 6738fd47c..a628f65d0 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/Readme-Streamport.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/Readme-Streamport.txt @@ -1,37 +1,37 @@ -Tracealyzer Stream Port for TCP/IP (Win32 example) -Percepio AB -www.percepio.com -------------------------------------------------- - -This directory contains a "stream port" for the Tracealyzer recorder library, -i.e., the I/O code needed for streaming a Tracealyzer RTOS trace over specific -interface. The stream port is defined by a set of macros in trcStreamPort.h, -found in the "include" directory. - -This particular stream port is for streaming over TCP/IP on Windows, intended -for the FreeRTOS Windows port (WIN32-MSVC). To try it: - -1. Open the WIN32-MSVC demo project found in the FreeRTOS demo folder. You -need will Visual Studio, but there are free versions (Express or Community). - -2. Make sure the project includes a recent version or the recorder library -(v3.1.x). - -3. Make sure the recorder library is configured for streaming mode (see -trcConfig.h). - -4. Make sure the project's include paths contains trcStreamPort.h found in -this include folder (and not any other stream port), and the related code -in this folder. - -5. Build and start the Win32 demo application. It should begin waiting for -a connection. - -6. In Tracealyzer, open File -> Settings... -> Streaming Trace Settings. -Specify target connection: TCP, host: 127.0.0.1 (i.e. localhost) and port 8888. - -7. In Tracealyzer, now open File -> Connect to Target System... and there -click "Start Recording". Now you should see a live CPU load graph and some -counters. Let it record for a few seconds, then click "Stop Recording" and then "View Trace". - -See also http://percepio.com/2016/10/05/rtos-tracing. +Tracealyzer Stream Port for TCP/IP (Win32 example) +Percepio AB +www.percepio.com +------------------------------------------------- + +This directory contains a "stream port" for the Tracealyzer recorder library, +i.e., the I/O code needed for streaming a Tracealyzer RTOS trace over specific +interface. The stream port is defined by a set of macros in trcStreamPort.h, +found in the "include" directory. + +This particular stream port is for streaming over TCP/IP on Windows, intended +for the FreeRTOS Windows port (WIN32-MSVC). To try it: + +1. Open the WIN32-MSVC demo project found in the FreeRTOS demo folder. You +need will Visual Studio, but there are free versions (Express or Community). + +2. Make sure the project includes a recent version or the recorder library +(v3.1.x). + +3. Make sure the recorder library is configured for streaming mode (see +trcConfig.h). + +4. Make sure the project's include paths contains trcStreamPort.h found in +this include folder (and not any other stream port), and the related code +in this folder. + +5. Build and start the Win32 demo application. It should begin waiting for +a connection. + +6. In Tracealyzer, open File -> Settings... -> Streaming Trace Settings. +Specify target connection: TCP, host: 127.0.0.1 (i.e. localhost) and port 8888. + +7. In Tracealyzer, now open File -> Connect to Target System... and there +click "Start Recording". Now you should see a live CPU load graph and some +counters. Let it record for a few seconds, then click "Stop Recording" and then "View Trace". + +See also http://percepio.com/2016/10/05/rtos-tracing. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/config/trcStreamPortConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/config/trcStreamPortConfig.h index 76ad0744e..58e04bf84 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/config/trcStreamPortConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/config/trcStreamPortConfig.h @@ -1,41 +1,41 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The configuration for trace streaming ("stream ports"). - */ - -#ifndef TRC_STREAM_PORT_CONFIG_H -#define TRC_STREAM_PORT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* This define will determine whether to use the internal buffer or not. -If file writing creates additional trace events (i.e. it uses semaphores or mutexes), -then the internal buffer must be enabled to avoid infinite recursion. */ -#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0 - -/******************************************************************************* -* Configuration Macro: TRC_CFG_STREAM_PORT_TCPIP_PORT -* -* Specifies the TCP/IP port. -******************************************************************************/ -#define TRC_CFG_STREAM_PORT_TCPIP_PORT 8888 - -/******************************************************************************* -* Configuration Macro: TRC_CFG_STREAM_PORT_BUFFER_SIZE -* -* Specifies the size of the internal buffer, if one is used. -******************************************************************************/ -#define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000 - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The configuration for trace streaming ("stream ports"). + */ + +#ifndef TRC_STREAM_PORT_CONFIG_H + #define TRC_STREAM_PORT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/* This define will determine whether to use the internal buffer or not. + * If file writing creates additional trace events (i.e. it uses semaphores or mutexes), + * then the internal buffer must be enabled to avoid infinite recursion. */ + #define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 0 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_STREAM_PORT_TCPIP_PORT + * + * Specifies the TCP/IP port. + ******************************************************************************/ + #define TRC_CFG_STREAM_PORT_TCPIP_PORT 8888 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_STREAM_PORT_BUFFER_SIZE + * + * Specifies the size of the internal buffer, if one is used. + ******************************************************************************/ + #define TRC_CFG_STREAM_PORT_BUFFER_SIZE 10000 + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/include/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/include/trcStreamPort.h index fae09bdfa..08a0abdb2 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/include/trcStreamPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/include/trcStreamPort.h @@ -1,81 +1,85 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The interface definitions for trace streaming ("stream ports"). - * This "stream port" sets up the recorder to use TCP/IP as streaming channel. - * The example is for Windows sockets (Winsock), for use with Windows ports. - */ - -#ifndef TRC_STREAM_PORT_H -#define TRC_STREAM_PORT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER) - -/** - * @def TRC_STREAM_PORT_BUFFER_SIZE - * - * @brief The buffer size, aligned to base type. - */ -#define TRC_STREAM_PORT_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) - -typedef struct TraceStreamPortBuffer -{ -#if (TRC_USE_INTERNAL_BUFFER) - uint8_t buffer[(TRC_STREAM_PORT_BUFFER_SIZE)]; -#else - TraceUnsignedBaseType_t buffer[1]; -#endif -} TraceStreamPortBuffer_t; - -int32_t prvTraceWriteToSocket(void* data, uint32_t size, int32_t* ptrBytesWritten); -int32_t prvTraceReadFromSocket(void* data, uint32_t bufsize, int32_t* ptrBytesRead); - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer); - -#define xTraceStreamPortAllocate(uiSize, ppvData) ((void)(uiSize), xTraceStaticBufferGet(ppvData)) - -#if (TRC_USE_INTERNAL_BUFFER == 1) -/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */ -#define xTraceStreamPortCommit xTraceInternalEventBufferPush -#else -/* Write directly */ -#define xTraceStreamPortCommit xTraceStreamPortWriteData -#endif - -#define xTraceStreamPortWriteData(pvData, uiSize, piBytesWritten) (prvTraceWriteToSocket(pvData, uiSize, piBytesWritten) == 0 ? TRC_SUCCESS : TRC_FAIL) - -#define xTraceStreamPortReadData(pvData, uiSize, piBytesRead) (prvTraceReadFromSocket(pvData, uiSize, piBytesRead) == 0 ? TRC_SUCCESS : TRC_FAIL) - -#define xTraceStreamPortOnEnable(uiStartOption) ((void)(uiStartOption), TRC_SUCCESS) - -#define xTraceStreamPortOnDisable() (TRC_SUCCESS) - -#define xTraceStreamPortOnTraceBegin() (TRC_SUCCESS) - -traceResult xTraceStreamPortOnTraceEnd(void); - -#ifdef __cplusplus -} -#endif - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ - -#endif /* TRC_STREAM_PORT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface definitions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to use TCP/IP as streaming channel. + * The example is for Windows sockets (Winsock), for use with Windows ports. + */ + +#ifndef TRC_STREAM_PORT_H + #define TRC_STREAM_PORT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + #include + #include + + #ifdef __cplusplus + extern "C" { + #endif + + #define TRC_USE_INTERNAL_BUFFER ( TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER ) + +/** + * @def TRC_STREAM_PORT_BUFFER_SIZE + * + * @brief The buffer size, aligned to base type. + */ + #define TRC_STREAM_PORT_BUFFER_SIZE ( ( ( ( TRC_CFG_STREAM_PORT_BUFFER_SIZE ) + sizeof( TraceUnsignedBaseType_t ) - 1 ) / sizeof( TraceUnsignedBaseType_t ) ) * sizeof( TraceUnsignedBaseType_t ) ) + + typedef struct TraceStreamPortBuffer + { + #if ( TRC_USE_INTERNAL_BUFFER ) + uint8_t buffer[ ( TRC_STREAM_PORT_BUFFER_SIZE ) ]; + #else + TraceUnsignedBaseType_t buffer[ 1 ]; + #endif + } TraceStreamPortBuffer_t; + + int32_t prvTraceWriteToSocket( void * data, + uint32_t size, + int32_t * ptrBytesWritten ); + int32_t prvTraceReadFromSocket( void * data, + uint32_t bufsize, + int32_t * ptrBytesRead ); + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ); + + #define xTraceStreamPortAllocate( uiSize, ppvData ) ( ( void ) ( uiSize ), xTraceStaticBufferGet( ppvData ) ) + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) +/* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */ + #define xTraceStreamPortCommit xTraceInternalEventBufferPush + #else +/* Write directly */ + #define xTraceStreamPortCommit xTraceStreamPortWriteData + #endif + + #define xTraceStreamPortWriteData( pvData, uiSize, piBytesWritten ) ( prvTraceWriteToSocket( pvData, uiSize, piBytesWritten ) == 0 ? TRC_SUCCESS : TRC_FAIL ) + + #define xTraceStreamPortReadData( pvData, uiSize, piBytesRead ) ( prvTraceReadFromSocket( pvData, uiSize, piBytesRead ) == 0 ? TRC_SUCCESS : TRC_FAIL ) + + #define xTraceStreamPortOnEnable( uiStartOption ) ( ( void ) ( uiStartOption ), TRC_SUCCESS ) + + #define xTraceStreamPortOnDisable() ( TRC_SUCCESS ) + + #define xTraceStreamPortOnTraceBegin() ( TRC_SUCCESS ) + + traceResult xTraceStreamPortOnTraceEnd( void ); + + #ifdef __cplusplus +} + #endif + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + + #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#endif /* TRC_STREAM_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/trcStreamPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/trcStreamPort.c index cffdbe4f5..adeae7a2f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/trcStreamPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/TCPIP_Win32/trcStreamPort.c @@ -1,238 +1,259 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Supporting functions for trace streaming, used by the "stream ports" - * for reading and writing data to the interface. - * Existing ports can easily be modified to fit another setup, e.g., a - * different TCP/IP stack, or to define your own stream port. - */ - -#include -#include - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#pragma comment(lib,"ws2_32.lib") //Winsock Library - -typedef struct TraceStreamPortTCPIP -{ -#if (TRC_USE_INTERNAL_BUFFER) - uint8_t buffer[(TRC_STREAM_PORT_BUFFER_SIZE)]; -#else - TraceUnsignedBaseType_t buffer[1]; -#endif -} TraceStreamPortTCPIP_t; - -static TraceStreamPortTCPIP_t* pxStreamPortFile; -static SOCKET server_socket = (UINT_PTR)0, trace_socket = (UINT_PTR)0; -struct sockaddr_in server, client; - -static int prvInitServerSocketIfNeeded(void); -static int prvInitWinsockIfNeeded(void); -static int prvInitTraceSocketIfNeeded(void); -static void prvCloseAllSockets(void); - -static int prvInitWinsockIfNeeded(void) -{ - WSADATA wsa; - - if (server_socket) - return 0; - - if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) - { - return -1; - } - - return 0; -} - -static int prvInitServerSocketIfNeeded(void) -{ - if (prvInitWinsockIfNeeded() < 0) - { - return -1; - } - - if (server_socket) - return 0; - - if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) - { - return -1; - } - - server.sin_family = AF_INET; - server.sin_addr.s_addr = INADDR_ANY; - server.sin_port = htons(TRC_CFG_STREAM_PORT_TCPIP_PORT); - - if (bind(server_socket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) - { - closesocket(server_socket); - WSACleanup(); - server_socket = (UINT_PTR)0; - return -1; - } - - if (listen(server_socket, 3) < 0) - { - closesocket(server_socket); - WSACleanup(); - server_socket = (UINT_PTR)0; - return -1; - } - - return 0; -} - -static int prvInitTraceSocketIfNeeded(void) -{ - int c; - - if (!server_socket) - return -1; - - if (trace_socket) - return 0; - - c = sizeof(struct sockaddr_in); - trace_socket = accept(server_socket, (struct sockaddr *)&client, &c); - if (trace_socket == INVALID_SOCKET) - { - trace_socket = (UINT_PTR)0; - - closesocket(server_socket); - WSACleanup(); - server_socket = (UINT_PTR)0; - - return -1; - } - - return 0; -} - -int32_t prvTraceWriteToSocket(void* data, uint32_t size, int32_t *ptrBytesWritten) -{ - int ret; - - if (prvInitServerSocketIfNeeded() < 0) - { - return -1; - } - - if (prvInitTraceSocketIfNeeded() < 0) - { - return -1; - } - - if (!trace_socket) - { - if (ptrBytesWritten != 0) - { - *ptrBytesWritten = 0; - } - return -1; - } - ret = send(trace_socket, data, size, 0); - if (ret <= 0) - { - if (ptrBytesWritten != 0) - { - *ptrBytesWritten = 0; - } - - closesocket(trace_socket); - trace_socket = (UINT_PTR)0; - return ret; - } - - if (ptrBytesWritten != 0) - { - *ptrBytesWritten = ret; - } - - return 0; -} - -int32_t prvTraceReadFromSocket(void* data, uint32_t bufsize, int32_t *ptrBytesRead) -{ - unsigned long bytesAvailable = 0; - - if (prvInitServerSocketIfNeeded() < 0) - return -1; - - if (prvInitTraceSocketIfNeeded() < 0) - return -1; - - if (ioctlsocket(trace_socket, FIONREAD, &bytesAvailable) != NO_ERROR) - { - closesocket(trace_socket); - trace_socket = (UINT_PTR)0; - return -1; - } - - if (bytesAvailable > 0) - { - *ptrBytesRead = recv(trace_socket, data, bufsize, 0); - if (*ptrBytesRead == SOCKET_ERROR) - { - closesocket(trace_socket); - trace_socket = (UINT_PTR)0; - return -1; - } - } - - return 0; -} - -static void prvCloseAllSockets(void) -{ - if (trace_socket != 0) - { - closesocket(trace_socket); - trace_socket = 0; - } - - if (server_socket != 0) - { - closesocket(server_socket); - server_socket = 0; - } -} - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortTCPIP_t); - - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - pxStreamPortFile = (TraceStreamPortTCPIP_t*)pxBuffer; - -#if (TRC_USE_INTERNAL_BUFFER == 1) - return xTraceInternalEventBufferInitialize(pxStreamPortFile->buffer, sizeof(pxStreamPortFile->buffer)); -#else - return TRC_SUCCESS; -#endif -} - -traceResult xTraceStreamPortOnTraceEnd(void) -{ - prvCloseAllSockets(); - - return TRC_SUCCESS; -} - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Supporting functions for trace streaming, used by the "stream ports" + * for reading and writing data to the interface. + * Existing ports can easily be modified to fit another setup, e.g., a + * different TCP/IP stack, or to define your own stream port. + */ + +#include +#include + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #pragma comment(lib,"ws2_32.lib") /*Winsock Library */ + + typedef struct TraceStreamPortTCPIP + { + #if ( TRC_USE_INTERNAL_BUFFER ) + uint8_t buffer[ ( TRC_STREAM_PORT_BUFFER_SIZE ) ]; + #else + TraceUnsignedBaseType_t buffer[ 1 ]; + #endif + } TraceStreamPortTCPIP_t; + + static TraceStreamPortTCPIP_t * pxStreamPortFile; + static SOCKET server_socket = ( UINT_PTR ) 0, trace_socket = ( UINT_PTR ) 0; + struct sockaddr_in server, client; + + static int prvInitServerSocketIfNeeded( void ); + static int prvInitWinsockIfNeeded( void ); + static int prvInitTraceSocketIfNeeded( void ); + static void prvCloseAllSockets( void ); + + static int prvInitWinsockIfNeeded( void ) + { + WSADATA wsa; + + if( server_socket ) + { + return 0; + } + + if( WSAStartup( MAKEWORD( 2, 2 ), &wsa ) != 0 ) + { + return -1; + } + + return 0; + } + + static int prvInitServerSocketIfNeeded( void ) + { + if( prvInitWinsockIfNeeded() < 0 ) + { + return -1; + } + + if( server_socket ) + { + return 0; + } + + if( ( server_socket = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET ) + { + return -1; + } + + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + server.sin_port = htons( TRC_CFG_STREAM_PORT_TCPIP_PORT ); + + if( bind( server_socket, ( struct sockaddr * ) &server, sizeof( server ) ) == SOCKET_ERROR ) + { + closesocket( server_socket ); + WSACleanup(); + server_socket = ( UINT_PTR ) 0; + return -1; + } + + if( listen( server_socket, 3 ) < 0 ) + { + closesocket( server_socket ); + WSACleanup(); + server_socket = ( UINT_PTR ) 0; + return -1; + } + + return 0; + } + + static int prvInitTraceSocketIfNeeded( void ) + { + int c; + + if( !server_socket ) + { + return -1; + } + + if( trace_socket ) + { + return 0; + } + + c = sizeof( struct sockaddr_in ); + trace_socket = accept( server_socket, ( struct sockaddr * ) &client, &c ); + + if( trace_socket == INVALID_SOCKET ) + { + trace_socket = ( UINT_PTR ) 0; + + closesocket( server_socket ); + WSACleanup(); + server_socket = ( UINT_PTR ) 0; + + return -1; + } + + return 0; + } + + int32_t prvTraceWriteToSocket( void * data, + uint32_t size, + int32_t * ptrBytesWritten ) + { + int ret; + + if( prvInitServerSocketIfNeeded() < 0 ) + { + return -1; + } + + if( prvInitTraceSocketIfNeeded() < 0 ) + { + return -1; + } + + if( !trace_socket ) + { + if( ptrBytesWritten != 0 ) + { + *ptrBytesWritten = 0; + } + + return -1; + } + + ret = send( trace_socket, data, size, 0 ); + + if( ret <= 0 ) + { + if( ptrBytesWritten != 0 ) + { + *ptrBytesWritten = 0; + } + + closesocket( trace_socket ); + trace_socket = ( UINT_PTR ) 0; + return ret; + } + + if( ptrBytesWritten != 0 ) + { + *ptrBytesWritten = ret; + } + + return 0; + } + + int32_t prvTraceReadFromSocket( void * data, + uint32_t bufsize, + int32_t * ptrBytesRead ) + { + unsigned long bytesAvailable = 0; + + if( prvInitServerSocketIfNeeded() < 0 ) + { + return -1; + } + + if( prvInitTraceSocketIfNeeded() < 0 ) + { + return -1; + } + + if( ioctlsocket( trace_socket, FIONREAD, &bytesAvailable ) != NO_ERROR ) + { + closesocket( trace_socket ); + trace_socket = ( UINT_PTR ) 0; + return -1; + } + + if( bytesAvailable > 0 ) + { + *ptrBytesRead = recv( trace_socket, data, bufsize, 0 ); + + if( *ptrBytesRead == SOCKET_ERROR ) + { + closesocket( trace_socket ); + trace_socket = ( UINT_PTR ) 0; + return -1; + } + } + + return 0; + } + + static void prvCloseAllSockets( void ) + { + if( trace_socket != 0 ) + { + closesocket( trace_socket ); + trace_socket = 0; + } + + if( server_socket != 0 ) + { + closesocket( server_socket ); + server_socket = 0; + } + } + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceStreamPortBuffer_t, TraceStreamPortTCPIP_t ); + + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + pxStreamPortFile = ( TraceStreamPortTCPIP_t * ) pxBuffer; + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + return xTraceInternalEventBufferInitialize( pxStreamPortFile->buffer, sizeof( pxStreamPortFile->buffer ) ); + #else + return TRC_SUCCESS; + #endif + } + + traceResult xTraceStreamPortOnTraceEnd( void ) + { + prvCloseAllSockets(); + + return TRC_SUCCESS; + } + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + +#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/config/trcStreamPortConfig.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/config/trcStreamPortConfig.h index 69549ade2..41916609a 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/config/trcStreamPortConfig.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/config/trcStreamPortConfig.h @@ -1,35 +1,35 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The configuration for trace streaming ("stream ports"). - */ - -#ifndef TRC_STREAM_PORT_CONFIG_H -#define TRC_STREAM_PORT_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* This define will determine whether to use the internal buffer or not. -If file writing creates additional trace events (i.e. it uses semaphores or mutexes), -then the internal buffer must be enabled to avoid infinite recursion. */ -#define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 1 - -/** -* @def TRC_CFG_INTERNAL_BUFFER_SIZE -* -* @brief Configures the size of the internal buffer if used. -* is enabled. -*/ -#define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 35000 - -#ifdef __cplusplus -} -#endif - -#endif /* TRC_STREAM_PORT_CONFIG_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The configuration for trace streaming ("stream ports"). + */ + +#ifndef TRC_STREAM_PORT_CONFIG_H + #define TRC_STREAM_PORT_CONFIG_H + + #ifdef __cplusplus + extern "C" { + #endif + +/* This define will determine whether to use the internal buffer or not. + * If file writing creates additional trace events (i.e. it uses semaphores or mutexes), + * then the internal buffer must be enabled to avoid infinite recursion. */ + #define TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER 1 + +/** + * @def TRC_CFG_INTERNAL_BUFFER_SIZE + * + * @brief Configures the size of the internal buffer if used. + * is enabled. + */ + #define TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE 35000 + + #ifdef __cplusplus +} + #endif + +#endif /* TRC_STREAM_PORT_CONFIG_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/include/trcStreamPort.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/include/trcStreamPort.h index 53f5717c5..e62f99bc3 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/include/trcStreamPort.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/include/trcStreamPort.h @@ -1,130 +1,137 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The interface definitions for trace streaming ("stream ports"). - * This "stream port" sets up the recorder to use XMOS xScope as a streaming channel. - */ - -#ifndef TRC_STREAMING_PORT_H -#define TRC_STREAMING_PORT_H - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#define TRC_USE_INTERNAL_BUFFER (TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER) - -/* Aligned */ -#define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ((((TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE) + sizeof(TraceUnsignedBaseType_t) - 1) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t)) - -/** - * @brief A structure representing the trace stream port buffer. - */ -typedef struct TraceStreamPortBuffer -{ -#if (TRC_USE_INTERNAL_BUFFER == 1) - uint8_t uiBufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE]; -#endif - uint8_t uiBuffer[4]; -} TraceStreamPortBuffer_t; - -/** - * @internal Stream port initialize callback. - * - * This function is called by the recorder as part of its initialization phase. - * - * @param[in] pxBuffer Buffer - * @retval TRC_FAIL Initialization failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer); - -/** - * @brief Stream port begin callback. - * - * This function is called by the recorder as part of its begin phase. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortOnBegin(void); - -/** - * @brief Stream port end callback. - * - * This function is called by the recorder as part of its end phase. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortOnEnd(void); - -/** - * @brief Allocates data from the stream port. - * - * @param[in] uiSize Allocation size - * @param[out] ppvData Allocation data pointer - * - * @retval TRC_FAIL Allocate failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortAllocate(uint32_t uiSize, void** ppvData); - -/** - * @brief Commits data to the stream port, depending on the implementation/configuration of the - * stream port this data might be directly written to the stream port interface, buffered, or - * something else. - * - * @param[in] pvData Data to commit - * @param[in] uiSize Data to commit size - * @param[out] piBytesCommitted Bytes commited - * - * @retval TRC_FAIL Commit failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortCommit(void* pvData, uint32_t uiSize, int32_t* piBytesCommitted); - -/** - * @brief Writes data through the stream port interface. - * - * @param[in] pvData Data to write - * @param[in] uiSize Data to write size - * @param[out] piBytesWritten Bytes written - * - * @retval TRC_FAIL Write failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortWriteData(void* pvData, uint32_t uiSize, int32_t* piBytesWritten); - -/** - * @brief Reads data through the stream port interface. - * - * @param[in] pvData Destination data buffer - * @param[in] uiSize Destination data buffer size - * @param[out] piBytesRead Bytes read - * - * @retval TRC_FAIL Read failed - * @retval TRC_SUCCESS Success - */ -traceResult xTraceStreamPortReadData(void* pvData, uint32_t uiSize, int32_t* piBytesRead); - -#ifdef __cplusplus -} -#endif - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ - -#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ - -#endif /* TRC_STREAMING_PORT_H */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface definitions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to use XMOS xScope as a streaming channel. + */ + +#ifndef TRC_STREAMING_PORT_H + #define TRC_STREAMING_PORT_H + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #ifdef __cplusplus + extern "C" { + #endif + + #include + #include + + #define TRC_USE_INTERNAL_BUFFER ( TRC_CFG_STREAM_PORT_USE_INTERNAL_BUFFER ) + +/* Aligned */ + #define TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ( ( ( ( TRC_CFG_STREAM_PORT_INTERNAL_BUFFER_SIZE ) + sizeof( TraceUnsignedBaseType_t ) - 1 ) / sizeof( TraceUnsignedBaseType_t ) ) * sizeof( TraceUnsignedBaseType_t ) ) + +/** + * @brief A structure representing the trace stream port buffer. + */ + typedef struct TraceStreamPortBuffer + { + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + uint8_t uiBufferInternal[ TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ]; + #endif + uint8_t uiBuffer[ 4 ]; + } TraceStreamPortBuffer_t; + +/** + * @internal Stream port initialize callback. + * + * This function is called by the recorder as part of its initialization phase. + * + * @param[in] pxBuffer Buffer + * @retval TRC_FAIL Initialization failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ); + +/** + * @brief Stream port begin callback. + * + * This function is called by the recorder as part of its begin phase. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortOnBegin( void ); + +/** + * @brief Stream port end callback. + * + * This function is called by the recorder as part of its end phase. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortOnEnd( void ); + +/** + * @brief Allocates data from the stream port. + * + * @param[in] uiSize Allocation size + * @param[out] ppvData Allocation data pointer + * + * @retval TRC_FAIL Allocate failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortAllocate( uint32_t uiSize, + void ** ppvData ); + +/** + * @brief Commits data to the stream port, depending on the implementation/configuration of the + * stream port this data might be directly written to the stream port interface, buffered, or + * something else. + * + * @param[in] pvData Data to commit + * @param[in] uiSize Data to commit size + * @param[out] piBytesCommitted Bytes commited + * + * @retval TRC_FAIL Commit failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortCommit( void * pvData, + uint32_t uiSize, + int32_t * piBytesCommitted ); + +/** + * @brief Writes data through the stream port interface. + * + * @param[in] pvData Data to write + * @param[in] uiSize Data to write size + * @param[out] piBytesWritten Bytes written + * + * @retval TRC_FAIL Write failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortWriteData( void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ); + +/** + * @brief Reads data through the stream port interface. + * + * @param[in] pvData Destination data buffer + * @param[in] uiSize Destination data buffer size + * @param[out] piBytesRead Bytes read + * + * @retval TRC_FAIL Read failed + * @retval TRC_SUCCESS Success + */ + traceResult xTraceStreamPortReadData( void * pvData, + uint32_t uiSize, + int32_t * piBytesRead ); + + #ifdef __cplusplus +} + #endif + + #endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + + #endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#endif /* TRC_STREAMING_PORT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/trcStreamPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/trcStreamPort.c index 46ecbf5be..9fdc36d13 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/trcStreamPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/XMOS_xScope/trcStreamPort.c @@ -1,101 +1,110 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * Supporting functions for trace streaming, used by the "stream ports" - * for reading and writing data to the interface. - */ - -#include -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -typedef struct TraceStreamPortXS { -#if (TRC_USE_INTERNAL_BUFFER == 1) - uint8_t uiBufferInternal[TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE]; -#endif - uint8_t uiBuffer[4]; -} TraceStreamPortXS_t; - -static TraceStreamPortXS_t* pxStreamPortXS; - -traceResult xTraceStreamPortInitialize(TraceStreamPortBuffer_t* pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceStreamPortBuffer_t, TraceStreamPortXS_t); - - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - pxStreamPortXS = (TraceStreamPortXS_t*)pxBuffer; - -#if (TRC_USE_INTERNAL_BUFFER == 1) - return xTraceInternalEventBufferInitialize(pxStreamPortXS->uiBufferInternal, sizeof(pxStreamPortXS->uiBufferInternal)); -#else - return TRC_SUCCESS; -#endif -} - -traceResult xTraceStreamPortOnBegin(void) -{ - return TRC_SUCCESS; -} - -traceResult xTraceStreamPortOnEnd(void) -{ - return TRC_SUCCESS; -} - -traceResult xTraceStreamPortAllocate(uint32_t uiSize, void** ppvData) -{ - (void)uiSize; - - return xTraceStaticBufferGet(ppvData); -} - -traceResult xTraceStreamPortCommit(void* pvData, uint32_t uiSize, int32_t* piBytesCommitted) -{ - if (pvData == 0) - { - return TRC_FAIL; - } - -#if (TRC_USE_INTERNAL_BUFFER == 1) - /* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */ - return xTraceInternalEventBufferPush(pvData, uiSize, piBytesCommitted); -#else - /* Write directly to file */ - return xTraceStreamPortWriteData(pvData, uiSize, piBytesCommitted); -#endif -} - -traceResult xTraceStreamPortWriteData(void* pvData, uint32_t uiSize, int32_t* piBytesWritten) -{ - /* xscope_bytes is supposed to be thread safe, so we do not bother with any - * critical sections here. */ - xscope_bytes(0, uiSize, (unsigned char*)pvData); - - if (piBytesWritten != 0) { - /* Since xScope always write all bytes (not all might be received) we flag this as - * a full write */ - *piBytesWritten = (int32_t)uiSize; - } - - return TRC_SUCCESS; -} - -traceResult xTraceStreamPortReadData(void* pvData, uint32_t uiSize, int32_t* piBytesRead) -{ - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ \ No newline at end of file +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Supporting functions for trace streaming, used by the "stream ports" + * for reading and writing data to the interface. + */ + +#include +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + typedef struct TraceStreamPortXS + { + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + uint8_t uiBufferInternal[ TRC_STREAM_PORT_INTERNAL_BUFFER_SIZE ]; + #endif + uint8_t uiBuffer[ 4 ]; + } TraceStreamPortXS_t; + + static TraceStreamPortXS_t * pxStreamPortXS; + + traceResult xTraceStreamPortInitialize( TraceStreamPortBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceStreamPortBuffer_t, TraceStreamPortXS_t ); + + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + pxStreamPortXS = ( TraceStreamPortXS_t * ) pxBuffer; + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + return xTraceInternalEventBufferInitialize( pxStreamPortXS->uiBufferInternal, sizeof( pxStreamPortXS->uiBufferInternal ) ); + #else + return TRC_SUCCESS; + #endif + } + + traceResult xTraceStreamPortOnBegin( void ) + { + return TRC_SUCCESS; + } + + traceResult xTraceStreamPortOnEnd( void ) + { + return TRC_SUCCESS; + } + + traceResult xTraceStreamPortAllocate( uint32_t uiSize, + void ** ppvData ) + { + ( void ) uiSize; + + return xTraceStaticBufferGet( ppvData ); + } + + traceResult xTraceStreamPortCommit( void * pvData, + uint32_t uiSize, + int32_t * piBytesCommitted ) + { + if( pvData == 0 ) + { + return TRC_FAIL; + } + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + /* Push to internal buffer. It will call on xTraceStreamPortWriteData() periodically. */ + return xTraceInternalEventBufferPush( pvData, uiSize, piBytesCommitted ); + #else + /* Write directly to file */ + return xTraceStreamPortWriteData( pvData, uiSize, piBytesCommitted ); + #endif + } + + traceResult xTraceStreamPortWriteData( void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ) + { + /* xscope_bytes is supposed to be thread safe, so we do not bother with any + * critical sections here. */ + xscope_bytes( 0, uiSize, ( unsigned char * ) pvData ); + + if( piBytesWritten != 0 ) + { + /* Since xScope always write all bytes (not all might be received) we flag this as + * a full write */ + *piBytesWritten = ( int32_t ) uiSize; + } + + return TRC_SUCCESS; + } + + traceResult xTraceStreamPortReadData( void * pvData, + uint32_t uiSize, + int32_t * piBytesRead ) + { + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcAssert.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcAssert.c index 8d40867d6..62b570696 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcAssert.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcAssert.c @@ -1,125 +1,131 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for errors. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -#if (defined(TRC_CFG_TEST_MODE) && (TRC_CFG_TEST_MODE) == 1) - -extern inline TraceBaseType_t prvTraceAssertCheckCondition(TraceBaseType_t condition); - -#endif - -#define TRC_ASSERT_STATE_INDEX_LINE_NUMBER 0 - -typedef struct TraceAssertInfo -{ - TraceEntryHandle_t xEntry; -} TraceAssertInfo_t; - -static TraceAssertInfo_t* pxAssertInfo; - -traceResult xTraceAssertInitialize(TraceAssertBuffer_t *pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceAssertBuffer_t, TraceAssertInfo_t); - - TRC_ASSERT(pxBuffer != 0); - - pxAssertInfo = (TraceAssertInfo_t*)pxBuffer; - pxAssertInfo->xEntry = 0; - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ASSERT); - - return TRC_SUCCESS; -} - -void prvTraceAssertCreate(const char* szFilePath, TraceUnsignedBaseType_t uxLineNumber) -{ - TraceBaseType_t i, xLength; - TraceUnsignedBaseType_t uxEntryLineNumber = 0xFFFFFFFF; - static TraceUnsignedBaseType_t uxRecursionGuard = 0; - - if (uxRecursionGuard == 0) - { - /* Recursion can only get here once */ - uxRecursionGuard = 1; - - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ASSERT)) - { - return; - } - - if (pxAssertInfo->xEntry == 0) - { - if (xTraceEntryCreate(&pxAssertInfo->xEntry) == TRC_FAIL) - { - return; - } - } - - xTraceEntryGetState(pxAssertInfo->xEntry, TRC_ASSERT_STATE_INDEX_LINE_NUMBER, &uxEntryLineNumber); - - /* We only save the first ASSERT information */ - if (uxEntryLineNumber == 0) - { - /* Find length */ - for (i = 0; (szFilePath[i] != 0) && (i < 128); i++) {} - - xLength = i; - - /* Find last slash or backslash */ - for (i = xLength - 1; (i >= 0) && ((szFilePath[i] != '\\') && (szFilePath[i] != '/')); i--) {} - - /* We treat the entry as an object and set it's name and state */ - xTraceObjectSetName((TraceObjectHandle_t)pxAssertInfo->xEntry, &szFilePath[i + 1]); - xTraceObjectSetState((TraceObjectHandle_t)pxAssertInfo->xEntry, uxLineNumber); - - xTraceError(TRC_ERROR_ASSERT); - } - } - - xTraceDiagnosticsIncrease(TRC_DIAGNOSTICS_ASSERTS_TRIGGERED); -} - -traceResult xTraceAssertGet(TraceStringHandle_t *pxFileNameStringHandle, TraceUnsignedBaseType_t *puxLineNumber) -{ - TRC_ASSERT(pxFileNameStringHandle != 0); - - TRC_ASSERT(puxLineNumber != 0); - - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ASSERT)) - { - return TRC_FAIL; - } - - *puxLineNumber = 0; - xTraceEntryGetState(pxAssertInfo->xEntry, TRC_ASSERT_STATE_INDEX_LINE_NUMBER, puxLineNumber); - - if (*puxLineNumber == 0) - { - return TRC_FAIL; - } - - /* The string handle can be set to the entry handle */ - *pxFileNameStringHandle = (TraceStringHandle_t)pxAssertInfo->xEntry; - - return TRC_SUCCESS; -} - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for errors. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + + #if ( defined( TRC_CFG_TEST_MODE ) && ( TRC_CFG_TEST_MODE ) == 1 ) + + extern inline TraceBaseType_t prvTraceAssertCheckCondition( TraceBaseType_t condition ); + + #endif + + #define TRC_ASSERT_STATE_INDEX_LINE_NUMBER 0 + + typedef struct TraceAssertInfo + { + TraceEntryHandle_t xEntry; + } TraceAssertInfo_t; + + static TraceAssertInfo_t * pxAssertInfo; + + traceResult xTraceAssertInitialize( TraceAssertBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceAssertBuffer_t, TraceAssertInfo_t ); + + TRC_ASSERT( pxBuffer != 0 ); + + pxAssertInfo = ( TraceAssertInfo_t * ) pxBuffer; + pxAssertInfo->xEntry = 0; + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_ASSERT ); + + return TRC_SUCCESS; + } + + void prvTraceAssertCreate( const char * szFilePath, + TraceUnsignedBaseType_t uxLineNumber ) + { + TraceBaseType_t i, xLength; + TraceUnsignedBaseType_t uxEntryLineNumber = 0xFFFFFFFF; + static TraceUnsignedBaseType_t uxRecursionGuard = 0; + + if( uxRecursionGuard == 0 ) + { + /* Recursion can only get here once */ + uxRecursionGuard = 1; + + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ASSERT ) ) + { + return; + } + + if( pxAssertInfo->xEntry == 0 ) + { + if( xTraceEntryCreate( &pxAssertInfo->xEntry ) == TRC_FAIL ) + { + return; + } + } + + xTraceEntryGetState( pxAssertInfo->xEntry, TRC_ASSERT_STATE_INDEX_LINE_NUMBER, &uxEntryLineNumber ); + + /* We only save the first ASSERT information */ + if( uxEntryLineNumber == 0 ) + { + /* Find length */ + for( i = 0; ( szFilePath[ i ] != 0 ) && ( i < 128 ); i++ ) + { + } + + xLength = i; + + /* Find last slash or backslash */ + for( i = xLength - 1; ( i >= 0 ) && ( ( szFilePath[ i ] != '\\' ) && ( szFilePath[ i ] != '/' ) ); i-- ) + { + } + + /* We treat the entry as an object and set it's name and state */ + xTraceObjectSetName( ( TraceObjectHandle_t ) pxAssertInfo->xEntry, &szFilePath[ i + 1 ] ); + xTraceObjectSetState( ( TraceObjectHandle_t ) pxAssertInfo->xEntry, uxLineNumber ); + + xTraceError( TRC_ERROR_ASSERT ); + } + } + + xTraceDiagnosticsIncrease( TRC_DIAGNOSTICS_ASSERTS_TRIGGERED ); + } + + traceResult xTraceAssertGet( TraceStringHandle_t * pxFileNameStringHandle, + TraceUnsignedBaseType_t * puxLineNumber ) + { + TRC_ASSERT( pxFileNameStringHandle != 0 ); + + TRC_ASSERT( puxLineNumber != 0 ); + + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ASSERT ) ) + { + return TRC_FAIL; + } + + *puxLineNumber = 0; + xTraceEntryGetState( pxAssertInfo->xEntry, TRC_ASSERT_STATE_INDEX_LINE_NUMBER, puxLineNumber ); + + if( *puxLineNumber == 0 ) + { + return TRC_FAIL; + } + + /* The string handle can be set to the entry handle */ + *pxFileNameStringHandle = ( TraceStringHandle_t ) pxAssertInfo->xEntry; + + return TRC_SUCCESS; + } + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcCounter.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcCounter.c index 4c9f455d3..8aa847ada 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcCounter.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcCounter.c @@ -1,154 +1,164 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation of intervals. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#define TRC_COUNTER_VALUE_INDEX 0 -#define TRC_COUNTER_LOWER_LIMIT_INDEX 1 -#define TRC_COUNTER_UPPER_LIMIT_INDEX 2 - -static TraceCounterCallback_t xCallbackFunction; - -traceResult xTraceCounterSetCallback(TraceCounterCallback_t xCallback) -{ - TRC_ASSERT(xCallback != 0); - - xCallbackFunction = xCallback; - - /* We only set this component as initialized when the callback has been set */ - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER); - - return TRC_SUCCESS; -} - -traceResult xTraceCounterCreate(const char *szName, TraceBaseType_t xInitialValue, TraceBaseType_t xLowerLimit, TraceBaseType_t xUpperLimit, TraceCounterHandle_t *pxCounterHandle) -{ - TraceObjectHandle_t xObjectHandle; - TraceUnsignedBaseType_t uxStates[3]; - - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER)); - - /* This should never fail */ - TRC_ASSERT(pxCounterHandle != 0); - - TRC_ASSERT(xInitialValue >= xLowerLimit && xInitialValue <= xUpperLimit); - - uxStates[TRC_COUNTER_VALUE_INDEX] = xInitialValue; - uxStates[TRC_COUNTER_LOWER_LIMIT_INDEX] = xLowerLimit; - uxStates[TRC_COUNTER_UPPER_LIMIT_INDEX] = xUpperLimit; - - /* We need to check this */ - if (xTraceObjectRegisterInternal(PSF_EVENT_COUNTER_CREATE, 0, szName, 3, uxStates, TRC_ENTRY_OPTION_COUNTER, &xObjectHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - *pxCounterHandle = (TraceIntervalHandle_t)xObjectHandle; - - return TRC_SUCCESS; -} - -traceResult xTraceCounterIncrease(TraceCounterHandle_t xCounterHandle) -{ - return xTraceCounterAdd(xCounterHandle, 1); -} -traceResult xTraceCounterDecrease(TraceCounterHandle_t xCounterHandle) -{ - return xTraceCounterAdd(xCounterHandle, -1); -} - -traceResult xTraceCounterAdd(TraceCounterHandle_t xCounterHandle, TraceBaseType_t xValue) -{ - TraceBaseType_t xCurrent; - - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER)); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterGet(xCounterHandle, &xCurrent) == TRC_SUCCESS); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterSet(xCounterHandle, xCurrent + xValue) == TRC_SUCCESS); - - return TRC_SUCCESS; -} - -traceResult xTraceCounterSet(TraceCounterHandle_t xCounterHandle, TraceBaseType_t xValue) -{ - TraceEventHandle_t xEventHandle = 0; - TraceBaseType_t xLowerLimit; - TraceBaseType_t xUpperLimit; - - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER)); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState((TraceEntryHandle_t)xCounterHandle, TRC_COUNTER_VALUE_INDEX, (TraceUnsignedBaseType_t)xValue) == TRC_SUCCESS); - - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_COUNTER_CHANGE, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, (void*)xCounterHandle); - xTraceEventAdd32(xEventHandle, (TraceUnsignedBaseType_t)xValue); - xTraceEventEnd(xEventHandle); - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterGetLowerLimit(xCounterHandle, &xLowerLimit) == TRC_SUCCESS); - - if (xValue < xLowerLimit) - { - xCallbackFunction(xCounterHandle); - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceCounterGetUpperLimit(xCounterHandle, &xUpperLimit) == TRC_SUCCESS); - - if (xValue > xUpperLimit) - { - xCallbackFunction(xCounterHandle); - } - - return TRC_SUCCESS; -} - -traceResult xTraceCounterGet(TraceCounterHandle_t xCounterHandle, TraceBaseType_t* pxValue) -{ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER)); - - return xTraceEntryGetState((TraceEntryHandle_t)xCounterHandle, TRC_COUNTER_VALUE_INDEX, (TraceUnsignedBaseType_t*)pxValue); -} - -traceResult xTraceCounterGetUpperLimit(TraceCounterHandle_t xCounterHandle, TraceBaseType_t* pxValue) -{ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER)); - - return xTraceEntryGetState((TraceEntryHandle_t)xCounterHandle, TRC_COUNTER_UPPER_LIMIT_INDEX, (TraceUnsignedBaseType_t*)pxValue); -} - -traceResult xTraceCounterGetLowerLimit(TraceCounterHandle_t xCounterHandle, TraceBaseType_t* pxValue) -{ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER)); - - return xTraceEntryGetState((TraceEntryHandle_t)xCounterHandle, TRC_COUNTER_LOWER_LIMIT_INDEX, (TraceUnsignedBaseType_t*)pxValue); -} - -traceResult xTraceCounterGetName(TraceCounterHandle_t xCounterHandle, const char** pszName) -{ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_COUNTER)); - - return xTraceEntryGetSymbol((TraceEntryHandle_t)xCounterHandle, pszName); -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation of intervals. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #define TRC_COUNTER_VALUE_INDEX 0 + #define TRC_COUNTER_LOWER_LIMIT_INDEX 1 + #define TRC_COUNTER_UPPER_LIMIT_INDEX 2 + + static TraceCounterCallback_t xCallbackFunction; + + traceResult xTraceCounterSetCallback( TraceCounterCallback_t xCallback ) + { + TRC_ASSERT( xCallback != 0 ); + + xCallbackFunction = xCallback; + + /* We only set this component as initialized when the callback has been set */ + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_COUNTER ); + + return TRC_SUCCESS; + } + + traceResult xTraceCounterCreate( const char * szName, + TraceBaseType_t xInitialValue, + TraceBaseType_t xLowerLimit, + TraceBaseType_t xUpperLimit, + TraceCounterHandle_t * pxCounterHandle ) + { + TraceObjectHandle_t xObjectHandle; + TraceUnsignedBaseType_t uxStates[ 3 ]; + + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_COUNTER ) ); + + /* This should never fail */ + TRC_ASSERT( pxCounterHandle != 0 ); + + TRC_ASSERT( xInitialValue >= xLowerLimit && xInitialValue <= xUpperLimit ); + + uxStates[ TRC_COUNTER_VALUE_INDEX ] = xInitialValue; + uxStates[ TRC_COUNTER_LOWER_LIMIT_INDEX ] = xLowerLimit; + uxStates[ TRC_COUNTER_UPPER_LIMIT_INDEX ] = xUpperLimit; + + /* We need to check this */ + if( xTraceObjectRegisterInternal( PSF_EVENT_COUNTER_CREATE, 0, szName, 3, uxStates, TRC_ENTRY_OPTION_COUNTER, &xObjectHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + *pxCounterHandle = ( TraceIntervalHandle_t ) xObjectHandle; + + return TRC_SUCCESS; + } + + traceResult xTraceCounterIncrease( TraceCounterHandle_t xCounterHandle ) + { + return xTraceCounterAdd( xCounterHandle, 1 ); + } + traceResult xTraceCounterDecrease( TraceCounterHandle_t xCounterHandle ) + { + return xTraceCounterAdd( xCounterHandle, -1 ); + } + + traceResult xTraceCounterAdd( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t xValue ) + { + TraceBaseType_t xCurrent; + + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_COUNTER ) ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceCounterGet( xCounterHandle, &xCurrent ) == TRC_SUCCESS ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceCounterSet( xCounterHandle, xCurrent + xValue ) == TRC_SUCCESS ); + + return TRC_SUCCESS; + } + + traceResult xTraceCounterSet( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t xValue ) + { + TraceEventHandle_t xEventHandle = 0; + TraceBaseType_t xLowerLimit; + TraceBaseType_t xUpperLimit; + + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_COUNTER ) ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( ( TraceEntryHandle_t ) xCounterHandle, TRC_COUNTER_VALUE_INDEX, ( TraceUnsignedBaseType_t ) xValue ) == TRC_SUCCESS ); + + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_COUNTER_CHANGE, sizeof( void * ) + sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, ( void * ) xCounterHandle ); + xTraceEventAdd32( xEventHandle, ( TraceUnsignedBaseType_t ) xValue ); + xTraceEventEnd( xEventHandle ); + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceCounterGetLowerLimit( xCounterHandle, &xLowerLimit ) == TRC_SUCCESS ); + + if( xValue < xLowerLimit ) + { + xCallbackFunction( xCounterHandle ); + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceCounterGetUpperLimit( xCounterHandle, &xUpperLimit ) == TRC_SUCCESS ); + + if( xValue > xUpperLimit ) + { + xCallbackFunction( xCounterHandle ); + } + + return TRC_SUCCESS; + } + + traceResult xTraceCounterGet( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t * pxValue ) + { + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_COUNTER ) ); + + return xTraceEntryGetState( ( TraceEntryHandle_t ) xCounterHandle, TRC_COUNTER_VALUE_INDEX, ( TraceUnsignedBaseType_t * ) pxValue ); + } + + traceResult xTraceCounterGetUpperLimit( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t * pxValue ) + { + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_COUNTER ) ); + + return xTraceEntryGetState( ( TraceEntryHandle_t ) xCounterHandle, TRC_COUNTER_UPPER_LIMIT_INDEX, ( TraceUnsignedBaseType_t * ) pxValue ); + } + + traceResult xTraceCounterGetLowerLimit( TraceCounterHandle_t xCounterHandle, + TraceBaseType_t * pxValue ) + { + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_COUNTER ) ); + + return xTraceEntryGetState( ( TraceEntryHandle_t ) xCounterHandle, TRC_COUNTER_LOWER_LIMIT_INDEX, ( TraceUnsignedBaseType_t * ) pxValue ); + } + + traceResult xTraceCounterGetName( TraceCounterHandle_t xCounterHandle, + const char ** pszName ) + { + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_COUNTER ) ); + + return xTraceEntryGetSymbol( ( TraceEntryHandle_t ) xCounterHandle, pszName ); + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcDiagnostics.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcDiagnostics.c index 08683712a..7d175afcf 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcDiagnostics.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcDiagnostics.c @@ -1,166 +1,171 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation of the diagnostics. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -typedef struct TraceDiagnostics -{ - TraceBaseType_t metrics[TRC_DIAGNOSTICS_COUNT]; -} TraceDiagnostics_t; - -static TraceDiagnostics_t *pxDiagnostics; - -traceResult xTraceDiagnosticsInitialize(TraceDiagnosticsBuffer_t *pxBuffer) -{ - uint32_t i; - - TRC_ASSERT_EQUAL_SIZE(TraceDiagnosticsBuffer_t, TraceDiagnostics_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - pxDiagnostics = (TraceDiagnostics_t*)pxBuffer; - - for (i = 0; i < TRC_DIAGNOSTICS_COUNT; i++) - { - pxDiagnostics->metrics[i] = 0; - } - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS); - - return TRC_SUCCESS; -} - -traceResult xTraceDiagnosticsGet(TraceDiagnosticsType_t xType, TraceBaseType_t* pxValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS)); - - /* This should never fail */ - TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT); - - /* This should never fail */ - TRC_ASSERT(pxValue != 0); - - *pxValue = pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType]; - - return TRC_SUCCESS; -} - -traceResult xTraceDiagnosticsSet(TraceDiagnosticsType_t xType, TraceBaseType_t xValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS)); - - /* This should never fail */ - TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT); - - pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType] = xValue; - - return TRC_SUCCESS; -} - -traceResult xTraceDiagnosticsAdd(TraceDiagnosticsType_t xType, TraceBaseType_t xValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS)); - - /* This should never fail */ - TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT); - - pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType] += xValue; - - return TRC_SUCCESS; -} - -traceResult xTraceDiagnosticsIncrease(TraceDiagnosticsType_t xType) -{ - return xTraceDiagnosticsAdd(xType, 1); -} - -traceResult xTraceDiagnosticsDecrease(TraceDiagnosticsType_t xType) -{ - return xTraceDiagnosticsAdd(xType, -1); -} - -traceResult xTraceDiagnosticsSetIfHigher(TraceDiagnosticsType_t xType, TraceBaseType_t xValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS)); - - /* This should never fail */ - TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT); - - if (xValue > pxDiagnostics->metrics[xType]) - { - pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType] = xValue; - } - - return TRC_SUCCESS; -} - -traceResult xTraceDiagnosticsSetIfLower(TraceDiagnosticsType_t xType, TraceBaseType_t xValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS)); - - /* This should never fail */ - TRC_ASSERT((TraceUnsignedBaseType_t)xType < TRC_DIAGNOSTICS_COUNT); - - if (xValue < pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType]) - { - pxDiagnostics->metrics[(TraceUnsignedBaseType_t)xType] = xValue; - } - - return TRC_SUCCESS; -} - -traceResult xTraceDiagnosticsCheckStatus(void) -{ - /* It is probably good if we always check this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_DIAGNOSTICS)) - { - return TRC_FAIL; - } - - if (pxDiagnostics->metrics[TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM] > 0) - { - xTraceWarning(TRC_WARNING_ENTRY_TABLE_SLOTS); - pxDiagnostics->metrics[TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM] = 0; - } - - if (pxDiagnostics->metrics[TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH] > (TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH)) - { - xTraceWarning(TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH); - pxDiagnostics->metrics[TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH] = 0; - } - - if (pxDiagnostics->metrics[TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED] > 0) - { - xTraceWarning(TRC_WARNING_EVENT_SIZE_TRUNCATED); - pxDiagnostics->metrics[TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED] = 0; - } - - if (pxDiagnostics->metrics[TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS] > 0) - { - xTraceWarning(TRC_WARNING_STACKMON_NO_SLOTS); - pxDiagnostics->metrics[TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS] = 0; - } - - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation of the diagnostics. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + typedef struct TraceDiagnostics + { + TraceBaseType_t metrics[ TRC_DIAGNOSTICS_COUNT ]; + } TraceDiagnostics_t; + + static TraceDiagnostics_t * pxDiagnostics; + + traceResult xTraceDiagnosticsInitialize( TraceDiagnosticsBuffer_t * pxBuffer ) + { + uint32_t i; + + TRC_ASSERT_EQUAL_SIZE( TraceDiagnosticsBuffer_t, TraceDiagnostics_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + pxDiagnostics = ( TraceDiagnostics_t * ) pxBuffer; + + for( i = 0; i < TRC_DIAGNOSTICS_COUNT; i++ ) + { + pxDiagnostics->metrics[ i ] = 0; + } + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_DIAGNOSTICS ); + + return TRC_SUCCESS; + } + + traceResult xTraceDiagnosticsGet( TraceDiagnosticsType_t xType, + TraceBaseType_t * pxValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_DIAGNOSTICS ) ); + + /* This should never fail */ + TRC_ASSERT( ( TraceUnsignedBaseType_t ) xType < TRC_DIAGNOSTICS_COUNT ); + + /* This should never fail */ + TRC_ASSERT( pxValue != 0 ); + + *pxValue = pxDiagnostics->metrics[ ( TraceUnsignedBaseType_t ) xType ]; + + return TRC_SUCCESS; + } + + traceResult xTraceDiagnosticsSet( TraceDiagnosticsType_t xType, + TraceBaseType_t xValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_DIAGNOSTICS ) ); + + /* This should never fail */ + TRC_ASSERT( ( TraceUnsignedBaseType_t ) xType < TRC_DIAGNOSTICS_COUNT ); + + pxDiagnostics->metrics[ ( TraceUnsignedBaseType_t ) xType ] = xValue; + + return TRC_SUCCESS; + } + + traceResult xTraceDiagnosticsAdd( TraceDiagnosticsType_t xType, + TraceBaseType_t xValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_DIAGNOSTICS ) ); + + /* This should never fail */ + TRC_ASSERT( ( TraceUnsignedBaseType_t ) xType < TRC_DIAGNOSTICS_COUNT ); + + pxDiagnostics->metrics[ ( TraceUnsignedBaseType_t ) xType ] += xValue; + + return TRC_SUCCESS; + } + + traceResult xTraceDiagnosticsIncrease( TraceDiagnosticsType_t xType ) + { + return xTraceDiagnosticsAdd( xType, 1 ); + } + + traceResult xTraceDiagnosticsDecrease( TraceDiagnosticsType_t xType ) + { + return xTraceDiagnosticsAdd( xType, -1 ); + } + + traceResult xTraceDiagnosticsSetIfHigher( TraceDiagnosticsType_t xType, + TraceBaseType_t xValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_DIAGNOSTICS ) ); + + /* This should never fail */ + TRC_ASSERT( ( TraceUnsignedBaseType_t ) xType < TRC_DIAGNOSTICS_COUNT ); + + if( xValue > pxDiagnostics->metrics[ xType ] ) + { + pxDiagnostics->metrics[ ( TraceUnsignedBaseType_t ) xType ] = xValue; + } + + return TRC_SUCCESS; + } + + traceResult xTraceDiagnosticsSetIfLower( TraceDiagnosticsType_t xType, + TraceBaseType_t xValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_DIAGNOSTICS ) ); + + /* This should never fail */ + TRC_ASSERT( ( TraceUnsignedBaseType_t ) xType < TRC_DIAGNOSTICS_COUNT ); + + if( xValue < pxDiagnostics->metrics[ ( TraceUnsignedBaseType_t ) xType ] ) + { + pxDiagnostics->metrics[ ( TraceUnsignedBaseType_t ) xType ] = xValue; + } + + return TRC_SUCCESS; + } + + traceResult xTraceDiagnosticsCheckStatus( void ) + { + /* It is probably good if we always check this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_DIAGNOSTICS ) ) + { + return TRC_FAIL; + } + + if( pxDiagnostics->metrics[ TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM ] > 0 ) + { + xTraceWarning( TRC_WARNING_ENTRY_TABLE_SLOTS ); + pxDiagnostics->metrics[ TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM ] = 0; + } + + if( pxDiagnostics->metrics[ TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH ] > ( TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH ) ) + { + xTraceWarning( TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH ); + pxDiagnostics->metrics[ TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH ] = 0; + } + + if( pxDiagnostics->metrics[ TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED ] > 0 ) + { + xTraceWarning( TRC_WARNING_EVENT_SIZE_TRUNCATED ); + pxDiagnostics->metrics[ TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED ] = 0; + } + + if( pxDiagnostics->metrics[ TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS ] > 0 ) + { + xTraceWarning( TRC_WARNING_STACKMON_NO_SLOTS ); + pxDiagnostics->metrics[ TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS ] = 0; + } + + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEntryTable.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEntryTable.c index 8bbec98b4..cd544b8eb 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEntryTable.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEntryTable.c @@ -1,429 +1,445 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation of the entry table. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#define VALIDATE_ENTRY_HANDLE(xEntryHandle) ((((TraceUnsignedBaseType_t)(xEntryHandle) >= (TraceUnsignedBaseType_t)pxEntryTable) && ((TraceUnsignedBaseType_t)(xEntryHandle) < ((TraceUnsignedBaseType_t)pxEntryTable + sizeof(TraceEntryTable_t))))) - -#define GIVE_ENTRY_INDEX(xIndex) xIndexTable.axFreeIndexes[xIndexTable.uiFreeIndexCount] = (xIndex); xIndexTable.uiFreeIndexCount++ - -#define GET_FREE_INDEX_COUNT() xIndexTable.uiFreeIndexCount - -#define CALCULATE_ENTRY_INDEX(xEntryHandle) (TraceEntryIndex_t)(((TraceUnsignedBaseType_t)((TraceUnsignedBaseType_t)(xEntryHandle) - (TraceUnsignedBaseType_t)pxEntryTable) / sizeof(TraceEntry_t))) - -#if (TRC_ENTRY_TABLE_SLOTS > 256) -typedef uint16_t TraceEntryIndex_t; -#else -typedef uint8_t TraceEntryIndex_t; -#endif /* (TRC_CFG_ENTRY_TABLE_SLOTS > 256) */ - -typedef struct EntryIndexTable -{ - TraceEntryIndex_t axFreeIndexes[TRC_ENTRY_TABLE_SLOTS]; - uint32_t uiFreeIndexCount; -} TraceEntryIndexTable_t; - -typedef struct TraceEntryTable -{ - uint32_t uiSlots; - uint32_t uiEntrySymbolLength; - uint32_t uiEntryStateCount; - TraceEntry_t axEntries[TRC_ENTRY_TABLE_SLOTS]; -} TraceEntryTable_t; - -/* Private function definitions */ -traceResult prvEntryIndexInitialize(TraceEntryIndexTable_t *pxIndexTable); -traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex); - -/* Variables */ -static TraceEntryTable_t *pxEntryTable; -static TraceEntryIndexTable_t xIndexTable; - -traceResult xTraceEntryTableInitialize(TraceEntryTableBuffer_t *pxBuffer) -{ - uint32_t i, j; - - TRC_ASSERT_EQUAL_SIZE(TraceEntryTableBuffer_t, TraceEntryTable_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - /* This should never fail */ - TRC_ASSERT((TRC_ENTRY_TABLE_SLOTS) != 0); - - pxEntryTable = (TraceEntryTable_t*)pxBuffer; - - pxEntryTable->uiSlots = TRC_ENTRY_TABLE_SLOTS; - pxEntryTable->uiEntrySymbolLength = TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE; - pxEntryTable->uiEntryStateCount = TRC_ENTRY_TABLE_STATE_COUNT; - - for (i = 0; i < TRC_ENTRY_TABLE_SLOTS; i++) - { - pxEntryTable->axEntries[i].pvAddress = 0; - for (j = 0; j < TRC_ENTRY_TABLE_STATE_COUNT; j++) - { - pxEntryTable->axEntries[i].xStates[j] = 0; - } - pxEntryTable->axEntries[i].szSymbol[0] = 0; - } - - prvEntryIndexInitialize(&xIndexTable); - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY); - - return TRC_SUCCESS; -} - -traceResult xTraceEntryCreate(TraceEntryHandle_t *pxEntryHandle) -{ - uint32_t i; - TraceEntryIndex_t xIndex; - TraceEntry_t *pxEntry; - - TRACE_ALLOC_CRITICAL_SECTION(); - - /* We always check this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT(pxEntryHandle != 0); - - TRACE_ENTER_CRITICAL_SECTION(); - - if (prvEntryIndexTake(&xIndex) != TRC_SUCCESS) - { - xTraceDiagnosticsIncrease(TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM); - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - - pxEntry = &pxEntryTable->axEntries[xIndex]; - - pxEntry->pvAddress = (void*)pxEntry; /* We set a temporary address */ - - for (i = 0; i < TRC_ENTRY_TABLE_STATE_COUNT; i++) - { - pxEntry->xStates[i] = 0; - } - - pxEntry->uiOptions = 0; - pxEntry->szSymbol[0] = 0; - - *pxEntryHandle = (TraceEntryHandle_t)pxEntry; - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_SUCCESS; -} - -traceResult xTraceEntryDelete(TraceEntryHandle_t xEntryHandle) -{ - TraceEntryIndex_t xIndex; - - TRACE_ALLOC_CRITICAL_SECTION(); - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* This should never fail */ - TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); - - /* Calculate the index based on the entry address */ - /* Does not need to be locked. */ - /* This should never fail */ - xIndex = CALCULATE_ENTRY_INDEX(xEntryHandle); - - TRC_ASSERT(xIndex < TRC_ENTRY_TABLE_SLOTS); - - TRACE_ENTER_CRITICAL_SECTION(); - - if (((TraceEntry_t*)xEntryHandle)->pvAddress == 0) - { - /* Someone else has deleted this already? */ - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - - /* A valid address, so we assume it is OK. */ - /* For good measure, we clear the address field */ - ((TraceEntry_t*)xEntryHandle)->pvAddress = 0; - - /* Give back the index */ - GIVE_ENTRY_INDEX(xIndex); - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_SUCCESS; -} - -traceResult xTraceEntryFind(void* pvAddress, TraceEntryHandle_t* pxEntryHandle) -{ - uint32_t i; - TraceEntry_t* pxEntry; - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* This should never fail */ - TRC_ASSERT(pxEntryHandle != 0); - - /* This should never fail */ - TRC_ASSERT(pvAddress != 0); - - for (i = 0; i < TRC_ENTRY_TABLE_SLOTS; i++) - { - pxEntry = (TraceEntry_t*)(((uint32_t)pxEntryTable->axEntries) + (i * sizeof(TraceEntry_t))); - if (pxEntry->pvAddress == pvAddress) - { - *pxEntryHandle = (TraceEntryHandle_t)pxEntry; - - return TRC_SUCCESS; - } - } - - return TRC_FAIL; -} - -traceResult xTraceEntrySetSymbol(TraceEntryHandle_t xEntryHandle, const char* szSymbol) -{ - uint32_t i; - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - if (szSymbol == 0) - { - szSymbol = ""; - } - - /* Does not need to be locked. */ - /* This should never fail */ - TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); - - for (i = 0; i < (TRC_ENTRY_TABLE_SYMBOL_LENGTH); i++) - { - ((TraceEntry_t*)xEntryHandle)->szSymbol[i] = szSymbol[i]; /* We do this first to ensure we also get the 0 termination, if there is one */ - - if (szSymbol[i] == 0) - { - break; - } - } - - /* Check the length of "name", if longer than TRC_ENTRY_TABLE_SYMBOL_LENGTH */ - while ((szSymbol[i] != 0) && i < 128) - { - i++; - } - - /* Remember the longest symbol name */ - xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH, i); - - return TRC_SUCCESS; -} - -traceResult xTraceEntryGetCount(uint32_t* puiCount) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* This should never fail */ - TRC_ASSERT(puiCount != 0); - - *puiCount = TRC_ENTRY_TABLE_SLOTS - GET_FREE_INDEX_COUNT(); - - return TRC_SUCCESS; -} - -traceResult xTraceEntryGetAtIndex(uint32_t index, TraceEntryHandle_t* pxEntryHandle) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* This should never fail */ - TRC_ASSERT(index < TRC_ENTRY_TABLE_SLOTS); - - /* This should never fail */ - TRC_ASSERT(pxEntryHandle != 0); - - *pxEntryHandle = (TraceEntryHandle_t)((uint32_t)(pxEntryTable->axEntries) + (index * sizeof(TraceEntry_t))); - - return TRC_SUCCESS; -} - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -traceResult xTraceEntryCreateWithAddress(void* pvAddress, TraceEntryHandle_t* pxEntryHandle) -{ - /* This should never fail */ - TRC_ASSERT(pvAddress != 0); - - return TRC_ENTRY_CREATE_WITH_ADDRESS(pvAddress, pxEntryHandle); -} - -traceResult xTraceEntrySetState(TraceEntryHandle_t xEntryHandle, uint32_t uiStateIndex, TraceUnsignedBaseType_t uxState) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* This should never fail */ - TRC_ASSERT(uiStateIndex < (TRC_ENTRY_TABLE_STATE_COUNT)); - - /* This should never fail */ - TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); - - return TRC_ENTRY_SET_STATE(xEntryHandle, uiStateIndex, uxState); -} - -traceResult xTraceEntrySetOptions(TraceEntryHandle_t xEntryHandle, uint32_t uiMask) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* Does not need to be locked. */ - /* This should never fail */ - TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); - - return TRC_ENTRY_SET_OPTIONS(xEntryHandle, uiMask); -} - -traceResult xTraceEntryClearOptions(TraceEntryHandle_t xEntryHandle, uint32_t uiMask) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* Does not need to be locked. */ - /* This should never fail */ - TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); - - return TRC_ENTRY_CLEAR_OPTIONS(xEntryHandle, uiMask); -} - -traceResult xTraceEntryGetAddress(TraceEntryHandle_t xEntryHandle, void **ppvAddress) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* This should never fail */ - TRC_ASSERT(ppvAddress != 0); - - /* Does not need to be locked. */ - /* This should never fail */ - TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); - - return TRC_ENTRY_GET_ADDRESS(xEntryHandle, ppvAddress); -} - -traceResult xTraceEntryGetSymbol(TraceEntryHandle_t xEntryHandle, const char** pszSymbol) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* This should never fail */ - TRC_ASSERT(pszSymbol != 0); - - /* Does not need to be locked. */ - /* This should never fail */ - TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); - - return TRC_ENTRY_GET_SYMBOL(xEntryHandle, pszSymbol); -} - -traceResult xTraceEntryGetState(TraceEntryHandle_t xEntryHandle, uint32_t uiStateIndex, TraceUnsignedBaseType_t *puxState) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* This should never fail */ - TRC_ASSERT(puxState != 0); - - /* This should never fail */ - TRC_ASSERT(uiStateIndex < TRC_ENTRY_TABLE_STATE_COUNT); - - /* Does not need to be locked. */ - /* This should never fail */ - TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); - - return TRC_ENTRY_GET_STATE(xEntryHandle, uiStateIndex, puxState); -} - -traceResult xTraceEntryGetOptions(TraceEntryHandle_t xEntryHandle, uint32_t *puiOptions) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY)); - - /* This should never fail */ - TRC_ASSERT(puiOptions != 0); - - /* Does not need to be locked. */ - /* This should never fail */ - TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); - - return TRC_ENTRY_GET_OPTIONS(xEntryHandle, puiOptions); -} - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -/* PRIVATE FUNCTIONS */ - -traceResult prvEntryIndexInitialize(TraceEntryIndexTable_t* pxIndexTable) -{ - uint32_t i; - - for (i = 0; i < TRC_ENTRY_TABLE_SLOTS; i++) - { - pxIndexTable->axFreeIndexes[i] = (TraceEntryIndex_t)i; - } - - xIndexTable.uiFreeIndexCount = TRC_ENTRY_TABLE_SLOTS; - - return TRC_SUCCESS; -} - -traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex) -{ - /* Critical Section must be active! */ - TraceEntryIndex_t xIndex; - - if (xIndexTable.uiFreeIndexCount == 0) - { - return TRC_FAIL; - } - - /* Always take the first item */ - xIndex = xIndexTable.axFreeIndexes[0]; - xIndexTable.uiFreeIndexCount--; - - /* Move the last item to the first slot, to avoid holes */ - xIndexTable.axFreeIndexes[0] = xIndexTable.axFreeIndexes[xIndexTable.uiFreeIndexCount]; - -#if (TRC_ENTRY_TABLE_SLOTS > 256) - xIndexTable.axFreeIndexes[xIndexTable.uiFreeIndexCount] = UINT16_MAX; -#else - xIndexTable.axFreeIndexes[xIndexTable.uiFreeIndexCount] = UINT8_MAX; -#endif - - *pxIndex = xIndex; - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation of the entry table. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #define VALIDATE_ENTRY_HANDLE( xEntryHandle ) ( ( ( ( TraceUnsignedBaseType_t ) ( xEntryHandle ) >= ( TraceUnsignedBaseType_t ) pxEntryTable ) && ( ( TraceUnsignedBaseType_t ) ( xEntryHandle ) < ( ( TraceUnsignedBaseType_t ) pxEntryTable + sizeof( TraceEntryTable_t ) ) ) ) ) + + #define GIVE_ENTRY_INDEX( xIndex ) xIndexTable.axFreeIndexes[ xIndexTable.uiFreeIndexCount ] = ( xIndex ); xIndexTable.uiFreeIndexCount++ + + #define GET_FREE_INDEX_COUNT() xIndexTable.uiFreeIndexCount + + #define CALCULATE_ENTRY_INDEX( xEntryHandle ) ( TraceEntryIndex_t ) ( ( ( TraceUnsignedBaseType_t ) ( ( TraceUnsignedBaseType_t ) ( xEntryHandle ) - ( TraceUnsignedBaseType_t ) pxEntryTable ) / sizeof( TraceEntry_t ) ) ) + + #if ( TRC_ENTRY_TABLE_SLOTS > 256 ) + typedef uint16_t TraceEntryIndex_t; + #else + typedef uint8_t TraceEntryIndex_t; + #endif /* (TRC_CFG_ENTRY_TABLE_SLOTS > 256) */ + + typedef struct EntryIndexTable + { + TraceEntryIndex_t axFreeIndexes[ TRC_ENTRY_TABLE_SLOTS ]; + uint32_t uiFreeIndexCount; + } TraceEntryIndexTable_t; + + typedef struct TraceEntryTable + { + uint32_t uiSlots; + uint32_t uiEntrySymbolLength; + uint32_t uiEntryStateCount; + TraceEntry_t axEntries[ TRC_ENTRY_TABLE_SLOTS ]; + } TraceEntryTable_t; + +/* Private function definitions */ + traceResult prvEntryIndexInitialize( TraceEntryIndexTable_t * pxIndexTable ); + traceResult prvEntryIndexTake( TraceEntryIndex_t * pxIndex ); + +/* Variables */ + static TraceEntryTable_t * pxEntryTable; + static TraceEntryIndexTable_t xIndexTable; + + traceResult xTraceEntryTableInitialize( TraceEntryTableBuffer_t * pxBuffer ) + { + uint32_t i, j; + + TRC_ASSERT_EQUAL_SIZE( TraceEntryTableBuffer_t, TraceEntryTable_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( TRC_ENTRY_TABLE_SLOTS ) != 0 ); + + pxEntryTable = ( TraceEntryTable_t * ) pxBuffer; + + pxEntryTable->uiSlots = TRC_ENTRY_TABLE_SLOTS; + pxEntryTable->uiEntrySymbolLength = TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE; + pxEntryTable->uiEntryStateCount = TRC_ENTRY_TABLE_STATE_COUNT; + + for( i = 0; i < TRC_ENTRY_TABLE_SLOTS; i++ ) + { + pxEntryTable->axEntries[ i ].pvAddress = 0; + + for( j = 0; j < TRC_ENTRY_TABLE_STATE_COUNT; j++ ) + { + pxEntryTable->axEntries[ i ].xStates[ j ] = 0; + } + + pxEntryTable->axEntries[ i ].szSymbol[ 0 ] = 0; + } + + prvEntryIndexInitialize( &xIndexTable ); + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ); + + return TRC_SUCCESS; + } + + traceResult xTraceEntryCreate( TraceEntryHandle_t * pxEntryHandle ) + { + uint32_t i; + TraceEntryIndex_t xIndex; + TraceEntry_t * pxEntry; + + TRACE_ALLOC_CRITICAL_SECTION(); + + /* We always check this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT( pxEntryHandle != 0 ); + + TRACE_ENTER_CRITICAL_SECTION(); + + if( prvEntryIndexTake( &xIndex ) != TRC_SUCCESS ) + { + xTraceDiagnosticsIncrease( TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + + pxEntry = &pxEntryTable->axEntries[ xIndex ]; + + pxEntry->pvAddress = ( void * ) pxEntry; /* We set a temporary address */ + + for( i = 0; i < TRC_ENTRY_TABLE_STATE_COUNT; i++ ) + { + pxEntry->xStates[ i ] = 0; + } + + pxEntry->uiOptions = 0; + pxEntry->szSymbol[ 0 ] = 0; + + *pxEntryHandle = ( TraceEntryHandle_t ) pxEntry; + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_SUCCESS; + } + + traceResult xTraceEntryDelete( TraceEntryHandle_t xEntryHandle ) + { + TraceEntryIndex_t xIndex; + + TRACE_ALLOC_CRITICAL_SECTION(); + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* This should never fail */ + TRC_ASSERT( VALIDATE_ENTRY_HANDLE( xEntryHandle ) ); + + /* Calculate the index based on the entry address */ + /* Does not need to be locked. */ + /* This should never fail */ + xIndex = CALCULATE_ENTRY_INDEX( xEntryHandle ); + + TRC_ASSERT( xIndex < TRC_ENTRY_TABLE_SLOTS ); + + TRACE_ENTER_CRITICAL_SECTION(); + + if( ( ( TraceEntry_t * ) xEntryHandle )->pvAddress == 0 ) + { + /* Someone else has deleted this already? */ + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + + /* A valid address, so we assume it is OK. */ + /* For good measure, we clear the address field */ + ( ( TraceEntry_t * ) xEntryHandle )->pvAddress = 0; + + /* Give back the index */ + GIVE_ENTRY_INDEX( xIndex ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_SUCCESS; + } + + traceResult xTraceEntryFind( void * pvAddress, + TraceEntryHandle_t * pxEntryHandle ) + { + uint32_t i; + TraceEntry_t * pxEntry; + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* This should never fail */ + TRC_ASSERT( pxEntryHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( pvAddress != 0 ); + + for( i = 0; i < TRC_ENTRY_TABLE_SLOTS; i++ ) + { + pxEntry = ( TraceEntry_t * ) ( ( ( uint32_t ) pxEntryTable->axEntries ) + ( i * sizeof( TraceEntry_t ) ) ); + + if( pxEntry->pvAddress == pvAddress ) + { + *pxEntryHandle = ( TraceEntryHandle_t ) pxEntry; + + return TRC_SUCCESS; + } + } + + return TRC_FAIL; + } + + traceResult xTraceEntrySetSymbol( TraceEntryHandle_t xEntryHandle, + const char * szSymbol ) + { + uint32_t i; + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + if( szSymbol == 0 ) + { + szSymbol = ""; + } + + /* Does not need to be locked. */ + /* This should never fail */ + TRC_ASSERT( VALIDATE_ENTRY_HANDLE( xEntryHandle ) ); + + for( i = 0; i < ( TRC_ENTRY_TABLE_SYMBOL_LENGTH ); i++ ) + { + ( ( TraceEntry_t * ) xEntryHandle )->szSymbol[ i ] = szSymbol[ i ]; /* We do this first to ensure we also get the 0 termination, if there is one */ + + if( szSymbol[ i ] == 0 ) + { + break; + } + } + + /* Check the length of "name", if longer than TRC_ENTRY_TABLE_SYMBOL_LENGTH */ + while( ( szSymbol[ i ] != 0 ) && i < 128 ) + { + i++; + } + + /* Remember the longest symbol name */ + xTraceDiagnosticsSetIfHigher( TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH, i ); + + return TRC_SUCCESS; + } + + traceResult xTraceEntryGetCount( uint32_t * puiCount ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* This should never fail */ + TRC_ASSERT( puiCount != 0 ); + + *puiCount = TRC_ENTRY_TABLE_SLOTS - GET_FREE_INDEX_COUNT(); + + return TRC_SUCCESS; + } + + traceResult xTraceEntryGetAtIndex( uint32_t index, + TraceEntryHandle_t * pxEntryHandle ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* This should never fail */ + TRC_ASSERT( index < TRC_ENTRY_TABLE_SLOTS ); + + /* This should never fail */ + TRC_ASSERT( pxEntryHandle != 0 ); + + *pxEntryHandle = ( TraceEntryHandle_t ) ( ( uint32_t ) ( pxEntryTable->axEntries ) + ( index * sizeof( TraceEntry_t ) ) ); + + return TRC_SUCCESS; + } + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + + traceResult xTraceEntryCreateWithAddress( void * pvAddress, + TraceEntryHandle_t * pxEntryHandle ) + { + /* This should never fail */ + TRC_ASSERT( pvAddress != 0 ); + + return TRC_ENTRY_CREATE_WITH_ADDRESS( pvAddress, pxEntryHandle ); + } + + traceResult xTraceEntrySetState( TraceEntryHandle_t xEntryHandle, + uint32_t uiStateIndex, + TraceUnsignedBaseType_t uxState ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* This should never fail */ + TRC_ASSERT( uiStateIndex < ( TRC_ENTRY_TABLE_STATE_COUNT ) ); + + /* This should never fail */ + TRC_ASSERT( VALIDATE_ENTRY_HANDLE( xEntryHandle ) ); + + return TRC_ENTRY_SET_STATE( xEntryHandle, uiStateIndex, uxState ); + } + + traceResult xTraceEntrySetOptions( TraceEntryHandle_t xEntryHandle, + uint32_t uiMask ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* Does not need to be locked. */ + /* This should never fail */ + TRC_ASSERT( VALIDATE_ENTRY_HANDLE( xEntryHandle ) ); + + return TRC_ENTRY_SET_OPTIONS( xEntryHandle, uiMask ); + } + + traceResult xTraceEntryClearOptions( TraceEntryHandle_t xEntryHandle, + uint32_t uiMask ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* Does not need to be locked. */ + /* This should never fail */ + TRC_ASSERT( VALIDATE_ENTRY_HANDLE( xEntryHandle ) ); + + return TRC_ENTRY_CLEAR_OPTIONS( xEntryHandle, uiMask ); + } + + traceResult xTraceEntryGetAddress( TraceEntryHandle_t xEntryHandle, + void ** ppvAddress ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* This should never fail */ + TRC_ASSERT( ppvAddress != 0 ); + + /* Does not need to be locked. */ + /* This should never fail */ + TRC_ASSERT( VALIDATE_ENTRY_HANDLE( xEntryHandle ) ); + + return TRC_ENTRY_GET_ADDRESS( xEntryHandle, ppvAddress ); + } + + traceResult xTraceEntryGetSymbol( TraceEntryHandle_t xEntryHandle, + const char ** pszSymbol ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* This should never fail */ + TRC_ASSERT( pszSymbol != 0 ); + + /* Does not need to be locked. */ + /* This should never fail */ + TRC_ASSERT( VALIDATE_ENTRY_HANDLE( xEntryHandle ) ); + + return TRC_ENTRY_GET_SYMBOL( xEntryHandle, pszSymbol ); + } + + traceResult xTraceEntryGetState( TraceEntryHandle_t xEntryHandle, + uint32_t uiStateIndex, + TraceUnsignedBaseType_t * puxState ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* This should never fail */ + TRC_ASSERT( puxState != 0 ); + + /* This should never fail */ + TRC_ASSERT( uiStateIndex < TRC_ENTRY_TABLE_STATE_COUNT ); + + /* Does not need to be locked. */ + /* This should never fail */ + TRC_ASSERT( VALIDATE_ENTRY_HANDLE( xEntryHandle ) ); + + return TRC_ENTRY_GET_STATE( xEntryHandle, uiStateIndex, puxState ); + } + + traceResult xTraceEntryGetOptions( TraceEntryHandle_t xEntryHandle, + uint32_t * puiOptions ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ENTRY ) ); + + /* This should never fail */ + TRC_ASSERT( puiOptions != 0 ); + + /* Does not need to be locked. */ + /* This should never fail */ + TRC_ASSERT( VALIDATE_ENTRY_HANDLE( xEntryHandle ) ); + + return TRC_ENTRY_GET_OPTIONS( xEntryHandle, puiOptions ); + } + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + +/* PRIVATE FUNCTIONS */ + + traceResult prvEntryIndexInitialize( TraceEntryIndexTable_t * pxIndexTable ) + { + uint32_t i; + + for( i = 0; i < TRC_ENTRY_TABLE_SLOTS; i++ ) + { + pxIndexTable->axFreeIndexes[ i ] = ( TraceEntryIndex_t ) i; + } + + xIndexTable.uiFreeIndexCount = TRC_ENTRY_TABLE_SLOTS; + + return TRC_SUCCESS; + } + + traceResult prvEntryIndexTake( TraceEntryIndex_t * pxIndex ) + { + /* Critical Section must be active! */ + TraceEntryIndex_t xIndex; + + if( xIndexTable.uiFreeIndexCount == 0 ) + { + return TRC_FAIL; + } + + /* Always take the first item */ + xIndex = xIndexTable.axFreeIndexes[ 0 ]; + xIndexTable.uiFreeIndexCount--; + + /* Move the last item to the first slot, to avoid holes */ + xIndexTable.axFreeIndexes[ 0 ] = xIndexTable.axFreeIndexes[ xIndexTable.uiFreeIndexCount ]; + + #if ( TRC_ENTRY_TABLE_SLOTS > 256 ) + xIndexTable.axFreeIndexes[ xIndexTable.uiFreeIndexCount ] = UINT16_MAX; + #else + xIndexTable.axFreeIndexes[ xIndexTable.uiFreeIndexCount ] = UINT8_MAX; + #endif + + *pxIndex = xIndex; + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcError.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcError.c index 2a6b2588c..b11c5a299 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcError.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcError.c @@ -1,339 +1,354 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for errors. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -/* We skip the slot for TRC_ERROR_NONE so error code 1 is the first bit */ -#define GET_ERROR_WARNING_FLAG(errorCode) (pxErrorInfo->uiErrorAndWarningFlags & (1 << ((errorCode) - 1))) -#define SET_ERROR_WARNING_FLAG(errorCode) (pxErrorInfo->uiErrorAndWarningFlags |= (1 << ((errorCode) - 1))) - -traceResult prvTraceErrorPrint(uint32_t uiErrorCode); -traceResult prvTraceErrorGetDescription(uint32_t uiErrorCode, const char** pszDesc); - -typedef struct TraceErrorInfo -{ - uint32_t uiErrorAndWarningFlags; - uint32_t uiErrorCode; - TraceStringHandle_t xWarningChannel; -} TraceErrorInfo_t; - -static TraceErrorInfo_t* pxErrorInfo; - -traceResult xTraceErrorInitialize(TraceErrorBuffer_t* pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceErrorBuffer_t, TraceErrorInfo_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - pxErrorInfo = (TraceErrorInfo_t*)pxBuffer; - - pxErrorInfo->uiErrorAndWarningFlags = 0; - pxErrorInfo->uiErrorCode = 0; - pxErrorInfo->xWarningChannel = 0; - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ERROR); - - return TRC_SUCCESS; -} - -/* Called on warnings, when the recording can continue. */ -traceResult xTraceWarning(uint32_t uiErrorCode) -{ - /* Probably good to verify this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ERROR)) - { - /* If not initialized */ - return TRC_FAIL; - } - - if (GET_ERROR_WARNING_FLAG(uiErrorCode) == 0) - { - /* Will never reach this point more than once per warning type, since we verify if uiErrorAndWarningFlags[uiErrorCode] has already been set */ - SET_ERROR_WARNING_FLAG(uiErrorCode); - - prvTraceErrorPrint(uiErrorCode); - } - - return TRC_SUCCESS; -} - -/* Called on critical errors in the recorder. Stops the recorder! */ -traceResult xTraceError(uint32_t uiErrorCode) -{ - /* Probably good to verify this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ERROR)) - { - return TRC_FAIL; - } - - if (pxErrorInfo->uiErrorCode == TRC_ERROR_NONE) - { - /* Will never reach this point more than once, since we verify if uiErrorCode has already been set */ - SET_ERROR_WARNING_FLAG(uiErrorCode); - pxErrorInfo->uiErrorCode = uiErrorCode; - - if (prvTraceErrorPrint(uiErrorCode) == TRC_FAIL) - { - xTraceDisable(); - - return TRC_FAIL; - } - - xTracePrint(pxErrorInfo->xWarningChannel, "Recorder stopped in xTraceError(...)!"); - xTraceDisable(); - } - - return TRC_SUCCESS; -} - -/******************************************************************************* - * xTraceErrorGetLast - * - * Returns the last error or warning, as a string, or NULL if none. - *****************************************************************************/ -traceResult xTraceErrorGetLast(const char **pszError) -{ - /* Probably good to verify this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ERROR)) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT(pszError != 0); - - return prvTraceErrorGetDescription(pxErrorInfo->uiErrorCode, pszError); -} - -/******************************************************************************* - * xTraceErrorClear - * - * Clears any errors. - *****************************************************************************/ -traceResult xTraceErrorClear(void) -{ - /* Probably good to verify this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ERROR)) - { - /* If not initialized */ - return TRC_FAIL; - } - - pxErrorInfo->uiErrorCode = TRC_ERROR_NONE; - - return TRC_SUCCESS; -} - -/* Returns the error or warning, as a string, or NULL if none. */ -traceResult prvTraceErrorPrint(uint32_t uiErrorCode) -{ - const char* szDesc; - /* Note: the error messages are short, in order to fit in a User Event. - Instead, the users can read more in the below comments.*/ - - if (pxErrorInfo->xWarningChannel == 0) - { - /* The #WFR channel means "Warnings from Recorder" and - * is used to store warnings and errors from the recorder. - * The abbreviation #WFR is used instead of the longer full name, - * to avoid truncation by small slots in the symbol table. - * This is translated in Tracealyzer and shown as the full name, - * "Warnings from Recorder". - */ - if (xTraceStringRegister("#WFR", &pxErrorInfo->xWarningChannel) == TRC_FAIL) - { - return TRC_FAIL; - } - } - - prvTraceErrorGetDescription(uiErrorCode, &szDesc); - - switch (uiErrorCode) - { - case TRC_WARNING_ENTRY_TABLE_SLOTS: - case TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH: - case TRC_WARNING_EVENT_SIZE_TRUNCATED: - case TRC_WARNING_STREAM_PORT_READ: - case TRC_WARNING_STREAM_PORT_WRITE: - case TRC_WARNING_STREAM_PORT_INITIAL_BLOCKING: - case TRC_WARNING_STACKMON_NO_SLOTS: - case TRC_ERROR_STREAM_PORT_WRITE: - case TRC_ERROR_EVENT_CODE_TOO_LARGE: - case TRC_ERROR_ISR_NESTING_OVERFLOW: - case TRC_ERROR_DWT_NOT_SUPPORTED: - case TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED: - case TRC_ERROR_TZCTRLTASK_NOT_CREATED: - xTracePrint(pxErrorInfo->xWarningChannel, szDesc); - break; - - case TRC_ERROR_ASSERT: - /* A TRC_ASSERT has triggered */ - { - TraceUnsignedBaseType_t uxLineNumber; - TraceStringHandle_t xFileName; - - if (xTraceAssertGet(&xFileName, &uxLineNumber) == TRC_FAIL) - { - return TRC_FAIL; - } - - xTracePrintF(pxErrorInfo->xWarningChannel, szDesc, xFileName, (uint32_t)uxLineNumber); - - return TRC_SUCCESS; - } - - default: - /* No error, or an unknown error occurred */ - xTracePrintF(pxErrorInfo->xWarningChannel, "Unknown error code: 0x%08X", uiErrorCode); - - return TRC_FAIL; - } - - return TRC_SUCCESS; -} - -/* Returns the error or warning, as a string, or NULL if none. */ -traceResult prvTraceErrorGetDescription(uint32_t uiErrorCode, const char** pszDesc) -{ - /* Note: the error messages are short, in order to fit in a User Event. - Instead, the users can read more in the below comments.*/ - - switch (uiErrorCode) - { - case TRC_ERROR_NONE: - return TRC_FAIL; - - case TRC_WARNING_ENTRY_TABLE_SLOTS: - /* There was not enough symbol table slots for storing symbol names. - The number of missing slots is counted by NoRoomForSymbol. Inspect this - variable and increase TRC_CFG_ENTRY_TABLE_SLOTS by at least that value. */ - - *pszDesc = "Exceeded TRC_CFG_ENTRY_TABLE_SLOTS"; - break; - - case TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH: - /* A symbol name exceeded TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH in length. - Make sure the symbol names are at most TRC_CFG_SYMBOL_MAX_LENGTH, - or inspect uiLongestSymbolName in trcEntryTable and increase - TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH to at least this value. */ - - *pszDesc = "Exceeded TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH"; - break; - - case TRC_WARNING_EVENT_SIZE_TRUNCATED: - /* Some arguments was longer than the maximum payload size - and has been truncated by "uiMaxBytesTruncated" bytes. - - This usually happens for the following functions: - - xTracePrint - - xTracePrintF - - xTraceStringRegister - - A trace event may store a maximum of 56 bytes payload, including - data arguments and string characters. */ - - *pszDesc = "Event size exceeded"; - break; - - case TRC_WARNING_STREAM_PORT_READ: - /* TRC_STREAM_PORT_READ_DATA is expected to return 0 when completed successfully. - This means there is an error in the communication with host/Tracealyzer. */ - - *pszDesc = "TRC_STREAM_PORT_READ_DATA returned error"; - break; - - case TRC_WARNING_STREAM_PORT_WRITE: - /* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully. - This means there is an error in the communication with host/Tracealyzer. */ - - *pszDesc = "TRC_STREAM_PORT_WRITE_DATA returned error"; - break; - - case TRC_WARNING_STREAM_PORT_INITIAL_BLOCKING: - /* Blocking occurred during xTraceEnable. This happens if the trace buffer is - smaller than the initial transmission (trace header, object table, and symbol table). */ - - *pszDesc = "Blocking in xTraceEnable"; - break; - - case TRC_WARNING_STACKMON_NO_SLOTS: - /* Some tasks did not fit in the stack monitor. Increase the slot count. */ - - *pszDesc = "No slots left in Stack Monitor"; - break; - - case TRC_ERROR_STREAM_PORT_WRITE: - /* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully. - This means there is an error in the communication with host/Tracealyzer. */ - - *pszDesc = "TRC_STREAM_PORT_WRITE_DATA returned error"; - break; - - case TRC_ERROR_EVENT_CODE_TOO_LARGE: - /* The highest allowed event code is 4095, anything higher is an unexpected error. - Please contact support@percepio.com for assistance.*/ - - *pszDesc = "Invalid event code"; - break; - - case TRC_ERROR_ISR_NESTING_OVERFLOW: - /* Nesting of ISR trace calls exceeded the limit (TRC_CFG_MAX_ISR_NESTING). - If this is unlikely, make sure that you call vTraceStoreISRExit in the end - of all ISR handlers. Or increase TRC_CFG_MAX_ISR_NESTING. */ - - *pszDesc = "Exceeded ISR nesting"; - break; - - case TRC_ERROR_DWT_NOT_SUPPORTED: - /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip. - DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M - macro normally set by ARM's CMSIS library, since typically available. You can however select - SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/ - - *pszDesc = "DWT not supported"; - break; - - case TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED: - /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip. - DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M - macro normally set by ARM's CMSIS library, since typically available. You can however select - SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/ - - *pszDesc = "DWT_CYCCNT not supported"; - break; - - case TRC_ERROR_TZCTRLTASK_NOT_CREATED: - /* xTraceEnable failed creating the trace control task (TzCtrl) - incorrect parameters (priority?) - or insufficient heap size? */ - *pszDesc = "Could not create TzCtrl"; - break; - - case TRC_ERROR_ASSERT: - /* A TRC_ASSERT has triggered */ - *pszDesc = "ASSERT: %s (%d)"; - break; - - default: - /* An unknown error occurred */ - *pszDesc = "Unknown error code: 0x%08X"; - break; - } - - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for errors. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + +/* We skip the slot for TRC_ERROR_NONE so error code 1 is the first bit */ + #define GET_ERROR_WARNING_FLAG( errorCode ) ( pxErrorInfo->uiErrorAndWarningFlags & ( 1 << ( ( errorCode ) - 1 ) ) ) + #define SET_ERROR_WARNING_FLAG( errorCode ) ( pxErrorInfo->uiErrorAndWarningFlags |= ( 1 << ( ( errorCode ) - 1 ) ) ) + + traceResult prvTraceErrorPrint( uint32_t uiErrorCode ); + traceResult prvTraceErrorGetDescription( uint32_t uiErrorCode, + const char ** pszDesc ); + + typedef struct TraceErrorInfo + { + uint32_t uiErrorAndWarningFlags; + uint32_t uiErrorCode; + TraceStringHandle_t xWarningChannel; + } TraceErrorInfo_t; + + static TraceErrorInfo_t * pxErrorInfo; + + traceResult xTraceErrorInitialize( TraceErrorBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceErrorBuffer_t, TraceErrorInfo_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + pxErrorInfo = ( TraceErrorInfo_t * ) pxBuffer; + + pxErrorInfo->uiErrorAndWarningFlags = 0; + pxErrorInfo->uiErrorCode = 0; + pxErrorInfo->xWarningChannel = 0; + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_ERROR ); + + return TRC_SUCCESS; + } + +/* Called on warnings, when the recording can continue. */ + traceResult xTraceWarning( uint32_t uiErrorCode ) + { + /* Probably good to verify this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ERROR ) ) + { + /* If not initialized */ + return TRC_FAIL; + } + + if( GET_ERROR_WARNING_FLAG( uiErrorCode ) == 0 ) + { + /* Will never reach this point more than once per warning type, since we verify if uiErrorAndWarningFlags[uiErrorCode] has already been set */ + SET_ERROR_WARNING_FLAG( uiErrorCode ); + + prvTraceErrorPrint( uiErrorCode ); + } + + return TRC_SUCCESS; + } + +/* Called on critical errors in the recorder. Stops the recorder! */ + traceResult xTraceError( uint32_t uiErrorCode ) + { + /* Probably good to verify this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ERROR ) ) + { + return TRC_FAIL; + } + + if( pxErrorInfo->uiErrorCode == TRC_ERROR_NONE ) + { + /* Will never reach this point more than once, since we verify if uiErrorCode has already been set */ + SET_ERROR_WARNING_FLAG( uiErrorCode ); + pxErrorInfo->uiErrorCode = uiErrorCode; + + if( prvTraceErrorPrint( uiErrorCode ) == TRC_FAIL ) + { + xTraceDisable(); + + return TRC_FAIL; + } + + xTracePrint( pxErrorInfo->xWarningChannel, "Recorder stopped in xTraceError(...)!" ); + xTraceDisable(); + } + + return TRC_SUCCESS; + } + +/******************************************************************************* + * xTraceErrorGetLast + * + * Returns the last error or warning, as a string, or NULL if none. + *****************************************************************************/ + traceResult xTraceErrorGetLast( const char ** pszError ) + { + /* Probably good to verify this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ERROR ) ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT( pszError != 0 ); + + return prvTraceErrorGetDescription( pxErrorInfo->uiErrorCode, pszError ); + } + +/******************************************************************************* + * xTraceErrorClear + * + * Clears any errors. + *****************************************************************************/ + traceResult xTraceErrorClear( void ) + { + /* Probably good to verify this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ERROR ) ) + { + /* If not initialized */ + return TRC_FAIL; + } + + pxErrorInfo->uiErrorCode = TRC_ERROR_NONE; + + return TRC_SUCCESS; + } + +/* Returns the error or warning, as a string, or NULL if none. */ + traceResult prvTraceErrorPrint( uint32_t uiErrorCode ) + { + const char * szDesc; + + /* Note: the error messages are short, in order to fit in a User Event. + * Instead, the users can read more in the below comments.*/ + + if( pxErrorInfo->xWarningChannel == 0 ) + { + /* The #WFR channel means "Warnings from Recorder" and + * is used to store warnings and errors from the recorder. + * The abbreviation #WFR is used instead of the longer full name, + * to avoid truncation by small slots in the symbol table. + * This is translated in Tracealyzer and shown as the full name, + * "Warnings from Recorder". + */ + if( xTraceStringRegister( "#WFR", &pxErrorInfo->xWarningChannel ) == TRC_FAIL ) + { + return TRC_FAIL; + } + } + + prvTraceErrorGetDescription( uiErrorCode, &szDesc ); + + switch( uiErrorCode ) + { + case TRC_WARNING_ENTRY_TABLE_SLOTS: + case TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH: + case TRC_WARNING_EVENT_SIZE_TRUNCATED: + case TRC_WARNING_STREAM_PORT_READ: + case TRC_WARNING_STREAM_PORT_WRITE: + case TRC_WARNING_STREAM_PORT_INITIAL_BLOCKING: + case TRC_WARNING_STACKMON_NO_SLOTS: + case TRC_ERROR_STREAM_PORT_WRITE: + case TRC_ERROR_EVENT_CODE_TOO_LARGE: + case TRC_ERROR_ISR_NESTING_OVERFLOW: + case TRC_ERROR_DWT_NOT_SUPPORTED: + case TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED: + case TRC_ERROR_TZCTRLTASK_NOT_CREATED: + xTracePrint( pxErrorInfo->xWarningChannel, szDesc ); + break; + + case TRC_ERROR_ASSERT: + /* A TRC_ASSERT has triggered */ + { + TraceUnsignedBaseType_t uxLineNumber; + TraceStringHandle_t xFileName; + + if( xTraceAssertGet( &xFileName, &uxLineNumber ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + xTracePrintF( pxErrorInfo->xWarningChannel, szDesc, xFileName, ( uint32_t ) uxLineNumber ); + + return TRC_SUCCESS; + } + + default: + /* No error, or an unknown error occurred */ + xTracePrintF( pxErrorInfo->xWarningChannel, "Unknown error code: 0x%08X", uiErrorCode ); + + return TRC_FAIL; + } + + return TRC_SUCCESS; + } + +/* Returns the error or warning, as a string, or NULL if none. */ + traceResult prvTraceErrorGetDescription( uint32_t uiErrorCode, + const char ** pszDesc ) + { + /* Note: the error messages are short, in order to fit in a User Event. + * Instead, the users can read more in the below comments.*/ + + switch( uiErrorCode ) + { + case TRC_ERROR_NONE: + return TRC_FAIL; + + case TRC_WARNING_ENTRY_TABLE_SLOTS: + + /* There was not enough symbol table slots for storing symbol names. + * The number of missing slots is counted by NoRoomForSymbol. Inspect this + * variable and increase TRC_CFG_ENTRY_TABLE_SLOTS by at least that value. */ + + *pszDesc = "Exceeded TRC_CFG_ENTRY_TABLE_SLOTS"; + break; + + case TRC_WARNING_ENTRY_SYMBOL_MAX_LENGTH: + + /* A symbol name exceeded TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH in length. + * Make sure the symbol names are at most TRC_CFG_SYMBOL_MAX_LENGTH, + * or inspect uiLongestSymbolName in trcEntryTable and increase + * TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH to at least this value. */ + + *pszDesc = "Exceeded TRC_CFG_ENTRY_SYMBOL_MAX_LENGTH"; + break; + + case TRC_WARNING_EVENT_SIZE_TRUNCATED: + + /* Some arguments was longer than the maximum payload size + * and has been truncated by "uiMaxBytesTruncated" bytes. + * + * This usually happens for the following functions: + * - xTracePrint + * - xTracePrintF + * - xTraceStringRegister + * + * A trace event may store a maximum of 56 bytes payload, including + * data arguments and string characters. */ + + *pszDesc = "Event size exceeded"; + break; + + case TRC_WARNING_STREAM_PORT_READ: + + /* TRC_STREAM_PORT_READ_DATA is expected to return 0 when completed successfully. + * This means there is an error in the communication with host/Tracealyzer. */ + + *pszDesc = "TRC_STREAM_PORT_READ_DATA returned error"; + break; + + case TRC_WARNING_STREAM_PORT_WRITE: + + /* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully. + * This means there is an error in the communication with host/Tracealyzer. */ + + *pszDesc = "TRC_STREAM_PORT_WRITE_DATA returned error"; + break; + + case TRC_WARNING_STREAM_PORT_INITIAL_BLOCKING: + + /* Blocking occurred during xTraceEnable. This happens if the trace buffer is + * smaller than the initial transmission (trace header, object table, and symbol table). */ + + *pszDesc = "Blocking in xTraceEnable"; + break; + + case TRC_WARNING_STACKMON_NO_SLOTS: + /* Some tasks did not fit in the stack monitor. Increase the slot count. */ + + *pszDesc = "No slots left in Stack Monitor"; + break; + + case TRC_ERROR_STREAM_PORT_WRITE: + + /* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully. + * This means there is an error in the communication with host/Tracealyzer. */ + + *pszDesc = "TRC_STREAM_PORT_WRITE_DATA returned error"; + break; + + case TRC_ERROR_EVENT_CODE_TOO_LARGE: + + /* The highest allowed event code is 4095, anything higher is an unexpected error. + * Please contact support@percepio.com for assistance.*/ + + *pszDesc = "Invalid event code"; + break; + + case TRC_ERROR_ISR_NESTING_OVERFLOW: + + /* Nesting of ISR trace calls exceeded the limit (TRC_CFG_MAX_ISR_NESTING). + * If this is unlikely, make sure that you call vTraceStoreISRExit in the end + * of all ISR handlers. Or increase TRC_CFG_MAX_ISR_NESTING. */ + + *pszDesc = "Exceeded ISR nesting"; + break; + + case TRC_ERROR_DWT_NOT_SUPPORTED: + + /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip. + * DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M + * macro normally set by ARM's CMSIS library, since typically available. You can however select + * SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/ + + *pszDesc = "DWT not supported"; + break; + + case TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED: + + /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip. + * DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M + * macro normally set by ARM's CMSIS library, since typically available. You can however select + * SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/ + + *pszDesc = "DWT_CYCCNT not supported"; + break; + + case TRC_ERROR_TZCTRLTASK_NOT_CREATED: + + /* xTraceEnable failed creating the trace control task (TzCtrl) - incorrect parameters (priority?) + * or insufficient heap size? */ + *pszDesc = "Could not create TzCtrl"; + break; + + case TRC_ERROR_ASSERT: + /* A TRC_ASSERT has triggered */ + *pszDesc = "ASSERT: %s (%d)"; + break; + + default: + /* An unknown error occurred */ + *pszDesc = "Unknown error code: 0x%08X"; + break; + } + + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEvent.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEvent.c index 87d80feb6..ff9d36e04 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEvent.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEvent.c @@ -1,407 +1,432 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for events. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#define VERIFY_EVENT_SIZE(i) \ - if ((i) > (TRC_MAX_BLOB_SIZE)) \ - { \ - xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED, (TraceUnsignedBaseType_t)((i) - (TRC_MAX_BLOB_SIZE))); \ - (i) = TRC_MAX_BLOB_SIZE; \ - } - -TraceEventDataTable_t *pxTraceEventDataTable; - -int32_t DUMMY_iTraceBytesCommitted; - -TRACE_ALLOC_CRITICAL_SECTION(); - -traceResult xTraceEventInitialize(TraceEventDataBuffer_t* pxBuffer) -{ - TraceCoreEventData_t* pxCoreEventData; - uint32_t i, j; - - TRC_ASSERT_EQUAL_SIZE(TraceEventDataBuffer_t, TraceEventDataTable_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - pxTraceEventDataTable = (TraceEventDataTable_t*)pxBuffer; - - for (i = 0; i < TRC_CFG_CORE_COUNT; i++) - { - pxCoreEventData = &pxTraceEventDataTable->coreEventData[i]; - - pxCoreEventData->eventCounter = 0; - - for (j = 0; j < (TRC_CFG_MAX_ISR_NESTING) + 1; j++) - { - RESET_EVENT_DATA(&pxCoreEventData->eventData[j]); - } - } - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT); - - return TRC_SUCCESS; -} - -traceResult xTraceEventBeginRawOffline(uint32_t uiSize, TraceEventHandle_t* pxEventHandle) -{ - TraceEventData_t* pxEventData; - int32_t ISR_nesting; - - /* We need to check this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT(pxEventHandle != 0); - - TRACE_ENTER_CRITICAL_SECTION(); - - xTraceISRGetCurrentNesting(&ISR_nesting); - - /* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */ - pxEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventData[ISR_nesting + 1]; - - /* This should never fail */ - TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); - - VERIFY_EVENT_SIZE(uiSize); - - pxEventData->size = ((uiSize + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t); /* 4-byte align */ - - pxEventData->offset = 0; - - /* This can fail and we should handle it */ - if (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) == TRC_FAIL) - { - TRACE_EXIT_CRITICAL_SECTION(); - return TRC_FAIL; - } - - *pxEventHandle = (TraceEventHandle_t)pxEventData; - - return TRC_SUCCESS; -} - -traceResult xTraceEventBeginRawOfflineBlocking(uint32_t uiSize, TraceEventHandle_t* pxEventHandle) -{ - TraceEventData_t* pxEventData; - int32_t ISR_nesting; - uint32_t uiAttempts = 0; - - /* We need to check this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT(pxEventHandle != 0); - - TRACE_ENTER_CRITICAL_SECTION(); - - xTraceGetCurrentISRNesting(&ISR_nesting); - - /* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */ - pxEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventData[ISR_nesting + 1]; - - /* This should never fail */ - TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); - - VERIFY_EVENT_SIZE(uiSize); - - pxEventData->size = ((uiSize + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t); /* 4-byte align */ - - pxEventData->offset = 0; - - /* This can fail and we should handle it */ - while (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) != TRC_SUCCESS) - { - uiAttempts++; - } - - *pxEventHandle = (TraceEventHandle_t)pxEventData; - - return TRC_SUCCESS; -} - -traceResult xTraceEventEndOffline(TraceEventHandle_t xEventHandle) -{ - int32_t iBytesCommitted; - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0); - - xTraceStreamPortCommit(((TraceEventData_t*)xEventHandle)->pvBlob, ((TraceEventData_t*)xEventHandle)->size, &iBytesCommitted); - - RESET_EVENT_DATA((TraceEventData_t*)xEventHandle); - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_SUCCESS; -} - -traceResult xTraceEventEndOfflineBlocking(TraceEventHandle_t xEventHandle) -{ - TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle; - int32_t iBytesCommitted; - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(pxEventData != 0); - - while (pxEventData->size > 0) - { - iBytesCommitted = 0; - xTraceStreamPortCommit(pxEventData->pvBlob, pxEventData->size, &iBytesCommitted); - - pxEventData->size -= iBytesCommitted; - pxEventData->pvBlob = ((uint8_t*)pxEventData->pvBlob) + iBytesCommitted; - } - - RESET_EVENT_DATA(pxEventData); - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_SUCCESS; -} - -traceResult xTraceEventAddData(TraceEventHandle_t xEventHandle, void* pvData, uint32_t uiSize) -{ - uint32_t i; - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(pvData != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + uiSize <= ((TraceEventData_t*)xEventHandle)->size); - - for (i = 0; i < uiSize; i++) - { - TRC_EVENT_ADD_8(xEventHandle, ((uint8_t*)pvData)[i]); - } - - return TRC_SUCCESS; -} - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -traceResult xTraceEventGetSize(void *pvAddress, uint32_t* puiSize) -{ - /* This should never fail */ - TRC_ASSERT(pvAddress != 0); - - /* This should never fail */ - TRC_ASSERT(puiSize != 0); - - /* This should never fail */ - TRC_ASSERT((sizeof(TraceBaseEvent_t) + (TRC_EVENT_GET_PARAM_COUNT(((TraceBaseEvent_t*)pvAddress)->EventID)) * sizeof(uint32_t)) <= TRC_MAX_BLOB_SIZE); - - return TRC_EVENT_GET_SIZE(pvAddress, puiSize); -} - -traceResult xTraceEventGetRawData(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(ppvData != 0); - - /* This should never fail */ - TRC_ASSERT(uiOffset + uiSize <= ((TraceEventData_t*)xEventHandle)->size); - - return TRC_EVENT_GET_RAW_DATA(xEventHandle, uiOffset, uiSize, ppvData); -} - -traceResult xTraceEventGetPayload(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(ppvData != 0); - - /* This should never fail */ - TRC_ASSERT(uiOffset + uiSize <= ((TraceEventData_t*)xEventHandle)->size); - - return TRC_EVENT_GET_PAYLOAD(xEventHandle, uiOffset, uiSize, ppvData); -} - -traceResult xTraceEventPayloadRemaining(TraceEventHandle_t xEventHandle, uint32_t* puiValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(puiValue != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0); - - return TRC_EVENT_PAYLOAD_REMAINING(xEventHandle, puiValue); -} - -traceResult xTraceEventPayloadUsed(TraceEventHandle_t xEventHandle, uint32_t* puiValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(puiValue != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0); - - return TRC_EVENT_PAYLOAD_USED(xEventHandle, puiValue); -} - -traceResult xTraceEventPayloadSize(TraceEventHandle_t xEventHandle, uint32_t* puiValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(puiValue != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0); - - return TRC_EVENT_PAYLOAD_SIZE(xEventHandle, puiValue); -} - -traceResult xTraceEventAddPointer(TraceEventHandle_t xEventHandle, void* pvAddress) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(void*) <= ((TraceEventData_t*)xEventHandle)->size); - - /* Make sure we are writing at void* aligned offset */ - /* This should never fail */ - TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(void*) - 1)) == 0); - - return TRC_EVENT_ADD_POINTER(xEventHandle, pvAddress); -} - -traceResult xTraceEventAddUnsignedBaseType(TraceEventHandle_t xEventHandle, TraceUnsignedBaseType_t uxValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(TraceUnsignedBaseType_t) <= ((TraceEventData_t*)xEventHandle)->size); - - /* Make sure we are writing at TraceUnsignedBaseType_t aligned offset */ - /* This should never fail */ - TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(TraceUnsignedBaseType_t) - 1)) == 0); - - return TRC_EVENT_ADD_UNSIGNED_BASE_TYPE(xEventHandle, uxValue); -} - -traceResult xTraceEventAdd32(TraceEventHandle_t xEventHandle, uint32_t value) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint32_t) <= ((TraceEventData_t*)xEventHandle)->size); - - /* Make sure we are writing at 32-bit aligned offset */ - /* This should never fail */ - TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 3) == 0); - - return TRC_EVENT_ADD_32(xEventHandle, value); -} - -traceResult xTraceEventAdd16(TraceEventHandle_t xEventHandle, uint16_t value) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint16_t) <= ((TraceEventData_t*)xEventHandle)->size); - - /* Make sure we are writing at 16-bit aligned offset */ - /* This should never fail */ - TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 1) == 0); - - return TRC_EVENT_ADD_16(xEventHandle, value); -} - -traceResult xTraceEventAdd8(TraceEventHandle_t xEventHandle, uint8_t value) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); - - /* This should never fail */ - TRC_ASSERT(xEventHandle != 0); - - /* This should never fail */ - TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint8_t) <= ((TraceEventData_t*)xEventHandle)->size); - - return TRC_EVENT_ADD_8(xEventHandle, value); -} - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for events. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #define VERIFY_EVENT_SIZE( i ) \ + if( ( i ) > ( TRC_MAX_BLOB_SIZE ) ) \ + { \ + xTraceDiagnosticsSetIfHigher( TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED, ( TraceUnsignedBaseType_t ) ( ( i ) - ( TRC_MAX_BLOB_SIZE ) ) ); \ + ( i ) = TRC_MAX_BLOB_SIZE; \ + } + + TraceEventDataTable_t * pxTraceEventDataTable; + + int32_t DUMMY_iTraceBytesCommitted; + + TRACE_ALLOC_CRITICAL_SECTION(); + + traceResult xTraceEventInitialize( TraceEventDataBuffer_t * pxBuffer ) + { + TraceCoreEventData_t * pxCoreEventData; + uint32_t i, j; + + TRC_ASSERT_EQUAL_SIZE( TraceEventDataBuffer_t, TraceEventDataTable_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + pxTraceEventDataTable = ( TraceEventDataTable_t * ) pxBuffer; + + for( i = 0; i < TRC_CFG_CORE_COUNT; i++ ) + { + pxCoreEventData = &pxTraceEventDataTable->coreEventData[ i ]; + + pxCoreEventData->eventCounter = 0; + + for( j = 0; j < ( TRC_CFG_MAX_ISR_NESTING ) +1; j++ ) + { + RESET_EVENT_DATA( &pxCoreEventData->eventData[ j ] ); + } + } + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ); + + return TRC_SUCCESS; + } + + traceResult xTraceEventBeginRawOffline( uint32_t uiSize, + TraceEventHandle_t * pxEventHandle ) + { + TraceEventData_t * pxEventData; + int32_t ISR_nesting; + + /* We need to check this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT( pxEventHandle != 0 ); + + TRACE_ENTER_CRITICAL_SECTION(); + + xTraceISRGetCurrentNesting( &ISR_nesting ); + + /* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */ + pxEventData = &pxTraceEventDataTable->coreEventData[ TRC_CFG_GET_CURRENT_CORE() ].eventData[ ISR_nesting + 1 ]; + + /* This should never fail */ + TRC_ASSERT_CUSTOM_ON_FAIL( pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); + return TRC_FAIL; + + ); + + VERIFY_EVENT_SIZE( uiSize ); + + pxEventData->size = ( ( uiSize + ( sizeof( uint32_t ) - 1 ) ) / sizeof( uint32_t ) ) * sizeof( uint32_t ); /* 4-byte align */ + + pxEventData->offset = 0; + + /* This can fail and we should handle it */ + if( xTraceStreamPortAllocate( pxEventData->size, &pxEventData->pvBlob ) == TRC_FAIL ) + { + TRACE_EXIT_CRITICAL_SECTION(); + return TRC_FAIL; + } + + *pxEventHandle = ( TraceEventHandle_t ) pxEventData; + + return TRC_SUCCESS; + } + + traceResult xTraceEventBeginRawOfflineBlocking( uint32_t uiSize, + TraceEventHandle_t * pxEventHandle ) + { + TraceEventData_t * pxEventData; + int32_t ISR_nesting; + uint32_t uiAttempts = 0; + + /* We need to check this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT( pxEventHandle != 0 ); + + TRACE_ENTER_CRITICAL_SECTION(); + + xTraceGetCurrentISRNesting( &ISR_nesting ); + + /* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */ + pxEventData = &pxTraceEventDataTable->coreEventData[ TRC_CFG_GET_CURRENT_CORE() ].eventData[ ISR_nesting + 1 ]; + + /* This should never fail */ + TRC_ASSERT_CUSTOM_ON_FAIL( pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); + return TRC_FAIL; + + ); + + VERIFY_EVENT_SIZE( uiSize ); + + pxEventData->size = ( ( uiSize + ( sizeof( uint32_t ) - 1 ) ) / sizeof( uint32_t ) ) * sizeof( uint32_t ); /* 4-byte align */ + + pxEventData->offset = 0; + + /* This can fail and we should handle it */ + while( xTraceStreamPortAllocate( pxEventData->size, &pxEventData->pvBlob ) != TRC_SUCCESS ) + { + uiAttempts++; + } + + *pxEventHandle = ( TraceEventHandle_t ) pxEventData; + + return TRC_SUCCESS; + } + + traceResult xTraceEventEndOffline( TraceEventHandle_t xEventHandle ) + { + int32_t iBytesCommitted; + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->pvBlob != 0 ); + + xTraceStreamPortCommit( ( ( TraceEventData_t * ) xEventHandle )->pvBlob, ( ( TraceEventData_t * ) xEventHandle )->size, &iBytesCommitted ); + + RESET_EVENT_DATA( ( TraceEventData_t * ) xEventHandle ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_SUCCESS; + } + + traceResult xTraceEventEndOfflineBlocking( TraceEventHandle_t xEventHandle ) + { + TraceEventData_t * pxEventData = ( TraceEventData_t * ) xEventHandle; + int32_t iBytesCommitted; + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( pxEventData != 0 ); + + while( pxEventData->size > 0 ) + { + iBytesCommitted = 0; + xTraceStreamPortCommit( pxEventData->pvBlob, pxEventData->size, &iBytesCommitted ); + + pxEventData->size -= iBytesCommitted; + pxEventData->pvBlob = ( ( uint8_t * ) pxEventData->pvBlob ) + iBytesCommitted; + } + + RESET_EVENT_DATA( pxEventData ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_SUCCESS; + } + + traceResult xTraceEventAddData( TraceEventHandle_t xEventHandle, + void * pvData, + uint32_t uiSize ) + { + uint32_t i; + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( pvData != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->offset + uiSize <= ( ( TraceEventData_t * ) xEventHandle )->size ); + + for( i = 0; i < uiSize; i++ ) + { + TRC_EVENT_ADD_8( xEventHandle, ( ( uint8_t * ) pvData )[ i ] ); + } + + return TRC_SUCCESS; + } + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + + traceResult xTraceEventGetSize( void * pvAddress, + uint32_t * puiSize ) + { + /* This should never fail */ + TRC_ASSERT( pvAddress != 0 ); + + /* This should never fail */ + TRC_ASSERT( puiSize != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( sizeof( TraceBaseEvent_t ) + ( TRC_EVENT_GET_PARAM_COUNT( ( ( TraceBaseEvent_t * ) pvAddress )->EventID ) ) * sizeof( uint32_t ) ) <= TRC_MAX_BLOB_SIZE ); + + return TRC_EVENT_GET_SIZE( pvAddress, puiSize ); + } + + traceResult xTraceEventGetRawData( TraceEventHandle_t xEventHandle, + uint32_t uiOffset, + uint32_t uiSize, + void ** ppvData ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( ppvData != 0 ); + + /* This should never fail */ + TRC_ASSERT( uiOffset + uiSize <= ( ( TraceEventData_t * ) xEventHandle )->size ); + + return TRC_EVENT_GET_RAW_DATA( xEventHandle, uiOffset, uiSize, ppvData ); + } + + traceResult xTraceEventGetPayload( TraceEventHandle_t xEventHandle, + uint32_t uiOffset, + uint32_t uiSize, + void ** ppvData ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( ppvData != 0 ); + + /* This should never fail */ + TRC_ASSERT( uiOffset + uiSize <= ( ( TraceEventData_t * ) xEventHandle )->size ); + + return TRC_EVENT_GET_PAYLOAD( xEventHandle, uiOffset, uiSize, ppvData ); + } + + traceResult xTraceEventPayloadRemaining( TraceEventHandle_t xEventHandle, + uint32_t * puiValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( puiValue != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->pvBlob != 0 ); + + return TRC_EVENT_PAYLOAD_REMAINING( xEventHandle, puiValue ); + } + + traceResult xTraceEventPayloadUsed( TraceEventHandle_t xEventHandle, + uint32_t * puiValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( puiValue != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->pvBlob != 0 ); + + return TRC_EVENT_PAYLOAD_USED( xEventHandle, puiValue ); + } + + traceResult xTraceEventPayloadSize( TraceEventHandle_t xEventHandle, + uint32_t * puiValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( puiValue != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->pvBlob != 0 ); + + return TRC_EVENT_PAYLOAD_SIZE( xEventHandle, puiValue ); + } + + traceResult xTraceEventAddPointer( TraceEventHandle_t xEventHandle, + void * pvAddress ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->offset + sizeof( void * ) <= ( ( TraceEventData_t * ) xEventHandle )->size ); + + /* Make sure we are writing at void* aligned offset */ + /* This should never fail */ + TRC_ASSERT( ( ( ( TraceEventData_t * ) xEventHandle )->offset & ( sizeof( void * ) - 1 ) ) == 0 ); + + return TRC_EVENT_ADD_POINTER( xEventHandle, pvAddress ); + } + + traceResult xTraceEventAddUnsignedBaseType( TraceEventHandle_t xEventHandle, + TraceUnsignedBaseType_t uxValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->offset + sizeof( TraceUnsignedBaseType_t ) <= ( ( TraceEventData_t * ) xEventHandle )->size ); + + /* Make sure we are writing at TraceUnsignedBaseType_t aligned offset */ + /* This should never fail */ + TRC_ASSERT( ( ( ( TraceEventData_t * ) xEventHandle )->offset & ( sizeof( TraceUnsignedBaseType_t ) - 1 ) ) == 0 ); + + return TRC_EVENT_ADD_UNSIGNED_BASE_TYPE( xEventHandle, uxValue ); + } + + traceResult xTraceEventAdd32( TraceEventHandle_t xEventHandle, + uint32_t value ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->offset + sizeof( uint32_t ) <= ( ( TraceEventData_t * ) xEventHandle )->size ); + + /* Make sure we are writing at 32-bit aligned offset */ + /* This should never fail */ + TRC_ASSERT( ( ( ( TraceEventData_t * ) xEventHandle )->offset & 3 ) == 0 ); + + return TRC_EVENT_ADD_32( xEventHandle, value ); + } + + traceResult xTraceEventAdd16( TraceEventHandle_t xEventHandle, + uint16_t value ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->offset + sizeof( uint16_t ) <= ( ( TraceEventData_t * ) xEventHandle )->size ); + + /* Make sure we are writing at 16-bit aligned offset */ + /* This should never fail */ + TRC_ASSERT( ( ( ( TraceEventData_t * ) xEventHandle )->offset & 1 ) == 0 ); + + return TRC_EVENT_ADD_16( xEventHandle, value ); + } + + traceResult xTraceEventAdd8( TraceEventHandle_t xEventHandle, + uint8_t value ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) ); + + /* This should never fail */ + TRC_ASSERT( xEventHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( ( ( TraceEventData_t * ) xEventHandle )->offset + sizeof( uint8_t ) <= ( ( TraceEventData_t * ) xEventHandle )->size ); + + return TRC_EVENT_ADD_8( xEventHandle, value ); + } + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEventBuffer.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEventBuffer.c index d236b983a..52a58fdf8 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEventBuffer.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEventBuffer.c @@ -1,256 +1,260 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for the event buffer. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -traceResult xTraceEventBufferInitialize(TraceEventBuffer_t* pxTraceEventBuffer, uint32_t uiOptions, - uint8_t* puiBuffer, uint32_t uiSize) -{ - /* This should never fail */ - TRC_ASSERT(pxTraceEventBuffer != 0); - - /* This should never fail */ - TRC_ASSERT(puiBuffer != 0); - - pxTraceEventBuffer->uiOptions = uiOptions; - pxTraceEventBuffer->uiHead = 0; - pxTraceEventBuffer->uiTail = 0; - pxTraceEventBuffer->uiSize = uiSize; - pxTraceEventBuffer->uiFree = uiSize; - pxTraceEventBuffer->puiBuffer = puiBuffer; - pxTraceEventBuffer->uiTimerWraparounds = 0; - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT_BUFFER); - - return TRC_SUCCESS; -} - -/** - * @brief Pops the oldest event from the Event Buffer. - * - * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer. - * - * @retval TRC_FAIL Failure - * @retval TRC_SUCCESS Success - */ -static traceResult prvTraceEventBufferPop(TraceEventBuffer_t *pxTraceEventBuffer) -{ - uint32_t uiFreeSize = 0; - - /* Get size of event we are freeing */ - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventGetSize(((void*)&(pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiTail])), &uiFreeSize) == TRC_SUCCESS); - - pxTraceEventBuffer->uiFree += uiFreeSize; - - /* Update tail to point to the new last event */ - pxTraceEventBuffer->uiTail = (pxTraceEventBuffer->uiTail + uiFreeSize) % pxTraceEventBuffer->uiSize; - - return TRC_SUCCESS; -} - -traceResult xTraceEventBufferPush(TraceEventBuffer_t *pxTraceEventBuffer, void *pxData, uint32_t uiDataSize, int32_t *piBytesWritten) -{ - uint32_t uiBufferSize; - - /* This should never fail */ - TRC_ASSERT(pxTraceEventBuffer != 0); - - /* This should never fail */ - TRC_ASSERT(pxData != 0); - - uiBufferSize = pxTraceEventBuffer->uiSize; - - /* Check if the data size is larger than the buffer */ - /* This should never fail */ - TRC_ASSERT(uiDataSize <= uiBufferSize); - - /* Check byte alignment */ - /* This should never fail */ - TRC_ASSERT((uiDataSize % 4) == 0); - - /* Ensure bytes written start at 0 */ - /* This should never fail */ - TRC_ASSERT(piBytesWritten != 0); - - *piBytesWritten = 0; - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceTimestampGetWraparounds(&pxTraceEventBuffer->uiTimerWraparounds) == TRC_SUCCESS); - - /* In ring buffer mode we cannot provide lock free access since the producer modified - * the head and tail variables in the same call. This option is only safe when used - * with an internal buffer (streaming snapshot) which no consumer accesses. - */ - switch (pxTraceEventBuffer->uiOptions) - { - case TRC_EVENT_BUFFER_OPTION_OVERWRITE: - { - uint32_t uiHead = pxTraceEventBuffer->uiHead; - - /* If there isn't enough space in the buffer pop events until there is */ - while (pxTraceEventBuffer->uiFree < uiDataSize) - { - prvTraceEventBufferPop(pxTraceEventBuffer); - } - - /* Copy data */ - if ((uiBufferSize - uiHead) > uiDataSize) - { - TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pxData, uiDataSize); - } - else - { - TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pxData, uiBufferSize - uiHead); - TRC_MEMCPY(pxTraceEventBuffer->puiBuffer, - (void*)(&((uint8_t*)pxData)[(uiBufferSize - uiHead)]), - uiDataSize - (uiBufferSize - uiHead)); - } - - pxTraceEventBuffer->uiFree -= uiDataSize; - - pxTraceEventBuffer->uiHead = (uiHead + uiDataSize) % uiBufferSize; - - *piBytesWritten = uiDataSize; - - break; - } - - case TRC_EVENT_BUFFER_OPTION_SKIP: - { - /* Since a consumer could potentially update tail (free) during the procedure - * we have to save it here to avoid problems with the push algorithm. - */ - uint32_t uiHead = pxTraceEventBuffer->uiHead; - uint32_t uiTail = pxTraceEventBuffer->uiTail; - - if (uiHead >= uiTail) - { - uint32_t uiFreeSpace = (uiBufferSize - uiHead - sizeof(uint32_t)) + uiTail; - - if (uiFreeSpace < uiDataSize) - { - *piBytesWritten = 0; - - return TRC_SUCCESS; - } - - /* Copy data */ - if ((uiBufferSize - uiHead) > uiDataSize) - { - TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pxData, uiDataSize); - } - else - { - TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pxData, uiBufferSize - uiHead); - TRC_MEMCPY(pxTraceEventBuffer->puiBuffer, - (void*)(&((uint8_t*)pxData)[(uiBufferSize - uiHead)]), - uiDataSize - (uiBufferSize - uiHead)); - } - - pxTraceEventBuffer->uiHead = (uiHead + uiDataSize) % uiBufferSize; - } - else - { - uint32_t uiFreeSpace = uiTail - uiHead - sizeof(uint32_t); - - if (uiFreeSpace < uiDataSize) - { - *piBytesWritten = 0; - - return TRC_SUCCESS; - } - - /* Copy data */ - TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pxData, uiDataSize); - - pxTraceEventBuffer->uiHead = (uiHead + uiDataSize); - } - - *piBytesWritten = uiDataSize; - - break; - } - - default: - { - return TRC_FAIL; - } - } - - return TRC_SUCCESS; -} - -traceResult xTraceEventBufferTransfer(TraceEventBuffer_t* pxTraceEventBuffer, int32_t* piBytesWritten) -{ - int32_t iBytesWritten = 0; - int32_t iSumBytesWritten = 0; - uint32_t uiHead; - uint32_t uiTail; - - /* This should never fail */ - TRC_ASSERT(pxTraceEventBuffer != 0); - - /* This should never fail */ - TRC_ASSERT(piBytesWritten != 0); - - uiHead = pxTraceEventBuffer->uiHead; - uiTail = pxTraceEventBuffer->uiTail; - - /* Check if core event buffer is empty */ - if (uiHead == uiTail) - { - return TRC_SUCCESS; - } - - /* Check if we can do a direct write or if we have to handle wrapping */ - if (uiHead > uiTail) - { - xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (uiHead - uiTail), &iBytesWritten); - - pxTraceEventBuffer->uiTail = uiHead; - } - else - { - xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (pxTraceEventBuffer->uiSize - uiTail), &iBytesWritten); - - iSumBytesWritten += iBytesWritten; - - xTraceStreamPortWriteData(pxTraceEventBuffer->puiBuffer, uiHead, &iBytesWritten); - - pxTraceEventBuffer->uiTail = uiHead; - } - - iSumBytesWritten += iBytesWritten; - - *piBytesWritten = iSumBytesWritten; - - return TRC_SUCCESS; -} - -traceResult xTraceEventBufferClear(TraceEventBuffer_t* pxTraceEventBuffer) -{ - /* This should never fail */ - TRC_ASSERT(pxTraceEventBuffer != 0); - - pxTraceEventBuffer->uiHead = 0; - pxTraceEventBuffer->uiTail = 0; - pxTraceEventBuffer->uiFree = pxTraceEventBuffer->uiSize; - - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for the event buffer. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + traceResult xTraceEventBufferInitialize( TraceEventBuffer_t * pxTraceEventBuffer, + uint32_t uiOptions, + uint8_t * puiBuffer, + uint32_t uiSize ) + { + /* This should never fail */ + TRC_ASSERT( pxTraceEventBuffer != 0 ); + + /* This should never fail */ + TRC_ASSERT( puiBuffer != 0 ); + + pxTraceEventBuffer->uiOptions = uiOptions; + pxTraceEventBuffer->uiHead = 0; + pxTraceEventBuffer->uiTail = 0; + pxTraceEventBuffer->uiSize = uiSize; + pxTraceEventBuffer->uiFree = uiSize; + pxTraceEventBuffer->puiBuffer = puiBuffer; + pxTraceEventBuffer->uiTimerWraparounds = 0; + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_EVENT_BUFFER ); + + return TRC_SUCCESS; + } + +/** + * @brief Pops the oldest event from the Event Buffer. + * + * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer. + * + * @retval TRC_FAIL Failure + * @retval TRC_SUCCESS Success + */ + static traceResult prvTraceEventBufferPop( TraceEventBuffer_t * pxTraceEventBuffer ) + { + uint32_t uiFreeSize = 0; + + /* Get size of event we are freeing */ + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEventGetSize( ( ( void * ) &( pxTraceEventBuffer->puiBuffer[ pxTraceEventBuffer->uiTail ] ) ), &uiFreeSize ) == TRC_SUCCESS ); + + pxTraceEventBuffer->uiFree += uiFreeSize; + + /* Update tail to point to the new last event */ + pxTraceEventBuffer->uiTail = ( pxTraceEventBuffer->uiTail + uiFreeSize ) % pxTraceEventBuffer->uiSize; + + return TRC_SUCCESS; + } + + traceResult xTraceEventBufferPush( TraceEventBuffer_t * pxTraceEventBuffer, + void * pxData, + uint32_t uiDataSize, + int32_t * piBytesWritten ) + { + uint32_t uiBufferSize; + + /* This should never fail */ + TRC_ASSERT( pxTraceEventBuffer != 0 ); + + /* This should never fail */ + TRC_ASSERT( pxData != 0 ); + + uiBufferSize = pxTraceEventBuffer->uiSize; + + /* Check if the data size is larger than the buffer */ + /* This should never fail */ + TRC_ASSERT( uiDataSize <= uiBufferSize ); + + /* Check byte alignment */ + /* This should never fail */ + TRC_ASSERT( ( uiDataSize % 4 ) == 0 ); + + /* Ensure bytes written start at 0 */ + /* This should never fail */ + TRC_ASSERT( piBytesWritten != 0 ); + + *piBytesWritten = 0; + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceTimestampGetWraparounds( &pxTraceEventBuffer->uiTimerWraparounds ) == TRC_SUCCESS ); + + /* In ring buffer mode we cannot provide lock free access since the producer modified + * the head and tail variables in the same call. This option is only safe when used + * with an internal buffer (streaming snapshot) which no consumer accesses. + */ + switch( pxTraceEventBuffer->uiOptions ) + { + case TRC_EVENT_BUFFER_OPTION_OVERWRITE: + { + uint32_t uiHead = pxTraceEventBuffer->uiHead; + + /* If there isn't enough space in the buffer pop events until there is */ + while( pxTraceEventBuffer->uiFree < uiDataSize ) + { + prvTraceEventBufferPop( pxTraceEventBuffer ); + } + + /* Copy data */ + if( ( uiBufferSize - uiHead ) > uiDataSize ) + { + TRC_MEMCPY( &pxTraceEventBuffer->puiBuffer[ uiHead ], pxData, uiDataSize ); + } + else + { + TRC_MEMCPY( &pxTraceEventBuffer->puiBuffer[ uiHead ], pxData, uiBufferSize - uiHead ); + TRC_MEMCPY( pxTraceEventBuffer->puiBuffer, + ( void * ) ( &( ( uint8_t * ) pxData )[ ( uiBufferSize - uiHead ) ] ), + uiDataSize - ( uiBufferSize - uiHead ) ); + } + + pxTraceEventBuffer->uiFree -= uiDataSize; + + pxTraceEventBuffer->uiHead = ( uiHead + uiDataSize ) % uiBufferSize; + + *piBytesWritten = uiDataSize; + + break; + } + + case TRC_EVENT_BUFFER_OPTION_SKIP: + { + /* Since a consumer could potentially update tail (free) during the procedure + * we have to save it here to avoid problems with the push algorithm. + */ + uint32_t uiHead = pxTraceEventBuffer->uiHead; + uint32_t uiTail = pxTraceEventBuffer->uiTail; + + if( uiHead >= uiTail ) + { + uint32_t uiFreeSpace = ( uiBufferSize - uiHead - sizeof( uint32_t ) ) + uiTail; + + if( uiFreeSpace < uiDataSize ) + { + *piBytesWritten = 0; + + return TRC_SUCCESS; + } + + /* Copy data */ + if( ( uiBufferSize - uiHead ) > uiDataSize ) + { + TRC_MEMCPY( &pxTraceEventBuffer->puiBuffer[ pxTraceEventBuffer->uiHead ], pxData, uiDataSize ); + } + else + { + TRC_MEMCPY( &pxTraceEventBuffer->puiBuffer[ uiHead ], pxData, uiBufferSize - uiHead ); + TRC_MEMCPY( pxTraceEventBuffer->puiBuffer, + ( void * ) ( &( ( uint8_t * ) pxData )[ ( uiBufferSize - uiHead ) ] ), + uiDataSize - ( uiBufferSize - uiHead ) ); + } + + pxTraceEventBuffer->uiHead = ( uiHead + uiDataSize ) % uiBufferSize; + } + else + { + uint32_t uiFreeSpace = uiTail - uiHead - sizeof( uint32_t ); + + if( uiFreeSpace < uiDataSize ) + { + *piBytesWritten = 0; + + return TRC_SUCCESS; + } + + /* Copy data */ + TRC_MEMCPY( &pxTraceEventBuffer->puiBuffer[ pxTraceEventBuffer->uiHead ], pxData, uiDataSize ); + + pxTraceEventBuffer->uiHead = ( uiHead + uiDataSize ); + } + + *piBytesWritten = uiDataSize; + + break; + } + + default: + return TRC_FAIL; + } + + return TRC_SUCCESS; + } + + traceResult xTraceEventBufferTransfer( TraceEventBuffer_t * pxTraceEventBuffer, + int32_t * piBytesWritten ) + { + int32_t iBytesWritten = 0; + int32_t iSumBytesWritten = 0; + uint32_t uiHead; + uint32_t uiTail; + + /* This should never fail */ + TRC_ASSERT( pxTraceEventBuffer != 0 ); + + /* This should never fail */ + TRC_ASSERT( piBytesWritten != 0 ); + + uiHead = pxTraceEventBuffer->uiHead; + uiTail = pxTraceEventBuffer->uiTail; + + /* Check if core event buffer is empty */ + if( uiHead == uiTail ) + { + return TRC_SUCCESS; + } + + /* Check if we can do a direct write or if we have to handle wrapping */ + if( uiHead > uiTail ) + { + xTraceStreamPortWriteData( &pxTraceEventBuffer->puiBuffer[ uiTail ], ( uiHead - uiTail ), &iBytesWritten ); + + pxTraceEventBuffer->uiTail = uiHead; + } + else + { + xTraceStreamPortWriteData( &pxTraceEventBuffer->puiBuffer[ uiTail ], ( pxTraceEventBuffer->uiSize - uiTail ), &iBytesWritten ); + + iSumBytesWritten += iBytesWritten; + + xTraceStreamPortWriteData( pxTraceEventBuffer->puiBuffer, uiHead, &iBytesWritten ); + + pxTraceEventBuffer->uiTail = uiHead; + } + + iSumBytesWritten += iBytesWritten; + + *piBytesWritten = iSumBytesWritten; + + return TRC_SUCCESS; + } + + traceResult xTraceEventBufferClear( TraceEventBuffer_t * pxTraceEventBuffer ) + { + /* This should never fail */ + TRC_ASSERT( pxTraceEventBuffer != 0 ); + + pxTraceEventBuffer->uiHead = 0; + pxTraceEventBuffer->uiTail = 0; + pxTraceEventBuffer->uiFree = pxTraceEventBuffer->uiSize; + + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcExtension.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcExtension.c index 948082160..efb84022f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcExtension.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcExtension.c @@ -1,99 +1,108 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation of extensions. -*/ -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#define TRC_EXTENSION_BASE_EVENT_ID (TRC_EVENT_LAST_ID + 1) -uint32_t uiTraceNextFreeExtensionEventId = TRC_EXTENSION_BASE_EVENT_ID; - -#define TRC_EXTENSION_COMBINE_VERSION(_major, _minor, _patch) \ - ( \ - ((0x000000FF & (_major)) << 24) | \ - ((0x000000FF & (_minor)) << 16) | \ - ((0x0000FFFF & (_patch)) << 0) \ - ) - -#define TRC_EXTENSION_STATE_INDEX_VERSION 0 -#define TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID 1 -#define TRC_EXTENSION_STATE_INDEX_EVENT_COUNT 2 - -/* TODO: INITIALIZE */ - -traceResult xTraceExtensionCreate(const char* szName, uint8_t uiMajor, uint8_t uiMinor, uint16_t uiPatch, uint32_t uiEventCount, TraceExtensionHandle_t* pxExtensionHandle) -{ - TraceObjectHandle_t xObjectHandle; - TraceUnsignedBaseType_t uxStates[3]; - - /* This should never fail */ - TRC_ASSERT(uiEventCount != 0); - - /* This should never fail */ - TRC_ASSERT(pxExtensionHandle != 0); - - uxStates[TRC_EXTENSION_STATE_INDEX_VERSION] = TRC_EXTENSION_COMBINE_VERSION(uiMajor, uiMinor, uiPatch); - uxStates[TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID] = uiTraceNextFreeExtensionEventId; - uxStates[TRC_EXTENSION_STATE_INDEX_EVENT_COUNT] = uiEventCount; - - /* We need to check this */ - if (xTraceObjectRegisterInternal(PSF_EVENT_EXTENSION_CREATE, 0, szName, 3, uxStates, TRC_ENTRY_OPTION_EXTENSION, &xObjectHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - uiTraceNextFreeExtensionEventId += uiEventCount; - - *pxExtensionHandle = (TraceExtensionHandle_t)xObjectHandle; - - return TRC_SUCCESS; -} - -traceResult xTraceExtensionGetBaseEventId(TraceExtensionHandle_t xExtensionHandle, uint32_t *puiBaseEventId) -{ - TraceUnsignedBaseType_t uxBaseEventId; - - /* This should never fail */ - TRC_ASSERT(puiBaseEventId != 0); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState((TraceEntryHandle_t)xExtensionHandle, TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID, &uxBaseEventId) == TRC_SUCCESS); - - *puiBaseEventId = (uint32_t)uxBaseEventId; - - return TRC_SUCCESS; -} - -traceResult xTraceExtensionGetEventId(TraceExtensionHandle_t xExtensionHandle, uint32_t uiLocalEventId, uint32_t *puiGlobalEventId) -{ - TraceUnsignedBaseType_t uxBaseEventId; - - /* This should never fail */ - TRC_ASSERT(puiGlobalEventId != 0); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState((TraceEntryHandle_t)xExtensionHandle, TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID, &uxBaseEventId) == TRC_SUCCESS); - - *puiGlobalEventId = (uint32_t)uxBaseEventId + uiLocalEventId; - - return TRC_SUCCESS; -} - -traceResult xTraceExtensionGetConfigName(TraceExtensionHandle_t xExtensionHandle, const char **pszName) -{ - return xTraceEntryGetSymbol((TraceEntryHandle_t)xExtensionHandle, pszName); -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation of extensions. + */ +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #define TRC_EXTENSION_BASE_EVENT_ID ( TRC_EVENT_LAST_ID + 1 ) + uint32_t uiTraceNextFreeExtensionEventId = TRC_EXTENSION_BASE_EVENT_ID; + + #define TRC_EXTENSION_COMBINE_VERSION( _major, _minor, _patch ) \ + ( \ + ( ( 0x000000FF & ( _major ) ) << 24 ) | \ + ( ( 0x000000FF & ( _minor ) ) << 16 ) | \ + ( ( 0x0000FFFF & ( _patch ) ) << 0 ) \ + ) + + #define TRC_EXTENSION_STATE_INDEX_VERSION 0 + #define TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID 1 + #define TRC_EXTENSION_STATE_INDEX_EVENT_COUNT 2 + +/* TODO: INITIALIZE */ + + traceResult xTraceExtensionCreate( const char * szName, + uint8_t uiMajor, + uint8_t uiMinor, + uint16_t uiPatch, + uint32_t uiEventCount, + TraceExtensionHandle_t * pxExtensionHandle ) + { + TraceObjectHandle_t xObjectHandle; + TraceUnsignedBaseType_t uxStates[ 3 ]; + + /* This should never fail */ + TRC_ASSERT( uiEventCount != 0 ); + + /* This should never fail */ + TRC_ASSERT( pxExtensionHandle != 0 ); + + uxStates[ TRC_EXTENSION_STATE_INDEX_VERSION ] = TRC_EXTENSION_COMBINE_VERSION( uiMajor, uiMinor, uiPatch ); + uxStates[ TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID ] = uiTraceNextFreeExtensionEventId; + uxStates[ TRC_EXTENSION_STATE_INDEX_EVENT_COUNT ] = uiEventCount; + + /* We need to check this */ + if( xTraceObjectRegisterInternal( PSF_EVENT_EXTENSION_CREATE, 0, szName, 3, uxStates, TRC_ENTRY_OPTION_EXTENSION, &xObjectHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + uiTraceNextFreeExtensionEventId += uiEventCount; + + *pxExtensionHandle = ( TraceExtensionHandle_t ) xObjectHandle; + + return TRC_SUCCESS; + } + + traceResult xTraceExtensionGetBaseEventId( TraceExtensionHandle_t xExtensionHandle, + uint32_t * puiBaseEventId ) + { + TraceUnsignedBaseType_t uxBaseEventId; + + /* This should never fail */ + TRC_ASSERT( puiBaseEventId != 0 ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetState( ( TraceEntryHandle_t ) xExtensionHandle, TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID, &uxBaseEventId ) == TRC_SUCCESS ); + + *puiBaseEventId = ( uint32_t ) uxBaseEventId; + + return TRC_SUCCESS; + } + + traceResult xTraceExtensionGetEventId( TraceExtensionHandle_t xExtensionHandle, + uint32_t uiLocalEventId, + uint32_t * puiGlobalEventId ) + { + TraceUnsignedBaseType_t uxBaseEventId; + + /* This should never fail */ + TRC_ASSERT( puiGlobalEventId != 0 ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetState( ( TraceEntryHandle_t ) xExtensionHandle, TRC_EXTENSION_STATE_INDEX_BASE_EVENT_ID, &uxBaseEventId ) == TRC_SUCCESS ); + + *puiGlobalEventId = ( uint32_t ) uxBaseEventId + uiLocalEventId; + + return TRC_SUCCESS; + } + + traceResult xTraceExtensionGetConfigName( TraceExtensionHandle_t xExtensionHandle, + const char ** pszName ) + { + return xTraceEntryGetSymbol( ( TraceEntryHandle_t ) xExtensionHandle, pszName ); + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHardwarePort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHardwarePort.c index bfed5f092..9d6d6c802 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHardwarePort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHardwarePort.c @@ -1,141 +1,143 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The hardware abstraction layer for the trace recorder. - */ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */ -#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03))) -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) -#ifndef TRC_CFG_ARM_CM_USE_SYSTICK - -void xTraceHardwarePortInitCortexM() -{ - /* Make sure the DWT registers are unlocked, in case the debugger doesn't do this. */ - TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK; - - /* Make sure DWT is enabled is enabled, if supported */ - TRC_REG_DEMCR |= TRC_DEMCR_TRCENA; - - do - { - /* Verify that DWT is supported */ - if (TRC_REG_DEMCR == 0) - { - /* This function is called on Cortex-M3, M4 and M7 devices to initialize - the DWT unit, assumed present. The DWT cycle counter is used for timestamping. - - If the below error is produced, the DWT unit does not seem to be available. - - In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build - to use SysTick timestamping instead, or define your own timestamping by - setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED - and make the necessary definitions, as explained in trcHardwarePort.h.*/ - - xTraceError(TRC_ERROR_DWT_NOT_SUPPORTED); - break; - } - - /* Verify that DWT_CYCCNT is supported */ - if (TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT) - { - /* This function is called on Cortex-M3, M4 and M7 devices to initialize - the DWT unit, assumed present. The DWT cycle counter is used for timestamping. - - If the below error is produced, the cycle counter does not seem to be available. - - In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build - to use SysTick timestamping instead, or define your own timestamping by - setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED - and make the necessary definitions, as explained in trcHardwarePort.h.*/ - - xTraceError(TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED); - break; - } - - /* Reset the cycle counter */ - TRC_REG_DWT_CYCCNT = 0; - - /* Enable the cycle counter */ - TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA; - - } while (0); /* breaks above jump here */ -} -#endif /* TRC_CFG_ARM_CM_USE_SYSTICK */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ -#endif /* ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03))) */ - -#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_CYCLONE_V_HPS)) - -#define CS_TYPE_NONE 0 -#define CS_TYPE_TASK 1 -#define CS_TYPE_ISR_MASK_CHANGED 2 -#define CS_TYPE_ISR_MASK_NOT_CHANGED 3 - -#define CS_TYPE_INVALID 0xFFFFFFFF - -int cortex_a9_r5_enter_critical(void) -{ - uint32_t cs_type = CS_TYPE_INVALID; - - if ((prvGetCPSR() & 0x001F) == 0x13) // CSPR (ASPR) mode = SVC - { - /* Executing in an ISR other than the context-switch (where interrupts might have been enabled, motivating a critical section). */ - if (ulPortSetInterruptMask() == pdTRUE) - { - cs_type = CS_TYPE_ISR_MASK_NOT_CHANGED; - } - else - { - cs_type = CS_TYPE_ISR_MASK_CHANGED; - } - } - else if (pxTraceRecorderData->uiTraceSystemState == TRC_STATE_IN_TASKSWITCH) - { - // In the context-switch code. All interrupts are already masked here, so don't modify the mask. - cs_type = CS_TYPE_NONE; - } - else if (pxTraceRecorderData->uiTraceSystemState != TRC_STATE_IN_TASKSWITCH) - { - // Not within ISR or task-switch context, use a regular critical section. - vPortEnterCritical(); - cs_type = CS_TYPE_TASK; - } - - return cs_type; -} - -void cortex_a9_r5_exit_critical(int cs_type) -{ - switch (cs_type) - { - case CS_TYPE_TASK: - vPortExitCritical(); - break; - - case CS_TYPE_ISR_MASK_CHANGED: - vPortClearInterruptMask(pdFALSE); // pdFALSE means it will reset the IRQ mask. - break; - - case CS_TYPE_ISR_MASK_NOT_CHANGED: - case CS_TYPE_NONE: - // No action in these two cases. - break; - - default: - // Error, should not be possible; - for (;;); - } -} -#endif /* ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5)) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The hardware abstraction layer for the trace recorder. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + +/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */ + #if ( ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M ) && ( defined( __CORTEX_M ) && ( __CORTEX_M >= 0x03 ) ) ) + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + #ifndef TRC_CFG_ARM_CM_USE_SYSTICK + + void xTraceHardwarePortInitCortexM() + { + /* Make sure the DWT registers are unlocked, in case the debugger doesn't do this. */ + TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK; + + /* Make sure DWT is enabled is enabled, if supported */ + TRC_REG_DEMCR |= TRC_DEMCR_TRCENA; + + do + { + /* Verify that DWT is supported */ + if( TRC_REG_DEMCR == 0 ) + { + /* This function is called on Cortex-M3, M4 and M7 devices to initialize + * the DWT unit, assumed present. The DWT cycle counter is used for timestamping. + * + * If the below error is produced, the DWT unit does not seem to be available. + * + * In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build + * to use SysTick timestamping instead, or define your own timestamping by + * setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED + * and make the necessary definitions, as explained in trcHardwarePort.h.*/ + + xTraceError( TRC_ERROR_DWT_NOT_SUPPORTED ); + break; + } + + /* Verify that DWT_CYCCNT is supported */ + if( TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT ) + { + /* This function is called on Cortex-M3, M4 and M7 devices to initialize + * the DWT unit, assumed present. The DWT cycle counter is used for timestamping. + * + * If the below error is produced, the cycle counter does not seem to be available. + * + * In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build + * to use SysTick timestamping instead, or define your own timestamping by + * setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED + * and make the necessary definitions, as explained in trcHardwarePort.h.*/ + + xTraceError( TRC_ERROR_DWT_CYCCNT_NOT_SUPPORTED ); + break; + } + + /* Reset the cycle counter */ + TRC_REG_DWT_CYCCNT = 0; + + /* Enable the cycle counter */ + TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA; + } while( 0 ); /* breaks above jump here */ + } + #endif /* TRC_CFG_ARM_CM_USE_SYSTICK */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + #endif /* ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03))) */ + + #if ( ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9 ) || ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5 ) || ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_CYCLONE_V_HPS ) ) + + #define CS_TYPE_NONE 0 + #define CS_TYPE_TASK 1 + #define CS_TYPE_ISR_MASK_CHANGED 2 + #define CS_TYPE_ISR_MASK_NOT_CHANGED 3 + + #define CS_TYPE_INVALID 0xFFFFFFFF + + int cortex_a9_r5_enter_critical( void ) + { + uint32_t cs_type = CS_TYPE_INVALID; + + if( ( prvGetCPSR() & 0x001F ) == 0x13 ) /* CSPR (ASPR) mode = SVC */ + { + /* Executing in an ISR other than the context-switch (where interrupts might have been enabled, motivating a critical section). */ + if( ulPortSetInterruptMask() == pdTRUE ) + { + cs_type = CS_TYPE_ISR_MASK_NOT_CHANGED; + } + else + { + cs_type = CS_TYPE_ISR_MASK_CHANGED; + } + } + else if( pxTraceRecorderData->uiTraceSystemState == TRC_STATE_IN_TASKSWITCH ) + { + /* In the context-switch code. All interrupts are already masked here, so don't modify the mask. */ + cs_type = CS_TYPE_NONE; + } + else if( pxTraceRecorderData->uiTraceSystemState != TRC_STATE_IN_TASKSWITCH ) + { + /* Not within ISR or task-switch context, use a regular critical section. */ + vPortEnterCritical(); + cs_type = CS_TYPE_TASK; + } + + return cs_type; + } + + void cortex_a9_r5_exit_critical( int cs_type ) + { + switch( cs_type ) + { + case CS_TYPE_TASK: + vPortExitCritical(); + break; + + case CS_TYPE_ISR_MASK_CHANGED: + vPortClearInterruptMask( pdFALSE ); /* pdFALSE means it will reset the IRQ mask. */ + break; + + case CS_TYPE_ISR_MASK_NOT_CHANGED: + case CS_TYPE_NONE: + /* No action in these two cases. */ + break; + + default: + + /* Error, should not be possible; */ + for( ; ; ) + { + } + } + } + #endif /* ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_ZyncUltraScaleR5)) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHeap.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHeap.c index 6ec948004..c5187f019 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHeap.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcHeap.c @@ -1,161 +1,172 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for heaps. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#if (TRC_USE_HEAPS == 1) - -#define TRC_HEAP_STATE_INDEX_CURRENT 0 -#define TRC_HEAP_STATE_INDEX_HIGHWATERMARK 1 -#define TRC_HEAP_STATE_INDEX_MAX 2 - -traceResult xTraceHeapCreate(const char *szName, TraceUnsignedBaseType_t uxCurrent, TraceUnsignedBaseType_t uxHighWaterMark, TraceUnsignedBaseType_t uxMax, TraceHeapHandle_t *pxHeapHandle) -{ - TraceObjectHandle_t xObjectHandle; - TraceUnsignedBaseType_t uxStates[3]; - - /* This should never fail */ - TRC_ASSERT(pxHeapHandle != 0); - - uxStates[TRC_HEAP_STATE_INDEX_CURRENT] = uxCurrent; - uxStates[TRC_HEAP_STATE_INDEX_HIGHWATERMARK] = uxHighWaterMark; - uxStates[TRC_HEAP_STATE_INDEX_MAX] = uxMax; - - /* We need to check this */ - if (xTraceObjectRegisterInternal(PSF_EVENT_HEAP_CREATE, 0, szName, 3, uxStates, TRC_ENTRY_OPTION_HEAP, &xObjectHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - *pxHeapHandle = (TraceHeapHandle_t)xObjectHandle; - - return TRC_SUCCESS; -} - -traceResult xTraceHeapAlloc(TraceHeapHandle_t xHeapHandle, void *pvAddress, TraceUnsignedBaseType_t uxSize) -{ - TraceUnsignedBaseType_t uxCurrent, uxHighWaterMark; - TraceEventHandle_t xEventHandle = 0; - - if (xHeapHandle == 0) - { - /* This can happen */ - return TRC_FAIL; - } - - /* If the address is null we assume this was a failed alloc attempt */ - if (pvAddress != 0) - { - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, &uxCurrent) == TRC_SUCCESS); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, &uxHighWaterMark) == TRC_SUCCESS); - - uxCurrent += uxSize; - - if (uxCurrent > uxHighWaterMark) - { - uxHighWaterMark = uxCurrent; - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, uxHighWaterMark) == TRC_SUCCESS); - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, uxCurrent) == TRC_SUCCESS); - } - - /* We need to check this */ - if (xTraceEventBegin(pvAddress != 0 ? PSF_EVENT_MALLOC : PSF_EVENT_MALLOC_FAILED, sizeof(void*) + sizeof(TraceUnsignedBaseType_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pvAddress); - xTraceEventAddUnsignedBaseType(xEventHandle, uxSize); - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -traceResult xTraceHeapFree(TraceHeapHandle_t xHeapHandle, void *pvAddress, TraceUnsignedBaseType_t uxSize) -{ - TraceUnsignedBaseType_t uxCurrent; - TraceEventHandle_t xEventHandle = 0; - - if (xHeapHandle == 0) - { - /* This can happen */ - return TRC_FAIL; - } - - /* If the address is null we assume this was a failed alloc attempt */ - if (pvAddress != 0) - { - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, &uxCurrent) == TRC_SUCCESS); - - uxCurrent -= uxSize; - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, uxCurrent) == TRC_SUCCESS); - } - - /* We need to check this */ - if (xTraceEventBegin(pvAddress != 0 ? PSF_EVENT_FREE : PSF_EVENT_FREE_FAILED, sizeof(void*) + sizeof(TraceUnsignedBaseType_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pvAddress); - xTraceEventAddUnsignedBaseType(xEventHandle, uxSize); - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -traceResult xTraceHeapGetCurrent(TraceHeapHandle_t xHeapHandle, TraceUnsignedBaseType_t *puxCurrent) -{ - /* This should never fail */ - TRC_ASSERT(xHeapHandle != 0); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, puxCurrent) == TRC_SUCCESS); - - return TRC_SUCCESS; -} - -traceResult xTraceHeapGetHighWaterMark(TraceHeapHandle_t xHeapHandle, TraceUnsignedBaseType_t *puxHighWaterMark) -{ - /* This should never fail */ - TRC_ASSERT(xHeapHandle != 0); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, puxHighWaterMark) == TRC_SUCCESS); - - return TRC_SUCCESS; -} - -traceResult xTraceHeapGetMax(TraceHeapHandle_t xHeapHandle, TraceUnsignedBaseType_t *puxMax) -{ - /* This should never fail */ - TRC_ASSERT(xHeapHandle != 0); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_MAX, puxMax) == TRC_SUCCESS); - - return TRC_SUCCESS; -} - -#endif /* (TRC_USE_HEAPS == 1) */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for heaps. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #if ( TRC_USE_HEAPS == 1 ) + + #define TRC_HEAP_STATE_INDEX_CURRENT 0 + #define TRC_HEAP_STATE_INDEX_HIGHWATERMARK 1 + #define TRC_HEAP_STATE_INDEX_MAX 2 + + traceResult xTraceHeapCreate( const char * szName, + TraceUnsignedBaseType_t uxCurrent, + TraceUnsignedBaseType_t uxHighWaterMark, + TraceUnsignedBaseType_t uxMax, + TraceHeapHandle_t * pxHeapHandle ) + { + TraceObjectHandle_t xObjectHandle; + TraceUnsignedBaseType_t uxStates[ 3 ]; + + /* This should never fail */ + TRC_ASSERT( pxHeapHandle != 0 ); + + uxStates[ TRC_HEAP_STATE_INDEX_CURRENT ] = uxCurrent; + uxStates[ TRC_HEAP_STATE_INDEX_HIGHWATERMARK ] = uxHighWaterMark; + uxStates[ TRC_HEAP_STATE_INDEX_MAX ] = uxMax; + + /* We need to check this */ + if( xTraceObjectRegisterInternal( PSF_EVENT_HEAP_CREATE, 0, szName, 3, uxStates, TRC_ENTRY_OPTION_HEAP, &xObjectHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + *pxHeapHandle = ( TraceHeapHandle_t ) xObjectHandle; + + return TRC_SUCCESS; + } + + traceResult xTraceHeapAlloc( TraceHeapHandle_t xHeapHandle, + void * pvAddress, + TraceUnsignedBaseType_t uxSize ) + { + TraceUnsignedBaseType_t uxCurrent, uxHighWaterMark; + TraceEventHandle_t xEventHandle = 0; + + if( xHeapHandle == 0 ) + { + /* This can happen */ + return TRC_FAIL; + } + + /* If the address is null we assume this was a failed alloc attempt */ + if( pvAddress != 0 ) + { + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetState( xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, &uxCurrent ) == TRC_SUCCESS ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetState( xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, &uxHighWaterMark ) == TRC_SUCCESS ); + + uxCurrent += uxSize; + + if( uxCurrent > uxHighWaterMark ) + { + uxHighWaterMark = uxCurrent; + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, uxHighWaterMark ) == TRC_SUCCESS ); + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, uxCurrent ) == TRC_SUCCESS ); + } + + /* We need to check this */ + if( xTraceEventBegin( ( pvAddress != 0 ) ? PSF_EVENT_MALLOC : PSF_EVENT_MALLOC_FAILED, sizeof( void * ) + sizeof( TraceUnsignedBaseType_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pvAddress ); + xTraceEventAddUnsignedBaseType( xEventHandle, uxSize ); + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + traceResult xTraceHeapFree( TraceHeapHandle_t xHeapHandle, + void * pvAddress, + TraceUnsignedBaseType_t uxSize ) + { + TraceUnsignedBaseType_t uxCurrent; + TraceEventHandle_t xEventHandle = 0; + + if( xHeapHandle == 0 ) + { + /* This can happen */ + return TRC_FAIL; + } + + /* If the address is null we assume this was a failed alloc attempt */ + if( pvAddress != 0 ) + { + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetState( xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, &uxCurrent ) == TRC_SUCCESS ); + + uxCurrent -= uxSize; + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, uxCurrent ) == TRC_SUCCESS ); + } + + /* We need to check this */ + if( xTraceEventBegin( ( pvAddress != 0 ) ? PSF_EVENT_FREE : PSF_EVENT_FREE_FAILED, sizeof( void * ) + sizeof( TraceUnsignedBaseType_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pvAddress ); + xTraceEventAddUnsignedBaseType( xEventHandle, uxSize ); + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + traceResult xTraceHeapGetCurrent( TraceHeapHandle_t xHeapHandle, + TraceUnsignedBaseType_t * puxCurrent ) + { + /* This should never fail */ + TRC_ASSERT( xHeapHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetState( xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, puxCurrent ) == TRC_SUCCESS ); + + return TRC_SUCCESS; + } + + traceResult xTraceHeapGetHighWaterMark( TraceHeapHandle_t xHeapHandle, + TraceUnsignedBaseType_t * puxHighWaterMark ) + { + /* This should never fail */ + TRC_ASSERT( xHeapHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetState( xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, puxHighWaterMark ) == TRC_SUCCESS ); + + return TRC_SUCCESS; + } + + traceResult xTraceHeapGetMax( TraceHeapHandle_t xHeapHandle, + TraceUnsignedBaseType_t * puxMax ) + { + /* This should never fail */ + TRC_ASSERT( xHeapHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetState( xHeapHandle, TRC_HEAP_STATE_INDEX_MAX, puxMax ) == TRC_SUCCESS ); + + return TRC_SUCCESS; + } + + #endif /* (TRC_USE_HEAPS == 1) */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcISR.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcISR.c index abcf3e484..48a429246 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcISR.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcISR.c @@ -1,274 +1,282 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for ISR tagging. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -TraceISRInfo_t* pxTraceISRInfo; - -traceResult xTraceISRInitialize(TraceISRInfoBuffer_t *pxBuffer) -{ - uint32_t uiCoreIndex; - uint32_t uiStackIndex; - - TRC_ASSERT_EQUAL_SIZE(TraceISRInfoBuffer_t, TraceISRInfo_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - pxTraceISRInfo = (TraceISRInfo_t*)pxBuffer; - - for (uiCoreIndex = 0; uiCoreIndex < (TRC_CFG_CORE_COUNT); uiCoreIndex++) - { - TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[uiCoreIndex]; - - /* Initialize ISR stack */ - for (uiStackIndex = 0; uiStackIndex < (TRC_CFG_MAX_ISR_NESTING); uiStackIndex++) - { - pxCoreInfo->handleStack[uiStackIndex] = 0; - } - - pxCoreInfo->stackIndex = -1; - pxCoreInfo->isPendingContextSwitch = 0; - } - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ISR); - - return TRC_SUCCESS; -} - -traceResult xTraceISRRegister(const char* szName, uint32_t uiPriority, TraceISRHandle_t *pxISRHandle) -{ - TraceEntryHandle_t xEntryHandle; - TraceEventHandle_t xEventHandle = 0; - uint32_t i = 0, uiLength = 0, uiValue = 0; - - /* We need to check this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR)) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT(pxISRHandle != 0); - - if (szName == 0) - { - szName = ""; - } - - /* Always save in symbol table, in case the recording has not yet started */ - /* We need to check this */ - if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetSymbol(xEntryHandle, szName) == TRC_SUCCESS); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, 0, (TraceUnsignedBaseType_t)uiPriority) == TRC_SUCCESS); - - *pxISRHandle = (TraceISRHandle_t)xEntryHandle; - - for (i = 0; (szName[i] != 0) && (i < 128); i++) {} - - uiLength = i; - - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_DEFINE_ISR, uiLength + sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, (void*)xEntryHandle); - xTraceEventAdd32(xEventHandle, uiPriority); - xTraceEventAddData(xEventHandle, (void*)szName, uiLength); - - /* Check if we can truncate */ - xTraceEventPayloadRemaining(xEventHandle, &uiValue); - if (uiValue > 0) - { - xTraceEventAdd8(xEventHandle, 0); - } - - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -traceResult xTraceISRBegin(TraceISRHandle_t xISRHandle) -{ - TraceEventHandle_t xEventHandle = 0; - TRACE_ALLOC_CRITICAL_SECTION(); - - (void)xEventHandle; - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR)); - - TRACE_ENTER_CRITICAL_SECTION(); - - /* We are at the start of a possible ISR chain. - * No context switches should have been triggered now. - */ - TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()]; - - if (pxCoreInfo->stackIndex == -1) - { - pxCoreInfo->isPendingContextSwitch = 0; - } - - if (pxCoreInfo->stackIndex < (TRC_CFG_MAX_ISR_NESTING) - 1) - { - pxCoreInfo->stackIndex++; - pxCoreInfo->handleStack[pxCoreInfo->stackIndex] = xISRHandle; - -#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_ISR_BEGIN, sizeof(void*), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, (void*)xISRHandle); - xTraceEventEnd(xEventHandle); - } -#endif - } - else - { - TRACE_EXIT_CRITICAL_SECTION(); - - xTraceError(TRC_ERROR_ISR_NESTING_OVERFLOW); - - return TRC_FAIL; - } - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_SUCCESS; -} - -traceResult xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired) -{ - TraceEventHandle_t xEventHandle = 0; - TRACE_ALLOC_CRITICAL_SECTION(); - - (void)xEventHandle; - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR)); - - TRACE_ENTER_CRITICAL_SECTION(); - - TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()]; - - /* Is there a pending task-switch? (perhaps from an earlier ISR) */ - pxCoreInfo->isPendingContextSwitch |= xIsTaskSwitchRequired; - - if (pxCoreInfo->stackIndex > 0) - { - pxCoreInfo->stackIndex--; - -#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) - /* Store return to interrupted ISR (if nested ISRs)*/ - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_ISR_RESUME, sizeof(void*), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, (void*)pxCoreInfo->handleStack[pxCoreInfo->stackIndex]); - xTraceEventEnd(xEventHandle); - } -#endif - } - else - { - pxCoreInfo->stackIndex--; - - /* Store return to interrupted task, if no context switch will occur in between. */ - if ((pxCoreInfo->isPendingContextSwitch == 0) || (xTraceKernelPortIsSchedulerSuspended())) - { -#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_TASK_ACTIVATE, sizeof(void*), &xEventHandle) == TRC_SUCCESS) - { - void *pvCurrentTask = 0; - - xTraceTaskGetCurrent(&pvCurrentTask); - xTraceEventAddPointer(xEventHandle, pvCurrentTask); - xTraceEventEnd(xEventHandle); - } -#endif - } - } - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_SUCCESS; -} - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -traceResult xTraceISRGetCurrentNesting(int32_t* puiValue) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR)); - - /* This should never fail */ - TRC_ASSERT(puiValue != 0); - - TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()]; - *puiValue = pxCoreInfo->stackIndex; - - return TRC_SUCCESS; -} - -int32_t xTraceISRGetCurrentNestingReturned(void) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR)); - - return pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()].stackIndex; -} - -traceResult xTraceISRGetCurrent(TraceISRHandle_t* pxISRHandle) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR)); - - /* This should never fail */ - TRC_ASSERT(pxISRHandle != 0); - - TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()]; - - if (pxCoreInfo->stackIndex < 0) - { - return TRC_FAIL; - } - - *pxISRHandle = pxCoreInfo->handleStack[pxCoreInfo->stackIndex]; - - return TRC_SUCCESS; -} - -#endif - -/* DEPRECATED */ -TraceISRHandle_t xTraceSetISRProperties(const char* szName, uint32_t uiPriority) -{ - TraceISRHandle_t xISRHandle = 0; - - xTraceISRRegister(szName, uiPriority, &xISRHandle); - - return xISRHandle; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for ISR tagging. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + TraceISRInfo_t * pxTraceISRInfo; + + traceResult xTraceISRInitialize( TraceISRInfoBuffer_t * pxBuffer ) + { + uint32_t uiCoreIndex; + uint32_t uiStackIndex; + + TRC_ASSERT_EQUAL_SIZE( TraceISRInfoBuffer_t, TraceISRInfo_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + pxTraceISRInfo = ( TraceISRInfo_t * ) pxBuffer; + + for( uiCoreIndex = 0; uiCoreIndex < ( TRC_CFG_CORE_COUNT ); uiCoreIndex++ ) + { + TraceISRCoreInfo_t * pxCoreInfo = &pxTraceISRInfo->coreInfos[ uiCoreIndex ]; + + /* Initialize ISR stack */ + for( uiStackIndex = 0; uiStackIndex < ( TRC_CFG_MAX_ISR_NESTING ); uiStackIndex++ ) + { + pxCoreInfo->handleStack[ uiStackIndex ] = 0; + } + + pxCoreInfo->stackIndex = -1; + pxCoreInfo->isPendingContextSwitch = 0; + } + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_ISR ); + + return TRC_SUCCESS; + } + + traceResult xTraceISRRegister( const char * szName, + uint32_t uiPriority, + TraceISRHandle_t * pxISRHandle ) + { + TraceEntryHandle_t xEntryHandle; + TraceEventHandle_t xEventHandle = 0; + uint32_t i = 0, uiLength = 0, uiValue = 0; + + /* We need to check this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ISR ) ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT( pxISRHandle != 0 ); + + if( szName == 0 ) + { + szName = ""; + } + + /* Always save in symbol table, in case the recording has not yet started */ + /* We need to check this */ + if( xTraceEntryCreate( &xEntryHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetSymbol( xEntryHandle, szName ) == TRC_SUCCESS ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( xEntryHandle, 0, ( TraceUnsignedBaseType_t ) uiPriority ) == TRC_SUCCESS ); + + *pxISRHandle = ( TraceISRHandle_t ) xEntryHandle; + + for( i = 0; ( szName[ i ] != 0 ) && ( i < 128 ); i++ ) + { + } + + uiLength = i; + + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_DEFINE_ISR, uiLength + sizeof( void * ) + sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, ( void * ) xEntryHandle ); + xTraceEventAdd32( xEventHandle, uiPriority ); + xTraceEventAddData( xEventHandle, ( void * ) szName, uiLength ); + + /* Check if we can truncate */ + xTraceEventPayloadRemaining( xEventHandle, &uiValue ); + + if( uiValue > 0 ) + { + xTraceEventAdd8( xEventHandle, 0 ); + } + + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + traceResult xTraceISRBegin( TraceISRHandle_t xISRHandle ) + { + TraceEventHandle_t xEventHandle = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + ( void ) xEventHandle; + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ISR ) ); + + TRACE_ENTER_CRITICAL_SECTION(); + + /* We are at the start of a possible ISR chain. + * No context switches should have been triggered now. + */ + TraceISRCoreInfo_t * pxCoreInfo = &pxTraceISRInfo->coreInfos[ TRC_CFG_GET_CURRENT_CORE() ]; + + if( pxCoreInfo->stackIndex == -1 ) + { + pxCoreInfo->isPendingContextSwitch = 0; + } + + if( pxCoreInfo->stackIndex < ( TRC_CFG_MAX_ISR_NESTING ) -1 ) + { + pxCoreInfo->stackIndex++; + pxCoreInfo->handleStack[ pxCoreInfo->stackIndex ] = xISRHandle; + + #if ( TRC_CFG_INCLUDE_ISR_TRACING == 1 ) + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_ISR_BEGIN, sizeof( void * ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, ( void * ) xISRHandle ); + xTraceEventEnd( xEventHandle ); + } + #endif + } + else + { + TRACE_EXIT_CRITICAL_SECTION(); + + xTraceError( TRC_ERROR_ISR_NESTING_OVERFLOW ); + + return TRC_FAIL; + } + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_SUCCESS; + } + + traceResult xTraceISREnd( TraceBaseType_t xIsTaskSwitchRequired ) + { + TraceEventHandle_t xEventHandle = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + ( void ) xEventHandle; + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ISR ) ); + + TRACE_ENTER_CRITICAL_SECTION(); + + TraceISRCoreInfo_t * pxCoreInfo = &pxTraceISRInfo->coreInfos[ TRC_CFG_GET_CURRENT_CORE() ]; + + /* Is there a pending task-switch? (perhaps from an earlier ISR) */ + pxCoreInfo->isPendingContextSwitch |= xIsTaskSwitchRequired; + + if( pxCoreInfo->stackIndex > 0 ) + { + pxCoreInfo->stackIndex--; + + #if ( TRC_CFG_INCLUDE_ISR_TRACING == 1 ) + /* Store return to interrupted ISR (if nested ISRs)*/ + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_ISR_RESUME, sizeof( void * ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, ( void * ) pxCoreInfo->handleStack[ pxCoreInfo->stackIndex ] ); + xTraceEventEnd( xEventHandle ); + } + #endif + } + else + { + pxCoreInfo->stackIndex--; + + /* Store return to interrupted task, if no context switch will occur in between. */ + if( ( pxCoreInfo->isPendingContextSwitch == 0 ) || ( xTraceKernelPortIsSchedulerSuspended() ) ) + { + #if ( TRC_CFG_INCLUDE_ISR_TRACING == 1 ) + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_TASK_ACTIVATE, sizeof( void * ), &xEventHandle ) == TRC_SUCCESS ) + { + void * pvCurrentTask = 0; + + xTraceTaskGetCurrent( &pvCurrentTask ); + xTraceEventAddPointer( xEventHandle, pvCurrentTask ); + xTraceEventEnd( xEventHandle ); + } + #endif + } + } + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_SUCCESS; + } + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + + traceResult xTraceISRGetCurrentNesting( int32_t * puiValue ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ISR ) ); + + /* This should never fail */ + TRC_ASSERT( puiValue != 0 ); + + TraceISRCoreInfo_t * pxCoreInfo = &pxTraceISRInfo->coreInfos[ TRC_CFG_GET_CURRENT_CORE() ]; + *puiValue = pxCoreInfo->stackIndex; + + return TRC_SUCCESS; + } + + int32_t xTraceISRGetCurrentNestingReturned( void ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ISR ) ); + + return pxTraceISRInfo->coreInfos[ TRC_CFG_GET_CURRENT_CORE() ].stackIndex; + } + + traceResult xTraceISRGetCurrent( TraceISRHandle_t * pxISRHandle ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_ISR ) ); + + /* This should never fail */ + TRC_ASSERT( pxISRHandle != 0 ); + + TraceISRCoreInfo_t * pxCoreInfo = &pxTraceISRInfo->coreInfos[ TRC_CFG_GET_CURRENT_CORE() ]; + + if( pxCoreInfo->stackIndex < 0 ) + { + return TRC_FAIL; + } + + *pxISRHandle = pxCoreInfo->handleStack[ pxCoreInfo->stackIndex ]; + + return TRC_SUCCESS; + } + + #endif /* if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) */ + +/* DEPRECATED */ + TraceISRHandle_t xTraceSetISRProperties( const char * szName, + uint32_t uiPriority ) + { + TraceISRHandle_t xISRHandle = 0; + + xTraceISRRegister( szName, uiPriority, &xISRHandle ); + + return xISRHandle; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcInternalEventBuffer.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcInternalEventBuffer.c index 100350a84..8ada2f707 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcInternalEventBuffer.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcInternalEventBuffer.c @@ -1,75 +1,78 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The implementation of the internal buffer. - */ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#if (TRC_USE_INTERNAL_BUFFER == 1) - -#include -#include -#include - -static TraceMultiCoreEventBuffer_t *pxInternalEventBuffer; - -traceResult xTraceInternalEventBufferInitialize(uint8_t* puiBuffer, uint32_t uiSize) -{ - /* uiSize must be larger than sizeof(TraceMultiCoreEventBuffer_t) or there will be no room for any data */ - /* This should never fail */ - TRC_ASSERT(uiSize > sizeof(TraceMultiCoreEventBuffer_t)); - - /* pxInternalBuffer will be placed at the beginning of the puiBuffer */ - pxInternalEventBuffer = (TraceMultiCoreEventBuffer_t*)puiBuffer; - - /* Send in a an address pointing after the TraceMultiCoreEventBuffer_t */ - /* We need to check this */ - if (xTraceMultiCoreEventBufferInitialize(pxInternalEventBuffer, TRC_EVENT_BUFFER_OPTION_SKIP, - &puiBuffer[sizeof(TraceMultiCoreEventBuffer_t)], uiSize - sizeof(TraceMultiCoreEventBuffer_t)) == TRC_FAIL) - { - return TRC_FAIL; - } - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER); - - return TRC_SUCCESS; -} - -traceResult xTraceInternalEventBufferPush(void *pvData, uint32_t uiSize, int32_t *piBytesWritten) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER)); - - return xTraceMultiCoreEventBufferPush(pxInternalEventBuffer, pvData, uiSize, piBytesWritten); -} - -traceResult xTraceInternalEventBufferTransfer(int32_t *piBytesWritten) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER)); - - return xTraceMultiCoreEventBufferTransfer(pxInternalEventBuffer, piBytesWritten); -} - -traceResult xTraceInternalEventBufferClear() -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER)); - - return xTraceMultiCoreEventBufferClear(pxInternalEventBuffer); -} - -#endif /* (TRC_USE_INTERNAL_BUFFER == 1) */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation of the internal buffer. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + + #include + #include + #include + + static TraceMultiCoreEventBuffer_t * pxInternalEventBuffer; + + traceResult xTraceInternalEventBufferInitialize( uint8_t * puiBuffer, + uint32_t uiSize ) + { + /* uiSize must be larger than sizeof(TraceMultiCoreEventBuffer_t) or there will be no room for any data */ + /* This should never fail */ + TRC_ASSERT( uiSize > sizeof( TraceMultiCoreEventBuffer_t ) ); + + /* pxInternalBuffer will be placed at the beginning of the puiBuffer */ + pxInternalEventBuffer = ( TraceMultiCoreEventBuffer_t * ) puiBuffer; + + /* Send in a an address pointing after the TraceMultiCoreEventBuffer_t */ + /* We need to check this */ + if( xTraceMultiCoreEventBufferInitialize( pxInternalEventBuffer, TRC_EVENT_BUFFER_OPTION_SKIP, + &puiBuffer[ sizeof( TraceMultiCoreEventBuffer_t ) ], uiSize - sizeof( TraceMultiCoreEventBuffer_t ) ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER ); + + return TRC_SUCCESS; + } + + traceResult xTraceInternalEventBufferPush( void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER ) ); + + return xTraceMultiCoreEventBufferPush( pxInternalEventBuffer, pvData, uiSize, piBytesWritten ); + } + + traceResult xTraceInternalEventBufferTransfer( int32_t * piBytesWritten ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER ) ); + + return xTraceMultiCoreEventBufferTransfer( pxInternalEventBuffer, piBytesWritten ); + } + + traceResult xTraceInternalEventBufferClear() + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_INTERNAL_EVENT_BUFFER ) ); + + return xTraceMultiCoreEventBufferClear( pxInternalEventBuffer ); + } + + #endif /* (TRC_USE_INTERNAL_BUFFER == 1) */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcInterval.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcInterval.c index 49a1da045..4a517abca 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcInterval.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcInterval.c @@ -1,83 +1,85 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation of intervals. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#define TRC_INTERVAL_STATE_INDEX 0 - -traceResult xTraceIntervalCreate(const char *szName, TraceIntervalHandle_t *pxIntervalHandle) -{ - TraceObjectHandle_t xObjectHandle; - - /* This should never fail */ - TRC_ASSERT(pxIntervalHandle != 0); - - /* We need to check this */ - if (xTraceObjectRegister(PSF_EVENT_INTERVAL_CREATE, 0, szName, 0, &xObjectHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions((TraceEntryHandle_t)xObjectHandle, TRC_ENTRY_OPTION_INTERVAL) == TRC_SUCCESS); - - *pxIntervalHandle = (TraceIntervalHandle_t)xObjectHandle; - - return TRC_SUCCESS; -} - -traceResult xTraceIntervalStart(TraceIntervalHandle_t xIntervalHandle) -{ - TraceEventHandle_t xEventHandle = 0; - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState((TraceEntryHandle_t)xIntervalHandle, TRC_INTERVAL_STATE_INDEX, 1) == TRC_SUCCESS); - - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_INTERVAL_STATECHANGE, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, (void*)xIntervalHandle); - xTraceEventAdd32(xEventHandle, 1); - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -traceResult xTraceIntervalStop(TraceIntervalHandle_t xIntervalHandle) -{ - TraceEventHandle_t xEventHandle = 0; - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState((TraceEntryHandle_t)xIntervalHandle, TRC_INTERVAL_STATE_INDEX, 0) == TRC_SUCCESS); - - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_INTERVAL_STATECHANGE, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, (void*)xIntervalHandle); - xTraceEventAdd32(xEventHandle, 0); - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -traceResult xTraceIntervalGetState(TraceIntervalHandle_t xIntervalHandle, TraceUnsignedBaseType_t *puxState) -{ - return xTraceEntryGetState((TraceEntryHandle_t)xIntervalHandle, TRC_INTERVAL_STATE_INDEX, puxState); -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation of intervals. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #define TRC_INTERVAL_STATE_INDEX 0 + + traceResult xTraceIntervalCreate( const char * szName, + TraceIntervalHandle_t * pxIntervalHandle ) + { + TraceObjectHandle_t xObjectHandle; + + /* This should never fail */ + TRC_ASSERT( pxIntervalHandle != 0 ); + + /* We need to check this */ + if( xTraceObjectRegister( PSF_EVENT_INTERVAL_CREATE, 0, szName, 0, &xObjectHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetOptions( ( TraceEntryHandle_t ) xObjectHandle, TRC_ENTRY_OPTION_INTERVAL ) == TRC_SUCCESS ); + + *pxIntervalHandle = ( TraceIntervalHandle_t ) xObjectHandle; + + return TRC_SUCCESS; + } + + traceResult xTraceIntervalStart( TraceIntervalHandle_t xIntervalHandle ) + { + TraceEventHandle_t xEventHandle = 0; + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( ( TraceEntryHandle_t ) xIntervalHandle, TRC_INTERVAL_STATE_INDEX, 1 ) == TRC_SUCCESS ); + + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_INTERVAL_STATECHANGE, sizeof( void * ) + sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, ( void * ) xIntervalHandle ); + xTraceEventAdd32( xEventHandle, 1 ); + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + traceResult xTraceIntervalStop( TraceIntervalHandle_t xIntervalHandle ) + { + TraceEventHandle_t xEventHandle = 0; + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( ( TraceEntryHandle_t ) xIntervalHandle, TRC_INTERVAL_STATE_INDEX, 0 ) == TRC_SUCCESS ); + + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_INTERVAL_STATECHANGE, sizeof( void * ) + sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, ( void * ) xIntervalHandle ); + xTraceEventAdd32( xEventHandle, 0 ); + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + traceResult xTraceIntervalGetState( TraceIntervalHandle_t xIntervalHandle, + TraceUnsignedBaseType_t * puxState ) + { + return xTraceEntryGetState( ( TraceEntryHandle_t ) xIntervalHandle, TRC_INTERVAL_STATE_INDEX, puxState ); + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c index 3108e017b..87d8b05f0 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c @@ -1,655 +1,683 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The FreeRTOS specific parts of the trace recorder - */ - -#include -#include - -#if (!defined(TRC_USE_TRACEALYZER_RECORDER) && configUSE_TRACE_FACILITY == 1) - -#error Trace Recorder: You need to include trcRecorder.h at the end of your FreeRTOSConfig.h! - -#endif - -#if (defined(TRC_USE_TRACEALYZER_RECORDER) && TRC_USE_TRACEALYZER_RECORDER == 1) - -#ifndef TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS - -/* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS is missing in trcConfig.h. */ -#error "TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS must be defined in trcConfig.h." - -#endif - -#ifndef TRC_CFG_INCLUDE_TIMER_EVENTS - -/* TRC_CFG_INCLUDE_TIMER_EVENTS is missing in trcConfig.h. */ -#error "TRC_CFG_INCLUDE_TIMER_EVENTS must be defined in trcConfig.h." - -#endif - -#ifndef TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS - -/* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS is missing in trcConfig.h. */ -#error "TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS must be defined in trcConfig.h." - -#endif - -#ifndef TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS - -/* TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS is missing in trcConfig.h. Define this as 1 if using FreeRTOS v10 or later and like to trace stream buffer or message buffer events, otherwise 0. */ -#error "TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be defined in trcConfig.h." - -#endif - -#if (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)) -/* - The below error message is to alert you on the following issue: - - The hardware port selected in trcConfig.h uses the operating system timer for the - timestamping, i.e., the periodic interrupt timer that drives the OS tick interrupt. - - When using "tickless idle" mode, the recorder needs an independent time source in - order to correctly record the durations of the idle times. Otherwise, the trace may appear - to have a different length than in reality, and the reported CPU load is also affected. - - You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING - macro in your trcConfig.h file. But then the time scale may be incorrect during - tickless idle periods. - - To get this correct, override the default timestamping by setting TRC_CFG_HARDWARE_PORT - in trcConfig.h to TRC_HARDWARE_PORT_APPLICATION_DEFINED and define the HWTC macros - accordingly, using a free running counter or an independent periodic interrupt timer. - See trcHardwarePort.h for details. - - For ARM Cortex-M3, M4 and M7 MCUs this is not an issue, since the recorder uses the - DWT cycle counter for timestamping in these cases. -*/ - -#ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING -#error Trace Recorder: This timestamping mode is not recommended with Tickless Idle. -#endif - -#endif - -#include -#include - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) || (defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)) - -#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1) - -#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) - -static StackType_t stackTzCtrl[TRC_CFG_CTRL_TASK_STACK_SIZE]; -static StaticTask_t tcbTzCtrl; - -#else - -#error "configSUPPORT_STATIC_ALLOCATION not supported before FreeRTOS v9" - -#endif - -#endif - -/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */ -static portTASK_FUNCTION(TzCtrl, pvParameters); - -#endif - -#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -/* If the project does not include the FreeRTOS timers, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */ -#include - -#endif - -#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -/* If the project does not include the FreeRTOS event groups, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */ -#include - -#endif - -#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -/* If the project does not include the FreeRTOS stream buffers, TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be set to 0 */ -#include - -#endif - -#if (TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND != TRC_ACKNOWLEDGED) && (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_0 || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_1) && (configUSE_QUEUE_SETS == 1) - -#error "When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace point in prvNotifyQueueSetContainer() in queue.c is renamed from traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from other traceQUEUE_SEND trace points. Then set TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND in trcConfig.h to TRC_ACKNOWLEDGED to get rid of this error." - -#endif - -#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) - -traceResult xTraceKernelPortGetUnusedStack(void* pvTask, TraceUnsignedBaseType_t* puxUnusedStack) -{ - *puxUnusedStack = uxTaskGetStackHighWaterMark(pvTask); - - return TRC_SUCCESS; -} - -#endif - -traceResult xTraceKernelPortDelay(uint32_t uiTicks) -{ - vTaskDelay(uiTicks); - - return TRC_SUCCESS; -} - -unsigned char xTraceKernelPortIsSchedulerSuspended(void) -{ - /* Assumed to be available in FreeRTOS. According to the FreeRTOS docs, - INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in - FreeRTOSConfig.h for this function to be available. */ - - return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED; -} - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -typedef struct TraceKernelPortData -{ - TraceHeapHandle_t xSystemHeapHandle; - TraceKernelPortTaskHandle_t xTzCtrlHandle; -} TraceKernelPortData_t; - -static TraceKernelPortData_t* pxKernelPortData; - -#define TRC_PORT_MALLOC(size) pvPortMalloc(size) - -traceResult xTraceKernelPortInitialize(TraceKernelPortDataBuffer_t* pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceKernelPortDataBuffer_t, TraceKernelPortData_t); - - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - pxKernelPortData = (TraceKernelPortData_t*)pxBuffer; - - pxKernelPortData->xSystemHeapHandle = 0; - pxKernelPortData->xTzCtrlHandle = 0; - - return TRC_SUCCESS; -} - -traceResult xTraceKernelPortEnable(void) -{ - HeapStats_t xHeapStats; - void* pvAlloc; - - if (pxKernelPortData->xSystemHeapHandle == 0) - { - /* Some magic to make sure the heap has been initialized! */ - pvAlloc = pvPortMalloc(1); - if (pvAlloc != 0) - { - vPortFree(pvAlloc); - } - - vPortGetHeapStats(&xHeapStats); - xTraceHeapCreate("System Heap", configTOTAL_HEAP_SIZE - xHeapStats.xAvailableHeapSpaceInBytes, configTOTAL_HEAP_SIZE - xHeapStats.xMinimumEverFreeBytesRemaining, configTOTAL_HEAP_SIZE, &pxKernelPortData->xSystemHeapHandle); - } - - if (pxKernelPortData->xTzCtrlHandle == 0) - { - /* Creates the TzCtrl task - receives trace commands (start, stop, ...) */ -#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1) - pxKernelPortData->xTzCtrlHandle = xTaskCreateStatic(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl); -#else - xTaskCreate(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, &pxKernelPortData->xTzCtrlHandle); -#endif - - if (pxKernelPortData->xTzCtrlHandle == 0) - { - xTraceError(TRC_ERROR_TZCTRLTASK_NOT_CREATED); - - return TRC_FAIL; - } - } - - return TRC_SUCCESS; -} - -static portTASK_FUNCTION(TzCtrl, pvParameters) -{ - (void)pvParameters; - - while (1) - { - xTraceTzCtrl(); - - vTaskDelay(TRC_CFG_CTRL_TASK_DELAY); - } -} - -#if (TRC_CFG_SCHEDULING_ONLY == 0) - -void vTraceSetQueueName(void* pvQueue, const char* szName) -{ - xTraceObjectSetNameWithoutHandle(pvQueue, szName); -} - -void vTraceSetSemaphoreName(void* pvSemaphore, const char* szName) -{ - xTraceObjectSetNameWithoutHandle(pvSemaphore, szName); -} - -void vTraceSetMutexName(void* pvMutex, const char* szName) -{ - xTraceObjectSetNameWithoutHandle(pvMutex, szName); -} - -#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -void vTraceSetEventGroupName(void* pvEventGroup, const char* szName) -{ - xTraceObjectSetNameWithoutHandle(pvEventGroup, szName); -} - -#endif - -#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -void vTraceSetStreamBufferName(void* pvStreamBuffer, const char* szName) -{ - xTraceObjectSetNameWithoutHandle(pvStreamBuffer, szName); -} - -void vTraceSetMessageBufferName(void* pvMessageBuffer, const char* szName) -{ - xTraceObjectSetNameWithoutHandle(pvMessageBuffer, szName); -} - -#endif - -#endif - -TraceHeapHandle_t xTraceKernelPortGetSystemHeapHandle(void) -{ - return pxKernelPortData->xSystemHeapHandle; -} - -#endif - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) - -uint32_t prvTraceGetQueueNumber(void* handle); - -#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X) - -extern unsigned char ucQueueGetQueueNumber(xQueueHandle pxQueue); -extern void vQueueSetQueueNumber(xQueueHandle pxQueue, unsigned char ucQueueNumber); -extern unsigned char ucQueueGetQueueType(xQueueHandle pxQueue); - -uint32_t prvTraceGetQueueNumber(void* handle) -{ - return (uint32_t)ucQueueGetQueueNumber(handle); -} - -#else - -uint32_t prvTraceGetQueueNumber(void* handle) -{ - return (uint32_t)uxQueueGetQueueNumber(handle); -} - -#endif - -uint8_t prvTraceGetQueueType(void* pvQueue) -{ - // This is either declared in header file in FreeRTOS 8 and later, or as extern above - return ucQueueGetQueueType(pvQueue); -} - -/* Tasks */ -uint16_t prvTraceGetTaskNumberLow16(void* pvTask) -{ - return TRACE_GET_LOW16(uxTaskGetTaskNumber(pvTask)); -} - -uint16_t prvTraceGetTaskNumberHigh16(void* pvTask) -{ - return TRACE_GET_HIGH16(uxTaskGetTaskNumber(pvTask)); -} - -void prvTraceSetTaskNumberLow16(void* pvTask, uint16_t uiValue) -{ - vTaskSetTaskNumber(pvTask, TRACE_SET_LOW16(uxTaskGetTaskNumber(pvTask), uiValue)); -} - -void prvTraceSetTaskNumberHigh16(void* pvTask, uint16_t uiValue) -{ - vTaskSetTaskNumber(pvTask, TRACE_SET_HIGH16(uxTaskGetTaskNumber(pvTask), uiValue)); -} - -uint16_t prvTraceGetQueueNumberLow16(void* pvQueue) -{ - return TRACE_GET_LOW16(prvTraceGetQueueNumber(pvQueue)); -} - -uint16_t prvTraceGetQueueNumberHigh16(void* pvQueue) -{ - return TRACE_GET_HIGH16(prvTraceGetQueueNumber(pvQueue)); -} - -void prvTraceSetQueueNumberLow16(void* pvQueue, uint16_t uiValue) -{ - vQueueSetQueueNumber(pvQueue, TRACE_SET_LOW16(prvTraceGetQueueNumber(pvQueue), uiValue)); -} - -void prvTraceSetQueueNumberHigh16(void* pvQueue, uint16_t uiValue) -{ - vQueueSetQueueNumber(pvQueue, TRACE_SET_HIGH16(prvTraceGetQueueNumber(pvQueue), uiValue)); -} - -#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -uint16_t prvTraceGetTimerNumberLow16(void* pvTimer) -{ - return TRACE_GET_LOW16(uxTimerGetTimerNumber(pvTimer)); -} - -uint16_t prvTraceGetTimerNumberHigh16(void* pvTimer) -{ - return TRACE_GET_HIGH16(uxTimerGetTimerNumber(pvTimer)); -} - -void prvTraceSetTimerNumberLow16(void* pvTimer, uint16_t uiValue) -{ - vTimerSetTimerNumber(pvTimer, TRACE_SET_LOW16(uxTimerGetTimerNumber(pvTimer), uiValue)); -} - -void prvTraceSetTimerNumberHigh16(void* pvTimer, uint16_t uiValue) -{ - vTimerSetTimerNumber(pvTimer, TRACE_SET_HIGH16(uxTimerGetTimerNumber(pvTimer), uiValue)); -} - -#endif - -#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -uint16_t prvTraceGetEventGroupNumberLow16(void* pvEventGroup) -{ - return TRACE_GET_LOW16(uxEventGroupGetNumber(pvEventGroup)); -} - -uint16_t prvTraceGetEventGroupNumberHigh16(void* pvEventGroup) -{ - return TRACE_GET_HIGH16(uxEventGroupGetNumber(pvEventGroup)); -} - -void prvTraceSetEventGroupNumberLow16(void* pvEventGroup, uint16_t uiValue) -{ - vEventGroupSetNumber(pvEventGroup, TRACE_SET_LOW16(uxEventGroupGetNumber(pvEventGroup), uiValue)); -} - -void prvTraceSetEventGroupNumberHigh16(void* pvEventGroup, uint16_t uiValue) -{ - vEventGroupSetNumber(pvEventGroup, TRACE_SET_HIGH16(uxEventGroupGetNumber(pvEventGroup), uiValue)); -} - -#endif - -#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -uint16_t prvTraceGetStreamBufferNumberLow16(void* pvStreamBuffer) -{ - return TRACE_GET_LOW16(uxStreamBufferGetStreamBufferNumber(pvStreamBuffer)); -} - -uint16_t prvTraceGetStreamBufferNumberHigh16(void* pvStreamBuffer) -{ - return TRACE_GET_HIGH16(uxStreamBufferGetStreamBufferNumber(pvStreamBuffer)); -} - -void prvTraceSetStreamBufferNumberLow16(void* pvStreamBuffer, uint16_t uiValue) -{ - vStreamBufferSetStreamBufferNumber(pvStreamBuffer, TRACE_SET_LOW16(uxStreamBufferGetStreamBufferNumber(pvStreamBuffer), uiValue)); -} - -void prvTraceSetStreamBufferNumberHigh16(void* pvStreamBuffer, uint16_t uiValue) -{ - vStreamBufferSetStreamBufferNumber(pvStreamBuffer, TRACE_SET_HIGH16(uxStreamBufferGetStreamBufferNumber(pvStreamBuffer), uiValue)); -} - -#endif - -static TraceKernelPortTaskHandle_t xTzCtrlHandle = 0; /* TzCtrl task TCB */ - -/* Internal flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */ -int uiInEventGroupSetBitsFromISR = 0; - -/** - * @internal Class reference table - */ -traceObjectClass TraceQueueClassTable[5] = { - TRACE_CLASS_QUEUE, - TRACE_CLASS_MUTEX, - TRACE_CLASS_SEMAPHORE, - TRACE_CLASS_SEMAPHORE, - TRACE_CLASS_MUTEX -}; - -#if (TRC_CFG_SCHEDULING_ONLY == 0) - -void vTraceSetQueueName(void* pvQueue, const char* szName) -{ - prvTraceSetObjectName(TRACE_CLASS_QUEUE, TRACE_GET_OBJECT_NUMBER(QUEUE, pvQueue), szName); -} - -void vTraceSetSemaphoreName(void* pvSemaphore, const char* szName) -{ - prvTraceSetObjectName(TRACE_CLASS_SEMAPHORE, TRACE_GET_OBJECT_NUMBER(QUEUE, pvSemaphore), szName); -} - -void vTraceSetMutexName(void* pvMutex, const char* szName) -{ - prvTraceSetObjectName(TRACE_CLASS_MUTEX, TRACE_GET_OBJECT_NUMBER(QUEUE, pvMutex), szName); -} - -#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X) - -void vTraceSetEventGroupName(void* pvEventGroup, const char* szName) -{ - prvTraceSetObjectName(TRACE_CLASS_EVENTGROUP, TRACE_GET_OBJECT_NUMBER(EVENTGROUP, pvEventGroup), szName); -} - -#endif - -#if (TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) - -void vTraceSetStreamBufferName(void* pvStreamBuffer, const char* szName) -{ - prvTraceSetObjectName(TRACE_CLASS_STREAMBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, pvStreamBuffer), szName); -} - -void vTraceSetMessageBufferName(void* pvStreamBuffer, const char* szName) -{ - prvTraceSetObjectName(TRACE_CLASS_MESSAGEBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, pvStreamBuffer), szName); -} - -#endif - -#endif - -void* prvTraceGetCurrentTaskHandle() -{ - return xTaskGetCurrentTaskHandle(); -} - -traceResult xTraceKernelPortInitialize(TraceKernelPortDataBuffer_t* pxBuffer) -{ - (void)pxBuffer; - - return TRC_SUCCESS; -} - -traceResult xTraceKernelPortEnable(void) -{ -#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) - - if (xTzCtrlHandle == 0) - { -#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1) - - xTzCtrlHandle = xTaskCreateStatic(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl); - -#else - - xTaskCreate(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, &xTzCtrlHandle); - -#endif - } - -#else - - (void)xTzCtrlHandle; - -#endif - - return TRC_SUCCESS; -} - -#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) - -static portTASK_FUNCTION(TzCtrl, pvParameters) -{ - (void)pvParameters; - - while (1) - { - if (xTraceIsRecorderEnabled()) - { - prvReportStackUsage(); - } - - vTaskDelay(TRC_CFG_CTRL_TASK_DELAY); - } -} - -#endif - -traceResult xTraceKernelPortInitObjectPropertyTable() -{ - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectClasses = TRACE_NCLASSES; - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[0] = TRC_CFG_NQUEUE; - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[1] = TRC_CFG_NSEMAPHORE; - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[2] = TRC_CFG_NMUTEX; - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[3] = TRC_CFG_NTASK; - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = TRC_CFG_NISR; - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = TRC_CFG_NTIMER; - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = TRC_CFG_NEVENTGROUP; - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[7] = TRC_CFG_NSTREAMBUFFER; - RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[8] = TRC_CFG_NMESSAGEBUFFER; - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[0] = TRC_CFG_NAME_LEN_QUEUE; - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[1] = TRC_CFG_NAME_LEN_SEMAPHORE; - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[2] = TRC_CFG_NAME_LEN_MUTEX; - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[3] = TRC_CFG_NAME_LEN_TASK; - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[4] = TRC_CFG_NAME_LEN_ISR; - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[5] = TRC_CFG_NAME_LEN_TIMER; - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = TRC_CFG_NAME_LEN_EVENTGROUP; - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[7] = TRC_CFG_NAME_LEN_STREAMBUFFER; - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[8] = TRC_CFG_NAME_LEN_MESSAGEBUFFER; - RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue; - RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore; - RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex; - RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[3] = PropertyTableSizeTask; - RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR; - RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[5] = PropertyTableSizeTimer; - RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[6] = PropertyTableSizeEventGroup; - RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[7] = PropertyTableSizeStreamBuffer; - RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[8] = PropertyTableSizeMessageBuffer; - RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue; - RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore; - RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex; - RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[3] = StartIndexTask; - RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR; - RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[5] = StartIndexTimer; - RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[6] = StartIndexEventGroup; - RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[7] = StartIndexStreamBuffer; - RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[8] = StartIndexMessageBuffer; - RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE; - - return TRC_SUCCESS; -} - -traceResult xTraceKernelPortInitObjectHandleStack() -{ - uint32_t i = 0; - - objectHandleStacks.indexOfNextAvailableHandle[0] = objectHandleStacks.lowestIndexOfClass[0] = 0; - objectHandleStacks.indexOfNextAvailableHandle[1] = objectHandleStacks.lowestIndexOfClass[1] = (TRC_CFG_NQUEUE); - objectHandleStacks.indexOfNextAvailableHandle[2] = objectHandleStacks.lowestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE); - objectHandleStacks.indexOfNextAvailableHandle[3] = objectHandleStacks.lowestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX); - objectHandleStacks.indexOfNextAvailableHandle[4] = objectHandleStacks.lowestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK); - objectHandleStacks.indexOfNextAvailableHandle[5] = objectHandleStacks.lowestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR); - objectHandleStacks.indexOfNextAvailableHandle[6] = objectHandleStacks.lowestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER); - objectHandleStacks.indexOfNextAvailableHandle[7] = objectHandleStacks.lowestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP); - objectHandleStacks.indexOfNextAvailableHandle[8] = objectHandleStacks.lowestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER); - - objectHandleStacks.highestIndexOfClass[0] = (TRC_CFG_NQUEUE) - 1; - objectHandleStacks.highestIndexOfClass[1] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) - 1; - objectHandleStacks.highestIndexOfClass[2] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) - 1; - objectHandleStacks.highestIndexOfClass[3] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) - 1; - objectHandleStacks.highestIndexOfClass[4] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) - 1; - objectHandleStacks.highestIndexOfClass[5] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) - 1; - objectHandleStacks.highestIndexOfClass[6] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) - 1; - objectHandleStacks.highestIndexOfClass[7] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) - 1; - objectHandleStacks.highestIndexOfClass[8] = (TRC_CFG_NQUEUE) + (TRC_CFG_NSEMAPHORE) + (TRC_CFG_NMUTEX) + (TRC_CFG_NTASK) + (TRC_CFG_NISR) + (TRC_CFG_NTIMER) + (TRC_CFG_NEVENTGROUP) + (TRC_CFG_NSTREAMBUFFER) + (TRC_CFG_NMESSAGEBUFFER) - 1; - - for (i = 0; i < TRACE_NCLASSES; i++) - { - objectHandleStacks.handleCountWaterMarksOfClass[i] = 0; - } - - for (i = 0; i < TRACE_KERNEL_OBJECT_COUNT; i++) - { - objectHandleStacks.objectHandles[i] = 0; - } - - return TRC_SUCCESS; -} - -const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass) -{ - switch(objectclass) - { - case TRACE_CLASS_TASK: - return "Not enough TASK handles - increase TRC_CFG_NTASK in trcSnapshotConfig.h"; - case TRACE_CLASS_ISR: - return "Not enough ISR handles - increase TRC_CFG_NISR in trcSnapshotConfig.h"; - case TRACE_CLASS_SEMAPHORE: - return "Not enough SEMAPHORE handles - increase TRC_CFG_NSEMAPHORE in trcSnapshotConfig.h"; - case TRACE_CLASS_MUTEX: - return "Not enough MUTEX handles - increase TRC_CFG_NMUTEX in trcSnapshotConfig.h"; - case TRACE_CLASS_QUEUE: - return "Not enough QUEUE handles - increase TRC_CFG_NQUEUE in trcSnapshotConfig.h"; - case TRACE_CLASS_TIMER: - return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h"; - case TRACE_CLASS_EVENTGROUP: - return "Not enough EVENTGROUP handles - increase TRC_CFG_NEVENTGROUP in trcSnapshotConfig.h"; - case TRACE_CLASS_STREAMBUFFER: - return "Not enough STREAMBUFFER handles - increase TRC_CFG_NSTREAMBUFFER in trcSnapshotConfig.h"; - case TRACE_CLASS_MESSAGEBUFFER: - return "Not enough MESSAGEBUFFER handles - increase TRC_CFG_NMESSAGEBUFFER in trcSnapshotConfig.h"; - default: - return "pszTraceGetErrorHandles: Invalid objectclass!"; - } -} - -#endif - -#endif +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The FreeRTOS specific parts of the trace recorder + */ + +#include +#include + +#if ( !defined( TRC_USE_TRACEALYZER_RECORDER ) && configUSE_TRACE_FACILITY == 1 ) + + #error Trace Recorder: You need to include trcRecorder.h at the end of your FreeRTOSConfig.h! + +#endif + +#if ( defined( TRC_USE_TRACEALYZER_RECORDER ) && TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #ifndef TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS + +/* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS is missing in trcConfig.h. */ + #error "TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS must be defined in trcConfig.h." + + #endif + + #ifndef TRC_CFG_INCLUDE_TIMER_EVENTS + +/* TRC_CFG_INCLUDE_TIMER_EVENTS is missing in trcConfig.h. */ + #error "TRC_CFG_INCLUDE_TIMER_EVENTS must be defined in trcConfig.h." + + #endif + + #ifndef TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS + +/* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS is missing in trcConfig.h. */ + #error "TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS must be defined in trcConfig.h." + + #endif + + #ifndef TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS + +/* TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS is missing in trcConfig.h. Define this as 1 if using FreeRTOS v10 or later and like to trace stream buffer or message buffer events, otherwise 0. */ + #error "TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be defined in trcConfig.h." + + #endif + + #if ( configUSE_TICKLESS_IDLE != 0 && ( TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR ) ) + +/* + * The below error message is to alert you on the following issue: + * + * The hardware port selected in trcConfig.h uses the operating system timer for the + * timestamping, i.e., the periodic interrupt timer that drives the OS tick interrupt. + * + * When using "tickless idle" mode, the recorder needs an independent time source in + * order to correctly record the durations of the idle times. Otherwise, the trace may appear + * to have a different length than in reality, and the reported CPU load is also affected. + * + * You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING + * macro in your trcConfig.h file. But then the time scale may be incorrect during + * tickless idle periods. + * + * To get this correct, override the default timestamping by setting TRC_CFG_HARDWARE_PORT + * in trcConfig.h to TRC_HARDWARE_PORT_APPLICATION_DEFINED and define the HWTC macros + * accordingly, using a free running counter or an independent periodic interrupt timer. + * See trcHardwarePort.h for details. + * + * For ARM Cortex-M3, M4 and M7 MCUs this is not an issue, since the recorder uses the + * DWT cycle counter for timestamping in these cases. + */ + + #ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING + #error Trace Recorder: This timestamping mode is not recommended with Tickless Idle. + #endif + + #endif + + #include + #include + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) || ( defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) ) + + #if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + #if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 ) + + static StackType_t stackTzCtrl[ TRC_CFG_CTRL_TASK_STACK_SIZE ]; + static StaticTask_t tcbTzCtrl; + + #else + + #error "configSUPPORT_STATIC_ALLOCATION not supported before FreeRTOS v9" + + #endif + + #endif /* if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + +/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */ + static portTASK_FUNCTION( TzCtrl, pvParameters ); + + #endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) || ( defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) ) */ + + #if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + +/* If the project does not include the FreeRTOS timers, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */ + #include + + #endif + + #if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + +/* If the project does not include the FreeRTOS event groups, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */ + #include + + #endif + + #if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + +/* If the project does not include the FreeRTOS stream buffers, TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be set to 0 */ + #include + + #endif + + #if ( TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND != TRC_ACKNOWLEDGED ) && ( TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_0 || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_1 ) && ( configUSE_QUEUE_SETS == 1 ) + + #error "When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace point in prvNotifyQueueSetContainer() in queue.c is renamed from traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from other traceQUEUE_SEND trace points. Then set TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND in trcConfig.h to TRC_ACKNOWLEDGED to get rid of this error." + + #endif + + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) + + traceResult xTraceKernelPortGetUnusedStack( void * pvTask, + TraceUnsignedBaseType_t * puxUnusedStack ) + { + *puxUnusedStack = uxTaskGetStackHighWaterMark( pvTask ); + + return TRC_SUCCESS; + } + + #endif + + traceResult xTraceKernelPortDelay( uint32_t uiTicks ) + { + vTaskDelay( uiTicks ); + + return TRC_SUCCESS; + } + + unsigned char xTraceKernelPortIsSchedulerSuspended( void ) + { + /* Assumed to be available in FreeRTOS. According to the FreeRTOS docs, + * INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in + * FreeRTOSConfig.h for this function to be available. */ + + return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED; + } + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + typedef struct TraceKernelPortData + { + TraceHeapHandle_t xSystemHeapHandle; + TraceKernelPortTaskHandle_t xTzCtrlHandle; + } TraceKernelPortData_t; + + static TraceKernelPortData_t * pxKernelPortData; + + #define TRC_PORT_MALLOC( size ) pvPortMalloc( size ) + + traceResult xTraceKernelPortInitialize( TraceKernelPortDataBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceKernelPortDataBuffer_t, TraceKernelPortData_t ); + + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + pxKernelPortData = ( TraceKernelPortData_t * ) pxBuffer; + + pxKernelPortData->xSystemHeapHandle = 0; + pxKernelPortData->xTzCtrlHandle = 0; + + return TRC_SUCCESS; + } + + traceResult xTraceKernelPortEnable( void ) + { + HeapStats_t xHeapStats; + void * pvAlloc; + + if( pxKernelPortData->xSystemHeapHandle == 0 ) + { + /* Some magic to make sure the heap has been initialized! */ + pvAlloc = pvPortMalloc( 1 ); + + if( pvAlloc != 0 ) + { + vPortFree( pvAlloc ); + } + + vPortGetHeapStats( &xHeapStats ); + xTraceHeapCreate( "System Heap", configTOTAL_HEAP_SIZE - xHeapStats.xAvailableHeapSpaceInBytes, configTOTAL_HEAP_SIZE - xHeapStats.xMinimumEverFreeBytesRemaining, configTOTAL_HEAP_SIZE, &pxKernelPortData->xSystemHeapHandle ); + } + + if( pxKernelPortData->xTzCtrlHandle == 0 ) + { + /* Creates the TzCtrl task - receives trace commands (start, stop, ...) */ + #if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) + pxKernelPortData->xTzCtrlHandle = xTaskCreateStatic( TzCtrl, STRING_CAST( "TzCtrl" ), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl ); + #else + xTaskCreate( TzCtrl, STRING_CAST( "TzCtrl" ), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, &pxKernelPortData->xTzCtrlHandle ); + #endif + + if( pxKernelPortData->xTzCtrlHandle == 0 ) + { + xTraceError( TRC_ERROR_TZCTRLTASK_NOT_CREATED ); + + return TRC_FAIL; + } + } + + return TRC_SUCCESS; + } + + static portTASK_FUNCTION( TzCtrl, pvParameters ) + { + ( void ) pvParameters; + + while( 1 ) + { + xTraceTzCtrl(); + + vTaskDelay( TRC_CFG_CTRL_TASK_DELAY ); + } + } + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + + void vTraceSetQueueName( void * pvQueue, + const char * szName ) + { + xTraceObjectSetNameWithoutHandle( pvQueue, szName ); + } + + void vTraceSetSemaphoreName( void * pvSemaphore, + const char * szName ) + { + xTraceObjectSetNameWithoutHandle( pvSemaphore, szName ); + } + + void vTraceSetMutexName( void * pvMutex, + const char * szName ) + { + xTraceObjectSetNameWithoutHandle( pvMutex, szName ); + } + + #if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + + void vTraceSetEventGroupName( void * pvEventGroup, + const char * szName ) + { + xTraceObjectSetNameWithoutHandle( pvEventGroup, szName ); + } + + #endif + + #if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + + void vTraceSetStreamBufferName( void * pvStreamBuffer, + const char * szName ) + { + xTraceObjectSetNameWithoutHandle( pvStreamBuffer, szName ); + } + + void vTraceSetMessageBufferName( void * pvMessageBuffer, + const char * szName ) + { + xTraceObjectSetNameWithoutHandle( pvMessageBuffer, szName ); + } + + #endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + + #endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + + TraceHeapHandle_t xTraceKernelPortGetSystemHeapHandle( void ) + { + return pxKernelPortData->xSystemHeapHandle; + } + + #endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) */ + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) + + uint32_t prvTraceGetQueueNumber( void * handle ); + + #if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X ) + + extern unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue ); + extern void vQueueSetQueueNumber( xQueueHandle pxQueue, + unsigned char ucQueueNumber ); + extern unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ); + + uint32_t prvTraceGetQueueNumber( void * handle ) + { + return ( uint32_t ) ucQueueGetQueueNumber( handle ); + } + + #else /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X ) */ + + uint32_t prvTraceGetQueueNumber( void * handle ) + { + return ( uint32_t ) uxQueueGetQueueNumber( handle ); + } + + #endif /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X ) */ + + uint8_t prvTraceGetQueueType( void * pvQueue ) + { + /* This is either declared in header file in FreeRTOS 8 and later, or as extern above */ + return ucQueueGetQueueType( pvQueue ); + } + +/* Tasks */ + uint16_t prvTraceGetTaskNumberLow16( void * pvTask ) + { + return TRACE_GET_LOW16( uxTaskGetTaskNumber( pvTask ) ); + } + + uint16_t prvTraceGetTaskNumberHigh16( void * pvTask ) + { + return TRACE_GET_HIGH16( uxTaskGetTaskNumber( pvTask ) ); + } + + void prvTraceSetTaskNumberLow16( void * pvTask, + uint16_t uiValue ) + { + vTaskSetTaskNumber( pvTask, TRACE_SET_LOW16( uxTaskGetTaskNumber( pvTask ), uiValue ) ); + } + + void prvTraceSetTaskNumberHigh16( void * pvTask, + uint16_t uiValue ) + { + vTaskSetTaskNumber( pvTask, TRACE_SET_HIGH16( uxTaskGetTaskNumber( pvTask ), uiValue ) ); + } + + uint16_t prvTraceGetQueueNumberLow16( void * pvQueue ) + { + return TRACE_GET_LOW16( prvTraceGetQueueNumber( pvQueue ) ); + } + + uint16_t prvTraceGetQueueNumberHigh16( void * pvQueue ) + { + return TRACE_GET_HIGH16( prvTraceGetQueueNumber( pvQueue ) ); + } + + void prvTraceSetQueueNumberLow16( void * pvQueue, + uint16_t uiValue ) + { + vQueueSetQueueNumber( pvQueue, TRACE_SET_LOW16( prvTraceGetQueueNumber( pvQueue ), uiValue ) ); + } + + void prvTraceSetQueueNumberHigh16( void * pvQueue, + uint16_t uiValue ) + { + vQueueSetQueueNumber( pvQueue, TRACE_SET_HIGH16( prvTraceGetQueueNumber( pvQueue ), uiValue ) ); + } + + #if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + + uint16_t prvTraceGetTimerNumberLow16( void * pvTimer ) + { + return TRACE_GET_LOW16( uxTimerGetTimerNumber( pvTimer ) ); + } + + uint16_t prvTraceGetTimerNumberHigh16( void * pvTimer ) + { + return TRACE_GET_HIGH16( uxTimerGetTimerNumber( pvTimer ) ); + } + + void prvTraceSetTimerNumberLow16( void * pvTimer, + uint16_t uiValue ) + { + vTimerSetTimerNumber( pvTimer, TRACE_SET_LOW16( uxTimerGetTimerNumber( pvTimer ), uiValue ) ); + } + + void prvTraceSetTimerNumberHigh16( void * pvTimer, + uint16_t uiValue ) + { + vTimerSetTimerNumber( pvTimer, TRACE_SET_HIGH16( uxTimerGetTimerNumber( pvTimer ), uiValue ) ); + } + + #endif /* if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + + #if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + + uint16_t prvTraceGetEventGroupNumberLow16( void * pvEventGroup ) + { + return TRACE_GET_LOW16( uxEventGroupGetNumber( pvEventGroup ) ); + } + + uint16_t prvTraceGetEventGroupNumberHigh16( void * pvEventGroup ) + { + return TRACE_GET_HIGH16( uxEventGroupGetNumber( pvEventGroup ) ); + } + + void prvTraceSetEventGroupNumberLow16( void * pvEventGroup, + uint16_t uiValue ) + { + vEventGroupSetNumber( pvEventGroup, TRACE_SET_LOW16( uxEventGroupGetNumber( pvEventGroup ), uiValue ) ); + } + + void prvTraceSetEventGroupNumberHigh16( void * pvEventGroup, + uint16_t uiValue ) + { + vEventGroupSetNumber( pvEventGroup, TRACE_SET_HIGH16( uxEventGroupGetNumber( pvEventGroup ), uiValue ) ); + } + + #endif /* if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + + #if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + + uint16_t prvTraceGetStreamBufferNumberLow16( void * pvStreamBuffer ) + { + return TRACE_GET_LOW16( uxStreamBufferGetStreamBufferNumber( pvStreamBuffer ) ); + } + + uint16_t prvTraceGetStreamBufferNumberHigh16( void * pvStreamBuffer ) + { + return TRACE_GET_HIGH16( uxStreamBufferGetStreamBufferNumber( pvStreamBuffer ) ); + } + + void prvTraceSetStreamBufferNumberLow16( void * pvStreamBuffer, + uint16_t uiValue ) + { + vStreamBufferSetStreamBufferNumber( pvStreamBuffer, TRACE_SET_LOW16( uxStreamBufferGetStreamBufferNumber( pvStreamBuffer ), uiValue ) ); + } + + void prvTraceSetStreamBufferNumberHigh16( void * pvStreamBuffer, + uint16_t uiValue ) + { + vStreamBufferSetStreamBufferNumber( pvStreamBuffer, TRACE_SET_HIGH16( uxStreamBufferGetStreamBufferNumber( pvStreamBuffer ), uiValue ) ); + } + + #endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + + static TraceKernelPortTaskHandle_t xTzCtrlHandle = 0; /* TzCtrl task TCB */ + +/* Internal flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */ + int uiInEventGroupSetBitsFromISR = 0; + +/** + * @internal Class reference table + */ + traceObjectClass TraceQueueClassTable[ 5 ] = + { + TRACE_CLASS_QUEUE, + TRACE_CLASS_MUTEX, + TRACE_CLASS_SEMAPHORE, + TRACE_CLASS_SEMAPHORE, + TRACE_CLASS_MUTEX + }; + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + + void vTraceSetQueueName( void * pvQueue, + const char * szName ) + { + prvTraceSetObjectName( TRACE_CLASS_QUEUE, TRACE_GET_OBJECT_NUMBER( QUEUE, pvQueue ), szName ); + } + + void vTraceSetSemaphoreName( void * pvSemaphore, + const char * szName ) + { + prvTraceSetObjectName( TRACE_CLASS_SEMAPHORE, TRACE_GET_OBJECT_NUMBER( QUEUE, pvSemaphore ), szName ); + } + + void vTraceSetMutexName( void * pvMutex, + const char * szName ) + { + prvTraceSetObjectName( TRACE_CLASS_MUTEX, TRACE_GET_OBJECT_NUMBER( QUEUE, pvMutex ), szName ); + } + + #if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X ) + + void vTraceSetEventGroupName( void * pvEventGroup, + const char * szName ) + { + prvTraceSetObjectName( TRACE_CLASS_EVENTGROUP, TRACE_GET_OBJECT_NUMBER( EVENTGROUP, pvEventGroup ), szName ); + } + + #endif + + #if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) + + void vTraceSetStreamBufferName( void * pvStreamBuffer, + const char * szName ) + { + prvTraceSetObjectName( TRACE_CLASS_STREAMBUFFER, TRACE_GET_OBJECT_NUMBER( STREAMBUFFER, pvStreamBuffer ), szName ); + } + + void vTraceSetMessageBufferName( void * pvStreamBuffer, + const char * szName ) + { + prvTraceSetObjectName( TRACE_CLASS_MESSAGEBUFFER, TRACE_GET_OBJECT_NUMBER( STREAMBUFFER, pvStreamBuffer ), szName ); + } + + #endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */ + + #endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + + void * prvTraceGetCurrentTaskHandle() + { + return xTaskGetCurrentTaskHandle(); + } + + traceResult xTraceKernelPortInitialize( TraceKernelPortDataBuffer_t * pxBuffer ) + { + ( void ) pxBuffer; + + return TRC_SUCCESS; + } + + traceResult xTraceKernelPortEnable( void ) + { + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) + if( xTzCtrlHandle == 0 ) + { + #if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) + xTzCtrlHandle = xTaskCreateStatic( TzCtrl, STRING_CAST( "TzCtrl" ), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl ); + #else + xTaskCreate( TzCtrl, STRING_CAST( "TzCtrl" ), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, &xTzCtrlHandle ); + #endif + } + #else + ( void ) xTzCtrlHandle; + #endif + + return TRC_SUCCESS; + } + + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) + + static portTASK_FUNCTION( TzCtrl, pvParameters ) + { + ( void ) pvParameters; + + while( 1 ) + { + if( xTraceIsRecorderEnabled() ) + { + prvReportStackUsage(); + } + + vTaskDelay( TRC_CFG_CTRL_TASK_DELAY ); + } + } + + #endif /* if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + + traceResult xTraceKernelPortInitObjectPropertyTable() + { + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectClasses = TRACE_NCLASSES; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 0 ] = TRC_CFG_NQUEUE; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 1 ] = TRC_CFG_NSEMAPHORE; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 2 ] = TRC_CFG_NMUTEX; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 3 ] = TRC_CFG_NTASK; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 4 ] = TRC_CFG_NISR; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 5 ] = TRC_CFG_NTIMER; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 6 ] = TRC_CFG_NEVENTGROUP; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 7 ] = TRC_CFG_NSTREAMBUFFER; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 8 ] = TRC_CFG_NMESSAGEBUFFER; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 0 ] = TRC_CFG_NAME_LEN_QUEUE; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 1 ] = TRC_CFG_NAME_LEN_SEMAPHORE; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 2 ] = TRC_CFG_NAME_LEN_MUTEX; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 3 ] = TRC_CFG_NAME_LEN_TASK; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 4 ] = TRC_CFG_NAME_LEN_ISR; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 5 ] = TRC_CFG_NAME_LEN_TIMER; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 6 ] = TRC_CFG_NAME_LEN_EVENTGROUP; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 7 ] = TRC_CFG_NAME_LEN_STREAMBUFFER; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 8 ] = TRC_CFG_NAME_LEN_MESSAGEBUFFER; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 0 ] = PropertyTableSizeQueue; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 1 ] = PropertyTableSizeSemaphore; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 2 ] = PropertyTableSizeMutex; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 3 ] = PropertyTableSizeTask; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 4 ] = PropertyTableSizeISR; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 5 ] = PropertyTableSizeTimer; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 6 ] = PropertyTableSizeEventGroup; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 7 ] = PropertyTableSizeStreamBuffer; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 8 ] = PropertyTableSizeMessageBuffer; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 0 ] = StartIndexQueue; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 1 ] = StartIndexSemaphore; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 2 ] = StartIndexMutex; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 3 ] = StartIndexTask; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 4 ] = StartIndexISR; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 5 ] = StartIndexTimer; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 6 ] = StartIndexEventGroup; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 7 ] = StartIndexStreamBuffer; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 8 ] = StartIndexMessageBuffer; + RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE; + + return TRC_SUCCESS; + } + + traceResult xTraceKernelPortInitObjectHandleStack() + { + uint32_t i = 0; + + objectHandleStacks.indexOfNextAvailableHandle[ 0 ] = objectHandleStacks.lowestIndexOfClass[ 0 ] = 0; + objectHandleStacks.indexOfNextAvailableHandle[ 1 ] = objectHandleStacks.lowestIndexOfClass[ 1 ] = ( TRC_CFG_NQUEUE ); + objectHandleStacks.indexOfNextAvailableHandle[ 2 ] = objectHandleStacks.lowestIndexOfClass[ 2 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ); + objectHandleStacks.indexOfNextAvailableHandle[ 3 ] = objectHandleStacks.lowestIndexOfClass[ 3 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ); + objectHandleStacks.indexOfNextAvailableHandle[ 4 ] = objectHandleStacks.lowestIndexOfClass[ 4 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ); + objectHandleStacks.indexOfNextAvailableHandle[ 5 ] = objectHandleStacks.lowestIndexOfClass[ 5 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ); + objectHandleStacks.indexOfNextAvailableHandle[ 6 ] = objectHandleStacks.lowestIndexOfClass[ 6 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ); + objectHandleStacks.indexOfNextAvailableHandle[ 7 ] = objectHandleStacks.lowestIndexOfClass[ 7 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ); + objectHandleStacks.indexOfNextAvailableHandle[ 8 ] = objectHandleStacks.lowestIndexOfClass[ 8 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ) + ( TRC_CFG_NSTREAMBUFFER ); + + objectHandleStacks.highestIndexOfClass[ 0 ] = ( TRC_CFG_NQUEUE ) -1; + objectHandleStacks.highestIndexOfClass[ 1 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) -1; + objectHandleStacks.highestIndexOfClass[ 2 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) -1; + objectHandleStacks.highestIndexOfClass[ 3 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) -1; + objectHandleStacks.highestIndexOfClass[ 4 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) -1; + objectHandleStacks.highestIndexOfClass[ 5 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) -1; + objectHandleStacks.highestIndexOfClass[ 6 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ) -1; + objectHandleStacks.highestIndexOfClass[ 7 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ) + ( TRC_CFG_NSTREAMBUFFER ) -1; + objectHandleStacks.highestIndexOfClass[ 8 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ) + ( TRC_CFG_NSTREAMBUFFER ) + ( TRC_CFG_NMESSAGEBUFFER ) -1; + + for( i = 0; i < TRACE_NCLASSES; i++ ) + { + objectHandleStacks.handleCountWaterMarksOfClass[ i ] = 0; + } + + for( i = 0; i < TRACE_KERNEL_OBJECT_COUNT; i++ ) + { + objectHandleStacks.objectHandles[ i ] = 0; + } + + return TRC_SUCCESS; + } + + const char * pszTraceGetErrorNotEnoughHandles( traceObjectClass objectclass ) + { + switch( objectclass ) + { + case TRACE_CLASS_TASK: + return "Not enough TASK handles - increase TRC_CFG_NTASK in trcSnapshotConfig.h"; + + case TRACE_CLASS_ISR: + return "Not enough ISR handles - increase TRC_CFG_NISR in trcSnapshotConfig.h"; + + case TRACE_CLASS_SEMAPHORE: + return "Not enough SEMAPHORE handles - increase TRC_CFG_NSEMAPHORE in trcSnapshotConfig.h"; + + case TRACE_CLASS_MUTEX: + return "Not enough MUTEX handles - increase TRC_CFG_NMUTEX in trcSnapshotConfig.h"; + + case TRACE_CLASS_QUEUE: + return "Not enough QUEUE handles - increase TRC_CFG_NQUEUE in trcSnapshotConfig.h"; + + case TRACE_CLASS_TIMER: + return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h"; + + case TRACE_CLASS_EVENTGROUP: + return "Not enough EVENTGROUP handles - increase TRC_CFG_NEVENTGROUP in trcSnapshotConfig.h"; + + case TRACE_CLASS_STREAMBUFFER: + return "Not enough STREAMBUFFER handles - increase TRC_CFG_NSTREAMBUFFER in trcSnapshotConfig.h"; + + case TRACE_CLASS_MESSAGEBUFFER: + return "Not enough MESSAGEBUFFER handles - increase TRC_CFG_NMESSAGEBUFFER in trcSnapshotConfig.h"; + + default: + return "pszTraceGetErrorHandles: Invalid objectclass!"; + } + } + + #endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) */ + +#endif /* if ( defined( TRC_USE_TRACEALYZER_RECORDER ) && TRC_USE_TRACEALYZER_RECORDER == 1 ) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcMultiCoreEventBuffer.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcMultiCoreEventBuffer.c index 6cd5263ef..d114fecf6 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcMultiCoreEventBuffer.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcMultiCoreEventBuffer.c @@ -1,112 +1,117 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The interface for the multi-core event buffer. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -traceResult xTraceMultiCoreEventBufferInitialize(TraceMultiCoreEventBuffer_t* pxTraceMultiCoreEventBuffer, uint32_t uiOptions, - uint8_t* puiBuffer, uint32_t uiSize) -{ - uint32_t i; - - /* This should never fail */ - TRC_ASSERT(pxTraceMultiCoreEventBuffer != 0); - - /* This should never fail */ - TRC_ASSERT(puiBuffer != 0); - - uint32_t uiBufferSizePerCore = uiSize / TRC_CFG_CORE_COUNT; - - /* This should never fail */ - TRC_ASSERT(uiBufferSizePerCore != 0); - - for (i = 0; i < TRC_CFG_CORE_COUNT; i++) - { - /* Set the event buffer pointers to point into the allocated space we have been given, this ensures - * a flat memory layout necessary for usage in streaming snaphot. */ - pxTraceMultiCoreEventBuffer->xEventBuffer[i] = (TraceEventBuffer_t*)(&puiBuffer[i * uiBufferSizePerCore]); - - /* Initialize the event buffer structure with its memory buffer placed following its own structure data. */ - /* We need to check this */ - if (xTraceEventBufferInitialize(pxTraceMultiCoreEventBuffer->xEventBuffer[i], uiOptions, - &puiBuffer[(i * uiBufferSizePerCore) + sizeof(TraceEventBuffer_t)], - uiBufferSizePerCore - sizeof(TraceEventBuffer_t)) == TRC_FAIL) - { - return TRC_FAIL; - } - } - - return TRC_SUCCESS; -} - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -traceResult xTraceMultiCoreEventBufferPush(TraceMultiCoreEventBuffer_t* pxTraceMultiCoreEventBuffer, - void* pvData, uint32_t uiSize, int32_t* piBytesWritten) -{ - /* This should never fail */ - TRC_ASSERT(pxTraceMultiCoreEventBuffer != 0); - - TRC_ASSERT((TRC_CFG_GET_CURRENT_CORE()) < (TRC_CFG_CORE_COUNT)); - - return xTraceEventBufferPush(pxTraceMultiCoreEventBuffer->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], pvData, uiSize, piBytesWritten); -} - -#endif - -traceResult xTraceMultiCoreEventBufferTransfer(TraceMultiCoreEventBuffer_t* pxTraceMultiCoreEventBuffer, int32_t* piBytesWritten) -{ - int32_t iBytesWritten = 0; - uint32_t coreId; - - /* This should never fail */ - TRC_ASSERT(pxTraceMultiCoreEventBuffer != 0); - - /* This should never fail */ - TRC_ASSERT(piBytesWritten != 0); - - *piBytesWritten = 0; - - for (coreId = 0; coreId < TRC_CFG_CORE_COUNT; coreId++) - { - /* We need to check this */ - if (xTraceEventBufferTransfer(pxTraceMultiCoreEventBuffer->xEventBuffer[coreId], &iBytesWritten) == TRC_FAIL) - { - return TRC_FAIL; - } - - *piBytesWritten += iBytesWritten; - } - - return TRC_SUCCESS; -} - -traceResult xTraceMultiCoreEventBufferClear(TraceMultiCoreEventBuffer_t* pxTraceMultiCoreEventBuffer) -{ - uint32_t coreId; - - /* This should never fail */ - TRC_ASSERT(pxTraceMultiCoreEventBuffer != 0); - - for (coreId = 0; coreId < TRC_CFG_CORE_COUNT; coreId++) - { - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventBufferClear(pxTraceMultiCoreEventBuffer->xEventBuffer[coreId]) == TRC_SUCCESS); - } - - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The interface for the multi-core event buffer. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + traceResult xTraceMultiCoreEventBufferInitialize( TraceMultiCoreEventBuffer_t * pxTraceMultiCoreEventBuffer, + uint32_t uiOptions, + uint8_t * puiBuffer, + uint32_t uiSize ) + { + uint32_t i; + + /* This should never fail */ + TRC_ASSERT( pxTraceMultiCoreEventBuffer != 0 ); + + /* This should never fail */ + TRC_ASSERT( puiBuffer != 0 ); + + uint32_t uiBufferSizePerCore = uiSize / TRC_CFG_CORE_COUNT; + + /* This should never fail */ + TRC_ASSERT( uiBufferSizePerCore != 0 ); + + for( i = 0; i < TRC_CFG_CORE_COUNT; i++ ) + { + /* Set the event buffer pointers to point into the allocated space we have been given, this ensures + * a flat memory layout necessary for usage in streaming snaphot. */ + pxTraceMultiCoreEventBuffer->xEventBuffer[ i ] = ( TraceEventBuffer_t * ) ( &puiBuffer[ i * uiBufferSizePerCore ] ); + + /* Initialize the event buffer structure with its memory buffer placed following its own structure data. */ + /* We need to check this */ + if( xTraceEventBufferInitialize( pxTraceMultiCoreEventBuffer->xEventBuffer[ i ], uiOptions, + &puiBuffer[ ( i * uiBufferSizePerCore ) + sizeof( TraceEventBuffer_t ) ], + uiBufferSizePerCore - sizeof( TraceEventBuffer_t ) ) == TRC_FAIL ) + { + return TRC_FAIL; + } + } + + return TRC_SUCCESS; + } + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + + traceResult xTraceMultiCoreEventBufferPush( TraceMultiCoreEventBuffer_t * pxTraceMultiCoreEventBuffer, + void * pvData, + uint32_t uiSize, + int32_t * piBytesWritten ) + { + /* This should never fail */ + TRC_ASSERT( pxTraceMultiCoreEventBuffer != 0 ); + + TRC_ASSERT( ( TRC_CFG_GET_CURRENT_CORE() ) < ( TRC_CFG_CORE_COUNT ) ); + + return xTraceEventBufferPush( pxTraceMultiCoreEventBuffer->xEventBuffer[ TRC_CFG_GET_CURRENT_CORE() ], pvData, uiSize, piBytesWritten ); + } + + #endif /* if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) */ + + traceResult xTraceMultiCoreEventBufferTransfer( TraceMultiCoreEventBuffer_t * pxTraceMultiCoreEventBuffer, + int32_t * piBytesWritten ) + { + int32_t iBytesWritten = 0; + uint32_t coreId; + + /* This should never fail */ + TRC_ASSERT( pxTraceMultiCoreEventBuffer != 0 ); + + /* This should never fail */ + TRC_ASSERT( piBytesWritten != 0 ); + + *piBytesWritten = 0; + + for( coreId = 0; coreId < TRC_CFG_CORE_COUNT; coreId++ ) + { + /* We need to check this */ + if( xTraceEventBufferTransfer( pxTraceMultiCoreEventBuffer->xEventBuffer[ coreId ], &iBytesWritten ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + *piBytesWritten += iBytesWritten; + } + + return TRC_SUCCESS; + } + + traceResult xTraceMultiCoreEventBufferClear( TraceMultiCoreEventBuffer_t * pxTraceMultiCoreEventBuffer ) + { + uint32_t coreId; + + /* This should never fail */ + TRC_ASSERT( pxTraceMultiCoreEventBuffer != 0 ); + + for( coreId = 0; coreId < TRC_CFG_CORE_COUNT; coreId++ ) + { + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEventBufferClear( pxTraceMultiCoreEventBuffer->xEventBuffer[ coreId ] ) == TRC_SUCCESS ); + } + + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcObject.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcObject.c index a5f16b6bc..948bfc6e3 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcObject.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcObject.c @@ -1,349 +1,382 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for strings. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#include - -#ifndef TRC_SEND_NAME_ONLY_ON_DELETE -#define TRC_SEND_NAME_ONLY_ON_DELETE 0 -#endif - -traceResult prvTraceObjectSendState(uint32_t uiEventCode, void* pvObject, TraceUnsignedBaseType_t uxState); -traceResult prvTraceObjectSendNameEvent(void* pvObject, const char* szName); - -traceResult xTraceObjectRegisterInternal(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxStateCount, TraceUnsignedBaseType_t uxStates[], TraceUnsignedBaseType_t uxOptions, TraceObjectHandle_t* pxObjectHandle) -{ - TraceEntryHandle_t xEntryHandle; - TraceEventHandle_t xEventHandle = 0; - TraceUnsignedBaseType_t i; - - TRACE_ALLOC_CRITICAL_SECTION(); - - /* This should never fail */ - TRC_ASSERT(pxObjectHandle != 0); - - /* This should never fail */ - TRC_ASSERT(uxStateCount <= (TRC_ENTRY_TABLE_STATE_COUNT)); - - TRACE_ENTER_CRITICAL_SECTION(); - - if (pvObject != 0) - { - /* An address was supplied */ - if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL) - { - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - } - else - { - /* No address was supplied */ - if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL) - { - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - } - - for (i = 0; i < uxStateCount; i++) - { - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, i, uxStates[i]) == TRC_SUCCESS); - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions(xEntryHandle, uxOptions) == TRC_SUCCESS); - - *pxObjectHandle = (TraceObjectHandle_t)xEntryHandle; - - TRACE_EXIT_CRITICAL_SECTION(); - - if (szName != 0 && szName[0] != 0) - { - /* Not a null or empty string */ - /* This will set the symbol and create an event for it */ - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetName((TraceObjectHandle_t)xEntryHandle, szName) == TRC_SUCCESS); - } - - /* Send the create event, if possible */ - /*We need to check this */ - if (xTraceEventBegin(uiEventCode, sizeof(void*) + uxStateCount * sizeof(TraceUnsignedBaseType_t) + sizeof(TraceUnsignedBaseType_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pvObject); - for (i = 0; i < uxStateCount; i++) - { - xTraceEventAddUnsignedBaseType(xEventHandle, uxStates[i]); - } - xTraceEventAddUnsignedBaseType(xEventHandle, uxOptions); - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -traceResult xTraceObjectRegister(uint32_t uiEventCode, void *pvObject, const char* szName, TraceUnsignedBaseType_t uxState, TraceObjectHandle_t *pxObjectHandle) -{ - TraceEntryHandle_t xEntryHandle; - - TRACE_ALLOC_CRITICAL_SECTION(); - - /* This should never fail */ - TRC_ASSERT(pxObjectHandle != 0); - - TRACE_ENTER_CRITICAL_SECTION(); - - if (pvObject != 0) - { - /* An address was supplied */ - if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL) - { - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - } - else - { - /* No address was supplied */ - if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL) - { - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, 0, uxState) == TRC_SUCCESS); - - *pxObjectHandle = (TraceObjectHandle_t)xEntryHandle; - - TRACE_EXIT_CRITICAL_SECTION(); - - if (szName != 0 && szName[0] != 0) - { - /* Not a null or empty string */ - /* This will set the symbol and create an event for it */ - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetName((TraceObjectHandle_t)xEntryHandle, szName) == TRC_SUCCESS); - } - - /* Send the create event, if possible */ - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(prvTraceObjectSendState(uiEventCode, pvObject, uxState) == TRC_SUCCESS); - - return TRC_SUCCESS; -} - -traceResult xTraceObjectUnregister(TraceObjectHandle_t xObjectHandle, uint32_t uiEventCode, TraceUnsignedBaseType_t uxState) -{ - void* pvObject; - const char *szName; - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xObjectHandle, &pvObject) == TRC_SUCCESS); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetSymbol((TraceEntryHandle_t)xObjectHandle, &szName) == TRC_SUCCESS); - -#if (TRC_SEND_NAME_ONLY_ON_DELETE == 1) - /* Send name event because this is a delete */ - /* This should never fail */ - TRC_ASSERT(prvTraceObjectSendNameEvent(pvObject, szName) == TRC_SUCCESS); -#endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 1) */ - - /* Send the delete event, if possible */ - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(prvTraceObjectSendState(uiEventCode, pvObject, uxState) == TRC_SUCCESS); - - return xTraceEntryDelete(xObjectHandle); -} - -traceResult xTraceObjectSetName(TraceObjectHandle_t xObjectHandle, const char* szName) -{ - void* pvObject; - - if (szName == 0) - { - szName = ""; - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xObjectHandle, &pvObject) == TRC_SUCCESS); - -#if (TRC_SEND_NAME_ONLY_ON_DELETE == 0) - /* Send name event now since we don't do it on delete events */ - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(prvTraceObjectSendNameEvent(pvObject, szName) == TRC_SUCCESS); -#endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 0) */ - - return xTraceEntrySetSymbol((TraceEntryHandle_t)xObjectHandle, szName); -} - -traceResult xTraceObjectRegisterWithoutHandle(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxState) -{ - TraceObjectHandle_t xObjectHandle; - - return xTraceObjectRegister(uiEventCode, pvObject, szName, uxState, &xObjectHandle); -} - -traceResult xTraceObjectUnregisterWithoutHandle(uint32_t uiEventCode, void* pvObject, TraceUnsignedBaseType_t uxState) -{ - TraceEntryHandle_t xEntryHandle; - traceResult xResult; - - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ENTER_CRITICAL_SECTION(); - - if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL) - { - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - - xResult = xTraceObjectUnregister((TraceObjectHandle_t)xEntryHandle, uiEventCode, uxState); - - TRACE_EXIT_CRITICAL_SECTION(); - - return xResult; -} - -traceResult xTraceObjectSetNameWithoutHandle(void* pvObject, const char* szName) -{ - TraceEntryHandle_t xEntryHandle; - traceResult xResult; - - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ENTER_CRITICAL_SECTION(); - - if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL) - { - /* No previous entry found. Create one. */ - if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL) - { - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - } - - xResult = xTraceObjectSetName((TraceObjectHandle_t)xEntryHandle, szName); - - TRACE_EXIT_CRITICAL_SECTION(); - - return xResult; -} - -traceResult xTraceObjectSetSpecificStateWithoutHandle(void* pvObject, uint32_t uiIndex, TraceUnsignedBaseType_t uxState) -{ - TraceEntryHandle_t xEntryHandle; - traceResult xResult; - - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ENTER_CRITICAL_SECTION(); - - if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL) - { - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - - xResult = xTraceObjectSetSpecificState((TraceObjectHandle_t)xEntryHandle, uiIndex, uxState); - - TRACE_EXIT_CRITICAL_SECTION(); - - return xResult; -} - -traceResult xTraceObjectSetOptionsWithoutHandle(void* pvObject, uint32_t uiMask) -{ - TraceEntryHandle_t xEntryHandle; - traceResult xResult; - - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ENTER_CRITICAL_SECTION(); - - if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL) - { - /* No previous entry found. Create one. */ - if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL) - { - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - } - - xResult = xTraceObjectSetOptions((TraceObjectHandle_t)xEntryHandle, uiMask); - - TRACE_EXIT_CRITICAL_SECTION(); - - return xResult; -} - -traceResult prvTraceObjectSendState(uint32_t uiEventCode, void* pvObject, TraceUnsignedBaseType_t uxState) -{ - TraceEventHandle_t xEventHandle = 0; - - if (xTraceEventBegin(uiEventCode, sizeof(void*) + sizeof(TraceUnsignedBaseType_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pvObject); - xTraceEventAddUnsignedBaseType(xEventHandle, uxState); - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -traceResult prvTraceObjectSendNameEvent(void* pvObject, const char* szName) -{ - uint32_t i = 0, uiLength = 0, uiValue = 0; - TraceEventHandle_t xEventHandle = 0; - - for (i = 0; (szName[i] != 0) && (i < (TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE)); i++) {} - - uiLength = i; - - if (xTraceEventBegin(PSF_EVENT_OBJ_NAME, sizeof(void*) + uiLength, &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pvObject); - xTraceEventAddData(xEventHandle, (void*)szName, uiLength); - - /* Check if we can truncate */ - xTraceEventPayloadRemaining(xEventHandle, &uiValue); - if (uiValue > 0) - { - xTraceEventAdd8(xEventHandle, 0); - } - - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for strings. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #include + + #ifndef TRC_SEND_NAME_ONLY_ON_DELETE + #define TRC_SEND_NAME_ONLY_ON_DELETE 0 + #endif + + traceResult prvTraceObjectSendState( uint32_t uiEventCode, + void * pvObject, + TraceUnsignedBaseType_t uxState ); + traceResult prvTraceObjectSendNameEvent( void * pvObject, + const char * szName ); + + traceResult xTraceObjectRegisterInternal( uint32_t uiEventCode, + void * pvObject, + const char * szName, + TraceUnsignedBaseType_t uxStateCount, + TraceUnsignedBaseType_t uxStates[], + TraceUnsignedBaseType_t uxOptions, + TraceObjectHandle_t * pxObjectHandle ) + { + TraceEntryHandle_t xEntryHandle; + TraceEventHandle_t xEventHandle = 0; + TraceUnsignedBaseType_t i; + + TRACE_ALLOC_CRITICAL_SECTION(); + + /* This should never fail */ + TRC_ASSERT( pxObjectHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( uxStateCount <= ( TRC_ENTRY_TABLE_STATE_COUNT ) ); + + TRACE_ENTER_CRITICAL_SECTION(); + + if( pvObject != 0 ) + { + /* An address was supplied */ + if( xTraceEntryCreateWithAddress( pvObject, &xEntryHandle ) == TRC_FAIL ) + { + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + } + else + { + /* No address was supplied */ + if( xTraceEntryCreate( &xEntryHandle ) == TRC_FAIL ) + { + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + } + + for( i = 0; i < uxStateCount; i++ ) + { + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( xEntryHandle, i, uxStates[ i ] ) == TRC_SUCCESS ); + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetOptions( xEntryHandle, uxOptions ) == TRC_SUCCESS ); + + *pxObjectHandle = ( TraceObjectHandle_t ) xEntryHandle; + + TRACE_EXIT_CRITICAL_SECTION(); + + if( ( szName != 0 ) && ( szName[ 0 ] != 0 ) ) + { + /* Not a null or empty string */ + /* This will set the symbol and create an event for it */ + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceObjectSetName( ( TraceObjectHandle_t ) xEntryHandle, szName ) == TRC_SUCCESS ); + } + + /* Send the create event, if possible */ + /*We need to check this */ + if( xTraceEventBegin( uiEventCode, sizeof( void * ) + uxStateCount * sizeof( TraceUnsignedBaseType_t ) + sizeof( TraceUnsignedBaseType_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pvObject ); + + for( i = 0; i < uxStateCount; i++ ) + { + xTraceEventAddUnsignedBaseType( xEventHandle, uxStates[ i ] ); + } + + xTraceEventAddUnsignedBaseType( xEventHandle, uxOptions ); + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + traceResult xTraceObjectRegister( uint32_t uiEventCode, + void * pvObject, + const char * szName, + TraceUnsignedBaseType_t uxState, + TraceObjectHandle_t * pxObjectHandle ) + { + TraceEntryHandle_t xEntryHandle; + + TRACE_ALLOC_CRITICAL_SECTION(); + + /* This should never fail */ + TRC_ASSERT( pxObjectHandle != 0 ); + + TRACE_ENTER_CRITICAL_SECTION(); + + if( pvObject != 0 ) + { + /* An address was supplied */ + if( xTraceEntryCreateWithAddress( pvObject, &xEntryHandle ) == TRC_FAIL ) + { + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + } + else + { + /* No address was supplied */ + if( xTraceEntryCreate( &xEntryHandle ) == TRC_FAIL ) + { + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( xEntryHandle, 0, uxState ) == TRC_SUCCESS ); + + *pxObjectHandle = ( TraceObjectHandle_t ) xEntryHandle; + + TRACE_EXIT_CRITICAL_SECTION(); + + if( ( szName != 0 ) && ( szName[ 0 ] != 0 ) ) + { + /* Not a null or empty string */ + /* This will set the symbol and create an event for it */ + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceObjectSetName( ( TraceObjectHandle_t ) xEntryHandle, szName ) == TRC_SUCCESS ); + } + + /* Send the create event, if possible */ + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( prvTraceObjectSendState( uiEventCode, pvObject, uxState ) == TRC_SUCCESS ); + + return TRC_SUCCESS; + } + + traceResult xTraceObjectUnregister( TraceObjectHandle_t xObjectHandle, + uint32_t uiEventCode, + TraceUnsignedBaseType_t uxState ) + { + void * pvObject; + const char * szName; + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetAddress( ( TraceEntryHandle_t ) xObjectHandle, &pvObject ) == TRC_SUCCESS ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetSymbol( ( TraceEntryHandle_t ) xObjectHandle, &szName ) == TRC_SUCCESS ); + + #if ( TRC_SEND_NAME_ONLY_ON_DELETE == 1 ) + /* Send name event because this is a delete */ + /* This should never fail */ + TRC_ASSERT( prvTraceObjectSendNameEvent( pvObject, szName ) == TRC_SUCCESS ); + #endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 1) */ + + /* Send the delete event, if possible */ + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( prvTraceObjectSendState( uiEventCode, pvObject, uxState ) == TRC_SUCCESS ); + + return xTraceEntryDelete( xObjectHandle ); + } + + traceResult xTraceObjectSetName( TraceObjectHandle_t xObjectHandle, + const char * szName ) + { + void * pvObject; + + if( szName == 0 ) + { + szName = ""; + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetAddress( ( TraceEntryHandle_t ) xObjectHandle, &pvObject ) == TRC_SUCCESS ); + + #if ( TRC_SEND_NAME_ONLY_ON_DELETE == 0 ) + /* Send name event now since we don't do it on delete events */ + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( prvTraceObjectSendNameEvent( pvObject, szName ) == TRC_SUCCESS ); + #endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 0) */ + + return xTraceEntrySetSymbol( ( TraceEntryHandle_t ) xObjectHandle, szName ); + } + + traceResult xTraceObjectRegisterWithoutHandle( uint32_t uiEventCode, + void * pvObject, + const char * szName, + TraceUnsignedBaseType_t uxState ) + { + TraceObjectHandle_t xObjectHandle; + + return xTraceObjectRegister( uiEventCode, pvObject, szName, uxState, &xObjectHandle ); + } + + traceResult xTraceObjectUnregisterWithoutHandle( uint32_t uiEventCode, + void * pvObject, + TraceUnsignedBaseType_t uxState ) + { + TraceEntryHandle_t xEntryHandle; + traceResult xResult; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + if( xTraceEntryFind( pvObject, &xEntryHandle ) == TRC_FAIL ) + { + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + + xResult = xTraceObjectUnregister( ( TraceObjectHandle_t ) xEntryHandle, uiEventCode, uxState ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return xResult; + } + + traceResult xTraceObjectSetNameWithoutHandle( void * pvObject, + const char * szName ) + { + TraceEntryHandle_t xEntryHandle; + traceResult xResult; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + if( xTraceEntryFind( pvObject, &xEntryHandle ) == TRC_FAIL ) + { + /* No previous entry found. Create one. */ + if( xTraceEntryCreateWithAddress( pvObject, &xEntryHandle ) == TRC_FAIL ) + { + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + } + + xResult = xTraceObjectSetName( ( TraceObjectHandle_t ) xEntryHandle, szName ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return xResult; + } + + traceResult xTraceObjectSetSpecificStateWithoutHandle( void * pvObject, + uint32_t uiIndex, + TraceUnsignedBaseType_t uxState ) + { + TraceEntryHandle_t xEntryHandle; + traceResult xResult; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + if( xTraceEntryFind( pvObject, &xEntryHandle ) == TRC_FAIL ) + { + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + + xResult = xTraceObjectSetSpecificState( ( TraceObjectHandle_t ) xEntryHandle, uiIndex, uxState ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return xResult; + } + + traceResult xTraceObjectSetOptionsWithoutHandle( void * pvObject, + uint32_t uiMask ) + { + TraceEntryHandle_t xEntryHandle; + traceResult xResult; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + if( xTraceEntryFind( pvObject, &xEntryHandle ) == TRC_FAIL ) + { + /* No previous entry found. Create one. */ + if( xTraceEntryCreateWithAddress( pvObject, &xEntryHandle ) == TRC_FAIL ) + { + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + } + + xResult = xTraceObjectSetOptions( ( TraceObjectHandle_t ) xEntryHandle, uiMask ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return xResult; + } + + traceResult prvTraceObjectSendState( uint32_t uiEventCode, + void * pvObject, + TraceUnsignedBaseType_t uxState ) + { + TraceEventHandle_t xEventHandle = 0; + + if( xTraceEventBegin( uiEventCode, sizeof( void * ) + sizeof( TraceUnsignedBaseType_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pvObject ); + xTraceEventAddUnsignedBaseType( xEventHandle, uxState ); + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + traceResult prvTraceObjectSendNameEvent( void * pvObject, + const char * szName ) + { + uint32_t i = 0, uiLength = 0, uiValue = 0; + TraceEventHandle_t xEventHandle = 0; + + for( i = 0; ( szName[ i ] != 0 ) && ( i < ( TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE ) ); i++ ) + { + } + + uiLength = i; + + if( xTraceEventBegin( PSF_EVENT_OBJ_NAME, sizeof( void * ) + uiLength, &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pvObject ); + xTraceEventAddData( xEventHandle, ( void * ) szName, uiLength ); + + /* Check if we can truncate */ + xTraceEventPayloadRemaining( xEventHandle, &uiValue ); + + if( uiValue > 0 ) + { + xTraceEventAdd8( xEventHandle, 0 ); + } + + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcPrint.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcPrint.c index c693719df..c6098c02b 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcPrint.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcPrint.c @@ -1,314 +1,330 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for print. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) - -#include - -static traceResult prvTraceVPrintF(TraceStringHandle_t xChannel, const char* szFormat, uint32_t uiLength, uint32_t uiArgs, va_list *pxVL); - -typedef struct TracePrintInfo -{ - TraceStringHandle_t defaultChannel; - TraceStringHandle_t consoleChannel; -} TracePrintInfo_t; - -static TracePrintInfo_t *pxPrintInfo; - -traceResult xTracePrintInitialize(TracePrintBuffer_t *pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TracePrintBuffer_t, TracePrintInfo_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - pxPrintInfo = (TracePrintInfo_t*)pxBuffer; - pxPrintInfo->defaultChannel = 0; - pxPrintInfo->consoleChannel = 0; - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_PRINT); - - return TRC_SUCCESS; -} - -/****************************************************************************** - * xTracePrint - * - * Generates "User Events", with unformatted text. - * - * User Events can be used for very efficient application logging, and are shown - * as yellow labels in the main trace view. - * - * You may group User Events into User Event Channels. The yellow User Event - * labels shows the logged string, preceded by the channel name within - * brackets. For example: - * - * "[MyChannel] Hello World!" - * - * The User Event Channels are shown in the View Filter, which makes it easy to - * select what User Events you wish to display. User Event Channels are created - * using xTraceStringRegister(). - * - * Example: - * - * TraceStringHandle_t xChannel = xTraceStringRegister("MyChannel"); - * ... - * xTracePrint(xChannel, "Hello World!"); - * - ******************************************************************************/ -traceResult xTracePrint(TraceStringHandle_t xChannel, const char* szString) -{ - uint32_t uiLength = 0; - uint32_t i = 0; - - /* We need to check this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_PRINT)) - { - return TRC_FAIL; - } - - if (szString == 0) - { - szString = ""; - } - - while ((szString[i] != 0) && (i < 128)) - { - i++; - } - - uiLength = i + 1; /* Null termination */ - - return prvTraceVPrintF(xChannel, szString, uiLength, 0, (va_list*)0); -} - -/******************************************************************************* -* xTraceConsoleChannelPrintF -* -* Wrapper for vTracePrint, using the default channel. Can be used as a drop-in -* replacement for printf and similar functions, e.g. in a debug logging macro. -* -* Example: -* -* // Old: #define LogString debug_console_printf -* -* // New, log to Tracealyzer instead: -* #define LogString xTraceConsoleChannelPrintF -* ... -* LogString("My value is: %d", myValue); -******************************************************************************/ -traceResult xTraceConsoleChannelPrintF(const char* szFormat, ...) -{ - traceResult xResult; - va_list xVL; - - /* We need to check this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_PRINT)) - { - return TRC_FAIL; - } - - if (pxPrintInfo->consoleChannel == 0) - { - if (xTraceStringRegister("Debug Console", &pxPrintInfo->consoleChannel) == TRC_FAIL) - { - return TRC_FAIL; - } - } - - va_start(xVL, szFormat); - xResult = xTraceVPrintF(pxPrintInfo->consoleChannel, szFormat, xVL); - va_end(xVL); - - return xResult; -} - -/****************************************************************************** - * xTracePrintF - * - * Generates "User Events", with formatted text and data, similar to a "printf". - * It is very fast since the actual formatting is done on the host side when the - * trace is displayed. - * - * User Events can be used for very efficient application logging, and are shown - * as yellow labels in the main trace view. - * An advantage of User Events is that data can be plotted in the "User Event - * Signal Plot" view, visualizing any data you log as User Events, discrete - * states or control system signals (e.g. system inputs or outputs). - * - * You may group User Events into User Event Channels. The yellow User Event - * labels show the logged string, preceded by the channel name within brackets. - * - * Example: - * - * "[MyChannel] Hello World!" - * - * The User Event Channels are shown in the View Filter, which makes it easy to - * select what User Events you wish to display. User Event Channels are created - * using xTraceStringRegister(). - * - * Example: - * - * TraceStringHandle_t adc_uechannel = xTraceStringRegister("ADC User Events"); - * ... - * xTracePrintF(adc_uechannel, - * "ADC channel %d: %d volts", - * ch, adc_reading); - * - * All data arguments are assumed to be 32 bit wide. The following formats are - * supported: - * %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> " -42" - * %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> " 42" - * %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> " 2A" - * %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> " 2a" - * %s - string (currently, this must be an earlier stored symbol name) - * - * Up to 15 data arguments are allowed, with a total size of maximum 60 byte - * including 8 byte for the base event fields and the format string. So with - * one data argument, the maximum string length is 48 chars. If this is exceeded - * the string is truncated (4 bytes at a time). - * - ******************************************************************************/ -traceResult xTracePrintF(TraceStringHandle_t xChannel, const char* szFormat, ...) -{ - traceResult xResult; - va_list xVL; - - /* We need to check this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_PRINT)) - { - return TRC_FAIL; - } - - va_start(xVL, szFormat); - xResult = xTraceVPrintF(xChannel, szFormat, xVL); - va_end(xVL); - - return xResult; -} - -/****************************************************************************** - * xTraceVPrintF - * - * xTracePrintF variant that accepts a va_list. - * See xTraceVPrintF documentation for further details. - * - ******************************************************************************/ -traceResult xTraceVPrintF(TraceStringHandle_t xChannel, const char* szFormat, va_list xVL) -{ - uint32_t i = 0; - uint32_t uiArgs = 0; - uint32_t uiLength; - - /* We need to check this */ - if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_PRINT)) - { - return TRC_FAIL; - } - - if (szFormat == 0) - { - szFormat = ""; - } - - /* Count the number of arguments in the format string (e.g., %d) */ - for (i = 0; (szFormat[i] != 0) && (i < 128); i++) - { - if (szFormat[i] == '%') - { - if (szFormat[i + 1] == 0) - { - /* Found end of string, let for loop detect it */ - continue; - } - - if (szFormat[i + 1] != '%') - { - uiArgs++; /* Found an argument */ - } - - i++; /* Move past format specifier or non-argument '%' */ - } - } - - uiLength = i + 1; /* Null termination */ - - return prvTraceVPrintF(xChannel, szFormat, uiLength, uiArgs, &xVL); -} - -static traceResult prvTraceVPrintF(TraceStringHandle_t xChannel, const char* szFormat, uint32_t uiLength, uint32_t uiArgs, va_list *pxVL) -{ - TraceEventHandle_t xEventHandle = 0; - uint32_t i, uiRemaining; - uint32_t uiValue; - uint32_t uiEventCode = PSF_EVENT_USER_EVENT + 1 + uiArgs; /* Add channel (1) */ - uint32_t uiSize = sizeof(void*) + uiArgs * sizeof(TraceUnsignedBaseType_t) + uiLength; /* Add channel (sizeof(void*)) */ - - if (xChannel == 0) - { - if (pxPrintInfo->defaultChannel == 0) - { - /* Channel is not present */ - if (xTraceStringRegister("Default", &pxPrintInfo->defaultChannel) == TRC_FAIL) - { - return TRC_FAIL; - } - } - - xChannel = pxPrintInfo->defaultChannel; - } - - /* Added channel to uiEventCode and uiSize */ - if (xTraceEventBegin(uiEventCode, uiSize , &xEventHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - /* Add xChannel */ - xTraceEventAddPointer(xEventHandle, (void*)xChannel); - - /* Add all arguments */ - for (i = 0; i < uiArgs; i++) - { - xTraceEventAddUnsignedBaseType(xEventHandle, va_arg(*pxVL, TraceUnsignedBaseType_t)); - } - - xTraceEventPayloadRemaining(xEventHandle, &uiRemaining); - if (uiRemaining < uiLength) - { - uiLength = uiRemaining - 1; /* Make room for null termination */ - } - - /* Add format string */ - xTraceEventAddData(xEventHandle, (void*)szFormat, uiLength); - - /* Check if we can truncate */ - xTraceEventPayloadRemaining(xEventHandle, &uiValue); - if (uiValue > 0) - { - xTraceEventAdd8(xEventHandle, 0); - } - - xTraceEventEnd(xEventHandle); - - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for print. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) + + #include + + static traceResult prvTraceVPrintF( TraceStringHandle_t xChannel, + const char * szFormat, + uint32_t uiLength, + uint32_t uiArgs, + va_list * pxVL ); + + typedef struct TracePrintInfo + { + TraceStringHandle_t defaultChannel; + TraceStringHandle_t consoleChannel; + } TracePrintInfo_t; + + static TracePrintInfo_t * pxPrintInfo; + + traceResult xTracePrintInitialize( TracePrintBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TracePrintBuffer_t, TracePrintInfo_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + pxPrintInfo = ( TracePrintInfo_t * ) pxBuffer; + pxPrintInfo->defaultChannel = 0; + pxPrintInfo->consoleChannel = 0; + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_PRINT ); + + return TRC_SUCCESS; + } + +/****************************************************************************** +* xTracePrint +* +* Generates "User Events", with unformatted text. +* +* User Events can be used for very efficient application logging, and are shown +* as yellow labels in the main trace view. +* +* You may group User Events into User Event Channels. The yellow User Event +* labels shows the logged string, preceded by the channel name within +* brackets. For example: +* +* "[MyChannel] Hello World!" +* +* The User Event Channels are shown in the View Filter, which makes it easy to +* select what User Events you wish to display. User Event Channels are created +* using xTraceStringRegister(). +* +* Example: +* +* TraceStringHandle_t xChannel = xTraceStringRegister("MyChannel"); +* ... +* xTracePrint(xChannel, "Hello World!"); +* +******************************************************************************/ + traceResult xTracePrint( TraceStringHandle_t xChannel, + const char * szString ) + { + uint32_t uiLength = 0; + uint32_t i = 0; + + /* We need to check this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_PRINT ) ) + { + return TRC_FAIL; + } + + if( szString == 0 ) + { + szString = ""; + } + + while( ( szString[ i ] != 0 ) && ( i < 128 ) ) + { + i++; + } + + uiLength = i + 1; /* Null termination */ + + return prvTraceVPrintF( xChannel, szString, uiLength, 0, ( va_list * ) 0 ); + } + +/******************************************************************************* + * xTraceConsoleChannelPrintF + * + * Wrapper for vTracePrint, using the default channel. Can be used as a drop-in + * replacement for printf and similar functions, e.g. in a debug logging macro. + * + * Example: + * + * // Old: #define LogString debug_console_printf + * + * // New, log to Tracealyzer instead: + * #define LogString xTraceConsoleChannelPrintF + * ... + * LogString("My value is: %d", myValue); + ******************************************************************************/ + traceResult xTraceConsoleChannelPrintF( const char * szFormat, + ... ) + { + traceResult xResult; + va_list xVL; + + /* We need to check this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_PRINT ) ) + { + return TRC_FAIL; + } + + if( pxPrintInfo->consoleChannel == 0 ) + { + if( xTraceStringRegister( "Debug Console", &pxPrintInfo->consoleChannel ) == TRC_FAIL ) + { + return TRC_FAIL; + } + } + + va_start( xVL, szFormat ); + xResult = xTraceVPrintF( pxPrintInfo->consoleChannel, szFormat, xVL ); + va_end( xVL ); + + return xResult; + } + +/****************************************************************************** +* xTracePrintF +* +* Generates "User Events", with formatted text and data, similar to a "printf". +* It is very fast since the actual formatting is done on the host side when the +* trace is displayed. +* +* User Events can be used for very efficient application logging, and are shown +* as yellow labels in the main trace view. +* An advantage of User Events is that data can be plotted in the "User Event +* Signal Plot" view, visualizing any data you log as User Events, discrete +* states or control system signals (e.g. system inputs or outputs). +* +* You may group User Events into User Event Channels. The yellow User Event +* labels show the logged string, preceded by the channel name within brackets. +* +* Example: +* +* "[MyChannel] Hello World!" +* +* The User Event Channels are shown in the View Filter, which makes it easy to +* select what User Events you wish to display. User Event Channels are created +* using xTraceStringRegister(). +* +* Example: +* +* TraceStringHandle_t adc_uechannel = xTraceStringRegister("ADC User Events"); +* ... +* xTracePrintF(adc_uechannel, +* "ADC channel %d: %d volts", +* ch, adc_reading); +* +* All data arguments are assumed to be 32 bit wide. The following formats are +* supported: +* %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> " -42" +* %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> " 42" +* %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> " 2A" +* %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> " 2a" +* %s - string (currently, this must be an earlier stored symbol name) +* +* Up to 15 data arguments are allowed, with a total size of maximum 60 byte +* including 8 byte for the base event fields and the format string. So with +* one data argument, the maximum string length is 48 chars. If this is exceeded +* the string is truncated (4 bytes at a time). +* +******************************************************************************/ + traceResult xTracePrintF( TraceStringHandle_t xChannel, + const char * szFormat, + ... ) + { + traceResult xResult; + va_list xVL; + + /* We need to check this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_PRINT ) ) + { + return TRC_FAIL; + } + + va_start( xVL, szFormat ); + xResult = xTraceVPrintF( xChannel, szFormat, xVL ); + va_end( xVL ); + + return xResult; + } + +/****************************************************************************** +* xTraceVPrintF +* +* xTracePrintF variant that accepts a va_list. +* See xTraceVPrintF documentation for further details. +* +******************************************************************************/ + traceResult xTraceVPrintF( TraceStringHandle_t xChannel, + const char * szFormat, + va_list xVL ) + { + uint32_t i = 0; + uint32_t uiArgs = 0; + uint32_t uiLength; + + /* We need to check this */ + if( !xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_PRINT ) ) + { + return TRC_FAIL; + } + + if( szFormat == 0 ) + { + szFormat = ""; + } + + /* Count the number of arguments in the format string (e.g., %d) */ + for( i = 0; ( szFormat[ i ] != 0 ) && ( i < 128 ); i++ ) + { + if( szFormat[ i ] == '%' ) + { + if( szFormat[ i + 1 ] == 0 ) + { + /* Found end of string, let for loop detect it */ + continue; + } + + if( szFormat[ i + 1 ] != '%' ) + { + uiArgs++; /* Found an argument */ + } + + i++; /* Move past format specifier or non-argument '%' */ + } + } + + uiLength = i + 1; /* Null termination */ + + return prvTraceVPrintF( xChannel, szFormat, uiLength, uiArgs, &xVL ); + } + + static traceResult prvTraceVPrintF( TraceStringHandle_t xChannel, + const char * szFormat, + uint32_t uiLength, + uint32_t uiArgs, + va_list * pxVL ) + { + TraceEventHandle_t xEventHandle = 0; + uint32_t i, uiRemaining; + uint32_t uiValue; + uint32_t uiEventCode = PSF_EVENT_USER_EVENT + 1 + uiArgs; /* Add channel (1) */ + uint32_t uiSize = sizeof( void * ) + uiArgs * sizeof( TraceUnsignedBaseType_t ) + uiLength; /* Add channel (sizeof(void*)) */ + + if( xChannel == 0 ) + { + if( pxPrintInfo->defaultChannel == 0 ) + { + /* Channel is not present */ + if( xTraceStringRegister( "Default", &pxPrintInfo->defaultChannel ) == TRC_FAIL ) + { + return TRC_FAIL; + } + } + + xChannel = pxPrintInfo->defaultChannel; + } + + /* Added channel to uiEventCode and uiSize */ + if( xTraceEventBegin( uiEventCode, uiSize, &xEventHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + /* Add xChannel */ + xTraceEventAddPointer( xEventHandle, ( void * ) xChannel ); + + /* Add all arguments */ + for( i = 0; i < uiArgs; i++ ) + { + xTraceEventAddUnsignedBaseType( xEventHandle, va_arg( *pxVL, TraceUnsignedBaseType_t ) ); + } + + xTraceEventPayloadRemaining( xEventHandle, &uiRemaining ); + + if( uiRemaining < uiLength ) + { + uiLength = uiRemaining - 1; /* Make room for null termination */ + } + + /* Add format string */ + xTraceEventAddData( xEventHandle, ( void * ) szFormat, uiLength ); + + /* Check if we can truncate */ + xTraceEventPayloadRemaining( xEventHandle, &uiValue ); + + if( uiValue > 0 ) + { + xTraceEventAdd8( xEventHandle, 0 ); + } + + xTraceEventEnd( xEventHandle ); + + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c index a674cfeb9..235ab20a6 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c @@ -1,3317 +1,3505 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The generic core of the trace recorder's snapshot mode. - */ - -#include - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#include -#include - -#ifndef TRC_CFG_RECORDER_DATA_INIT -#define TRC_CFG_RECORDER_DATA_INIT 1 -#endif - -#if ((TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR)) - #error "CUSTOM timestamping mode is not (yet) supported in snapshot mode!" -#endif - -/* DO NOT CHANGE */ -#define TRACE_MINOR_VERSION 7 - -/* Keeps track of the task's stack low mark */ -typedef struct { - void* tcb; - uint32_t uiPreviousLowMark; -} TaskStackMonitorEntry_t; - -TraceKernelPortDataBuffer_t xKernelPortDataBuffer; - -#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) -/******************************************************************************* -* isrstack -* -* Keeps track of nested interrupts. -******************************************************************************/ -static traceHandle isrstack[TRC_CFG_MAX_ISR_NESTING]; - -/******************************************************************************* -* isPendingContextSwitch -* -* Used to indicate if there is a pending context switch. -* If there is a pending context switch the recorder will not create an event -* when returning from the ISR. -******************************************************************************/ -int32_t isPendingContextSwitch = 0; -#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1) */ - -/******************************************************************************* -* readyEventsEnabled -* -* This can be used to dynamically disable ready events. -******************************************************************************/ -#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1 -static int readyEventsEnabled = 1; -#endif /*!defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1*/ - -/******************************************************************************* - * uiTraceTickCount - * - * This variable is should be updated by the Kernel tick interrupt. This does - * not need to be modified when developing a new timer port. It is preferred to - * keep any timer port changes in the HWTC macro definitions, which typically - * give sufficient flexibility. - ******************************************************************************/ -uint32_t uiTraceTickCount = 0; - -/******************************************************************************* -* trace_disable_timestamp -* -* This can be used to disable timestamps as it will cause -* prvTracePortGetTimeStamp() to return the previous timestamp. -******************************************************************************/ -uint32_t trace_disable_timestamp = 0; - -/******************************************************************************* -* last_timestamp -* -* The most recent timestamp. -******************************************************************************/ -static uint32_t last_timestamp = 0; - -/******************************************************************************* -* uiTraceSystemState -* -* Indicates if we are currently performing a context switch or just running application code. -******************************************************************************/ -volatile uint32_t uiTraceSystemState = TRC_STATE_IN_STARTUP; - -/******************************************************************************* -* recorder_busy -* -* Flag that shows if inside a critical section of the recorder. -******************************************************************************/ -volatile int recorder_busy = 0; - -/******************************************************************************* -* timestampFrequency -* -* Holds the value set by vTraceSetFrequency. -******************************************************************************/ -uint32_t timestampFrequency = 0; - -/******************************************************************************* -* nISRactive -* -* The number of currently active (including preempted) ISRs. -******************************************************************************/ -int8_t nISRactive = 0; - -/******************************************************************************* -* handle_of_last_logged_task -* -* The current task. -******************************************************************************/ -traceHandle handle_of_last_logged_task = 0; - -/******************************************************************************* -* vTraceStopHookPtr -* -* Called when the recorder is stopped, set by vTraceSetStopHook. -******************************************************************************/ -TRACE_STOP_HOOK vTraceStopHookPtr = (TRACE_STOP_HOOK)0; - -/******************************************************************************* -* init_hwtc_count -* -* Initial TRC_HWTC_COUNT value, for detecting if the time-stamping source is -* enabled. If using the OS periodic timer for time-stamping, this might not -* have been configured on the earliest events during the startup. -******************************************************************************/ -uint32_t init_hwtc_count; - -/******************************************************************************* -* CurrentFilterMask -* -* The filter mask that will be checked against each object's FilterGroup to see -* if they should be included in the trace or not. -******************************************************************************/ -uint16_t CurrentFilterMask TRC_CFG_RECORDER_DATA_ATTRIBUTE; - -/******************************************************************************* -* CurrentFilterGroup -* -* The current filter group that will be assigned to newly created objects. -******************************************************************************/ -uint16_t CurrentFilterGroup TRC_CFG_RECORDER_DATA_ATTRIBUTE; - -/******************************************************************************* -* objectHandleStacks -* -* A set of stacks that keeps track of available object handles for each class. -* The stacks are empty initially, meaning that allocation of new handles will be -* based on a counter (for each object class). Any delete operation will -* return the handle to the corresponding stack, for reuse on the next allocate. -******************************************************************************/ -objectHandleStackType objectHandleStacks TRC_CFG_RECORDER_DATA_ATTRIBUTE; - -/******************************************************************************* -* traceErrorMessage -* -* The last error message of the recorder. NULL if no error message. -******************************************************************************/ -const char* traceErrorMessage TRC_CFG_RECORDER_DATA_ATTRIBUTE; - -#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) -/******************************************************************************* -* tasksInStackMonitor -* -* Keeps track of all stack low marks for tasks. -******************************************************************************/ -TaskStackMonitorEntry_t tasksInStackMonitor[TRC_CFG_STACK_MONITOR_MAX_TASKS] TRC_CFG_RECORDER_DATA_ATTRIBUTE; - -/******************************************************************************* -* tasksNotIncluded -* -* The number of tasks that did not fit in the stack monitor. -******************************************************************************/ -int tasksNotIncluded TRC_CFG_RECORDER_DATA_ATTRIBUTE; -#endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ - -/******************************************************************************* -* RecorderData -* -* The main data structure in snapshot mode, when using the default static memory -* allocation (TRC_RECORDER_BUFFER_ALLOCATION_STATIC). The recorder uses a pointer -* RecorderDataPtr to access the data, to also allow for dynamic or custom data -* allocation (see TRC_CFG_RECORDER_BUFFER_ALLOCATION). -******************************************************************************/ -#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC) -RecorderDataType RecorderData TRC_CFG_RECORDER_DATA_ATTRIBUTE; -#endif - -/* Pointer to the main data structure, when in snapshot mode */ -RecorderDataType* RecorderDataPtr TRC_CFG_RECORDER_DATA_ATTRIBUTE; - -#if (TRC_CFG_RECORDER_DATA_INIT != 0) -uint32_t RecorderInitialized = 0; -#else /* (TRC_CFG_RECORDER_DATA_INIT != 0) */ -uint32_t RecorderInitialized TRC_CFG_RECORDER_DATA_ATTRIBUTE; -#endif /* (TRC_CFG_RECORDER_DATA_INIT != 0) */ - -/*************** Private Functions *******************************************/ -static void prvStrncpy(char* dst, const char* src, uint32_t maxLength); -static uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id); -static void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength); -static void* prvTraceNextFreeEventBufferSlot(void); -static uint16_t prvTraceGetDTS(uint16_t param_maxDTS); -static TraceStringHandle_t prvTraceOpenSymbol(const char* name, TraceStringHandle_t userEventChannel); -static void prvTraceUpdateCounters(void); - -void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size); - -#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) -static void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nEntries); -#endif - -static TraceStringHandle_t prvTraceCreateSymbolTableEntry(const char* name, - uint8_t crc6, - uint8_t len, - TraceStringHandle_t channel); - -static TraceStringHandle_t prvTraceLookupSymbolTableEntry(const char* name, - uint8_t crc6, - uint8_t len, - TraceStringHandle_t channel); - - -#if (TRC_CFG_INCLUDE_ISR_TRACING == 0) -/* ISR tracing is turned off */ -void prvTraceIncreaseISRActive(void); -void prvTraceDecreaseISRActive(void); -#endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/ - -#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) -static uint8_t prvTraceGet8BitHandle(traceHandle handle); -#else -#define prvTraceGet8BitHandle(x) ((uint8_t)x) -#endif - -#if (TRC_CFG_SCHEDULING_ONLY == 0) -static uint32_t prvTraceGetParam(uint32_t, uint32_t); -#endif - -/******************************************************************************* - * prvTracePortGetTimeStamp - * - * Returns the current time based on the HWTC macros which provide a hardware - * isolation layer towards the hardware timer/counter. - * - * The HWTC macros and prvTracePortGetTimeStamp is the main porting issue - * or the trace recorder library. Typically you should not need to change - * the code of prvTracePortGetTimeStamp if using the HWTC macros. - * - ******************************************************************************/ -void prvTracePortGetTimeStamp(uint32_t *puiTimestamp); - -static void prvTraceTaskInstanceFinish(int8_t direct); - -/******************************************************************************* -* prvTraceInitTimestamps -* -* This will only be called once the recorder is started, and we can assume that -* all hardware has been initialized. -******************************************************************************/ -static void prvTraceInitTimestamps(void); - -static void prvTraceStart(void); - -static void prvTraceStop(void); - -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) -#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) -static void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl); -static void prvTraceUBHelper1(traceUBChannel channel, TraceStringHandle_t eventLabel, TraceStringHandle_t formatLabel, va_list vl); -static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t noOfSlots); -#endif /* (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) */ -#endif /* ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) */ - -uint16_t uiIndexOfObject(traceHandle objecthandle, uint8_t objectclass); - -/******************************************************************************* - * prvTraceError - * - * Called by various parts in the recorder. Stops the recorder and stores a - * pointer to an error message, which is printed by the monitor task. - ******************************************************************************/ -void prvTraceError(const char* msg); - -/********* Public Functions **************************************************/ - -#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM) -traceResult xTraceSetBuffer(TraceRecorderDataBuffer_t* pxBuffer) -{ - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - RecorderDataPtr = (RecorderDataType*)pxBuffer; - - return TRC_SUCCESS; -} -#endif - -traceResult xTraceGetEventBuffer(void** ppvBuffer, TraceUnsignedBaseType_t* puiSize) -{ - if (ppvBuffer == 0 || puiSize == 0) - { - return TRC_FAIL; - } - - *ppvBuffer = (void*)RecorderDataPtr; - *puiSize = sizeof(RecorderDataType); - - return TRC_SUCCESS; -} - -traceResult xTraceEnable(uint32_t uiStartOption) -{ - /* Make sure recorder data is initialized */ - if (xTraceInitialize() == TRC_FAIL) - { - return TRC_FAIL; - } - - if (uiStartOption == TRC_START) - { - if (xTraceKernelPortEnable() == TRC_FAIL) - { - return TRC_FAIL; - } - - prvTraceInitTimestamps(); - - prvTraceStart(); - } - else if (uiStartOption == TRC_START_AWAIT_HOST) - { - prvTraceError("xTraceEnable(TRC_START_AWAIT_HOST) not allowed in Snapshot mode"); - - return TRC_FAIL; - } - else if (uiStartOption != TRC_START_FROM_HOST) - { - prvTraceError("xTraceEnable(TRC_START_FROM_HOST) not allowed in Snapshot mode"); - - return TRC_FAIL; - } - - return TRC_SUCCESS; -} - - -traceResult xTraceDisable(void) -{ - prvTraceStop(); - - return TRC_SUCCESS; -} - -void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction) -{ - vTraceStopHookPtr = stopHookFunction; -} - -void vTraceClear(void) -{ - TRACE_ALLOC_CRITICAL_SECTION(); - trcCRITICAL_SECTION_BEGIN(); - RecorderDataPtr->absTimeLastEventSecond = 0; - RecorderDataPtr->absTimeLastEvent = 0; - RecorderDataPtr->nextFreeIndex = 0; - RecorderDataPtr->numEvents = 0; - RecorderDataPtr->bufferIsFull = 0; - traceErrorMessage = 0; - RecorderDataPtr->internalErrorOccured = 0; - (void)memset(RecorderDataPtr->eventData, 0, RecorderDataPtr->maxEvents * 4); - handle_of_last_logged_task = 0; - trcCRITICAL_SECTION_END(); -} - -static void prvTraceStart(void) -{ - traceHandle handle; - TRACE_ALLOC_CRITICAL_SECTION(); - - handle = 0; - - if (RecorderDataPtr == 0) - { - TRACE_ASSERT(RecorderDataPtr != 0, "Recorder not initialized. Use vTraceEnable() instead!", TRC_UNUSED); - return; - } - - if (RecorderDataPtr->recorderActive == 1) - return; /* Already running */ - - if (traceErrorMessage == 0) - { - trcCRITICAL_SECTION_BEGIN(); - RecorderDataPtr->recorderActive = 1; - - handle = TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()); - if (handle == 0) - { - /* This occurs if the scheduler is not yet started. - This creates a dummy "(startup)" task entry internally in the - recorder */ - handle = prvTraceGetObjectHandle(TRACE_CLASS_TASK); - prvTraceSetObjectName(TRACE_CLASS_TASK, handle, "(startup)"); - - prvTraceSetPriorityProperty(TRACE_CLASS_TASK, handle, 0); - } - - prvTraceStoreTaskswitch(handle); /* Register the currently running task */ - trcCRITICAL_SECTION_END(); - } -} - -/******************************************************************************* - * prvTraceStop - * - * Stops the recorder. The recording can be resumed by calling vTraceStart. - * This does not reset the recorder. Use vTraceClear if that is desired. - ******************************************************************************/ -static void prvTraceStop(void) -{ - if (RecorderDataPtr != 0) - { - RecorderDataPtr->recorderActive = 0; - } - - if (vTraceStopHookPtr != (TRACE_STOP_HOOK)0) - { - (*vTraceStopHookPtr)(); /* An application call-back function. */ - } -} - -/******************************************************************************* -* xTraceIsRecorderEnabled -* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0. -******************************************************************************/ -uint32_t xTraceIsRecorderEnabled(void) -{ - if (RecorderInitialized == 1 && RecorderDataPtr != 0) - { - return RecorderDataPtr->recorderActive; - } - else - { - return 0; - } -} - -/****************************************************************************** -* xTraceIsRecorderInitialized -* -* Returns true (1) if the recorder is initialized. -******************************************************************************/ -uint32_t xTraceIsRecorderInitialized(void) -{ - return RecorderInitialized; -} - -/******************************************************************************* - * xTraceErrorGetLast - * - * Gives the last error message, if any. NULL if no error message is stored. - * Any error message is also presented when opening a trace file. - ******************************************************************************/ -const char* xTraceErrorGetLast(void) -{ - return traceErrorMessage; -} - -/******************************************************************************* -* vTraceClearError -* -* Removes any previous error message generated by recorder calling prvTraceError. -* By calling this function, it may be possible to start/restart the trace -* despite errors in the recorder, but there is no guarantee that the trace -* recorder will work correctly in that case, depending on the type of error. -******************************************************************************/ -void vTraceClearError(void) -{ - traceErrorMessage = 0; - if (RecorderDataPtr != 0) - { - RecorderDataPtr->internalErrorOccured = 0; - } -} - -/******************************************************************************* - * xTraceGetTraceBuffer - * - * Returns a pointer to the recorder data structure. Use this together with - * uiTraceGetTraceBufferSize if you wish to implement an own store/upload - * solution, e.g., in case a debugger connection is not available for uploading - * the data. - ******************************************************************************/ -void* xTraceGetTraceBuffer(void) -{ - return RecorderDataPtr; -} - -/******************************************************************************* - * uiTraceGetTraceBufferSize - * - * Gets the size of the recorder data structure. For use together with - * vTraceGetTraceBuffer if you wish to implement an own store/upload solution, - * e.g., in case a debugger connection is not available for uploading the data. - ******************************************************************************/ -uint32_t uiTraceGetTraceBufferSize(void) -{ - return sizeof(RecorderDataType); -} - -/******************************************************************************* -* prvTraceInitTimestamps -* -* If vTraceEnable(TRC_INIT) was called BEFORE the clock was initialized, this -* function must be called AFTER the clock is initialized to set a proper -* initial timestamp value. If vTraceEnable(...) is only called AFTER clock is -* initialized, there is no need to call this function. -******************************************************************************/ -static void prvTraceInitTimestamps(void) -{ - init_hwtc_count = TRC_HWTC_COUNT; -} - -/****************************************************************************** - * prvTraceTaskInstanceFinish - * - * Private common function for the vTraceTaskInstanceFinishXXX functions. - *****************************************************************************/ -static void prvTraceTaskInstanceFinish(int8_t direct) -{ - TaskInstanceStatusEvent* tis; - uint8_t dts45; - - TRACE_ALLOC_CRITICAL_SECTION(); - - trcCRITICAL_SECTION_BEGIN(); - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - { - dts45 = (uint8_t)prvTraceGetDTS(0xFF); - tis = (TaskInstanceStatusEvent*) prvTraceNextFreeEventBufferSlot(); - if (tis != 0) - { - if (direct == 0) - tis->type = TASK_INSTANCE_FINISHED_NEXT_KSE; - else - tis->type = TASK_INSTANCE_FINISHED_DIRECT; - - tis->dts = dts45; - prvTraceUpdateCounters(); - } - } - trcCRITICAL_SECTION_END(); -} - -/****************************************************************************** - * xTraceTaskInstanceFinishedNext(void) - * - * Marks the current task instance as finished on the next kernel call. - * - * If that kernel call is blocking, the instance ends after the blocking event - * and the corresponding return event is then the start of the next instance. - * If the kernel call is not blocking, the viewer instead splits the current - * fragment right before the kernel call, which makes this call the first event - * of the next instance. - * - * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h - * - * Example: - * - * while(1) - * { - * xQueueReceive(CommandQueue, &command, timeoutDuration); - * processCommand(command); - * xTraceTaskInstanceFinishedNext(); - * } - *****************************************************************************/ -traceResult xTraceTaskInstanceFinishedNext(void) -{ - prvTraceTaskInstanceFinish(0); - - return TRC_SUCCESS; -} - -/****************************************************************************** - * xTraceTaskInstanceFinishedNow(void) - * - * Marks the current task instance as finished at this very instant. - * This makes the viewer to splits the current fragment at this point and begin - * a new actor instance. - * - * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h - * - * Example: - * - * This example will generate two instances for each loop iteration. - * The first instance ends at xTraceTaskInstanceFinishedNow(), while the second - * instance ends at the next xQueueReceive call. - * - * while (1) - * { - * xQueueReceive(CommandQueue, &command, timeoutDuration); - * ProcessCommand(command); - * xTraceTaskInstanceFinishedNow(); - * DoSometingElse(); - * xTraceTaskInstanceFinishedNext(); - * } - *****************************************************************************/ -traceResult xTraceTaskInstanceFinishedNow(void) -{ - prvTraceTaskInstanceFinish(1); - - return TRC_SUCCESS; -} - -/******************************************************************************* - * Interrupt recording functions - ******************************************************************************/ - -#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) - -/******************************************************************************* - * xTraceSetISRProperties - * - * Stores a name and priority level for an Interrupt Service Routine, to allow - * for better visualization. Returns a traceHandle used by vTraceStoreISRBegin. - * - * Example: - * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt - * ... - * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); - * ... - * void ISR_handler() - * { - * vTraceStoreISRBegin(Timer1Handle); - * ... - * vTraceStoreISREnd(0); - * } - ******************************************************************************/ - traceHandle xTraceSetISRProperties(const char* name, uint8_t priority) -{ - static traceHandle handle = 0; - TRACE_ASSERT(RecorderDataPtr != 0, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0); - TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "xTraceSetISRProperties: Invalid value for handle", 0); - TRACE_ASSERT(name != 0, "xTraceSetISRProperties: name == NULL", 0); - - handle++; - - prvTraceSetObjectName(TRACE_CLASS_ISR, handle, name); - prvTraceSetPriorityProperty(TRACE_CLASS_ISR, handle, priority); - - return handle; -} - -/******************************************************************************* - * vTraceStoreISRBegin - * - * Registers the beginning of an Interrupt Service Routine, using a traceHandle - * provided by xTraceSetISRProperties. - * - * Example: - * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt - * ... - * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); - * ... - * void ISR_handler() - * { - * vTraceStoreISRBegin(Timer1Handle); - * ... - * vTraceStoreISREnd(0); - * } - ******************************************************************************/ -void vTraceStoreISRBegin(traceHandle handle) -{ - TRACE_ALLOC_CRITICAL_SECTION(); - - if (recorder_busy) - { - /************************************************************************* - * This occurs if an ISR calls a trace function, preempting a previous - * trace call that is being processed in a different ISR or task. - * If this occurs, there is probably a problem in the definition of the - * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and - * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt - * and any other ISRs that calls the trace recorder directly or via - * traced kernel functions. The ARM port disables all interrupts using the - * PRIMASK register to avoid this issue. - *************************************************************************/ - prvTraceError("vTraceStoreISRBegin - recorder busy! See code comment."); - return; - } - trcCRITICAL_SECTION_BEGIN(); - - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - { - uint16_t dts4; - - TRACE_ASSERT(handle != 0, "vTraceStoreISRBegin: Invalid ISR handle (NULL)", TRC_UNUSED); - TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceStoreISRBegin: Invalid ISR handle (> NISR)", TRC_UNUSED); - - dts4 = (uint16_t)prvTraceGetDTS(0xFFFF); - - if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */ - { - if (nISRactive < TRC_CFG_MAX_ISR_NESTING) - { - TSEvent* ts; - uint8_t hnd8 = prvTraceGet8BitHandle(handle); - isrstack[nISRactive] = handle; - nISRactive++; - ts = (TSEvent*)prvTraceNextFreeEventBufferSlot(); - if (ts != 0) - { - ts->type = TS_ISR_BEGIN; - ts->dts = dts4; - ts->objHandle = hnd8; - prvTraceUpdateCounters(); - } - } - else - { - /* This should not occur unless something is very wrong */ - prvTraceError("Too many nested interrupts!"); - } - } - } - trcCRITICAL_SECTION_END(); -} - -/******************************************************************************* - * vTraceStoreISREnd - * - * Registers the end of an Interrupt Service Routine. - * - * The parameter pendingISR indicates if the interrupt has requested a - * task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the - * interrupt is assumed to return to the previous context. - * - * Example: - * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt - * traceHandle traceHandleIsrTimer1 = 0; // The ID set by the recorder - * ... - * traceHandleIsrTimer1 = xTraceSetISRProperties("ISRTimer1", PRIO_OF_ISR_TIMER1); - * ... - * void ISR_handler() - * { - * vTraceStoreISRBegin(traceHandleIsrTimer1); - * ... - * vTraceStoreISREnd(0); - * } - ******************************************************************************/ -void vTraceStoreISREnd(int pendingISR) -{ - TSEvent* ts; - uint16_t dts5; - uint8_t hnd8 = 0, type = 0; - - TRACE_ALLOC_CRITICAL_SECTION(); - - if (! RecorderDataPtr->recorderActive || ! handle_of_last_logged_task) - { - return; - } - - if (recorder_busy) - { - /************************************************************************* - * This occurs if an ISR calls a trace function, preempting a previous - * trace call that is being processed in a different ISR or task. - * If this occurs, there is probably a problem in the definition of the - * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and - * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt - * and any other ISRs that calls the trace recorder directly or via - * traced kernel functions. The ARM port disables all interrupts using the - * PRIMASK register to avoid this issue. - *************************************************************************/ - prvTraceError("vTraceStoreISREnd - recorder busy! See code comment."); - return; - } - - if (nISRactive == 0) - { - prvTraceError("Unmatched call to vTraceStoreISREnd (nISRactive == 0, expected > 0)"); - return; - } - - trcCRITICAL_SECTION_BEGIN(); - isPendingContextSwitch |= pendingISR; /* Is there a pending context switch right now? If so, we will not create an event since we will get an event when that context switch is executed. */ - nISRactive--; - if (nISRactive > 0) - { - /* Return to another ISR */ - type = TS_ISR_RESUME; - hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive - 1]); /* isrstack[nISRactive] is the handle of the ISR we're currently exiting. isrstack[nISRactive - 1] is the handle of the ISR that was executing previously. */ - } - else if ((isPendingContextSwitch == 0) || (xTraceKernelPortIsSchedulerSuspended())) - { - /* Return to interrupted task, if no context switch will occur in between. */ - type = TS_TASK_RESUME; - hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task); - } - - if (type != 0) - { - dts5 = (uint16_t)prvTraceGetDTS(0xFFFF); - ts = (TSEvent*)prvTraceNextFreeEventBufferSlot(); - if (ts != 0) - { - ts->type = type; - ts->objHandle = hnd8; - ts->dts = dts5; - prvTraceUpdateCounters(); - } - } - - trcCRITICAL_SECTION_END(); -} - -#else - -/* ISR tracing is turned off */ -void prvTraceIncreaseISRActive(void) -{ - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - nISRactive++; -} - -void prvTraceDecreaseISRActive(void) -{ - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - nISRactive--; -} -#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1)*/ - - -/********************************************************************************/ -/* User Event functions */ -/********************************************************************************/ - -#define MAX_ARG_SIZE (4+32) - -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) -static uint8_t writeInt8(void * buffer, uint8_t i, uint8_t value) -{ - TRACE_ASSERT(buffer != 0, "writeInt8: buffer == NULL", 0); - - if (i >= MAX_ARG_SIZE) - { - return 255; - } - - ((uint8_t*)buffer)[i] = value; - - if (i + 1 > MAX_ARG_SIZE) - { - return 255; - } - - return ((uint8_t) (i + 1)); -} -#endif - -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) -static uint8_t writeInt16(void * buffer, uint8_t i, uint16_t value) -{ - TRACE_ASSERT(buffer != 0, "writeInt16: buffer == NULL", 0); - - /* Align to multiple of 2 */ - while ((i % 2) != 0) - { - if (i >= MAX_ARG_SIZE) - { - return 255; - } - - ((uint8_t*)buffer)[i] = 0; - i++; - } - - if (i + 2 > MAX_ARG_SIZE) - { - return 255; - } - - ((uint16_t*)buffer)[i/2] = value; - - return ((uint8_t) (i + 2)); -} -#endif - -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) -static uint8_t writeInt32(void * buffer, uint8_t i, uint32_t value) -{ - TRACE_ASSERT(buffer != 0, "writeInt32: buffer == NULL", 0); - - /* A 32 bit value should begin at an even 4-byte address */ - while ((i % 4) != 0) - { - if (i >= MAX_ARG_SIZE) - { - return 255; - } - - ((uint8_t*)buffer)[i] = 0; - i++; - } - - if (i + 4 > MAX_ARG_SIZE) - { - return 255; - } - - ((uint32_t*)buffer)[i/4] = value; - - return ((uint8_t) (i + 4)); -} -#endif - -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_INCLUDE_FLOAT_SUPPORT)) -static uint8_t writeFloat(void * buffer, uint8_t i, float value) -{ - TRACE_ASSERT(buffer != 0, "writeFloat: buffer == NULL", 0); - - /* A 32 bit value should begin at an even 4-byte address */ - while ((i % 4) != 0) - { - if (i >= MAX_ARG_SIZE) - { - return 255; - } - - ((uint8_t*)buffer)[i] = 0; - i++; - } - - if (i + 4 > MAX_ARG_SIZE) - { - return 255; - } - - ((float*)buffer)[i/4] = value; - - return i + 4; -} -#endif - -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_INCLUDE_FLOAT_SUPPORT)) -static uint8_t writeDouble(void * buffer, uint8_t i, double value) -{ - uint32_t * dest; - uint32_t * src = (uint32_t*)&value; - - TRACE_ASSERT(buffer != 0, "writeDouble: buffer == NULL", 0); - - /* The double is written as two 32 bit values, and should begin at an even - 4-byte address (to avoid having to align with 8 byte) */ - while (i % 4 != 0) - { - if (i >= MAX_ARG_SIZE) - { - return 255; - } - - ((uint8_t*)buffer)[i] = 0; - i++; - } - - if (i + 8 > MAX_ARG_SIZE) - { - return 255; - } - - dest = &(((uint32_t *)buffer)[i/4]); - - dest[0] = src[0]; - dest[1] = src[1]; - - return i + 8; -} -#endif - -/******************************************************************************* - * prvTraceUserEventFormat - * - * Parses the format string and stores the arguments in the buffer. - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) -static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_t* buffer, uint8_t byteOffset) -{ - uint16_t formatStrIndex = 0; - uint8_t argCounter = 0; - uint8_t i = byteOffset; - - while (formatStr[formatStrIndex] != '\0') - { - if (formatStr[formatStrIndex] == '%') - { - if (formatStr[formatStrIndex + 1] == '%') - { - formatStrIndex += 2; - continue; - } - - /* We found a possible argument */ - argCounter++; - - formatStrIndex++; - - while ((formatStr[formatStrIndex] >= '0' && formatStr[formatStrIndex] <= '9') || formatStr[formatStrIndex] == '#' || formatStr[formatStrIndex] == '.') - formatStrIndex++; - - /* This check is necessary to avoid moving past end of string. */ - if (formatStr[formatStrIndex] != '\0') - { - switch (formatStr[formatStrIndex]) - { - case 'd': - i = writeInt32( buffer, - i, - (uint32_t)va_arg(vl, uint32_t)); - break; - case 'x': - case 'X': - case 'u': - i = writeInt32( buffer, - i, - (uint32_t)va_arg(vl, uint32_t)); - break; - case 's': - { - TraceStringHandle_t xString; - xTraceStringRegister((char*)va_arg(vl, char*), &xString); - - i = writeInt16(buffer, - i, - (uint16_t)xString); - } - break; - -#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT) - /* Yes, "double" as type also in the float - case. This since "float" is promoted into "double" - by the va_arg stuff. */ - case 'f': - i = writeFloat( buffer, - i, - (float)va_arg(vl, double)); - break; -#else - /* No support for floats, but attempt to store a float user event - avoid a possible crash due to float reference. Instead store the - data on uint_32 format (will not be displayed anyway). This is just - to keep va_arg and i consistent. */ - - case 'f': - i = writeInt32( buffer, - i, - (uint32_t)va_arg(vl, double)); - break; -#endif - case 'l': - formatStrIndex++; - switch (formatStr[formatStrIndex]) - { -#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT) - case 'f': i = writeDouble(buffer, - i, - (double)va_arg(vl, double)); - break; -#else - /* No support for floats, but attempt to store a float user event - avoid a possible crash due to float reference. Instead store the - data on uint_32 format (will not be displayed anyway). This is just - to keep va_arg and i consistent. */ - case 'f': - i = writeInt32( buffer, /* In this case, the value will not be shown anyway */ - i, - (uint32_t)va_arg(vl, double)); - - i = writeInt32( buffer, /* Do it twice, to write in total 8 bytes */ - i, - (uint32_t)va_arg(vl, double)); - break; -#endif - default: - break; - } - break; - case 'h': - formatStrIndex++; - switch (formatStr[formatStrIndex]) - { - case 'd': - i = writeInt16( buffer, - i, - (uint16_t)va_arg(vl, uint32_t)); - break; - case 'u': - i = writeInt16( buffer, - i, - (uint16_t)va_arg(vl, uint32_t)); - break; - - default: - break; - } - break; - case 'b': - formatStrIndex++; - switch (formatStr[formatStrIndex]) - { - case 'd': - i = writeInt8( buffer, - i, - (uint8_t)va_arg(vl, uint32_t)); - break; - case 'u': - i = writeInt8( buffer, - i, - (uint8_t)va_arg(vl, uint32_t)); - break; - - default: - break; - } - break; - default: - /* False alarm: this wasn't a valid format specifier */ - argCounter--; - break; - } - - if (argCounter > 15) - { - prvTraceError("xTracePrintF - Too many arguments, max 15 allowed!"); - return 0; - } - } - else - break; - } - formatStrIndex++; - if (i == 255) - { - prvTraceError("xTracePrintF - Too large arguments, max 32 byte allowed!"); - return 0; - } - } - return (uint8_t)(i+3)/4; -} -#endif - -/******************************************************************************* - * prvTraceClearChannelBuffer - * - * Clears a number of items in the channel buffer, starting from nextSlotToWrite. - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) -static void prvTraceClearChannelBuffer(uint32_t count) -{ - uint32_t slots; - - TRACE_ASSERT((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) >= count, - "prvTraceClearChannelBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED); - - /* Check if we're close to the end of the buffer */ - if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE)) - { - slots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */ - (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, slots); - (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[0], 0, (count - slots)); - } - else - (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, count); -} -#endif - -/******************************************************************************* - * prvTraceCopyToDataBuffer - * - * Copies a number of items to the data buffer, starting from nextSlotToWrite. - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) -static void prvTraceCopyToDataBuffer(uint32_t* data, uint32_t count) -{ - uint32_t slots; - - TRACE_ASSERT(data != 0, - "prvTraceCopyToDataBuffer: data == NULL.", TRC_UNUSED); - TRACE_ASSERT(count <= (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE), - "prvTraceCopyToDataBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED); - /* Check if we're close to the end of the buffer */ - if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE)) - { - slots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */ - (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, slots * 4); - (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[0], data + slots, (count - slots) * 4); - } - else - { - (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, count * 4); - } -} -#endif - -/******************************************************************************* - * prvTraceUBHelper1 - * - * Calls on prvTraceUserEventFormat() to do the actual formatting, then goes on - * to the next helper function. - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) -static void prvTraceUBHelper1(traceUBChannel channel, TraceStringHandle_t eventLabel, TraceStringHandle_t formatLabel, va_list vl) -{ - uint32_t data[(3 + MAX_ARG_SIZE) / 4]; - uint8_t byteOffset = 4; /* Need room for timestamp */ - uint8_t noOfSlots; - - if (channel == 0) - { - /* We are dealing with an unknown channel format pair */ - byteOffset = (uint8_t)(byteOffset + 4); /* Also need room for channel and format */ - ((uint16_t*)data)[2] = eventLabel; - ((uint16_t*)data)[3] = formatLabel; - } - - noOfSlots = prvTraceUserEventFormat((char*)&(RecorderDataPtr->SymbolTable.symbytes[formatLabel+4]), vl, (uint8_t*)data, byteOffset); - - prvTraceUBHelper2(channel, data, noOfSlots); -} -#endif - -/******************************************************************************* - * prvTraceUBHelper2 - * - * This function simply copies the data buffer to the actual user event buffer. - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) -static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t noOfSlots) -{ - static uint32_t old_timestamp = 0; - uint32_t old_nextSlotToWrite = 0; - - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ASSERT((TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) >= noOfSlots, "prvTraceUBHelper2: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED); - - trcCRITICAL_SECTION_BEGIN(); - /* Store the timestamp */ - prvTracePortGetTimeStamp(data); - - if (*data < old_timestamp) - { - RecorderDataPtr->userEventBuffer.wraparoundCounter++; - } - - old_timestamp = *data; - - /* Start by erasing any information in the channel buffer */ - prvTraceClearChannelBuffer(noOfSlots); - - prvTraceCopyToDataBuffer(data, noOfSlots); /* Will wrap around the data if necessary */ - - old_nextSlotToWrite = RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Save the index that we want to write the channel data at when we're done */ - RecorderDataPtr->userEventBuffer.nextSlotToWrite = (RecorderDataPtr->userEventBuffer.nextSlotToWrite + noOfSlots) % (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE); /* Make sure we never end up outside the buffer */ - - /* Write to the channel buffer to indicate that this user event is ready to be used */ - if (channel != 0) - { - RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = channel; - } - else - { - /* 0xFF indicates that this is not a normal channel id */ - RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = (traceUBChannel)0xFF; - } - trcCRITICAL_SECTION_END(); -} -#endif - -/******************************************************************************* - * xTraceRegisterUBChannel - * - * Registers a channel for Separated User Events, i.e., those stored in the - * separate user event buffer. - * - * Note: Only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is enabled in - * trcSnapshotConfig.h - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) -traceUBChannel xTraceRegisterUBChannel(TraceStringHandle_t channel, TraceStringHandle_t formatStr) -{ - uint8_t i; - traceUBChannel retVal = 0; - - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ASSERT(formatStr != 0, "xTraceRegisterChannelFormat: formatStr == 0", (traceUBChannel)0); - - trcCRITICAL_SECTION_BEGIN(); - for (i = 1; i <= (TRC_CFG_UB_CHANNELS); i++) /* Size of the channels buffer is TRC_CFG_UB_CHANNELS + 1. Index 0 is unused. */ - { - if(RecorderDataPtr->userEventBuffer.channels[i].name == 0 && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == 0) - { - /* Found empty slot */ - RecorderDataPtr->userEventBuffer.channels[i].name = channel; - RecorderDataPtr->userEventBuffer.channels[i].defaultFormat = formatStr; - retVal = (traceUBChannel)i; - break; - } - - if (RecorderDataPtr->userEventBuffer.channels[i].name == channel && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == formatStr) - { - /* Found a match */ - retVal = (traceUBChannel)i; - break; - } - } - trcCRITICAL_SECTION_END(); - - return retVal; -} -#endif - -/****************************************************************************** - * vTraceUBData - * - * Slightly faster version of xTracePrintF() due to no lookups. - * - * Note: This is only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is - * enabled in trcSnapshotConfig.h - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) -void vTraceUBData(traceUBChannel channelPair, ...) -{ - va_list vl; - - TRACE_ASSERT(channelPair != 0, "vTraceUBData: Not a valid traceUBChannel!", TRC_UNUSED); - - va_start(vl, channelPair); - vTraceUBData_Helper(channelPair, vl); - va_end(vl); -} -#endif - -/* Extracts the channel name and format string from the traceUBChannel, then calls prvTraceUBHelper1. */ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) -void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl) -{ - TraceStringHandle_t channel; - TraceStringHandle_t formatStr; - - TRACE_ASSERT(channelPair != 0, "vTraceUBData_Helper: channelPair == 0", TRC_UNUSED); - TRACE_ASSERT(channelPair <= (TRC_CFG_UB_CHANNELS), "vTraceUBData_Helper: ", TRC_UNUSED); - - channel = RecorderDataPtr->userEventBuffer.channels[channelPair].name; - formatStr = RecorderDataPtr->userEventBuffer.channels[channelPair].defaultFormat; - - prvTraceUBHelper1(channelPair, channel, formatStr, vl); -} -#endif - -/****************************************************************************** - * vTraceUBEvent - * - * Slightly faster version of ... due to no lookups. - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) -void vTraceUBEvent(traceUBChannel channelPair) -{ - uint32_t data[(3 + MAX_ARG_SIZE) / 4]; - - TRACE_ASSERT(channelPair != 0, "vTraceUBEvent: channelPair == 0", TRC_UNUSED); - TRACE_ASSERT(channelPair <= (TRC_CFG_UB_CHANNELS), "vTraceUBEvent: ", TRC_UNUSED); - - prvTraceUBHelper2(channelPair, data, 1); /* Only need one slot for timestamp */ -} -#endif - -/****************************************************************************** - * xTracePrintF - * - * Generates User Event with formatted text and data, similar to a "printf". - * It is very fast compared to a normal "printf" since this function only - * stores the arguments. The actual formatting is done - * on the host PC when the trace is displayed in the viewer tool. - * - * User Event labels are created using xTraceStringRegister. - * Example: - * - * TraceStringHandle_t adc_uechannel; - * xTraceStringRegister("ADC User Events", &adc_uechannel); - * ... - * xTracePrintF(adc_uechannel, - * "ADC channel %d: %lf volts", - * ch, (double)adc_reading/(double)scale); - * - * Calling xTraceStringRegister multiple times will not create duplicate entries, but - * it is of course faster to just do it once, and then keep the handle for later - * use. If you don't have any data arguments, only a text label/string, it is - * better to use xTracePrint - it is faster. - * - * Format specifiers supported: - * %d - 32 bit signed integer - * %u - 32 bit unsigned integer - * %f - 32 bit float - * %s - string (is copied to the recorder symbol table) - * %hd - 16 bit signed integer - * %hu - 16 bit unsigned integer - * %bd - 8 bit signed integer - * %bu - 8 bit unsigned integer - * %lf - double-precision float (Note! See below...) - * - * Up to 15 data arguments are allowed, with a total size of maximum 32 byte. - * In case this is exceeded, the user event is changed into an error message. - * - * The data is stored in trace buffer, and is packed to allow storing multiple - * smaller data entries in the same 4-byte record, e.g., four 8-bit values. - * A string requires two bytes, as the symbol table is limited to 64K. Storing - * a double (%lf) uses two records, so this is quite costly. Use float (%f) - * unless the higher precision is really necessary. - * - * Note that the double-precision float (%lf) assumes a 64 bit double - * representation. This does not seem to be the case on e.g. PIC24 and PIC32. - * Before using a %lf argument on a 16-bit MCU, please verify that - * "sizeof(double)" actually gives 8 as expected. If not, use %f instead. - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) -traceResult xTracePrintF(TraceStringHandle_t eventLabel, const char* formatStr, ...) -{ - va_list vl; - - va_start(vl, formatStr); - xTraceVPrintF(eventLabel, formatStr, vl); - va_end(vl); - - return TRC_SUCCESS; -} -#endif - -/****************************************************************************** - * xTraceVPrintF - * - * xTracePrintF variant that accepts a va_list. - * See xTracePrintF documentation for further details. - * - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) -traceResult xTraceVPrintF(TraceStringHandle_t eventLabel, const char* formatStr, va_list vl) -{ -#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0) - uint32_t noOfSlots; - UserEvent* ue1; - uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4]; - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ASSERT(formatStr != 0, "vTraceVPrintF: formatStr == NULL", TRC_FAIL); - - trcCRITICAL_SECTION_BEGIN(); - - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - { - /* First, write the "primary" user event entry in the local buffer, but - let the event type be "EVENT_BEING_WRITTEN" for now...*/ - - ue1 = (UserEvent*)(&tempDataBuffer[0]); - - ue1->type = EVENT_BEING_WRITTEN; /* Update this as the last step */ - - noOfSlots = prvTraceUserEventFormat(formatStr, vl, (uint8_t*)tempDataBuffer, 4); - - /* Store the format string, with a reference to the channel symbol */ - ue1->payload = prvTraceOpenSymbol(formatStr, eventLabel); - - ue1->dts = (uint8_t)prvTraceGetDTS(0xFF); - - /* prvTraceGetDTS might stop the recorder in some cases... */ - if (RecorderDataPtr->recorderActive) - { - - /* If the data does not fit in the remaining main buffer, wrap around to - 0 if allowed, otherwise stop the recorder and quit). */ - if (RecorderDataPtr->nextFreeIndex + noOfSlots > RecorderDataPtr->maxEvents) - { - #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) - (void)memset(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4], - 0, - (RecorderDataPtr->maxEvents - RecorderDataPtr->nextFreeIndex)*4); - RecorderDataPtr->nextFreeIndex = 0; - RecorderDataPtr->bufferIsFull = 1; - #else - - /* Stop recorder, since the event data will not fit in the - buffer and not circular buffer in this case... */ - vTraceStop(); - #endif - } - - /* Check if recorder has been stopped (i.e., vTraceStop above) */ - if (RecorderDataPtr->recorderActive) - { - /* Check that the buffer to be overwritten does not contain any user - events that would be partially overwritten. If so, they must be "killed" - by replacing the user event and following data with NULL events (i.e., - using a memset to zero).*/ - #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) - prvCheckDataToBeOverwrittenForMultiEntryEvents((uint8_t)noOfSlots); - #endif - /* Copy the local buffer to the main buffer */ - (void)memcpy(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4], - tempDataBuffer, - noOfSlots * 4); - - /* Update the event type, i.e., number of data entries following the - main USER_EVENT entry (Note: important that this is after the memcpy, - but within the critical section!)*/ - RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4] = - (uint8_t) ( USER_EVENT + noOfSlots - 1 ); - - /* Update the main buffer event index (already checked that it fits in - the buffer, so no need to check for wrapping)*/ - - RecorderDataPtr->nextFreeIndex += noOfSlots; - RecorderDataPtr->numEvents += noOfSlots; - - if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE)) - { - #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) - /* We have reached the end, but this is a ring buffer. Start from the beginning again. */ - RecorderDataPtr->bufferIsFull = 1; - RecorderDataPtr->nextFreeIndex = 0; - #else - /* We have reached the end so we stop. */ - vTraceStop(); - #endif - } - } - - #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) - /* Make sure the next entry is cleared correctly */ - prvCheckDataToBeOverwrittenForMultiEntryEvents(1); - #endif - - } - } - trcCRITICAL_SECTION_END(); - -#elif (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) - /* Use the separate user event buffer */ - TraceStringHandle_t formatLabel; - traceUBChannel channel; - - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - { - xTraceStringRegister(formatStr, &formatLabel); - - channel = xTraceRegisterUBChannel(eventLabel, formatLabel); - - prvTraceUBHelper1(channel, eventLabel, formatLabel, vl); - } -#endif - - return TRC_SUCCESS; -} -#endif - -/****************************************************************************** - * xTracePrint - * - * Basic user event - * - * Generates a User Event with a text label. The label is created/looked up - * in the symbol table using xTraceStringRegister. - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) -traceResult xTracePrint(TraceStringHandle_t chn, const char* str) -{ -#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0) - UserEvent* ue; - uint8_t dts1; - TRACE_ALLOC_CRITICAL_SECTION(); - - trcCRITICAL_SECTION_BEGIN(); - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - { - dts1 = (uint8_t)prvTraceGetDTS(0xFF); - ue = (UserEvent*) prvTraceNextFreeEventBufferSlot(); - if (ue != 0) - { - ue->dts = dts1; - ue->type = USER_EVENT; - ue->payload = prvTraceOpenSymbol(str, chn); - prvTraceUpdateCounters(); - } - } - trcCRITICAL_SECTION_END(); - -#elif (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) - traceUBChannel channel; - uint32_t noOfSlots = 1; - uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4]; - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - { - TraceStringHandle_t trcStr = prvTraceOpenSymbol(str, chn); - channel = xTraceRegisterUBChannel(chn, trcStr); - - if (channel == 0) - { - /* We are dealing with an unknown channel format pair */ - noOfSlots++; /* Also need room for channel and format */ - ((uint16_t*)tempDataBuffer)[2] = chn; - ((uint16_t*)tempDataBuffer)[3] = trcStr; - } - - prvTraceUBHelper2(channel, tempDataBuffer, noOfSlots); - } -#endif - - return TRC_SUCCESS; -} -#endif - -/******************************************************************************* - * xTraceStringRegister - * - * Register strings in the recorder, e.g. for names of user event channels. - * - * Example: - * xTraceStringRegister("MyUserEvent", &myStringHandle); - * ... - * xTracePrintF(myEventHandle, "My value is: %d", myValue); - ******************************************************************************/ -#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) -traceResult xTraceStringRegister(const char* label, TraceStringHandle_t *pxString) -{ - TRACE_ASSERT(label != 0, "xTraceStringRegister: label == NULL", TRC_FAIL); - TRACE_ASSERT(RecorderDataPtr != 0, "Recorder not initialized, call vTraceEnable() first!", TRC_FAIL); - - *pxString = prvTraceOpenSymbol(label, 0); - - return TRC_SUCCESS; -} - -/* DEPRECATED */ -TraceStringHandle_t xTraceRegisterString(const char* name) -{ - TraceStringHandle_t trcStr = 0; - xTraceStringRegister(name, &trcStr); - - return trcStr; -} -#endif - -traceResult xTraceInitialize() -{ -#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) - uint32_t i; -#endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ - - if (RecorderInitialized != 0) - { - return TRC_SUCCESS; - } - - /* These are set on init so they aren't overwritten by late initialization values. */ - CurrentFilterMask = 0xFFFF; - CurrentFilterGroup = FilterGroup0; - traceErrorMessage = 0; - -#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) - tasksNotIncluded = 0; - - for (i = 0; i < TRC_CFG_STACK_MONITOR_MAX_TASKS; i++) - { - tasksInStackMonitor[i].tcb = 0; - tasksInStackMonitor[i].uiPreviousLowMark = 0; - } -#endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ - -#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC) - RecorderDataPtr = &RecorderData; -#elif (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC) - RecorderDataPtr = (RecorderDataType*)TRACE_MALLOC(sizeof(RecorderDataType)); - if (!RecorderDataPtr) - { - prvTraceError("Failed allocating recorder buffer!"); - return TRC_FAIL; - } -#elif (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM) - if (!RecorderDataPtr) - { - prvTraceError("Recorder data pointer not set! Use vTraceSetRecorderDataBuffer()."); - return TRC_FAIL; - } -#endif - - init_hwtc_count = TRC_HWTC_COUNT; - - if (xTraceKernelPortInitialize(&xKernelPortDataBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - (void)memset(RecorderDataPtr, 0, sizeof(RecorderDataType)); - - RecorderDataPtr->version = TRACE_KERNEL_VERSION; - RecorderDataPtr->minor_version = TRACE_MINOR_VERSION; - RecorderDataPtr->irq_priority_order = TRC_IRQ_PRIORITY_ORDER; - RecorderDataPtr->filesize = sizeof(RecorderDataType); - RecorderDataPtr->maxEvents = (TRC_CFG_EVENT_BUFFER_SIZE); - RecorderDataPtr->debugMarker0 = (int32_t)0xF0F0F0F0; - RecorderDataPtr->isUsing16bitHandles = TRC_CFG_USE_16BIT_OBJECT_HANDLES; - RecorderDataPtr->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD; - - /* This function is kernel specific */ - xTraceKernelPortInitObjectPropertyTable(); - - RecorderDataPtr->debugMarker1 = (int32_t)0xF1F1F1F1; - RecorderDataPtr->SymbolTable.symTableSize = (TRC_CFG_SYMBOL_TABLE_SIZE); - RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1; -#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1) - RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */ -#endif - RecorderDataPtr->debugMarker2 = (int32_t)0xF2F2F2F2; - prvStrncpy(RecorderDataPtr->systemInfo, "Trace Recorder Demo", 80); - RecorderDataPtr->debugMarker3 = (int32_t)0xF3F3F3F3; - RecorderDataPtr->endmarker0 = 0x0A; - RecorderDataPtr->endmarker1 = 0x0B; - RecorderDataPtr->endmarker2 = 0x0C; - RecorderDataPtr->endmarker3 = 0x0D; - RecorderDataPtr->endmarker4 = 0x71; - RecorderDataPtr->endmarker5 = 0x72; - RecorderDataPtr->endmarker6 = 0x73; - RecorderDataPtr->endmarker7 = 0x74; - RecorderDataPtr->endmarker8 = 0xF1; - RecorderDataPtr->endmarker9 = 0xF2; - RecorderDataPtr->endmarker10 = 0xF3; - RecorderDataPtr->endmarker11 = 0xF4; - -#if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER - RecorderDataPtr->userEventBuffer.bufferID = 1; - RecorderDataPtr->userEventBuffer.version = 0; - RecorderDataPtr->userEventBuffer.numberOfSlots = (TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE); - RecorderDataPtr->userEventBuffer.numberOfChannels = (TRC_CFG_UB_CHANNELS)+1; -#endif - - /* Kernel specific initialization of the objectHandleStacks variable */ - xTraceKernelPortInitObjectHandleStack(); - - - /* Finally, the 12-byte "start markers" are initialized, allowing for - Tracealyzer to find the trace data in a larger RAM dump. - - The start and end markers must be unique, but without proper precautions there - might be a risk of accidental duplicates of the start/end markers, e.g., due to - compiler optimizations. - - The below initialization of the start marker is therefore made in reverse order - and the fields are volatile to ensure this assignment order. This to avoid any - chance of accidental duplicates of this elsewhere in memory. - - Moreover, the fields are set byte-by-byte to avoid endian issues.*/ - - RecorderDataPtr->startmarker11 = 0xF4; - RecorderDataPtr->startmarker10 = 0xF3; - RecorderDataPtr->startmarker9 = 0xF2; - RecorderDataPtr->startmarker8 = 0xF1; - RecorderDataPtr->startmarker7 = 0x74; - RecorderDataPtr->startmarker6 = 0x73; - RecorderDataPtr->startmarker5 = 0x72; - RecorderDataPtr->startmarker4 = 0x71; - RecorderDataPtr->startmarker3 = 0x04; - RecorderDataPtr->startmarker2 = 0x03; - RecorderDataPtr->startmarker1 = 0x02; - RecorderDataPtr->startmarker0 = 0x01; - - if (traceErrorMessage != 0) - { - // An error was detected before vTraceEnable was called, make sure this is stored in the trace data. - prvStrncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80); - RecorderDataPtr->internalErrorOccured = 1; - prvTraceStop(); - } - -#ifdef TRC_PORT_SPECIFIC_INIT - TRC_PORT_SPECIFIC_INIT(); -#endif - - RecorderInitialized = 1; - - return TRC_SUCCESS; -} - -#if ((!defined TRC_CFG_INCLUDE_READY_EVENTS) || (TRC_CFG_INCLUDE_READY_EVENTS == 1)) - -void prvTraceSetReadyEventsEnabled(uint32_t flag) -{ - readyEventsEnabled = flag; -} - -/******************************************************************************* - * prvTraceStoreTaskReady - * - * This function stores a ready state for the task handle sent in as parameter. - ******************************************************************************/ -void prvTraceStoreTaskReady(traceHandle handle) -{ - uint16_t dts3; - TREvent* tr; - uint8_t hnd8; - - TRACE_ALLOC_CRITICAL_SECTION(); - - if (handle == 0) - { - /* On FreeRTOS v7.3.0, this occurs when creating tasks due to a bad - placement of the trace macro. In that case, the events are ignored. */ - return; - } - - if (! readyEventsEnabled) - { - /* When creating tasks, ready events are also created. If creating - a "hidden" (not traced) task, we must therefore disable recording - of ready events to avoid an undesired ready event... */ - return; - } - - TRACE_ASSERT(handle <= (TRC_CFG_NTASK), "prvTraceStoreTaskReady: Invalid value for handle", TRC_UNUSED); - - if (recorder_busy) - { - /************************************************************************* - * This occurs if an ISR calls a trace function, preempting a previous - * trace call that is being processed in a different ISR or task. - * If this occurs, there is probably a problem in the definition of the - * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and - * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt - * and any other ISRs that calls the trace recorder directly or via - * traced kernel functions. The ARM port disables all interrupts using the - * PRIMASK register to avoid this issue. - *************************************************************************/ - prvTraceError("Recorder busy - high priority ISR using syscall? (1)"); - return; - } - - trcCRITICAL_SECTION_BEGIN(); - if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */ - { - dts3 = (uint16_t)prvTraceGetDTS(0xFFFF); - hnd8 = prvTraceGet8BitHandle(handle); - tr = (TREvent*)prvTraceNextFreeEventBufferSlot(); - if (tr != 0) - { - tr->type = DIV_TASK_READY; - tr->dts = dts3; - tr->objHandle = hnd8; - prvTraceUpdateCounters(); - } - } - trcCRITICAL_SECTION_END(); -} -#endif - -/******************************************************************************* - * prvTraceStoreLowPower - * - * This function stores a low power state. - ******************************************************************************/ -void prvTraceStoreLowPower(uint32_t flag) -{ - uint16_t dts; - LPEvent* lp; - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ASSERT(flag <= 1, "prvTraceStoreLowPower: Invalid flag value", TRC_UNUSED); - - if (recorder_busy) - { - /************************************************************************* - * This occurs if an ISR calls a trace function, preempting a previous - * trace call that is being processed in a different ISR or task. - * If this occurs, there is probably a problem in the definition of the - * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and - * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt - * and any other ISRs that calls the trace recorder directly or via - * traced kernel functions. The ARM port disables all interrupts using the - * PRIMASK register to avoid this issue. - *************************************************************************/ - prvTraceError("Recorder busy - high priority ISR using syscall? (1)"); - return; - } - - trcCRITICAL_SECTION_BEGIN(); - if (RecorderDataPtr->recorderActive) - { - dts = (uint16_t)prvTraceGetDTS(0xFFFF); - lp = (LPEvent*)prvTraceNextFreeEventBufferSlot(); - if (lp != 0) - { - lp->type = (uint8_t) (LOW_POWER_BEGIN + ( uint8_t ) flag); /* BEGIN or END depending on flag */ - lp->dts = dts; - prvTraceUpdateCounters(); - } - } - trcCRITICAL_SECTION_END(); -} - -/******************************************************************************* - * vTraceStoreMemMangEvent - * - * This function stores malloc and free events. Each call requires two records, - * for size and address respectively. The event code parameter (ecode) is applied - * to the first record (size) and the following address record gets event - * code "ecode + 1", so make sure this is respected in the event code table. - * Note: On "free" calls, the signed_size parameter should be negative. - ******************************************************************************/ -#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) -#if (TRC_CFG_SCHEDULING_ONLY == 0) -void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size) -{ - uint8_t dts1; - MemEventSize * ms; - MemEventAddr * ma; - uint16_t size_low; - uint16_t addr_low; - uint8_t addr_high; - uint32_t size; - TRACE_ALLOC_CRITICAL_SECTION(); - - if (RecorderDataPtr == 0) - { - /* Occurs in vTraceInitTraceData, if using dynamic allocation. */ - return; - } - - if (signed_size < 0) - size = (uint32_t)(- signed_size); - else - size = (uint32_t)(signed_size); - - trcCRITICAL_SECTION_BEGIN(); - - /* Only update heapMemUsage if we have a valid address */ - if (address != 0) - { - RecorderDataPtr->heapMemUsage += (uint32_t)signed_size; - - if (RecorderDataPtr->heapMemUsage > RecorderDataPtr->heapMemMaxUsage) - { - RecorderDataPtr->heapMemMaxUsage = RecorderDataPtr->heapMemUsage; - } - } - - if (RecorderDataPtr->recorderActive) - { - dts1 = (uint8_t)prvTraceGetDTS(0xFF); - size_low = (uint16_t)prvTraceGetParam(0xFFFF, size); - ms = (MemEventSize *)prvTraceNextFreeEventBufferSlot(); - - if (ms != 0) - { - ms->dts = dts1; - ms->type = NULL_EVENT; /* Updated when all events are written */ - ms->size = size_low; - prvTraceUpdateCounters(); - - /* Storing a second record with address (signals "failed" if null) */ - #if (TRC_CFG_HEAP_SIZE_BELOW_16M) - /* If the heap address range is within 16 MB, i.e., the upper 8 bits - of addresses are constant, this optimization avoids storing an extra - event record by ignoring the upper 8 bit of the address */ - addr_low = address & 0xFFFF; - addr_high = (address >> 16) & 0xFF; - #else - /* The whole 32 bit address is stored using a second event record - for the upper 16 bit */ - addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address); - addr_high = 0; - #endif - - ma = (MemEventAddr *) prvTraceNextFreeEventBufferSlot(); - if (ma != 0) - { - ma->addr_low = addr_low; - ma->addr_high = addr_high; - ma->type = (uint8_t) (ecode + 1); /* Note this! */ - ms->type = (uint8_t) ecode; /* Set type of first event */ - prvTraceUpdateCounters(); - } - } - } - trcCRITICAL_SECTION_END(); -} -#endif /* TRC_CFG_SCHEDULING_ONLY */ -#endif - -/******************************************************************************* - * prvTraceStoreKernelCall - * - * This is the main integration point for storing kernel calls, and - * is called by the hooks in trcKernelHooks.h (see trcKernelPort.h for event codes). - ******************************************************************************/ -#if (TRC_CFG_SCHEDULING_ONLY == 0) -void prvTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber) -{ - KernelCall * kse; - uint16_t dts1; - uint8_t hnd8; - TRACE_ALLOC_CRITICAL_SECTION(); - - /* Avoids warnings when asserts are disabled */ - (void)objectClass; - - TRACE_ASSERT(ecode < 0xFF, "prvTraceStoreKernelCall: ecode >= 0xFF", TRC_UNUSED); - TRACE_ASSERT(objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCall: objectClass >= TRACE_NCLASSES", TRC_UNUSED); - TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "prvTraceStoreKernelCall: Invalid value for objectNumber", TRC_UNUSED); - - if (recorder_busy) - { - /************************************************************************* - * This occurs if an ISR calls a trace function, preempting a previous - * trace call that is being processed in a different ISR or task. - * If this occurs, there is probably a problem in the definition of the - * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and - * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt - * and any other ISRs that calls the trace recorder directly or via - * traced kernel functions. The ARM port disables all interrupts using the - * PRIMASK register to avoid this issue. - *************************************************************************/ - prvTraceError("Recorder busy - high priority ISR using syscall? (2)"); - return; - } - - if (handle_of_last_logged_task == 0) - { - return; - } - - trcCRITICAL_SECTION_BEGIN(); - if (RecorderDataPtr->recorderActive) - { - dts1 = (uint16_t)prvTraceGetDTS(0xFFFF); - hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber); - kse = (KernelCall*) prvTraceNextFreeEventBufferSlot(); - if (kse != 0) - { - kse->dts = dts1; - kse->type = (uint8_t)ecode; - kse->objHandle = hnd8; - prvTraceUpdateCounters(); - } - } - trcCRITICAL_SECTION_END(); -} -#endif /* TRC_CFG_SCHEDULING_ONLY */ - -/******************************************************************************* - * prvTraceStoreKernelCallWithParam - * - * Used for storing kernel calls with a handle and a numeric parameter. If the - * numeric parameter does not fit in one byte, and extra XPS event is inserted - * before the kernel call event containing the three upper bytes. - ******************************************************************************/ -#if (TRC_CFG_SCHEDULING_ONLY == 0) -void prvTraceStoreKernelCallWithParam(uint32_t evtcode, - traceObjectClass objectClass, - uint32_t objectNumber, - uint32_t param) -{ - KernelCallWithParamAndHandle * kse; - uint8_t dts2; - uint8_t hnd8; - uint8_t p8; - TRACE_ALLOC_CRITICAL_SECTION(); - - /* Avoids warnings when asserts are disabled */ - (void)objectClass; - - TRACE_ASSERT(evtcode < 0xFF, "prvTraceStoreKernelCallWithParam: evtcode >= 0xFF", TRC_UNUSED); - TRACE_ASSERT(objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCallWithParam: objectClass >= TRACE_NCLASSES", TRC_UNUSED); - TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "prvTraceStoreKernelCallWithParam: Invalid value for objectNumber", TRC_UNUSED); - - if (recorder_busy) - { - /************************************************************************* - * This occurs if an ISR calls a trace function, preempting a previous - * trace call that is being processed in a different ISR or task. - * If this occurs, there is probably a problem in the definition of the - * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and - * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt - * and any other ISRs that calls the trace recorder directly or via - * traced kernel functions. The ARM port disables all interrupts using the - * PRIMASK register to avoid this issue. - *************************************************************************/ - prvTraceError("Recorder busy - high priority ISR using syscall? (3)"); - return; - } - - trcCRITICAL_SECTION_BEGIN(); - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - { - dts2 = (uint8_t)prvTraceGetDTS(0xFF); - p8 = (uint8_t) prvTraceGetParam(0xFF, param); - hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber); - kse = (KernelCallWithParamAndHandle*) prvTraceNextFreeEventBufferSlot(); - if (kse != 0) - { - kse->dts = dts2; - kse->type = (uint8_t)evtcode; - kse->objHandle = hnd8; - kse->param = p8; - prvTraceUpdateCounters(); - } - } - trcCRITICAL_SECTION_END(); -} -#endif /* TRC_CFG_SCHEDULING_ONLY */ - - -/******************************************************************************* - * prvTraceGetParam - * - * Used for storing extra bytes for kernel calls with numeric parameters. - * - * May only be called within a critical section! - ******************************************************************************/ -#if (TRC_CFG_SCHEDULING_ONLY == 0) -static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param) -{ - XPSEvent* xps; - - TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF, - "prvTraceGetParam: Invalid value for param_max", param); - - if (param <= param_max) - { - return param; - } - else - { - xps = (XPSEvent*) prvTraceNextFreeEventBufferSlot(); - if (xps != 0) - { - xps->type = DIV_XPS; - xps->xps_8 = (uint8_t)((param & (0xFF00 & ~param_max)) >> 8); - xps->xps_16 = (uint16_t)((param & (0xFFFF0000 & ~param_max)) >> 16); - prvTraceUpdateCounters(); - } - - return param & param_max; - } -} -#endif - -/******************************************************************************* - * prvTraceStoreKernelCallWithNumericParamOnly - * - * Used for storing kernel calls with numeric parameters only. This is - * only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment. - ******************************************************************************/ -#if (TRC_CFG_SCHEDULING_ONLY == 0) -void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param) -{ - KernelCallWithParam16 * kse; - uint8_t dts6; - uint16_t restParam; - TRACE_ALLOC_CRITICAL_SECTION(); - - restParam = 0; - - TRACE_ASSERT(evtcode < 0xFF, "prvTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", TRC_UNUSED); - - if (recorder_busy) - { - /************************************************************************* - * This occurs if an ISR calls a trace function, preempting a previous - * trace call that is being processed in a different ISR or task. - * If this occurs, there is probably a problem in the definition of the - * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and - * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt - * and any other ISRs that calls the trace recorder directly or via - * traced kernel functions. The ARM port disables all interrupts using the - * PRIMASK register to avoid this issue. - *************************************************************************/ - prvTraceError("Recorder busy - high priority ISR using syscall? (4)"); - return; - } - - trcCRITICAL_SECTION_BEGIN(); - if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) - { - dts6 = (uint8_t)prvTraceGetDTS(0xFF); - restParam = (uint16_t)prvTraceGetParam(0xFFFF, param); - kse = (KernelCallWithParam16*) prvTraceNextFreeEventBufferSlot(); - if (kse != 0) - { - kse->dts = dts6; - kse->type = (uint8_t)evtcode; - kse->param = restParam; - prvTraceUpdateCounters(); - } - } - trcCRITICAL_SECTION_END(); -} -#endif /* TRC_CFG_SCHEDULING_ONLY */ - -/******************************************************************************* - * prvTraceStoreTaskswitch - * Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart. - * At this point interrupts are assumed to be disabled! - ******************************************************************************/ -void prvTraceStoreTaskswitch(traceHandle task_handle) -{ - uint16_t dts3; - TSEvent* ts; - uint8_t hnd8; -#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) - extern int32_t isPendingContextSwitch; -#endif - trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY(); - - TRACE_ASSERT(task_handle <= (TRC_CFG_NTASK), - "prvTraceStoreTaskswitch: Invalid value for task_handle", TRC_UNUSED); - - trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY(); - - if ((task_handle != handle_of_last_logged_task) && (RecorderDataPtr->recorderActive)) - { -#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) - isPendingContextSwitch = 0; -#endif - - dts3 = (uint16_t)prvTraceGetDTS(0xFFFF); - handle_of_last_logged_task = task_handle; - hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task); - ts = (TSEvent*)prvTraceNextFreeEventBufferSlot(); - - if (ts != 0) - { - if (prvTraceGetObjectState(TRACE_CLASS_TASK, - handle_of_last_logged_task) == TASK_STATE_INSTANCE_ACTIVE) - { - ts->type = TS_TASK_RESUME; - } - else - { - ts->type = TS_TASK_BEGIN; - } - - ts->dts = dts3; - ts->objHandle = hnd8; - - prvTraceSetObjectState(TRACE_CLASS_TASK, - handle_of_last_logged_task, - TASK_STATE_INSTANCE_ACTIVE); - - prvTraceUpdateCounters(); - } - } - - trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY(); -} - -/******************************************************************************* - * prvTraceStoreObjectNameOnCloseEvent - * - * Updates the symbol table with the name of this object from the dynamic - * objects table and stores a "close" event, holding the mapping between handle - * and name (a symbol table handle). The stored name-handle mapping is thus the - * "old" one, valid up until this point. - ******************************************************************************/ -void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle, - traceObjectClass objectclass) -{ - ObjCloseNameEvent * ce; - const char * name; - TraceStringHandle_t idx; - - TRACE_ASSERT(objectclass < TRACE_NCLASSES, - "prvTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED); - TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], - "prvTraceStoreObjectNameOnCloseEvent: Invalid value for handle", TRC_UNUSED); - - if (RecorderDataPtr->recorderActive) - { - uint8_t hnd8 = prvTraceGet8BitHandle(handle); - name = TRACE_PROPERTY_NAME_GET(objectclass, handle); - idx = prvTraceOpenSymbol(name, 0); - - // Interrupt disable not necessary, already done in trcHooks.h macro - ce = (ObjCloseNameEvent*) prvTraceNextFreeEventBufferSlot(); - if (ce != 0) - { - ce->type = (uint8_t) evtcode; - ce->objHandle = hnd8; - ce->symbolIndex = idx; - prvTraceUpdateCounters(); - } - } -} - -void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle, - traceObjectClass objectclass) -{ - ObjClosePropEvent * pe; - - TRACE_ASSERT(objectclass < TRACE_NCLASSES, - "prvTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED); - TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], - "prvTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", TRC_UNUSED); - - if (RecorderDataPtr->recorderActive) - { - // Interrupt disable not necessary, already done in trcHooks.h macro - pe = (ObjClosePropEvent*) prvTraceNextFreeEventBufferSlot(); - if (pe != 0) - { - if (objectclass == TRACE_CLASS_TASK) - { - pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle); - } - else - { - pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle); - } - pe->type = evtcode; - prvTraceUpdateCounters(); - } - } -} - -void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value) -{ - TRACE_ASSERT(objectclass < TRACE_NCLASSES, - "prvTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", TRC_UNUSED); - TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], - "prvTraceSetPriorityProperty: Invalid value for id", TRC_UNUSED); - - TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value; -} - -uint8_t prvTraceGetPriorityProperty(uint8_t objectclass, traceHandle id) -{ - TRACE_ASSERT(objectclass < TRACE_NCLASSES, - "prvTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0); - TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], - "prvTraceGetPriorityProperty: Invalid value for id", 0); - - return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id); -} - -void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value) -{ - TRACE_ASSERT(objectclass < TRACE_NCLASSES, - "prvTraceSetObjectState: objectclass >= TRACE_NCLASSES", TRC_UNUSED); - TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], - "prvTraceSetObjectState: Invalid value for id", TRC_UNUSED); - - TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value; -} - -uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id) -{ - TRACE_ASSERT(objectclass < TRACE_NCLASSES, - "prvTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0); - TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], - "prvTraceGetObjectState: Invalid value for id", 0); - - return TRACE_PROPERTY_OBJECT_STATE(objectclass, id); -} - -void prvTraceSetTaskInstanceFinished(traceHandle handle) -{ - /* Avoids warnings when asserts are disabled */ - (void)handle; - - TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK], - "prvTraceSetTaskInstanceFinished: Invalid value for handle", TRC_UNUSED); - -#if (TRC_CFG_USE_IMPLICIT_IFE_RULES == 1) - TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0; -#endif -} - -void* prvTraceNextFreeEventBufferSlot(void) -{ - if (! RecorderDataPtr->recorderActive) - { - /* If an XTS or XPS event prior to the main event has filled the buffer - before saving the main event, and store mode is "stop when full". */ - return 0; - } - - if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE)) - { - prvTraceError("Attempt to index outside event buffer!"); - return 0; - } - return (void*)(&RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex*4]); -} - -uint16_t uiIndexOfObject(traceHandle objecthandle, uint8_t objectclass) -{ - uint16_t index; - TRACE_ASSERT(objectclass < TRACE_NCLASSES, - "uiIndexOfObject: Invalid value for objectclass", 0); - TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], - "uiIndexOfObject: Invalid value for objecthandle", 0); - - if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) && - (objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass])) - { - index = (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] + - (RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle - 1))); - return index; - } - - prvTraceError("Object table lookup with invalid object handle or object class!"); - return 0; -} - -traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass) -{ - traceHandle handle; - static int indexOfHandle; - - TRACE_ALLOC_CRITICAL_SECTION(); - - TRACE_ASSERT(RecorderDataPtr != 0, "Recorder not initialized, call vTraceEnable() first!", (traceHandle)0); - - TRACE_ASSERT(objectclass < TRACE_NCLASSES, - "prvTraceGetObjectHandle: Invalid value for objectclass", (traceHandle)0); - - trcCRITICAL_SECTION_BEGIN(); - indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass]; - if (objectHandleStacks.objectHandles[indexOfHandle] == 0) - { - /* Zero is used to indicate a never before used handle, i.e., - new slots in the handle stack. The handle slot needs to - be initialized here (starts at 1). */ - objectHandleStacks.objectHandles[indexOfHandle] = - (traceHandle)(1 + indexOfHandle - - objectHandleStacks.lowestIndexOfClass[objectclass]); - } - - handle = objectHandleStacks.objectHandles[indexOfHandle]; - - if (objectHandleStacks.indexOfNextAvailableHandle[objectclass] - > objectHandleStacks.highestIndexOfClass[objectclass]) - { - prvTraceError(pszTraceGetErrorNotEnoughHandles(objectclass)); - handle = 0; - } - else - { - int hndCount; - objectHandleStacks.indexOfNextAvailableHandle[objectclass]++; - - hndCount = objectHandleStacks.indexOfNextAvailableHandle[objectclass] - - objectHandleStacks.lowestIndexOfClass[objectclass]; - - if (hndCount > - objectHandleStacks.handleCountWaterMarksOfClass[objectclass]) - { - objectHandleStacks.handleCountWaterMarksOfClass[objectclass] = - (traceHandle)hndCount; - } - } - trcCRITICAL_SECTION_END(); - - return handle; -} - -void prvTraceFreeObjectHandle(traceObjectClass objectclass, traceHandle handle) -{ - int indexOfHandle; - - TRACE_ASSERT(RecorderDataPtr != 0, "Recorder not initialized, call vTraceEnable() first!", TRC_UNUSED); - TRACE_ASSERT(objectclass < TRACE_NCLASSES, - "prvTraceFreeObjectHandle: Invalid value for objectclass", TRC_UNUSED); - TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], - "prvTraceFreeObjectHandle: Invalid value for handle", TRC_UNUSED); - - /* Check that there is room to push the handle on the stack */ - if ((objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 1) < - objectHandleStacks.lowestIndexOfClass[objectclass]) - { - /* Error */ - prvTraceError("Attempt to free more handles than allocated!"); - } - else - { - objectHandleStacks.indexOfNextAvailableHandle[objectclass]--; - indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass]; - objectHandleStacks.objectHandles[indexOfHandle] = handle; - } -} - -/******************************************************************************* - * prvMarkObjectAsUsed - * - * Sets an "is used flag" on object creation, using the first byte of the name - * field. This allows for counting the number of used Object Table slots, even - * if no names have been set. - ******************************************************************************/ -void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle) -{ - uint16_t idx = uiIndexOfObject(handle, objectclass); - RecorderDataPtr->ObjectPropertyTable.objbytes[idx] = 1; -} - -/******************************************************************************* - * prvStrncpy - * - * Private string copy function, to improve portability between compilers. - ******************************************************************************/ -static void prvStrncpy(char* dst, const char* src, uint32_t maxLength) -{ - uint32_t i; - for (i = 0; i < maxLength; i++) - { - dst[i] = src[i]; - if (src[i] == 0) - break; - } -} - -/******************************************************************************* - * prvTraceSetObjectName - * - * Registers the names of queues, semaphores and other kernel objects in the - * recorder's Object Property Table, at the given handle and object class. - ******************************************************************************/ -void prvTraceSetObjectName(traceObjectClass objectclass, - traceHandle handle, - const char* name) -{ - static uint16_t idx; - - if (name == 0) - { - name = ""; - } - - if (objectclass >= TRACE_NCLASSES) - { - prvTraceError("Illegal object class in prvTraceSetObjectName"); - return; - } - - if (handle == 0) - { - prvTraceError("Illegal handle (0) in prvTraceSetObjectName."); - return; - } - - if (handle > RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]) - { - /* ERROR */ - prvTraceError(pszTraceGetErrorNotEnoughHandles(objectclass)); - } - else - { - idx = uiIndexOfObject(handle, objectclass); - - if (traceErrorMessage == 0) - { - prvStrncpy((char*)&(RecorderDataPtr->ObjectPropertyTable.objbytes[idx]), - name, - RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ]); - } - } -} - -TraceStringHandle_t prvTraceOpenSymbol(const char* name, TraceStringHandle_t userEventChannel) -{ - uint16_t result; - uint8_t len; - uint8_t crc; - TRACE_ALLOC_CRITICAL_SECTION(); - - len = 0; - crc = 0; - - TRACE_ASSERT(name != 0, "prvTraceOpenSymbol: name == NULL", (TraceStringHandle_t)0); - - prvTraceGetChecksum(name, &crc, &len); - - trcCRITICAL_SECTION_BEGIN(); - result = prvTraceLookupSymbolTableEntry(name, crc, len, userEventChannel); - if (!result) - { - result = prvTraceCreateSymbolTableEntry(name, crc, len, userEventChannel); - } - trcCRITICAL_SECTION_END(); - - return result; -} - - -/****************************************************************************** -* vTraceSetFrequency -* -* Registers the clock rate of the time source for the event timestamping. -* This is normally not required, but if the default value (TRC_HWTC_FREQ_HZ) -* should be incorrect for your setup, you can override it using this function. -* -* Must be called prior to vTraceEnable, and the time source is assumed to -* have a fixed clock frequency after the startup. -* -* Note that, in snapshot mode, the value is divided by the TRC_HWTC_DIVISOR. -* This is a software "prescaler" that is also applied on the timestamps. -*****************************************************************************/ -void vTraceSetFrequency(uint32_t frequency) -{ - timestampFrequency = frequency; -} - -/******************************************************************************* - * Supporting functions - ******************************************************************************/ - -/******************************************************************************* - * prvTraceError - * - * Called by various parts in the recorder. Stops the recorder and stores a - * pointer to an error message, which is printed by the monitor task. - * If you are not using the monitor task, you may use xTraceErrorGetLast() - * from your application to check if the recorder is OK. - * - * Note: If a recorder error is registered before vTraceStart is called, the - * trace start will be aborted. This can occur if any of the Nxxxx constants - * (e.g., TRC_CFG_NTASK) in trcConfig.h is too small. - ******************************************************************************/ -void prvTraceError(const char* msg) -{ - /* Stop the recorder */ - if (RecorderDataPtr != 0) - { - xTraceDisable(); - } - - /* If first error only... */ - if (traceErrorMessage == 0) - { - traceErrorMessage = (char*)(intptr_t) msg; - if (RecorderDataPtr != 0) - { - prvStrncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80); - RecorderDataPtr->internalErrorOccured = 1; - } - } -} - -void vTraceSetFilterMask(uint16_t filterMask) -{ - CurrentFilterMask = filterMask; -} - -void vTraceSetFilterGroup(uint16_t filterGroup) -{ - CurrentFilterGroup = filterGroup; -} - -/****************************************************************************** - * prvCheckDataToBeOverwrittenForMultiEntryEvents - * - * This checks if the next event to be overwritten is a multi-entry user event, - * i.e., a USER_EVENT followed by data entries. - * Such data entries do not have an event code at byte 0, as other events. - * All 4 bytes are user data, so the first byte of such data events must - * not be interpreted as type field. The number of data entries following - * a USER_EVENT is given in the event code of the USER_EVENT. - * Therefore, when overwriting a USER_EVENT (when using in ring-buffer mode) - * any data entries following must be replaced with NULL events (code 0). - * - * This is assumed to execute within a critical section... - *****************************************************************************/ - -#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) -void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nofEntriesToCheck) -{ - /* Generic "int" type is desired - should be 16 bit variable on 16 bit HW */ - unsigned int i = 0; - unsigned int e = 0; - - TRACE_ASSERT(nofEntriesToCheck != 0, - "prvCheckDataToBeOverwrittenForMultiEntryEvents: nofEntriesToCheck == 0", TRC_UNUSED); - - while (i < nofEntriesToCheck) - { - e = RecorderDataPtr->nextFreeIndex + i; - if ((RecorderDataPtr->eventData[e*4] > USER_EVENT) && - (RecorderDataPtr->eventData[e*4] < USER_EVENT + 16)) - { - uint8_t nDataEvents = (uint8_t)(RecorderDataPtr->eventData[e*4] - USER_EVENT); - if ((e + nDataEvents) < RecorderDataPtr->maxEvents) - { - (void)memset(& RecorderDataPtr->eventData[e*4], 0, (size_t) (4 + 4 * nDataEvents)); - } - } - else if (RecorderDataPtr->eventData[e*4] == DIV_XPS) - { - if ((e + 1) < RecorderDataPtr->maxEvents) - { - /* Clear 8 bytes */ - (void)memset(& RecorderDataPtr->eventData[e*4], 0, 4 + 4); - } - else - { - /* Clear 8 bytes, 4 first and 4 last */ - (void)memset(& RecorderDataPtr->eventData[0], 0, 4); - (void)memset(& RecorderDataPtr->eventData[e*4], 0, 4); - } - } - i++; - } -} -#endif - -/******************************************************************************* - * prvTraceUpdateCounters - * - * Updates the index of the event buffer. - ******************************************************************************/ -void prvTraceUpdateCounters(void) -{ - if (RecorderDataPtr->recorderActive == 0) - { - return; - } - - RecorderDataPtr->numEvents++; - - RecorderDataPtr->nextFreeIndex++; - - if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE)) - { -#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) - RecorderDataPtr->bufferIsFull = 1; - RecorderDataPtr->nextFreeIndex = 0; -#else - vTraceStop(); -#endif - } - -#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) - prvCheckDataToBeOverwrittenForMultiEntryEvents(1); -#endif -} - -/****************************************************************************** - * prvTraceGetDTS - * - * Returns a differential timestamp (DTS), i.e., the time since - * last event, and creates an XTS event if the DTS does not fit in the - * number of bits given. The XTS event holds the MSB bytes of the DTS. - * - * The parameter param_maxDTS should be 0xFF for 8-bit dts or 0xFFFF for - * events with 16-bit dts fields. - *****************************************************************************/ -uint16_t prvTraceGetDTS(uint16_t param_maxDTS) -{ - static uint32_t old_timestamp = 0; - XTSEvent* xts = 0; - uint32_t dts = 0; - uint32_t timestamp = 0; - - TRACE_ASSERT(param_maxDTS == 0xFF || param_maxDTS == 0xFFFF, "prvTraceGetDTS: Invalid value for param_maxDTS", 0); - - - if (RecorderDataPtr->frequency == 0) - { - if (timestampFrequency != 0) - { - /* If to override default TRC_HWTC_FREQ_HZ value with value set by vTraceSetFrequency */ - RecorderDataPtr->frequency = timestampFrequency / (TRC_HWTC_DIVISOR); - } - else if (init_hwtc_count != (TRC_HWTC_COUNT)) - { - /* If using default value and timer has been started. - Note: If the default frequency value set here would be incorrect, e.g., - if the timer has actually not been configured yet, override this - with vTraceSetFrequency. - */ - RecorderDataPtr->frequency = (TRC_HWTC_FREQ_HZ) / (TRC_HWTC_DIVISOR); - } - /* If no override (vTraceSetFrequency) and timer inactive -> no action */ - } - - /************************************************************************** - * The below statements read the timestamp from the timer port module. - * If necessary, whole seconds are extracted using division while the rest - * comes from the modulo operation. - **************************************************************************/ - - prvTracePortGetTimeStamp(×tamp); - - /*************************************************************************** - * Since dts is unsigned the result will be correct even if timestamp has - * wrapped around. - ***************************************************************************/ - dts = timestamp - old_timestamp; - old_timestamp = timestamp; - - if (RecorderDataPtr->frequency > 0) - { - /* Check if dts > 1 second */ - if (dts > RecorderDataPtr->frequency) - { - /* More than 1 second has passed */ - RecorderDataPtr->absTimeLastEventSecond += dts / RecorderDataPtr->frequency; - /* The part that is not an entire second is added to absTimeLastEvent */ - RecorderDataPtr->absTimeLastEvent += dts % RecorderDataPtr->frequency; - } - else - { - RecorderDataPtr->absTimeLastEvent += dts; - } - - /* Check if absTimeLastEvent >= 1 second */ - if (RecorderDataPtr->absTimeLastEvent >= RecorderDataPtr->frequency) - { - /* RecorderDataPtr->absTimeLastEvent is more than or equal to 1 second, but always less than 2 seconds */ - RecorderDataPtr->absTimeLastEventSecond++; - RecorderDataPtr->absTimeLastEvent -= RecorderDataPtr->frequency; - /* RecorderDataPtr->absTimeLastEvent is now less than 1 second */ - } - } - else - { - /* Special case if the recorder has not yet started (frequency may be uninitialized, i.e., zero) */ - RecorderDataPtr->absTimeLastEvent = timestamp; - } - - /* If the dts (time since last event) does not fit in event->dts (only 8 or 16 bits) */ - if (dts > param_maxDTS) - { - /* Create an XTS event (eXtended TimeStamp) containing the higher dts bits*/ - xts = (XTSEvent*) prvTraceNextFreeEventBufferSlot(); - - if (xts != 0) - { - if (param_maxDTS == 0xFFFF) - { - xts->type = XTS16; - xts->xts_16 = (uint16_t)((dts / 0x10000) & 0xFFFF); - xts->xts_8 = 0; - } - else if (param_maxDTS == 0xFF) - { - xts->type = XTS8; - xts->xts_16 = (uint16_t)((dts / 0x100) & 0xFFFF); - xts->xts_8 = (uint8_t)((dts / 0x1000000) & 0xFF); - } - else - { - prvTraceError("Bad param_maxDTS in prvTraceGetDTS"); - } - prvTraceUpdateCounters(); - } - } - - return (uint16_t)dts & param_maxDTS; -} - -/******************************************************************************* - * prvTraceLookupSymbolTableEntry - * - * Find an entry in the symbol table, return 0 if not present. - * - * The strings are stored in a byte pool, with four bytes of "meta-data" for - * every string. - * byte 0-1: index of next entry with same checksum (for fast lookup). - * byte 2-3: reference to a symbol table entry, a label for xTracePrintF - * format strings only (the handle of the destination channel). - * byte 4..(4 + length): the string (object name or user event label), with - * zero-termination - ******************************************************************************/ -TraceStringHandle_t prvTraceLookupSymbolTableEntry(const char* name, - uint8_t crc6, - uint8_t len, - TraceStringHandle_t chn) -{ - uint16_t i = RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ]; - - TRACE_ASSERT(name != 0, "prvTraceLookupSymbolTableEntry: name == NULL", (TraceStringHandle_t)0); - TRACE_ASSERT(len != 0, "prvTraceLookupSymbolTableEntry: len == 0", (TraceStringHandle_t)0); - - while (i != 0) - { - if (RecorderDataPtr->SymbolTable.symbytes[i + 2] == (chn & 0x00FF)) - { - if (RecorderDataPtr->SymbolTable.symbytes[i + 3] == (chn / 0x100)) - { - if (RecorderDataPtr->SymbolTable.symbytes[i + 4 + len] == '\0') - { - if (strncmp((char*)(& RecorderDataPtr->SymbolTable.symbytes[i + 4]), name, len) == 0) - { - break; /* found */ - } - } - } - } - i = (uint16_t)(RecorderDataPtr->SymbolTable.symbytes[i] + (RecorderDataPtr->SymbolTable.symbytes[i + 1] * 0x100)); - } - return i; -} - -/******************************************************************************* - * prvTraceCreateSymbolTableEntry - * - * Creates an entry in the symbol table, independent if it exists already. - * - * The strings are stored in a byte pool, with four bytes of "meta-data" for - * every string. - * byte 0-1: index of next entry with same checksum (for fast lookup). - * byte 2-3: reference to a symbol table entry, a label for xTracePrintF - * format strings only (the handle of the destination channel). - * byte 4..(4 + length): the string (object name or user event label), with - * zero-termination - ******************************************************************************/ -TraceStringHandle_t prvTraceCreateSymbolTableEntry(const char* name, - uint8_t crc6, - uint8_t len, - TraceStringHandle_t channel) -{ - TraceStringHandle_t ret = 0; - - TRACE_ASSERT(name != 0, "prvTraceCreateSymbolTableEntry: name == NULL", 0); - TRACE_ASSERT(len != 0, "prvTraceCreateSymbolTableEntry: len == 0", 0); - - if (RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + len + 4 >= (TRC_CFG_SYMBOL_TABLE_SIZE)) - { - prvTraceError("Symbol table full. Increase TRC_CFG_SYMBOL_TABLE_SIZE in trcConfig.h"); - ret = 0; - } - else - { - - RecorderDataPtr->SymbolTable.symbytes - [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex] = - (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] & 0x00FF); - - RecorderDataPtr->SymbolTable.symbytes - [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 1] = - (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] / 0x100); - - RecorderDataPtr->SymbolTable.symbytes - [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 2] = - (uint8_t)(channel & 0x00FF); - - RecorderDataPtr->SymbolTable.symbytes - [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 3] = - (uint8_t)(channel / 0x100); - - /* set name (bytes 4...4+len-1) */ - prvStrncpy((char*)&(RecorderDataPtr->SymbolTable.symbytes - [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4]), name, len); - - /* Set zero termination (at offset 4+len) */ - RecorderDataPtr->SymbolTable.symbytes - [RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4 + len] = '\0'; - - /* store index of entry (for return value, and as head of LL[crc6]) */ - RecorderDataPtr->SymbolTable.latestEntryOfChecksum - [ crc6 ] = (uint16_t)RecorderDataPtr->SymbolTable.nextFreeSymbolIndex; - - RecorderDataPtr->SymbolTable.nextFreeSymbolIndex += (uint32_t) (len + 5); - - ret = (uint16_t)(RecorderDataPtr->SymbolTable.nextFreeSymbolIndex - (uint8_t)(len + 5)); - } - - return ret; -} - - -/******************************************************************************* - * prvTraceGetChecksum - * - * Calculates a simple 6-bit checksum from a string, used to index the string - * for fast symbol table lookup. - ******************************************************************************/ -void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength) -{ - unsigned char c; - int length = 1; /* Should be 1 to account for '\0' */ - int crc = 0; - - TRACE_ASSERT(pname != 0, "prvTraceGetChecksum: pname == NULL", TRC_UNUSED); - TRACE_ASSERT(pcrc != 0, "prvTraceGetChecksum: pcrc == NULL", TRC_UNUSED); - TRACE_ASSERT(plength != 0, "prvTraceGetChecksum: plength == NULL", TRC_UNUSED); - - if (pname != (const char *) 0) - { - for (; (c = (unsigned char) *pname++) != '\0';) - { - crc += c; - length++; - } - } - *pcrc = (uint8_t)(crc & 0x3F); - *plength = (uint8_t)length; -} - -#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) - -static void prvTraceStoreXID(traceHandle handle); - -/****************************************************************************** - * prvTraceStoreXID - * - * Stores an XID (eXtended IDentifier) event. - * This is used if an object/task handle is larger than 255. - * The parameter "handle" is the full (16 bit) handle, assumed to be 256 or - * larger. Handles below 256 should not use this function. - * - * NOTE: this function MUST be called from within a critical section. - *****************************************************************************/ -static void prvTraceStoreXID(traceHandle handle) -{ - XPSEvent* xid; - - TRACE_ASSERT(handle >= 256, "prvTraceStoreXID: Handle < 256", TRC_UNUSED); - - xid = (XPSEvent*)prvTraceNextFreeEventBufferSlot(); - - if (xid != 0) - { - xid->type = XID; - - /* This function is (only) used when traceHandle is 16 bit... */ - xid->xps_16 = handle; - - prvTraceUpdateCounters(); - } -} - -static uint8_t prvTraceGet8BitHandle(traceHandle handle) -{ - if (handle > 255) - { - prvTraceStoreXID(handle); - /* The full handle (16 bit) is stored in the XID event. - This code (255) is used instead of zero (which is an error code).*/ - return 255; - } - return (uint8_t)(handle & 0xFF); -} -#endif /*(TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)*/ - - -/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */ -#ifndef TRC_CFG_ARM_CM_USE_SYSTICK -#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03))) -void xTraceHardwarePortInitCortexM() -{ - /* Ensure that the DWT registers are unlocked and can be modified. */ - TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK; - - /* Make sure DWT is enabled, if supported */ - TRC_REG_DEMCR |= TRC_DEMCR_TRCENA; - - do{ - /* Verify that DWT is supported */ - if (TRC_REG_DEMCR == 0) - { - /* This function is called on Cortex-M3, M4 and M7 devices to initialize - the DWT unit, assumed present. The DWT cycle counter is used for timestamping. - - If the below error is produced, the DWT unit does not seem to be available. - - In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build - to use SysTick timestamping instead, or define your own timestamping by - setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED - and make the necessary definitions, as explained in trcHardwarePort.h.*/ - - prvTraceError("DWT unit not available, see code comment."); - break; - } - - /* Verify that DWT_CYCCNT is supported */ - if (TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT) - { - /* This function is called on Cortex-M3, M4 and M7 devices to initialize - the DWT unit, assumed present. The DWT cycle counter is used for timestamping. - - If the below error is produced, the cycle counter does not seem to be available. - - In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build - to use SysTick timestamping instead, or define your own timestamping by - setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED - and make the necessary definitions, as explained in trcHardwarePort.h.*/ - - prvTraceError("DWT_CYCCNT not available, see code comment."); - break; - } - - /* Reset the cycle counter */ - TRC_REG_DWT_CYCCNT = 0; - - /* Enable the cycle counter */ - TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA; - - }while(0); /* breaks above jump here */ -} -#endif -#endif - -/****************************************************************************** - * prvTracePortGetTimeStamp - * - * Returns the current time based on the HWTC macros which provide a hardware - * isolation layer towards the hardware timer/counter. - * - * The HWTC macros and prvTracePortGetTimeStamp is the main porting issue - * or the trace recorder library. Typically you should not need to change - * the code of prvTracePortGetTimeStamp if using the HWTC macros. - * - ******************************************************************************/ -void prvTracePortGetTimeStamp(uint32_t *pTimestamp) -{ - static uint32_t last_hwtc_count = 0; - uint32_t hwtc_count = 0; - -#if TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR - /* systick based timer */ - static uint32_t last_traceTickCount = 0; - uint32_t traceTickCount = 0; -#else /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/ - /* Free running timer */ - static uint32_t last_hwtc_rest = 0; - uint32_t diff = 0; - uint32_t diff_scaled = 0; -#endif /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/ - - if (trace_disable_timestamp == 1) - { - if (pTimestamp) - *pTimestamp = last_timestamp; - return; - } - - /* Retrieve TRC_HWTC_COUNT only once since the same value should be used all throughout this function. */ -#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR) - /* Get the increasing tick count */ - hwtc_count = (TRC_HWTC_COUNT); -#elif (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR) - /* Convert decreasing tick count into increasing tick count */ - hwtc_count = (TRC_HWTC_PERIOD) - (TRC_HWTC_COUNT); -#else - #error "TRC_HWTC_TYPE has unexpected value" -#endif - -#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32) - /* The Win32 port uses ulGetRunTimeCounterValue for timestamping, which in turn - uses QueryPerformanceCounter. That function is not always reliable when used over - multiple threads. We must therefore handle rare cases where the timestamp is less - than the previous. In practice, this should "never" roll over since the - performance counter is 64 bit wide. */ - - if (last_hwtc_count > hwtc_count) - { - hwtc_count = last_hwtc_count; - } -#endif - -#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR) - /* Timestamping is based on a timer that wraps at TRC_HWTC_PERIOD */ - if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000) - { - /* This means last_traceTickCount is higher than uiTraceTickCount, - so we have previously compensated for a missed tick. - Therefore we use the last stored value because that is more accurate. */ - traceTickCount = last_traceTickCount; - } - else - { - /* Business as usual */ - traceTickCount = uiTraceTickCount; - } - - /* Check for overflow. May occur if the update of uiTraceTickCount has been - delayed due to disabled interrupts. */ - if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count) - { - /* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */ - traceTickCount++; - } - - /* Check if the return address is OK, then we perform the calculation. */ - if (pTimestamp) - { - /* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */ - last_timestamp = traceTickCount * ((TRC_HWTC_PERIOD) / (TRC_HWTC_DIVISOR)); - /* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / TRC_HWTC_DIVISOR. */ - last_timestamp += (hwtc_count + traceTickCount * ((TRC_HWTC_PERIOD) % (TRC_HWTC_DIVISOR))) / (TRC_HWTC_DIVISOR); - } - /* Store the previous value */ - last_traceTickCount = traceTickCount; - -#else /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/ - - /* Timestamping is based on a free running timer */ - /* This part handles free running clocks that can be scaled down to avoid too large DTS values. - Without this, the scaled timestamp will incorrectly wrap at (2^32 / TRC_HWTC_DIVISOR) ticks. - The scaled timestamp returned from this function is supposed to go from 0 -> 2^32, which in real time would represent (0 -> 2^32 * TRC_HWTC_DIVISOR) ticks. */ - - /* First we see how long time has passed since the last timestamp call, and we also add the ticks that was lost when we scaled down the last time. */ - diff = (hwtc_count - last_hwtc_count) + last_hwtc_rest; - - /* Scale down the diff */ - diff_scaled = diff / (TRC_HWTC_DIVISOR); - - /* Find out how many ticks were lost when scaling down, so we can add them the next time */ - last_hwtc_rest = diff % (TRC_HWTC_DIVISOR); - - /* We increase the scaled timestamp by the scaled amount */ - last_timestamp += diff_scaled; -#endif /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/ - - /* Is anyone interested in the results? */ - if (pTimestamp) - *pTimestamp = last_timestamp; - - /* Store the previous value */ - last_hwtc_count = hwtc_count; -} - -#if defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) - -void prvAddTaskToStackMonitor(void* task) -{ - int i; - int foundEmptySlot = 0; - - // find an empty slot - for (i = 0; i < TRC_CFG_STACK_MONITOR_MAX_TASKS; i++) - { - if (tasksInStackMonitor[i].tcb == 0) - { - tasksInStackMonitor[i].tcb = task; - tasksInStackMonitor[i].uiPreviousLowMark = 0xFFFFFFFF; - foundEmptySlot = 1; - break; - } - } - - if (foundEmptySlot == 0) - { - tasksNotIncluded++; - } -} - -void prvRemoveTaskFromStackMonitor(void* task) -{ - int i; - - for (i = 0; i < TRC_CFG_STACK_MONITOR_MAX_TASKS; i++) - { - if (tasksInStackMonitor[i].tcb == task) - { - tasksInStackMonitor[i].tcb = 0; - tasksInStackMonitor[i].uiPreviousLowMark = 0; - } - } -} - -void prvReportStackUsage() -{ - static int i = 0; /* Static index used to loop over the monitored tasks */ - int count = 0; /* The number of generated reports */ - int initial = i; /* Used to make sure we break if we are back at the inital value */ - - do - { - /* Check the current spot */ - if (tasksInStackMonitor[i].tcb != 0) - { - /* Get the amount of unused stack */ - TraceUnsignedBaseType_t unusedStackSpace; - xTraceKernelPortGetUnusedStack(tasksInStackMonitor[i].tcb, &unusedStackSpace); - - /* Store for later use */ - if (tasksInStackMonitor[i].uiPreviousLowMark > unusedStackSpace) - tasksInStackMonitor[i].uiPreviousLowMark = unusedStackSpace; - - prvTraceStoreKernelCallWithParam(TRACE_UNUSED_STACK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(tasksInStackMonitor[i].tcb), tasksInStackMonitor[i].uiPreviousLowMark); - - count++; - } - - i = (i + 1) % TRC_CFG_STACK_MONITOR_MAX_TASKS; // Move i beyond this task - } while (count < TRC_CFG_STACK_MONITOR_MAX_REPORTS && i != initial); -} -#endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ - - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The generic core of the trace recorder's snapshot mode. + */ + +#include + +#if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #include + #include + + #ifndef TRC_CFG_RECORDER_DATA_INIT + #define TRC_CFG_RECORDER_DATA_INIT 1 + #endif + + #if ( ( TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR ) || ( TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR ) ) + #error "CUSTOM timestamping mode is not (yet) supported in snapshot mode!" + #endif + +/* DO NOT CHANGE */ + #define TRACE_MINOR_VERSION 7 + +/* Keeps track of the task's stack low mark */ + typedef struct + { + void * tcb; + uint32_t uiPreviousLowMark; + } TaskStackMonitorEntry_t; + + TraceKernelPortDataBuffer_t xKernelPortDataBuffer; + + #if ( TRC_CFG_INCLUDE_ISR_TRACING == 1 ) + +/******************************************************************************* + * isrstack + * + * Keeps track of nested interrupts. + ******************************************************************************/ + static traceHandle isrstack[ TRC_CFG_MAX_ISR_NESTING ]; + +/******************************************************************************* + * isPendingContextSwitch + * + * Used to indicate if there is a pending context switch. + * If there is a pending context switch the recorder will not create an event + * when returning from the ISR. + ******************************************************************************/ + int32_t isPendingContextSwitch = 0; + #endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1) */ + +/******************************************************************************* + * readyEventsEnabled + * + * This can be used to dynamically disable ready events. + ******************************************************************************/ + #if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1 + static int readyEventsEnabled = 1; + #endif /*!defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1*/ + +/******************************************************************************* + * uiTraceTickCount + * + * This variable is should be updated by the Kernel tick interrupt. This does + * not need to be modified when developing a new timer port. It is preferred to + * keep any timer port changes in the HWTC macro definitions, which typically + * give sufficient flexibility. + ******************************************************************************/ + uint32_t uiTraceTickCount = 0; + +/******************************************************************************* + * trace_disable_timestamp + * + * This can be used to disable timestamps as it will cause + * prvTracePortGetTimeStamp() to return the previous timestamp. + ******************************************************************************/ + uint32_t trace_disable_timestamp = 0; + +/******************************************************************************* + * last_timestamp + * + * The most recent timestamp. + ******************************************************************************/ + static uint32_t last_timestamp = 0; + +/******************************************************************************* + * uiTraceSystemState + * + * Indicates if we are currently performing a context switch or just running application code. + ******************************************************************************/ + volatile uint32_t uiTraceSystemState = TRC_STATE_IN_STARTUP; + +/******************************************************************************* + * recorder_busy + * + * Flag that shows if inside a critical section of the recorder. + ******************************************************************************/ + volatile int recorder_busy = 0; + +/******************************************************************************* + * timestampFrequency + * + * Holds the value set by vTraceSetFrequency. + ******************************************************************************/ + uint32_t timestampFrequency = 0; + +/******************************************************************************* + * nISRactive + * + * The number of currently active (including preempted) ISRs. + ******************************************************************************/ + int8_t nISRactive = 0; + +/******************************************************************************* + * handle_of_last_logged_task + * + * The current task. + ******************************************************************************/ + traceHandle handle_of_last_logged_task = 0; + +/******************************************************************************* + * vTraceStopHookPtr + * + * Called when the recorder is stopped, set by vTraceSetStopHook. + ******************************************************************************/ + TRACE_STOP_HOOK vTraceStopHookPtr = ( TRACE_STOP_HOOK ) 0; + +/******************************************************************************* + * init_hwtc_count + * + * Initial TRC_HWTC_COUNT value, for detecting if the time-stamping source is + * enabled. If using the OS periodic timer for time-stamping, this might not + * have been configured on the earliest events during the startup. + ******************************************************************************/ + uint32_t init_hwtc_count; + +/******************************************************************************* + * CurrentFilterMask + * + * The filter mask that will be checked against each object's FilterGroup to see + * if they should be included in the trace or not. + ******************************************************************************/ + uint16_t CurrentFilterMask TRC_CFG_RECORDER_DATA_ATTRIBUTE; + +/******************************************************************************* + * CurrentFilterGroup + * + * The current filter group that will be assigned to newly created objects. + ******************************************************************************/ + uint16_t CurrentFilterGroup TRC_CFG_RECORDER_DATA_ATTRIBUTE; + +/******************************************************************************* + * objectHandleStacks + * + * A set of stacks that keeps track of available object handles for each class. + * The stacks are empty initially, meaning that allocation of new handles will be + * based on a counter (for each object class). Any delete operation will + * return the handle to the corresponding stack, for reuse on the next allocate. + ******************************************************************************/ + objectHandleStackType objectHandleStacks TRC_CFG_RECORDER_DATA_ATTRIBUTE; + +/******************************************************************************* + * traceErrorMessage + * + * The last error message of the recorder. NULL if no error message. + ******************************************************************************/ + const char * traceErrorMessage TRC_CFG_RECORDER_DATA_ATTRIBUTE; + + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) + +/******************************************************************************* + * tasksInStackMonitor + * + * Keeps track of all stack low marks for tasks. + ******************************************************************************/ + TaskStackMonitorEntry_t tasksInStackMonitor[ TRC_CFG_STACK_MONITOR_MAX_TASKS ] TRC_CFG_RECORDER_DATA_ATTRIBUTE; + +/******************************************************************************* + * tasksNotIncluded + * + * The number of tasks that did not fit in the stack monitor. + ******************************************************************************/ + int tasksNotIncluded TRC_CFG_RECORDER_DATA_ATTRIBUTE; + #endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ + +/******************************************************************************* + * RecorderData + * + * The main data structure in snapshot mode, when using the default static memory + * allocation (TRC_RECORDER_BUFFER_ALLOCATION_STATIC). The recorder uses a pointer + * RecorderDataPtr to access the data, to also allow for dynamic or custom data + * allocation (see TRC_CFG_RECORDER_BUFFER_ALLOCATION). + ******************************************************************************/ + #if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC ) + RecorderDataType RecorderData TRC_CFG_RECORDER_DATA_ATTRIBUTE; + #endif + +/* Pointer to the main data structure, when in snapshot mode */ + RecorderDataType * RecorderDataPtr TRC_CFG_RECORDER_DATA_ATTRIBUTE; + + #if ( TRC_CFG_RECORDER_DATA_INIT != 0 ) + uint32_t RecorderInitialized = 0; + #else /* (TRC_CFG_RECORDER_DATA_INIT != 0) */ + uint32_t RecorderInitialized TRC_CFG_RECORDER_DATA_ATTRIBUTE; + #endif /* (TRC_CFG_RECORDER_DATA_INIT != 0) */ + +/*************** Private Functions *******************************************/ + static void prvStrncpy( char * dst, + const char * src, + uint32_t maxLength ); + static uint8_t prvTraceGetObjectState( uint8_t objectclass, + traceHandle id ); + static void prvTraceGetChecksum( const char * pname, + uint8_t * pcrc, + uint8_t * plength ); + static void * prvTraceNextFreeEventBufferSlot( void ); + static uint16_t prvTraceGetDTS( uint16_t param_maxDTS ); + static TraceStringHandle_t prvTraceOpenSymbol( const char * name, + TraceStringHandle_t userEventChannel ); + static void prvTraceUpdateCounters( void ); + + void vTraceStoreMemMangEvent( uint32_t ecode, + uint32_t address, + int32_t signed_size ); + + #if ( TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER ) + static void prvCheckDataToBeOverwrittenForMultiEntryEvents( uint8_t nEntries ); + #endif + + static TraceStringHandle_t prvTraceCreateSymbolTableEntry( const char * name, + uint8_t crc6, + uint8_t len, + TraceStringHandle_t channel ); + + static TraceStringHandle_t prvTraceLookupSymbolTableEntry( const char * name, + uint8_t crc6, + uint8_t len, + TraceStringHandle_t channel ); + + + #if ( TRC_CFG_INCLUDE_ISR_TRACING == 0 ) +/* ISR tracing is turned off */ + void prvTraceIncreaseISRActive( void ); + void prvTraceDecreaseISRActive( void ); + #endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/ + + #if ( TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1 ) + static uint8_t prvTraceGet8BitHandle( traceHandle handle ); + #else + #define prvTraceGet8BitHandle( x ) ( ( uint8_t ) x ) + #endif + + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + static uint32_t prvTraceGetParam( uint32_t, + uint32_t ); + #endif + +/******************************************************************************* + * prvTracePortGetTimeStamp + * + * Returns the current time based on the HWTC macros which provide a hardware + * isolation layer towards the hardware timer/counter. + * + * The HWTC macros and prvTracePortGetTimeStamp is the main porting issue + * or the trace recorder library. Typically you should not need to change + * the code of prvTracePortGetTimeStamp if using the HWTC macros. + * + ******************************************************************************/ + void prvTracePortGetTimeStamp( uint32_t * puiTimestamp ); + + static void prvTraceTaskInstanceFinish( int8_t direct ); + +/******************************************************************************* + * prvTraceInitTimestamps + * + * This will only be called once the recorder is started, and we can assume that + * all hardware has been initialized. + ******************************************************************************/ + static void prvTraceInitTimestamps( void ); + + static void prvTraceStart( void ); + + static void prvTraceStop( void ); + + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) + #if ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) + static void vTraceUBData_Helper( traceUBChannel channelPair, + va_list vl ); + static void prvTraceUBHelper1( traceUBChannel channel, + TraceStringHandle_t eventLabel, + TraceStringHandle_t formatLabel, + va_list vl ); + static void prvTraceUBHelper2( traceUBChannel channel, + uint32_t * data, + uint32_t noOfSlots ); + #endif /* (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) */ + #endif /* ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) */ + + uint16_t uiIndexOfObject( traceHandle objecthandle, + uint8_t objectclass ); + +/******************************************************************************* + * prvTraceError + * + * Called by various parts in the recorder. Stops the recorder and stores a + * pointer to an error message, which is printed by the monitor task. + ******************************************************************************/ + void prvTraceError( const char * msg ); + +/********* Public Functions **************************************************/ + + #if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM ) + traceResult xTraceSetBuffer( TraceRecorderDataBuffer_t * pxBuffer ) + { + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + RecorderDataPtr = ( RecorderDataType * ) pxBuffer; + + return TRC_SUCCESS; + } + #endif /* if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM ) */ + + traceResult xTraceGetEventBuffer( void ** ppvBuffer, + TraceUnsignedBaseType_t * puiSize ) + { + if( ( ppvBuffer == 0 ) || ( puiSize == 0 ) ) + { + return TRC_FAIL; + } + + *ppvBuffer = ( void * ) RecorderDataPtr; + *puiSize = sizeof( RecorderDataType ); + + return TRC_SUCCESS; + } + + traceResult xTraceEnable( uint32_t uiStartOption ) + { + /* Make sure recorder data is initialized */ + if( xTraceInitialize() == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( uiStartOption == TRC_START ) + { + if( xTraceKernelPortEnable() == TRC_FAIL ) + { + return TRC_FAIL; + } + + prvTraceInitTimestamps(); + + prvTraceStart(); + } + else if( uiStartOption == TRC_START_AWAIT_HOST ) + { + prvTraceError( "xTraceEnable(TRC_START_AWAIT_HOST) not allowed in Snapshot mode" ); + + return TRC_FAIL; + } + else if( uiStartOption != TRC_START_FROM_HOST ) + { + prvTraceError( "xTraceEnable(TRC_START_FROM_HOST) not allowed in Snapshot mode" ); + + return TRC_FAIL; + } + + return TRC_SUCCESS; + } + + + traceResult xTraceDisable( void ) + { + prvTraceStop(); + + return TRC_SUCCESS; + } + + void vTraceSetStopHook( TRACE_STOP_HOOK stopHookFunction ) + { + vTraceStopHookPtr = stopHookFunction; + } + + void vTraceClear( void ) + { + TRACE_ALLOC_CRITICAL_SECTION(); + trcCRITICAL_SECTION_BEGIN(); + RecorderDataPtr->absTimeLastEventSecond = 0; + RecorderDataPtr->absTimeLastEvent = 0; + RecorderDataPtr->nextFreeIndex = 0; + RecorderDataPtr->numEvents = 0; + RecorderDataPtr->bufferIsFull = 0; + traceErrorMessage = 0; + RecorderDataPtr->internalErrorOccurred = 0; + ( void ) memset( RecorderDataPtr->eventData, 0, RecorderDataPtr->maxEvents * 4 ); + handle_of_last_logged_task = 0; + trcCRITICAL_SECTION_END(); + } + + static void prvTraceStart( void ) + { + traceHandle handle; + + TRACE_ALLOC_CRITICAL_SECTION(); + + handle = 0; + + if( RecorderDataPtr == 0 ) + { + TRACE_ASSERT( RecorderDataPtr != 0, "Recorder not initialized. Use vTraceEnable() instead!", TRC_UNUSED ); + return; + } + + if( RecorderDataPtr->recorderActive == 1 ) + { + return; /* Already running */ + } + + if( traceErrorMessage == 0 ) + { + trcCRITICAL_SECTION_BEGIN(); + RecorderDataPtr->recorderActive = 1; + + handle = TRACE_GET_TASK_NUMBER( TRACE_GET_CURRENT_TASK() ); + + if( handle == 0 ) + { + /* This occurs if the scheduler is not yet started. + * This creates a dummy "(startup)" task entry internally in the + * recorder */ + handle = prvTraceGetObjectHandle( TRACE_CLASS_TASK ); + prvTraceSetObjectName( TRACE_CLASS_TASK, handle, "(startup)" ); + + prvTraceSetPriorityProperty( TRACE_CLASS_TASK, handle, 0 ); + } + + prvTraceStoreTaskswitch( handle ); /* Register the currently running task */ + trcCRITICAL_SECTION_END(); + } + } + +/******************************************************************************* + * prvTraceStop + * + * Stops the recorder. The recording can be resumed by calling vTraceStart. + * This does not reset the recorder. Use vTraceClear if that is desired. + ******************************************************************************/ + static void prvTraceStop( void ) + { + if( RecorderDataPtr != 0 ) + { + RecorderDataPtr->recorderActive = 0; + } + + if( vTraceStopHookPtr != ( TRACE_STOP_HOOK ) 0 ) + { + ( *vTraceStopHookPtr )(); /* An application call-back function. */ + } + } + +/******************************************************************************* + * xTraceIsRecorderEnabled + * Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0. + ******************************************************************************/ + uint32_t xTraceIsRecorderEnabled( void ) + { + if( ( RecorderInitialized == 1 ) && ( RecorderDataPtr != 0 ) ) + { + return RecorderDataPtr->recorderActive; + } + else + { + return 0; + } + } + +/****************************************************************************** +* xTraceIsRecorderInitialized +* +* Returns true (1) if the recorder is initialized. +******************************************************************************/ + uint32_t xTraceIsRecorderInitialized( void ) + { + return RecorderInitialized; + } + +/******************************************************************************* + * xTraceErrorGetLast + * + * Gives the last error message, if any. NULL if no error message is stored. + * Any error message is also presented when opening a trace file. + ******************************************************************************/ + const char * xTraceErrorGetLast( void ) + { + return traceErrorMessage; + } + +/******************************************************************************* + * vTraceClearError + * + * Removes any previous error message generated by recorder calling prvTraceError. + * By calling this function, it may be possible to start/restart the trace + * despite errors in the recorder, but there is no guarantee that the trace + * recorder will work correctly in that case, depending on the type of error. + ******************************************************************************/ + void vTraceClearError( void ) + { + traceErrorMessage = 0; + + if( RecorderDataPtr != 0 ) + { + RecorderDataPtr->internalErrorOccurred = 0; + } + } + +/******************************************************************************* + * xTraceGetTraceBuffer + * + * Returns a pointer to the recorder data structure. Use this together with + * uiTraceGetTraceBufferSize if you wish to implement an own store/upload + * solution, e.g., in case a debugger connection is not available for uploading + * the data. + ******************************************************************************/ + void * xTraceGetTraceBuffer( void ) + { + return RecorderDataPtr; + } + +/******************************************************************************* + * uiTraceGetTraceBufferSize + * + * Gets the size of the recorder data structure. For use together with + * vTraceGetTraceBuffer if you wish to implement an own store/upload solution, + * e.g., in case a debugger connection is not available for uploading the data. + ******************************************************************************/ + uint32_t uiTraceGetTraceBufferSize( void ) + { + return sizeof( RecorderDataType ); + } + +/******************************************************************************* + * prvTraceInitTimestamps + * + * If vTraceEnable(TRC_INIT) was called BEFORE the clock was initialized, this + * function must be called AFTER the clock is initialized to set a proper + * initial timestamp value. If vTraceEnable(...) is only called AFTER clock is + * initialized, there is no need to call this function. + ******************************************************************************/ + static void prvTraceInitTimestamps( void ) + { + init_hwtc_count = TRC_HWTC_COUNT; + } + +/****************************************************************************** + * prvTraceTaskInstanceFinish + * + * Private common function for the vTraceTaskInstanceFinishXXX functions. + *****************************************************************************/ + static void prvTraceTaskInstanceFinish( int8_t direct ) + { + TaskInstanceStatusEvent * tis; + uint8_t dts45; + + TRACE_ALLOC_CRITICAL_SECTION(); + + trcCRITICAL_SECTION_BEGIN(); + + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + dts45 = ( uint8_t ) prvTraceGetDTS( 0xFF ); + tis = ( TaskInstanceStatusEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( tis != 0 ) + { + if( direct == 0 ) + { + tis->type = TASK_INSTANCE_FINISHED_NEXT_KSE; + } + else + { + tis->type = TASK_INSTANCE_FINISHED_DIRECT; + } + + tis->dts = dts45; + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END(); + } + +/****************************************************************************** + * xTraceTaskInstanceFinishedNext(void) + * + * Marks the current task instance as finished on the next kernel call. + * + * If that kernel call is blocking, the instance ends after the blocking event + * and the corresponding return event is then the start of the next instance. + * If the kernel call is not blocking, the viewer instead splits the current + * fragment right before the kernel call, which makes this call the first event + * of the next instance. + * + * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h + * + * Example: + * + * while(1) + * { + * xQueueReceive(CommandQueue, &command, timeoutDuration); + * processCommand(command); + * xTraceTaskInstanceFinishedNext(); + * } + *****************************************************************************/ + traceResult xTraceTaskInstanceFinishedNext( void ) + { + prvTraceTaskInstanceFinish( 0 ); + + return TRC_SUCCESS; + } + +/****************************************************************************** + * xTraceTaskInstanceFinishedNow(void) + * + * Marks the current task instance as finished at this very instant. + * This makes the viewer to splits the current fragment at this point and begin + * a new actor instance. + * + * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h + * + * Example: + * + * This example will generate two instances for each loop iteration. + * The first instance ends at xTraceTaskInstanceFinishedNow(), while the second + * instance ends at the next xQueueReceive call. + * + * while (1) + * { + * xQueueReceive(CommandQueue, &command, timeoutDuration); + * ProcessCommand(command); + * xTraceTaskInstanceFinishedNow(); + * DoSometingElse(); + * xTraceTaskInstanceFinishedNext(); + * } + *****************************************************************************/ + traceResult xTraceTaskInstanceFinishedNow( void ) + { + prvTraceTaskInstanceFinish( 1 ); + + return TRC_SUCCESS; + } + +/******************************************************************************* + * Interrupt recording functions + ******************************************************************************/ + + #if ( TRC_CFG_INCLUDE_ISR_TRACING == 1 ) + +/******************************************************************************* + * xTraceSetISRProperties + * + * Stores a name and priority level for an Interrupt Service Routine, to allow + * for better visualization. Returns a traceHandle used by vTraceStoreISRBegin. + * + * Example: + * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt + * ... + * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(Timer1Handle); + * ... + * vTraceStoreISREnd(0); + * } + ******************************************************************************/ + traceHandle xTraceSetISRProperties( const char * name, + uint8_t priority ) + { + static traceHandle handle = 0; + + TRACE_ASSERT( RecorderDataPtr != 0, "Recorder not initialized, call vTraceEnable() first!", ( traceHandle ) 0 ); + TRACE_ASSERT( handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ TRACE_CLASS_ISR ], "xTraceSetISRProperties: Invalid value for handle", 0 ); + TRACE_ASSERT( name != 0, "xTraceSetISRProperties: name == NULL", 0 ); + + handle++; + + prvTraceSetObjectName( TRACE_CLASS_ISR, handle, name ); + prvTraceSetPriorityProperty( TRACE_CLASS_ISR, handle, priority ); + + return handle; + } + +/******************************************************************************* + * vTraceStoreISRBegin + * + * Registers the beginning of an Interrupt Service Routine, using a traceHandle + * provided by xTraceSetISRProperties. + * + * Example: + * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt + * ... + * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(Timer1Handle); + * ... + * vTraceStoreISREnd(0); + * } + ******************************************************************************/ + void vTraceStoreISRBegin( traceHandle handle ) + { + TRACE_ALLOC_CRITICAL_SECTION(); + + if( recorder_busy ) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError( "vTraceStoreISRBegin - recorder busy! See code comment." ); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + uint16_t dts4; + + TRACE_ASSERT( handle != 0, "vTraceStoreISRBegin: Invalid ISR handle (NULL)", TRC_UNUSED ); + TRACE_ASSERT( handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ TRACE_CLASS_ISR ], "vTraceStoreISRBegin: Invalid ISR handle (> NISR)", TRC_UNUSED ); + + dts4 = ( uint16_t ) prvTraceGetDTS( 0xFFFF ); + + if( RecorderDataPtr->recorderActive ) /* Need to repeat this check! */ + { + if( nISRactive < TRC_CFG_MAX_ISR_NESTING ) + { + TSEvent * ts; + uint8_t hnd8 = prvTraceGet8BitHandle( handle ); + isrstack[ nISRactive ] = handle; + nISRactive++; + ts = ( TSEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( ts != 0 ) + { + ts->type = TS_ISR_BEGIN; + ts->dts = dts4; + ts->objHandle = hnd8; + prvTraceUpdateCounters(); + } + } + else + { + /* This should not occur unless something is very wrong */ + prvTraceError( "Too many nested interrupts!" ); + } + } + } + + trcCRITICAL_SECTION_END(); + } + +/******************************************************************************* + * vTraceStoreISREnd + * + * Registers the end of an Interrupt Service Routine. + * + * The parameter pendingISR indicates if the interrupt has requested a + * task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the + * interrupt is assumed to return to the previous context. + * + * Example: + * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt + * traceHandle traceHandleIsrTimer1 = 0; // The ID set by the recorder + * ... + * traceHandleIsrTimer1 = xTraceSetISRProperties("ISRTimer1", PRIO_OF_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(traceHandleIsrTimer1); + * ... + * vTraceStoreISREnd(0); + * } + ******************************************************************************/ + void vTraceStoreISREnd( int pendingISR ) + { + TSEvent * ts; + uint16_t dts5; + uint8_t hnd8 = 0, type = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + if( !RecorderDataPtr->recorderActive || !handle_of_last_logged_task ) + { + return; + } + + if( recorder_busy ) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError( "vTraceStoreISREnd - recorder busy! See code comment." ); + return; + } + + if( nISRactive == 0 ) + { + prvTraceError( "Unmatched call to vTraceStoreISREnd (nISRactive == 0, expected > 0)" ); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + isPendingContextSwitch |= pendingISR; /* Is there a pending context switch right now? If so, we will not create an event since we will get an event when that context switch is executed. */ + nISRactive--; + + if( nISRactive > 0 ) + { + /* Return to another ISR */ + type = TS_ISR_RESUME; + hnd8 = prvTraceGet8BitHandle( isrstack[ nISRactive - 1 ] ); /* isrstack[nISRactive] is the handle of the ISR we're currently exiting. isrstack[nISRactive - 1] is the handle of the ISR that was executing previously. */ + } + else if( ( isPendingContextSwitch == 0 ) || ( xTraceKernelPortIsSchedulerSuspended() ) ) + { + /* Return to interrupted task, if no context switch will occur in between. */ + type = TS_TASK_RESUME; + hnd8 = prvTraceGet8BitHandle( handle_of_last_logged_task ); + } + + if( type != 0 ) + { + dts5 = ( uint16_t ) prvTraceGetDTS( 0xFFFF ); + ts = ( TSEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( ts != 0 ) + { + ts->type = type; + ts->objHandle = hnd8; + ts->dts = dts5; + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END(); + } + + #else /* if ( TRC_CFG_INCLUDE_ISR_TRACING == 1 ) */ + +/* ISR tracing is turned off */ + void prvTraceIncreaseISRActive( void ) + { + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + nISRactive++; + } + } + + void prvTraceDecreaseISRActive( void ) + { + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + nISRactive--; + } + } + #endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1)*/ + + +/********************************************************************************/ +/* User Event functions */ +/********************************************************************************/ + + #define MAX_ARG_SIZE ( 4 + 32 ) + + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) + static uint8_t writeInt8( void * buffer, + uint8_t i, + uint8_t value ) + { + TRACE_ASSERT( buffer != 0, "writeInt8: buffer == NULL", 0 ); + + if( i >= MAX_ARG_SIZE ) + { + return 255; + } + + ( ( uint8_t * ) buffer )[ i ] = value; + + if( i + 1 > MAX_ARG_SIZE ) + { + return 255; + } + + return( ( uint8_t ) ( i + 1 ) ); + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) */ + + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) + static uint8_t writeInt16( void * buffer, + uint8_t i, + uint16_t value ) + { + TRACE_ASSERT( buffer != 0, "writeInt16: buffer == NULL", 0 ); + + /* Align to multiple of 2 */ + while( ( i % 2 ) != 0 ) + { + if( i >= MAX_ARG_SIZE ) + { + return 255; + } + + ( ( uint8_t * ) buffer )[ i ] = 0; + i++; + } + + if( i + 2 > MAX_ARG_SIZE ) + { + return 255; + } + + ( ( uint16_t * ) buffer )[ i / 2 ] = value; + + return( ( uint8_t ) ( i + 2 ) ); + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) */ + + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) + static uint8_t writeInt32( void * buffer, + uint8_t i, + uint32_t value ) + { + TRACE_ASSERT( buffer != 0, "writeInt32: buffer == NULL", 0 ); + + /* A 32 bit value should begin at an even 4-byte address */ + while( ( i % 4 ) != 0 ) + { + if( i >= MAX_ARG_SIZE ) + { + return 255; + } + + ( ( uint8_t * ) buffer )[ i ] = 0; + i++; + } + + if( i + 4 > MAX_ARG_SIZE ) + { + return 255; + } + + ( ( uint32_t * ) buffer )[ i / 4 ] = value; + + return( ( uint8_t ) ( i + 4 ) ); + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) */ + + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_INCLUDE_FLOAT_SUPPORT ) ) + static uint8_t writeFloat( void * buffer, + uint8_t i, + float value ) + { + TRACE_ASSERT( buffer != 0, "writeFloat: buffer == NULL", 0 ); + + /* A 32 bit value should begin at an even 4-byte address */ + while( ( i % 4 ) != 0 ) + { + if( i >= MAX_ARG_SIZE ) + { + return 255; + } + + ( ( uint8_t * ) buffer )[ i ] = 0; + i++; + } + + if( i + 4 > MAX_ARG_SIZE ) + { + return 255; + } + + ( ( float * ) buffer )[ i / 4 ] = value; + + return i + 4; + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_INCLUDE_FLOAT_SUPPORT ) ) */ + + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_INCLUDE_FLOAT_SUPPORT ) ) + static uint8_t writeDouble( void * buffer, + uint8_t i, + double value ) + { + uint32_t * dest; + uint32_t * src = ( uint32_t * ) &value; + + TRACE_ASSERT( buffer != 0, "writeDouble: buffer == NULL", 0 ); + + /* The double is written as two 32 bit values, and should begin at an even + * 4-byte address (to avoid having to align with 8 byte) */ + while( i % 4 != 0 ) + { + if( i >= MAX_ARG_SIZE ) + { + return 255; + } + + ( ( uint8_t * ) buffer )[ i ] = 0; + i++; + } + + if( i + 8 > MAX_ARG_SIZE ) + { + return 255; + } + + dest = &( ( ( uint32_t * ) buffer )[ i / 4 ] ); + + dest[ 0 ] = src[ 0 ]; + dest[ 1 ] = src[ 1 ]; + + return i + 8; + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_INCLUDE_FLOAT_SUPPORT ) ) */ + +/******************************************************************************* + * prvTraceUserEventFormat + * + * Parses the format string and stores the arguments in the buffer. + ******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) + static uint8_t prvTraceUserEventFormat( const char * formatStr, + va_list vl, + uint8_t * buffer, + uint8_t byteOffset ) + { + uint16_t formatStrIndex = 0; + uint8_t argCounter = 0; + uint8_t i = byteOffset; + + while( formatStr[ formatStrIndex ] != '\0' ) + { + if( formatStr[ formatStrIndex ] == '%' ) + { + if( formatStr[ formatStrIndex + 1 ] == '%' ) + { + formatStrIndex += 2; + continue; + } + + /* We found a possible argument */ + argCounter++; + + formatStrIndex++; + + while( ( formatStr[ formatStrIndex ] >= '0' && formatStr[ formatStrIndex ] <= '9' ) || formatStr[ formatStrIndex ] == '#' || formatStr[ formatStrIndex ] == '.' ) + { + formatStrIndex++; + } + + /* This check is necessary to avoid moving past end of string. */ + if( formatStr[ formatStrIndex ] != '\0' ) + { + switch( formatStr[ formatStrIndex ] ) + { + case 'd': + i = writeInt32( buffer, + i, + ( uint32_t ) va_arg( vl, uint32_t ) ); + break; + + case 'x': + case 'X': + case 'u': + i = writeInt32( buffer, + i, + ( uint32_t ) va_arg( vl, uint32_t ) ); + break; + + case 's': + { + TraceStringHandle_t xString; + xTraceStringRegister( ( char * ) va_arg( vl, char * ), &xString ); + + i = writeInt16( buffer, + i, + ( uint16_t ) xString ); + } + break; + + #if ( TRC_CFG_INCLUDE_FLOAT_SUPPORT ) + + /* Yes, "double" as type also in the float + * case. This since "float" is promoted into "double" + * by the va_arg stuff. */ + case 'f': + i = writeFloat( buffer, + i, + ( float ) va_arg( vl, double ) ); + break; + #else + + /* No support for floats, but attempt to store a float user event + * avoid a possible crash due to float reference. Instead store the + * data on uint_32 format (will not be displayed anyway). This is just + * to keep va_arg and i consistent. */ + + case 'f': + i = writeInt32( buffer, + i, + ( uint32_t ) va_arg( vl, double ) ); + break; + #endif /* if ( TRC_CFG_INCLUDE_FLOAT_SUPPORT ) */ + case 'l': + formatStrIndex++; + + switch( formatStr[ formatStrIndex ] ) + { + #if ( TRC_CFG_INCLUDE_FLOAT_SUPPORT ) + case 'f': + i = writeDouble( buffer, + i, + ( double ) va_arg( vl, double ) ); + break; + #else + + /* No support for floats, but attempt to store a float user event + * avoid a possible crash due to float reference. Instead store the + * data on uint_32 format (will not be displayed anyway). This is just + * to keep va_arg and i consistent. */ + case 'f': + i = writeInt32( buffer, /* In this case, the value will not be shown anyway */ + i, + ( uint32_t ) va_arg( vl, double ) ); + + i = writeInt32( buffer, /* Do it twice, to write in total 8 bytes */ + i, + ( uint32_t ) va_arg( vl, double ) ); + break; + #endif /* if ( TRC_CFG_INCLUDE_FLOAT_SUPPORT ) */ + default: + break; + } + + break; + + case 'h': + formatStrIndex++; + + switch( formatStr[ formatStrIndex ] ) + { + case 'd': + i = writeInt16( buffer, + i, + ( uint16_t ) va_arg( vl, uint32_t ) ); + break; + + case 'u': + i = writeInt16( buffer, + i, + ( uint16_t ) va_arg( vl, uint32_t ) ); + break; + + default: + break; + } + + break; + + case 'b': + formatStrIndex++; + + switch( formatStr[ formatStrIndex ] ) + { + case 'd': + i = writeInt8( buffer, + i, + ( uint8_t ) va_arg( vl, uint32_t ) ); + break; + + case 'u': + i = writeInt8( buffer, + i, + ( uint8_t ) va_arg( vl, uint32_t ) ); + break; + + default: + break; + } + + break; + + default: + /* False alarm: this wasn't a valid format specifier */ + argCounter--; + break; + } + + if( argCounter > 15 ) + { + prvTraceError( "xTracePrintF - Too many arguments, max 15 allowed!" ); + return 0; + } + } + else + { + break; + } + } + + formatStrIndex++; + + if( i == 255 ) + { + prvTraceError( "xTracePrintF - Too large arguments, max 32 byte allowed!" ); + return 0; + } + } + + return ( uint8_t ) ( i + 3 ) / 4; + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) */ + +/******************************************************************************* + * prvTraceClearChannelBuffer + * + * Clears a number of items in the channel buffer, starting from nextSlotToWrite. + ******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) + static void prvTraceClearChannelBuffer( uint32_t count ) + { + uint32_t slots; + + TRACE_ASSERT( ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) >= count, + "prvTraceClearChannelBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED ); + + /* Check if we're close to the end of the buffer */ + if( RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) ) + { + slots = ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) -RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */ + ( void ) memset( &RecorderDataPtr->userEventBuffer.channelBuffer[ RecorderDataPtr->userEventBuffer.nextSlotToWrite ], 0, slots ); + ( void ) memset( &RecorderDataPtr->userEventBuffer.channelBuffer[ 0 ], 0, ( count - slots ) ); + } + else + { + ( void ) memset( &RecorderDataPtr->userEventBuffer.channelBuffer[ RecorderDataPtr->userEventBuffer.nextSlotToWrite ], 0, count ); + } + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) */ + +/******************************************************************************* + * prvTraceCopyToDataBuffer + * + * Copies a number of items to the data buffer, starting from nextSlotToWrite. + ******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) + static void prvTraceCopyToDataBuffer( uint32_t * data, + uint32_t count ) + { + uint32_t slots; + + TRACE_ASSERT( data != 0, + "prvTraceCopyToDataBuffer: data == NULL.", TRC_UNUSED ); + TRACE_ASSERT( count <= ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ), + "prvTraceCopyToDataBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED ); + + /* Check if we're close to the end of the buffer */ + if( RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) ) + { + slots = ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) -RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */ + ( void ) memcpy( &RecorderDataPtr->userEventBuffer.dataBuffer[ RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4 ], data, slots * 4 ); + ( void ) memcpy( &RecorderDataPtr->userEventBuffer.dataBuffer[ 0 ], data + slots, ( count - slots ) * 4 ); + } + else + { + ( void ) memcpy( &RecorderDataPtr->userEventBuffer.dataBuffer[ RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4 ], data, count * 4 ); + } + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) */ + +/******************************************************************************* + * prvTraceUBHelper1 + * + * Calls on prvTraceUserEventFormat() to do the actual formatting, then goes on + * to the next helper function. + ******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) + static void prvTraceUBHelper1( traceUBChannel channel, + TraceStringHandle_t eventLabel, + TraceStringHandle_t formatLabel, + va_list vl ) + { + uint32_t data[ ( 3 + MAX_ARG_SIZE ) / 4 ]; + uint8_t byteOffset = 4; /* Need room for timestamp */ + uint8_t noOfSlots; + + if( channel == 0 ) + { + /* We are dealing with an unknown channel format pair */ + byteOffset = ( uint8_t ) ( byteOffset + 4 ); /* Also need room for channel and format */ + ( ( uint16_t * ) data )[ 2 ] = eventLabel; + ( ( uint16_t * ) data )[ 3 ] = formatLabel; + } + + noOfSlots = prvTraceUserEventFormat( ( char * ) &( RecorderDataPtr->SymbolTable.symbytes[ formatLabel + 4 ] ), vl, ( uint8_t * ) data, byteOffset ); + + prvTraceUBHelper2( channel, data, noOfSlots ); + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) */ + +/******************************************************************************* + * prvTraceUBHelper2 + * + * This function simply copies the data buffer to the actual user event buffer. + ******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) + static void prvTraceUBHelper2( traceUBChannel channel, + uint32_t * data, + uint32_t noOfSlots ) + { + static uint32_t old_timestamp = 0; + uint32_t old_nextSlotToWrite = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT( ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) >= noOfSlots, "prvTraceUBHelper2: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED ); + + trcCRITICAL_SECTION_BEGIN(); + /* Store the timestamp */ + prvTracePortGetTimeStamp( data ); + + if( *data < old_timestamp ) + { + RecorderDataPtr->userEventBuffer.wraparoundCounter++; + } + + old_timestamp = *data; + + /* Start by erasing any information in the channel buffer */ + prvTraceClearChannelBuffer( noOfSlots ); + + prvTraceCopyToDataBuffer( data, noOfSlots ); /* Will wrap around the data if necessary */ + + old_nextSlotToWrite = RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Save the index that we want to write the channel data at when we're done */ + RecorderDataPtr->userEventBuffer.nextSlotToWrite = ( RecorderDataPtr->userEventBuffer.nextSlotToWrite + noOfSlots ) % ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ); /* Make sure we never end up outside the buffer */ + + /* Write to the channel buffer to indicate that this user event is ready to be used */ + if( channel != 0 ) + { + RecorderDataPtr->userEventBuffer.channelBuffer[ old_nextSlotToWrite ] = channel; + } + else + { + /* 0xFF indicates that this is not a normal channel id */ + RecorderDataPtr->userEventBuffer.channelBuffer[ old_nextSlotToWrite ] = ( traceUBChannel ) 0xFF; + } + + trcCRITICAL_SECTION_END(); + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) */ + +/******************************************************************************* + * xTraceRegisterUBChannel + * + * Registers a channel for Separated User Events, i.e., those stored in the + * separate user event buffer. + * + * Note: Only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is enabled in + * trcSnapshotConfig.h + ******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) + traceUBChannel xTraceRegisterUBChannel( TraceStringHandle_t channel, + TraceStringHandle_t formatStr ) + { + uint8_t i; + traceUBChannel retVal = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT( formatStr != 0, "xTraceRegisterChannelFormat: formatStr == 0", ( traceUBChannel ) 0 ); + + trcCRITICAL_SECTION_BEGIN(); + + for( i = 1; i <= ( TRC_CFG_UB_CHANNELS ); i++ ) /* Size of the channels buffer is TRC_CFG_UB_CHANNELS + 1. Index 0 is unused. */ + { + if( ( RecorderDataPtr->userEventBuffer.channels[ i ].name == 0 ) && ( RecorderDataPtr->userEventBuffer.channels[ i ].defaultFormat == 0 ) ) + { + /* Found empty slot */ + RecorderDataPtr->userEventBuffer.channels[ i ].name = channel; + RecorderDataPtr->userEventBuffer.channels[ i ].defaultFormat = formatStr; + retVal = ( traceUBChannel ) i; + break; + } + + if( ( RecorderDataPtr->userEventBuffer.channels[ i ].name == channel ) && ( RecorderDataPtr->userEventBuffer.channels[ i ].defaultFormat == formatStr ) ) + { + /* Found a match */ + retVal = ( traceUBChannel ) i; + break; + } + } + + trcCRITICAL_SECTION_END(); + + return retVal; + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) */ + +/****************************************************************************** +* vTraceUBData +* +* Slightly faster version of xTracePrintF() due to no lookups. +* +* Note: This is only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is +* enabled in trcSnapshotConfig.h +******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) + void vTraceUBData( traceUBChannel channelPair, + ... ) + { + va_list vl; + + TRACE_ASSERT( channelPair != 0, "vTraceUBData: Not a valid traceUBChannel!", TRC_UNUSED ); + + va_start( vl, channelPair ); + vTraceUBData_Helper( channelPair, vl ); + va_end( vl ); + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) */ + +/* Extracts the channel name and format string from the traceUBChannel, then calls prvTraceUBHelper1. */ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) + void vTraceUBData_Helper( traceUBChannel channelPair, + va_list vl ) + { + TraceStringHandle_t channel; + TraceStringHandle_t formatStr; + + TRACE_ASSERT( channelPair != 0, "vTraceUBData_Helper: channelPair == 0", TRC_UNUSED ); + TRACE_ASSERT( channelPair <= ( TRC_CFG_UB_CHANNELS ), "vTraceUBData_Helper: ", TRC_UNUSED ); + + channel = RecorderDataPtr->userEventBuffer.channels[ channelPair ].name; + formatStr = RecorderDataPtr->userEventBuffer.channels[ channelPair ].defaultFormat; + + prvTraceUBHelper1( channelPair, channel, formatStr, vl ); + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) */ + +/****************************************************************************** +* vTraceUBEvent +* +* Slightly faster version of ... due to no lookups. +******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) ) + void vTraceUBEvent( traceUBChannel channelPair ) + { + uint32_t data[ ( 3 + MAX_ARG_SIZE ) / 4 ]; + + TRACE_ASSERT( channelPair != 0, "vTraceUBEvent: channelPair == 0", TRC_UNUSED ); + TRACE_ASSERT( channelPair <= ( TRC_CFG_UB_CHANNELS ), "vTraceUBEvent: ", TRC_UNUSED ); + + prvTraceUBHelper2( channelPair, data, 1 ); /* Only need one slot for timestamp */ + } + #endif + +/****************************************************************************** +* xTracePrintF +* +* Generates User Event with formatted text and data, similar to a "printf". +* It is very fast compared to a normal "printf" since this function only +* stores the arguments. The actual formatting is done +* on the host PC when the trace is displayed in the viewer tool. +* +* User Event labels are created using xTraceStringRegister. +* Example: +* +* TraceStringHandle_t adc_uechannel; +* xTraceStringRegister("ADC User Events", &adc_uechannel); +* ... +* xTracePrintF(adc_uechannel, +* "ADC channel %d: %lf volts", +* ch, (double)adc_reading/(double)scale); +* +* Calling xTraceStringRegister multiple times will not create duplicate entries, but +* it is of course faster to just do it once, and then keep the handle for later +* use. If you don't have any data arguments, only a text label/string, it is +* better to use xTracePrint - it is faster. +* +* Format specifiers supported: +* %d - 32 bit signed integer +* %u - 32 bit unsigned integer +* %f - 32 bit float +* %s - string (is copied to the recorder symbol table) +* %hd - 16 bit signed integer +* %hu - 16 bit unsigned integer +* %bd - 8 bit signed integer +* %bu - 8 bit unsigned integer +* %lf - double-precision float (Note! See below...) +* +* Up to 15 data arguments are allowed, with a total size of maximum 32 byte. +* In case this is exceeded, the user event is changed into an error message. +* +* The data is stored in trace buffer, and is packed to allow storing multiple +* smaller data entries in the same 4-byte record, e.g., four 8-bit values. +* A string requires two bytes, as the symbol table is limited to 64K. Storing +* a double (%lf) uses two records, so this is quite costly. Use float (%f) +* unless the higher precision is really necessary. +* +* Note that the double-precision float (%lf) assumes a 64 bit double +* representation. This does not seem to be the case on e.g. PIC24 and PIC32. +* Before using a %lf argument on a 16-bit MCU, please verify that +* "sizeof(double)" actually gives 8 as expected. If not, use %f instead. +******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) + traceResult xTracePrintF( TraceStringHandle_t eventLabel, + const char * formatStr, + ... ) + { + va_list vl; + + va_start( vl, formatStr ); + xTraceVPrintF( eventLabel, formatStr, vl ); + va_end( vl ); + + return TRC_SUCCESS; + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) */ + +/****************************************************************************** +* xTraceVPrintF +* +* xTracePrintF variant that accepts a va_list. +* See xTracePrintF documentation for further details. +* +******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) + traceResult xTraceVPrintF( TraceStringHandle_t eventLabel, + const char * formatStr, + va_list vl ) + { + #if ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0 ) + uint32_t noOfSlots; + UserEvent * ue1; + uint32_t tempDataBuffer[ ( 3 + MAX_ARG_SIZE ) / 4 ]; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT( formatStr != 0, "vTraceVPrintF: formatStr == NULL", TRC_FAIL ); + + trcCRITICAL_SECTION_BEGIN(); + + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + /* First, write the "primary" user event entry in the local buffer, but + * let the event type be "EVENT_BEING_WRITTEN" for now...*/ + + ue1 = ( UserEvent * ) ( &tempDataBuffer[ 0 ] ); + + ue1->type = EVENT_BEING_WRITTEN; /* Update this as the last step */ + + noOfSlots = prvTraceUserEventFormat( formatStr, vl, ( uint8_t * ) tempDataBuffer, 4 ); + + /* Store the format string, with a reference to the channel symbol */ + ue1->payload = prvTraceOpenSymbol( formatStr, eventLabel ); + + ue1->dts = ( uint8_t ) prvTraceGetDTS( 0xFF ); + + /* prvTraceGetDTS might stop the recorder in some cases... */ + if( RecorderDataPtr->recorderActive ) + { + /* If the data does not fit in the remaining main buffer, wrap around to + * 0 if allowed, otherwise stop the recorder and quit). */ + if( RecorderDataPtr->nextFreeIndex + noOfSlots > RecorderDataPtr->maxEvents ) + { + #if ( TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER ) + ( void ) memset( &RecorderDataPtr->eventData[ RecorderDataPtr->nextFreeIndex * 4 ], + 0, + ( RecorderDataPtr->maxEvents - RecorderDataPtr->nextFreeIndex ) * 4 ); + RecorderDataPtr->nextFreeIndex = 0; + RecorderDataPtr->bufferIsFull = 1; + #else + + /* Stop recorder, since the event data will not fit in the + * buffer and not circular buffer in this case... */ + vTraceStop(); + #endif + } + + /* Check if recorder has been stopped (i.e., vTraceStop above) */ + if( RecorderDataPtr->recorderActive ) + { + /* Check that the buffer to be overwritten does not contain any user + * events that would be partially overwritten. If so, they must be "killed" + * by replacing the user event and following data with NULL events (i.e., + * using a memset to zero).*/ + #if ( TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER ) + prvCheckDataToBeOverwrittenForMultiEntryEvents( ( uint8_t ) noOfSlots ); + #endif + /* Copy the local buffer to the main buffer */ + ( void ) memcpy( &RecorderDataPtr->eventData[ RecorderDataPtr->nextFreeIndex * 4 ], + tempDataBuffer, + noOfSlots * 4 ); + + /* Update the event type, i.e., number of data entries following the + * main USER_EVENT entry (Note: important that this is after the memcpy, + * but within the critical section!)*/ + RecorderDataPtr->eventData[ RecorderDataPtr->nextFreeIndex * 4 ] = + ( uint8_t ) ( USER_EVENT + noOfSlots - 1 ); + + /* Update the main buffer event index (already checked that it fits in + * the buffer, so no need to check for wrapping)*/ + + RecorderDataPtr->nextFreeIndex += noOfSlots; + RecorderDataPtr->numEvents += noOfSlots; + + if( RecorderDataPtr->nextFreeIndex >= ( TRC_CFG_EVENT_BUFFER_SIZE ) ) + { + #if ( TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER ) + /* We have reached the end, but this is a ring buffer. Start from the beginning again. */ + RecorderDataPtr->bufferIsFull = 1; + RecorderDataPtr->nextFreeIndex = 0; + #else + /* We have reached the end so we stop. */ + vTraceStop(); + #endif + } + } + + #if ( TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER ) + /* Make sure the next entry is cleared correctly */ + prvCheckDataToBeOverwrittenForMultiEntryEvents( 1 ); + #endif + } + } + + trcCRITICAL_SECTION_END(); + #elif ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) + /* Use the separate user event buffer */ + TraceStringHandle_t formatLabel; + traceUBChannel channel; + + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + xTraceStringRegister( formatStr, &formatLabel ); + + channel = xTraceRegisterUBChannel( eventLabel, formatLabel ); + + prvTraceUBHelper1( channel, eventLabel, formatLabel, vl ); + } + #endif /* if ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0 ) */ + + return TRC_SUCCESS; + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) */ + +/****************************************************************************** +* xTracePrint +* +* Basic user event +* +* Generates a User Event with a text label. The label is created/looked up +* in the symbol table using xTraceStringRegister. +******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) + traceResult xTracePrint( TraceStringHandle_t chn, + const char * str ) + { + #if ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0 ) + UserEvent * ue; + uint8_t dts1; + TRACE_ALLOC_CRITICAL_SECTION(); + + trcCRITICAL_SECTION_BEGIN(); + + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + dts1 = ( uint8_t ) prvTraceGetDTS( 0xFF ); + ue = ( UserEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( ue != 0 ) + { + ue->dts = dts1; + ue->type = USER_EVENT; + ue->payload = prvTraceOpenSymbol( str, chn ); + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END(); + #elif ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) + traceUBChannel channel; + uint32_t noOfSlots = 1; + uint32_t tempDataBuffer[ ( 3 + MAX_ARG_SIZE ) / 4 ]; + + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + TraceStringHandle_t trcStr = prvTraceOpenSymbol( str, chn ); + channel = xTraceRegisterUBChannel( chn, trcStr ); + + if( channel == 0 ) + { + /* We are dealing with an unknown channel format pair */ + noOfSlots++; /* Also need room for channel and format */ + ( ( uint16_t * ) tempDataBuffer )[ 2 ] = chn; + ( ( uint16_t * ) tempDataBuffer )[ 3 ] = trcStr; + } + + prvTraceUBHelper2( channel, tempDataBuffer, noOfSlots ); + } + #endif /* if ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0 ) */ + + return TRC_SUCCESS; + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) */ + +/******************************************************************************* + * xTraceStringRegister + * + * Register strings in the recorder, e.g. for names of user event channels. + * + * Example: + * xTraceStringRegister("MyUserEvent", &myStringHandle); + * ... + * xTracePrintF(myEventHandle, "My value is: %d", myValue); + ******************************************************************************/ + #if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) + traceResult xTraceStringRegister( const char * label, + TraceStringHandle_t * pxString ) + { + TRACE_ASSERT( label != 0, "xTraceStringRegister: label == NULL", TRC_FAIL ); + TRACE_ASSERT( RecorderDataPtr != 0, "Recorder not initialized, call vTraceEnable() first!", TRC_FAIL ); + + *pxString = prvTraceOpenSymbol( label, 0 ); + + return TRC_SUCCESS; + } + +/* DEPRECATED */ + TraceStringHandle_t xTraceRegisterString( const char * name ) + { + TraceStringHandle_t trcStr = 0; + + xTraceStringRegister( name, &trcStr ); + + return trcStr; + } + #endif /* if ( ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) ) */ + + traceResult xTraceInitialize() + { + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) + uint32_t i; + #endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ + + if( RecorderInitialized != 0 ) + { + return TRC_SUCCESS; + } + + /* These are set on init so they aren't overwritten by late initialization values. */ + CurrentFilterMask = 0xFFFF; + CurrentFilterGroup = FilterGroup0; + traceErrorMessage = 0; + + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) + tasksNotIncluded = 0; + + for( i = 0; i < TRC_CFG_STACK_MONITOR_MAX_TASKS; i++ ) + { + tasksInStackMonitor[ i ].tcb = 0; + tasksInStackMonitor[ i ].uiPreviousLowMark = 0; + } + #endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ + + #if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC ) + RecorderDataPtr = &RecorderData; + #elif ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC ) + RecorderDataPtr = ( RecorderDataType * ) TRACE_MALLOC( sizeof( RecorderDataType ) ); + + if( !RecorderDataPtr ) + { + prvTraceError( "Failed allocating recorder buffer!" ); + return TRC_FAIL; + } + #elif ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM ) + if( !RecorderDataPtr ) + { + prvTraceError( "Recorder data pointer not set! Use vTraceSetRecorderDataBuffer()." ); + return TRC_FAIL; + } + #endif /* if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC ) */ + + init_hwtc_count = TRC_HWTC_COUNT; + + if( xTraceKernelPortInitialize( &xKernelPortDataBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + ( void ) memset( RecorderDataPtr, 0, sizeof( RecorderDataType ) ); + + RecorderDataPtr->version = TRACE_KERNEL_VERSION; + RecorderDataPtr->minor_version = TRACE_MINOR_VERSION; + RecorderDataPtr->irq_priority_order = TRC_IRQ_PRIORITY_ORDER; + RecorderDataPtr->filesize = sizeof( RecorderDataType ); + RecorderDataPtr->maxEvents = ( TRC_CFG_EVENT_BUFFER_SIZE ); + RecorderDataPtr->debugMarker0 = ( int32_t ) 0xF0F0F0F0; + RecorderDataPtr->isUsing16bitHandles = TRC_CFG_USE_16BIT_OBJECT_HANDLES; + RecorderDataPtr->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD; + + /* This function is kernel specific */ + xTraceKernelPortInitObjectPropertyTable(); + + RecorderDataPtr->debugMarker1 = ( int32_t ) 0xF1F1F1F1; + RecorderDataPtr->SymbolTable.symTableSize = ( TRC_CFG_SYMBOL_TABLE_SIZE ); + RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1; + #if ( TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1 ) + RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */ + #endif + RecorderDataPtr->debugMarker2 = ( int32_t ) 0xF2F2F2F2; + prvStrncpy( RecorderDataPtr->systemInfo, "Trace Recorder Demo", 80 ); + RecorderDataPtr->debugMarker3 = ( int32_t ) 0xF3F3F3F3; + RecorderDataPtr->endmarker0 = 0x0A; + RecorderDataPtr->endmarker1 = 0x0B; + RecorderDataPtr->endmarker2 = 0x0C; + RecorderDataPtr->endmarker3 = 0x0D; + RecorderDataPtr->endmarker4 = 0x71; + RecorderDataPtr->endmarker5 = 0x72; + RecorderDataPtr->endmarker6 = 0x73; + RecorderDataPtr->endmarker7 = 0x74; + RecorderDataPtr->endmarker8 = 0xF1; + RecorderDataPtr->endmarker9 = 0xF2; + RecorderDataPtr->endmarker10 = 0xF3; + RecorderDataPtr->endmarker11 = 0xF4; + + #if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER + RecorderDataPtr->userEventBuffer.bufferID = 1; + RecorderDataPtr->userEventBuffer.version = 0; + RecorderDataPtr->userEventBuffer.numberOfSlots = ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ); + RecorderDataPtr->userEventBuffer.numberOfChannels = ( TRC_CFG_UB_CHANNELS ) +1; + #endif + + /* Kernel specific initialization of the objectHandleStacks variable */ + xTraceKernelPortInitObjectHandleStack(); + + + /* Finally, the 12-byte "start markers" are initialized, allowing for + * Tracealyzer to find the trace data in a larger RAM dump. + * + * The start and end markers must be unique, but without proper precautions there + * might be a risk of accidental duplicates of the start/end markers, e.g., due to + * compiler optimizations. + * + * The below initialization of the start marker is therefore made in reverse order + * and the fields are volatile to ensure this assignment order. This to avoid any + * chance of accidental duplicates of this elsewhere in memory. + * + * Moreover, the fields are set byte-by-byte to avoid endian issues.*/ + + RecorderDataPtr->startmarker11 = 0xF4; + RecorderDataPtr->startmarker10 = 0xF3; + RecorderDataPtr->startmarker9 = 0xF2; + RecorderDataPtr->startmarker8 = 0xF1; + RecorderDataPtr->startmarker7 = 0x74; + RecorderDataPtr->startmarker6 = 0x73; + RecorderDataPtr->startmarker5 = 0x72; + RecorderDataPtr->startmarker4 = 0x71; + RecorderDataPtr->startmarker3 = 0x04; + RecorderDataPtr->startmarker2 = 0x03; + RecorderDataPtr->startmarker1 = 0x02; + RecorderDataPtr->startmarker0 = 0x01; + + if( traceErrorMessage != 0 ) + { + /* An error was detected before vTraceEnable was called, make sure this is stored in the trace data. */ + prvStrncpy( RecorderDataPtr->systemInfo, traceErrorMessage, 80 ); + RecorderDataPtr->internalErrorOccurred = 1; + prvTraceStop(); + } + + #ifdef TRC_PORT_SPECIFIC_INIT + TRC_PORT_SPECIFIC_INIT(); + #endif + + RecorderInitialized = 1; + + return TRC_SUCCESS; + } + + #if ( ( !defined TRC_CFG_INCLUDE_READY_EVENTS ) || ( TRC_CFG_INCLUDE_READY_EVENTS == 1 ) ) + + void prvTraceSetReadyEventsEnabled( uint32_t flag ) + { + readyEventsEnabled = flag; + } + +/******************************************************************************* + * prvTraceStoreTaskReady + * + * This function stores a ready state for the task handle sent in as parameter. + ******************************************************************************/ + void prvTraceStoreTaskReady( traceHandle handle ) + { + uint16_t dts3; + TREvent * tr; + uint8_t hnd8; + + TRACE_ALLOC_CRITICAL_SECTION(); + + if( handle == 0 ) + { + /* On FreeRTOS v7.3.0, this occurs when creating tasks due to a bad + * placement of the trace macro. In that case, the events are ignored. */ + return; + } + + if( !readyEventsEnabled ) + { + /* When creating tasks, ready events are also created. If creating + * a "hidden" (not traced) task, we must therefore disable recording + * of ready events to avoid an undesired ready event... */ + return; + } + + TRACE_ASSERT( handle <= ( TRC_CFG_NTASK ), "prvTraceStoreTaskReady: Invalid value for handle", TRC_UNUSED ); + + if( recorder_busy ) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError( "Recorder busy - high priority ISR using syscall? (1)" ); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + + if( RecorderDataPtr->recorderActive ) /* Need to repeat this check! */ + { + dts3 = ( uint16_t ) prvTraceGetDTS( 0xFFFF ); + hnd8 = prvTraceGet8BitHandle( handle ); + tr = ( TREvent * ) prvTraceNextFreeEventBufferSlot(); + + if( tr != 0 ) + { + tr->type = DIV_TASK_READY; + tr->dts = dts3; + tr->objHandle = hnd8; + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END(); + } + #endif /* if ( ( !defined TRC_CFG_INCLUDE_READY_EVENTS ) || ( TRC_CFG_INCLUDE_READY_EVENTS == 1 ) ) */ + +/******************************************************************************* + * prvTraceStoreLowPower + * + * This function stores a low power state. + ******************************************************************************/ + void prvTraceStoreLowPower( uint32_t flag ) + { + uint16_t dts; + LPEvent * lp; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT( flag <= 1, "prvTraceStoreLowPower: Invalid flag value", TRC_UNUSED ); + + if( recorder_busy ) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError( "Recorder busy - high priority ISR using syscall? (1)" ); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + + if( RecorderDataPtr->recorderActive ) + { + dts = ( uint16_t ) prvTraceGetDTS( 0xFFFF ); + lp = ( LPEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( lp != 0 ) + { + lp->type = ( uint8_t ) ( LOW_POWER_BEGIN + ( uint8_t ) flag ); /* BEGIN or END depending on flag */ + lp->dts = dts; + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END(); + } + +/******************************************************************************* + * vTraceStoreMemMangEvent + * + * This function stores malloc and free events. Each call requires two records, + * for size and address respectively. The event code parameter (ecode) is applied + * to the first record (size) and the following address record gets event + * code "ecode + 1", so make sure this is respected in the event code table. + * Note: On "free" calls, the signed_size parameter should be negative. + ******************************************************************************/ + #if ( TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1 ) + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + void vTraceStoreMemMangEvent( uint32_t ecode, + uint32_t address, + int32_t signed_size ) + { + uint8_t dts1; + MemEventSize * ms; + MemEventAddr * ma; + uint16_t size_low; + uint16_t addr_low; + uint8_t addr_high; + uint32_t size; + + TRACE_ALLOC_CRITICAL_SECTION(); + + if( RecorderDataPtr == 0 ) + { + /* Occurs in vTraceInitTraceData, if using dynamic allocation. */ + return; + } + + if( signed_size < 0 ) + { + size = ( uint32_t ) ( -signed_size ); + } + else + { + size = ( uint32_t ) ( signed_size ); + } + + trcCRITICAL_SECTION_BEGIN(); + + /* Only update heapMemUsage if we have a valid address */ + if( address != 0 ) + { + RecorderDataPtr->heapMemUsage += ( uint32_t ) signed_size; + + if( RecorderDataPtr->heapMemUsage > RecorderDataPtr->heapMemMaxUsage ) + { + RecorderDataPtr->heapMemMaxUsage = RecorderDataPtr->heapMemUsage; + } + } + + if( RecorderDataPtr->recorderActive ) + { + dts1 = ( uint8_t ) prvTraceGetDTS( 0xFF ); + size_low = ( uint16_t ) prvTraceGetParam( 0xFFFF, size ); + ms = ( MemEventSize * ) prvTraceNextFreeEventBufferSlot(); + + if( ms != 0 ) + { + ms->dts = dts1; + ms->type = NULL_EVENT; /* Updated when all events are written */ + ms->size = size_low; + prvTraceUpdateCounters(); + + /* Storing a second record with address (signals "failed" if null) */ + #if ( TRC_CFG_HEAP_SIZE_BELOW_16M ) + + /* If the heap address range is within 16 MB, i.e., the upper 8 bits + * of addresses are constant, this optimization avoids storing an extra + * event record by ignoring the upper 8 bit of the address */ + addr_low = address & 0xFFFF; + addr_high = ( address >> 16 ) & 0xFF; + #else + + /* The whole 32 bit address is stored using a second event record + * for the upper 16 bit */ + addr_low = ( uint16_t ) prvTraceGetParam( 0xFFFF, address ); + addr_high = 0; + #endif + + ma = ( MemEventAddr * ) prvTraceNextFreeEventBufferSlot(); + + if( ma != 0 ) + { + ma->addr_low = addr_low; + ma->addr_high = addr_high; + ma->type = ( uint8_t ) ( ecode + 1 ); /* Note this! */ + ms->type = ( uint8_t ) ecode; /* Set type of first event */ + prvTraceUpdateCounters(); + } + } + } + + trcCRITICAL_SECTION_END(); + } + #endif /* TRC_CFG_SCHEDULING_ONLY */ + #endif /* if ( TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1 ) */ + +/******************************************************************************* + * prvTraceStoreKernelCall + * + * This is the main integration point for storing kernel calls, and + * is called by the hooks in trcKernelHooks.h (see trcKernelPort.h for event codes). + ******************************************************************************/ + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + void prvTraceStoreKernelCall( uint32_t ecode, + traceObjectClass objectClass, + uint32_t objectNumber ) + { + KernelCall * kse; + uint16_t dts1; + uint8_t hnd8; + + TRACE_ALLOC_CRITICAL_SECTION(); + + /* Avoids warnings when asserts are disabled */ + ( void ) objectClass; + + TRACE_ASSERT( ecode < 0xFF, "prvTraceStoreKernelCall: ecode >= 0xFF", TRC_UNUSED ); + TRACE_ASSERT( objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCall: objectClass >= TRACE_NCLASSES", TRC_UNUSED ); + TRACE_ASSERT( objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectClass ], "prvTraceStoreKernelCall: Invalid value for objectNumber", TRC_UNUSED ); + + if( recorder_busy ) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError( "Recorder busy - high priority ISR using syscall? (2)" ); + return; + } + + if( handle_of_last_logged_task == 0 ) + { + return; + } + + trcCRITICAL_SECTION_BEGIN(); + + if( RecorderDataPtr->recorderActive ) + { + dts1 = ( uint16_t ) prvTraceGetDTS( 0xFFFF ); + hnd8 = prvTraceGet8BitHandle( ( traceHandle ) objectNumber ); + kse = ( KernelCall * ) prvTraceNextFreeEventBufferSlot(); + + if( kse != 0 ) + { + kse->dts = dts1; + kse->type = ( uint8_t ) ecode; + kse->objHandle = hnd8; + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END(); + } + #endif /* TRC_CFG_SCHEDULING_ONLY */ + +/******************************************************************************* + * prvTraceStoreKernelCallWithParam + * + * Used for storing kernel calls with a handle and a numeric parameter. If the + * numeric parameter does not fit in one byte, and extra XPS event is inserted + * before the kernel call event containing the three upper bytes. + ******************************************************************************/ + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + void prvTraceStoreKernelCallWithParam( uint32_t evtcode, + traceObjectClass objectClass, + uint32_t objectNumber, + uint32_t param ) + { + KernelCallWithParamAndHandle * kse; + uint8_t dts2; + uint8_t hnd8; + uint8_t p8; + + TRACE_ALLOC_CRITICAL_SECTION(); + + /* Avoids warnings when asserts are disabled */ + ( void ) objectClass; + + TRACE_ASSERT( evtcode < 0xFF, "prvTraceStoreKernelCallWithParam: evtcode >= 0xFF", TRC_UNUSED ); + TRACE_ASSERT( objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCallWithParam: objectClass >= TRACE_NCLASSES", TRC_UNUSED ); + TRACE_ASSERT( objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectClass ], "prvTraceStoreKernelCallWithParam: Invalid value for objectNumber", TRC_UNUSED ); + + if( recorder_busy ) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError( "Recorder busy - high priority ISR using syscall? (3)" ); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + dts2 = ( uint8_t ) prvTraceGetDTS( 0xFF ); + p8 = ( uint8_t ) prvTraceGetParam( 0xFF, param ); + hnd8 = prvTraceGet8BitHandle( ( traceHandle ) objectNumber ); + kse = ( KernelCallWithParamAndHandle * ) prvTraceNextFreeEventBufferSlot(); + + if( kse != 0 ) + { + kse->dts = dts2; + kse->type = ( uint8_t ) evtcode; + kse->objHandle = hnd8; + kse->param = p8; + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END(); + } + #endif /* TRC_CFG_SCHEDULING_ONLY */ + + +/******************************************************************************* + * prvTraceGetParam + * + * Used for storing extra bytes for kernel calls with numeric parameters. + * + * May only be called within a critical section! + ******************************************************************************/ + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + static uint32_t prvTraceGetParam( uint32_t param_max, + uint32_t param ) + { + XPSEvent * xps; + + TRACE_ASSERT( param_max == 0xFF || param_max == 0xFFFF, + "prvTraceGetParam: Invalid value for param_max", param ); + + if( param <= param_max ) + { + return param; + } + else + { + xps = ( XPSEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( xps != 0 ) + { + xps->type = DIV_XPS; + xps->xps_8 = ( uint8_t ) ( ( param & ( 0xFF00 & ~param_max ) ) >> 8 ); + xps->xps_16 = ( uint16_t ) ( ( param & ( 0xFFFF0000 & ~param_max ) ) >> 16 ); + prvTraceUpdateCounters(); + } + + return param & param_max; + } + } + #endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */ + +/******************************************************************************* + * prvTraceStoreKernelCallWithNumericParamOnly + * + * Used for storing kernel calls with numeric parameters only. This is + * only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment. + ******************************************************************************/ + #if ( TRC_CFG_SCHEDULING_ONLY == 0 ) + void prvTraceStoreKernelCallWithNumericParamOnly( uint32_t evtcode, + uint32_t param ) + { + KernelCallWithParam16 * kse; + uint8_t dts6; + uint16_t restParam; + + TRACE_ALLOC_CRITICAL_SECTION(); + + restParam = 0; + + TRACE_ASSERT( evtcode < 0xFF, "prvTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", TRC_UNUSED ); + + if( recorder_busy ) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError( "Recorder busy - high priority ISR using syscall? (4)" ); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + + if( RecorderDataPtr->recorderActive && handle_of_last_logged_task ) + { + dts6 = ( uint8_t ) prvTraceGetDTS( 0xFF ); + restParam = ( uint16_t ) prvTraceGetParam( 0xFFFF, param ); + kse = ( KernelCallWithParam16 * ) prvTraceNextFreeEventBufferSlot(); + + if( kse != 0 ) + { + kse->dts = dts6; + kse->type = ( uint8_t ) evtcode; + kse->param = restParam; + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END(); + } + #endif /* TRC_CFG_SCHEDULING_ONLY */ + +/******************************************************************************* + * prvTraceStoreTaskswitch + * Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart. + * At this point interrupts are assumed to be disabled! + ******************************************************************************/ + void prvTraceStoreTaskswitch( traceHandle task_handle ) + { + uint16_t dts3; + TSEvent * ts; + uint8_t hnd8; + + #if ( TRC_CFG_INCLUDE_ISR_TRACING == 1 ) + extern int32_t isPendingContextSwitch; + #endif + trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY(); + + TRACE_ASSERT( task_handle <= ( TRC_CFG_NTASK ), + "prvTraceStoreTaskswitch: Invalid value for task_handle", TRC_UNUSED ); + + trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY(); + + if( ( task_handle != handle_of_last_logged_task ) && ( RecorderDataPtr->recorderActive ) ) + { + #if ( TRC_CFG_INCLUDE_ISR_TRACING == 1 ) + isPendingContextSwitch = 0; + #endif + + dts3 = ( uint16_t ) prvTraceGetDTS( 0xFFFF ); + handle_of_last_logged_task = task_handle; + hnd8 = prvTraceGet8BitHandle( handle_of_last_logged_task ); + ts = ( TSEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( ts != 0 ) + { + if( prvTraceGetObjectState( TRACE_CLASS_TASK, + handle_of_last_logged_task ) == TASK_STATE_INSTANCE_ACTIVE ) + { + ts->type = TS_TASK_RESUME; + } + else + { + ts->type = TS_TASK_BEGIN; + } + + ts->dts = dts3; + ts->objHandle = hnd8; + + prvTraceSetObjectState( TRACE_CLASS_TASK, + handle_of_last_logged_task, + TASK_STATE_INSTANCE_ACTIVE ); + + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY(); + } + +/******************************************************************************* + * prvTraceStoreObjectNameOnCloseEvent + * + * Updates the symbol table with the name of this object from the dynamic + * objects table and stores a "close" event, holding the mapping between handle + * and name (a symbol table handle). The stored name-handle mapping is thus the + * "old" one, valid up until this point. + ******************************************************************************/ + void prvTraceStoreObjectNameOnCloseEvent( uint8_t evtcode, + traceHandle handle, + traceObjectClass objectclass ) + { + ObjCloseNameEvent * ce; + const char * name; + TraceStringHandle_t idx; + + TRACE_ASSERT( objectclass < TRACE_NCLASSES, + "prvTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED ); + TRACE_ASSERT( handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ], + "prvTraceStoreObjectNameOnCloseEvent: Invalid value for handle", TRC_UNUSED ); + + if( RecorderDataPtr->recorderActive ) + { + uint8_t hnd8 = prvTraceGet8BitHandle( handle ); + name = TRACE_PROPERTY_NAME_GET( objectclass, handle ); + idx = prvTraceOpenSymbol( name, 0 ); + + /* Interrupt disable not necessary, already done in trcHooks.h macro */ + ce = ( ObjCloseNameEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( ce != 0 ) + { + ce->type = ( uint8_t ) evtcode; + ce->objHandle = hnd8; + ce->symbolIndex = idx; + prvTraceUpdateCounters(); + } + } + } + + void prvTraceStoreObjectPropertiesOnCloseEvent( uint8_t evtcode, + traceHandle handle, + traceObjectClass objectclass ) + { + ObjClosePropEvent * pe; + + TRACE_ASSERT( objectclass < TRACE_NCLASSES, + "prvTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED ); + TRACE_ASSERT( handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ], + "prvTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", TRC_UNUSED ); + + if( RecorderDataPtr->recorderActive ) + { + /* Interrupt disable not necessary, already done in trcHooks.h macro */ + pe = ( ObjClosePropEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( pe != 0 ) + { + if( objectclass == TRACE_CLASS_TASK ) + { + pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY( objectclass, handle ); + } + else + { + pe->arg1 = TRACE_PROPERTY_OBJECT_STATE( objectclass, handle ); + } + + pe->type = evtcode; + prvTraceUpdateCounters(); + } + } + } + + void prvTraceSetPriorityProperty( uint8_t objectclass, + traceHandle id, + uint8_t value ) + { + TRACE_ASSERT( objectclass < TRACE_NCLASSES, + "prvTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", TRC_UNUSED ); + TRACE_ASSERT( id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ], + "prvTraceSetPriorityProperty: Invalid value for id", TRC_UNUSED ); + + TRACE_PROPERTY_ACTOR_PRIORITY( objectclass, id ) = value; + } + + uint8_t prvTraceGetPriorityProperty( uint8_t objectclass, + traceHandle id ) + { + TRACE_ASSERT( objectclass < TRACE_NCLASSES, + "prvTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0 ); + TRACE_ASSERT( id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ], + "prvTraceGetPriorityProperty: Invalid value for id", 0 ); + + return TRACE_PROPERTY_ACTOR_PRIORITY( objectclass, id ); + } + + void prvTraceSetObjectState( uint8_t objectclass, + traceHandle id, + uint8_t value ) + { + TRACE_ASSERT( objectclass < TRACE_NCLASSES, + "prvTraceSetObjectState: objectclass >= TRACE_NCLASSES", TRC_UNUSED ); + TRACE_ASSERT( id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ], + "prvTraceSetObjectState: Invalid value for id", TRC_UNUSED ); + + TRACE_PROPERTY_OBJECT_STATE( objectclass, id ) = value; + } + + uint8_t prvTraceGetObjectState( uint8_t objectclass, + traceHandle id ) + { + TRACE_ASSERT( objectclass < TRACE_NCLASSES, + "prvTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0 ); + TRACE_ASSERT( id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ], + "prvTraceGetObjectState: Invalid value for id", 0 ); + + return TRACE_PROPERTY_OBJECT_STATE( objectclass, id ); + } + + void prvTraceSetTaskInstanceFinished( traceHandle handle ) + { + /* Avoids warnings when asserts are disabled */ + ( void ) handle; + + TRACE_ASSERT( handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ TRACE_CLASS_TASK ], + "prvTraceSetTaskInstanceFinished: Invalid value for handle", TRC_UNUSED ); + + #if ( TRC_CFG_USE_IMPLICIT_IFE_RULES == 1 ) + TRACE_PROPERTY_OBJECT_STATE( TRACE_CLASS_TASK, handle ) = 0; + #endif + } + + void * prvTraceNextFreeEventBufferSlot( void ) + { + if( !RecorderDataPtr->recorderActive ) + { + /* If an XTS or XPS event prior to the main event has filled the buffer + * before saving the main event, and store mode is "stop when full". */ + return 0; + } + + if( RecorderDataPtr->nextFreeIndex >= ( TRC_CFG_EVENT_BUFFER_SIZE ) ) + { + prvTraceError( "Attempt to index outside event buffer!" ); + return 0; + } + + return ( void * ) ( &RecorderDataPtr->eventData[ RecorderDataPtr->nextFreeIndex * 4 ] ); + } + + uint16_t uiIndexOfObject( traceHandle objecthandle, + uint8_t objectclass ) + { + uint16_t index; + + TRACE_ASSERT( objectclass < TRACE_NCLASSES, + "uiIndexOfObject: Invalid value for objectclass", 0 ); + TRACE_ASSERT( objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ], + "uiIndexOfObject: Invalid value for objecthandle", 0 ); + + if( ( objectclass < TRACE_NCLASSES ) && ( objecthandle > 0 ) && + ( objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ] ) ) + { + index = ( uint16_t ) ( RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ objectclass ] + + ( RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ objectclass ] * ( objecthandle - 1 ) ) ); + return index; + } + + prvTraceError( "Object table lookup with invalid object handle or object class!" ); + return 0; + } + + traceHandle prvTraceGetObjectHandle( traceObjectClass objectclass ) + { + traceHandle handle; + static int indexOfHandle; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT( RecorderDataPtr != 0, "Recorder not initialized, call vTraceEnable() first!", ( traceHandle ) 0 ); + + TRACE_ASSERT( objectclass < TRACE_NCLASSES, + "prvTraceGetObjectHandle: Invalid value for objectclass", ( traceHandle ) 0 ); + + trcCRITICAL_SECTION_BEGIN(); + indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[ objectclass ]; + + if( objectHandleStacks.objectHandles[ indexOfHandle ] == 0 ) + { + /* Zero is used to indicate a never before used handle, i.e., + * new slots in the handle stack. The handle slot needs to + * be initialized here (starts at 1). */ + objectHandleStacks.objectHandles[ indexOfHandle ] = + ( traceHandle ) ( 1 + indexOfHandle - + objectHandleStacks.lowestIndexOfClass[ objectclass ] ); + } + + handle = objectHandleStacks.objectHandles[ indexOfHandle ]; + + if( objectHandleStacks.indexOfNextAvailableHandle[ objectclass ] + > objectHandleStacks.highestIndexOfClass[ objectclass ] ) + { + prvTraceError( pszTraceGetErrorNotEnoughHandles( objectclass ) ); + handle = 0; + } + else + { + int hndCount; + objectHandleStacks.indexOfNextAvailableHandle[ objectclass ]++; + + hndCount = objectHandleStacks.indexOfNextAvailableHandle[ objectclass ] - + objectHandleStacks.lowestIndexOfClass[ objectclass ]; + + if( hndCount > + objectHandleStacks.handleCountWaterMarksOfClass[ objectclass ] ) + { + objectHandleStacks.handleCountWaterMarksOfClass[ objectclass ] = + ( traceHandle ) hndCount; + } + } + + trcCRITICAL_SECTION_END(); + + return handle; + } + + void prvTraceFreeObjectHandle( traceObjectClass objectclass, + traceHandle handle ) + { + int indexOfHandle; + + TRACE_ASSERT( RecorderDataPtr != 0, "Recorder not initialized, call vTraceEnable() first!", TRC_UNUSED ); + TRACE_ASSERT( objectclass < TRACE_NCLASSES, + "prvTraceFreeObjectHandle: Invalid value for objectclass", TRC_UNUSED ); + TRACE_ASSERT( handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ], + "prvTraceFreeObjectHandle: Invalid value for handle", TRC_UNUSED ); + + /* Check that there is room to push the handle on the stack */ + if( ( objectHandleStacks.indexOfNextAvailableHandle[ objectclass ] - 1 ) < + objectHandleStacks.lowestIndexOfClass[ objectclass ] ) + { + /* Error */ + prvTraceError( "Attempt to free more handles than allocated!" ); + } + else + { + objectHandleStacks.indexOfNextAvailableHandle[ objectclass ]--; + indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[ objectclass ]; + objectHandleStacks.objectHandles[ indexOfHandle ] = handle; + } + } + +/******************************************************************************* + * prvMarkObjectAsUsed + * + * Sets an "is used flag" on object creation, using the first byte of the name + * field. This allows for counting the number of used Object Table slots, even + * if no names have been set. + ******************************************************************************/ + void prvMarkObjectAsUsed( traceObjectClass objectclass, + traceHandle handle ) + { + uint16_t idx = uiIndexOfObject( handle, objectclass ); + + RecorderDataPtr->ObjectPropertyTable.objbytes[ idx ] = 1; + } + +/******************************************************************************* + * prvStrncpy + * + * Private string copy function, to improve portability between compilers. + ******************************************************************************/ + static void prvStrncpy( char * dst, + const char * src, + uint32_t maxLength ) + { + uint32_t i; + + for( i = 0; i < maxLength; i++ ) + { + dst[ i ] = src[ i ]; + + if( src[ i ] == 0 ) + { + break; + } + } + } + +/******************************************************************************* + * prvTraceSetObjectName + * + * Registers the names of queues, semaphores and other kernel objects in the + * recorder's Object Property Table, at the given handle and object class. + ******************************************************************************/ + void prvTraceSetObjectName( traceObjectClass objectclass, + traceHandle handle, + const char * name ) + { + static uint16_t idx; + + if( name == 0 ) + { + name = ""; + } + + if( objectclass >= TRACE_NCLASSES ) + { + prvTraceError( "Illegal object class in prvTraceSetObjectName" ); + return; + } + + if( handle == 0 ) + { + prvTraceError( "Illegal handle (0) in prvTraceSetObjectName." ); + return; + } + + if( handle > RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ objectclass ] ) + { + /* ERROR */ + prvTraceError( pszTraceGetErrorNotEnoughHandles( objectclass ) ); + } + else + { + idx = uiIndexOfObject( handle, objectclass ); + + if( traceErrorMessage == 0 ) + { + prvStrncpy( ( char * ) &( RecorderDataPtr->ObjectPropertyTable.objbytes[ idx ] ), + name, + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ] ); + } + } + } + + TraceStringHandle_t prvTraceOpenSymbol( const char * name, + TraceStringHandle_t userEventChannel ) + { + uint16_t result; + uint8_t len; + uint8_t crc; + + TRACE_ALLOC_CRITICAL_SECTION(); + + len = 0; + crc = 0; + + TRACE_ASSERT( name != 0, "prvTraceOpenSymbol: name == NULL", ( TraceStringHandle_t ) 0 ); + + prvTraceGetChecksum( name, &crc, &len ); + + trcCRITICAL_SECTION_BEGIN(); + result = prvTraceLookupSymbolTableEntry( name, crc, len, userEventChannel ); + + if( !result ) + { + result = prvTraceCreateSymbolTableEntry( name, crc, len, userEventChannel ); + } + + trcCRITICAL_SECTION_END(); + + return result; + } + + +/****************************************************************************** + * vTraceSetFrequency + * + * Registers the clock rate of the time source for the event timestamping. + * This is normally not required, but if the default value (TRC_HWTC_FREQ_HZ) + * should be incorrect for your setup, you can override it using this function. + * + * Must be called prior to vTraceEnable, and the time source is assumed to + * have a fixed clock frequency after the startup. + * + * Note that, in snapshot mode, the value is divided by the TRC_HWTC_DIVISOR. + * This is a software "prescaler" that is also applied on the timestamps. + *****************************************************************************/ + void vTraceSetFrequency( uint32_t frequency ) + { + timestampFrequency = frequency; + } + +/******************************************************************************* + * Supporting functions + ******************************************************************************/ + +/******************************************************************************* + * prvTraceError + * + * Called by various parts in the recorder. Stops the recorder and stores a + * pointer to an error message, which is printed by the monitor task. + * If you are not using the monitor task, you may use xTraceErrorGetLast() + * from your application to check if the recorder is OK. + * + * Note: If a recorder error is registered before vTraceStart is called, the + * trace start will be aborted. This can occur if any of the Nxxxx constants + * (e.g., TRC_CFG_NTASK) in trcConfig.h is too small. + ******************************************************************************/ + void prvTraceError( const char * msg ) + { + /* Stop the recorder */ + if( RecorderDataPtr != 0 ) + { + xTraceDisable(); + } + + /* If first error only... */ + if( traceErrorMessage == 0 ) + { + traceErrorMessage = ( char * ) ( intptr_t ) msg; + + if( RecorderDataPtr != 0 ) + { + prvStrncpy( RecorderDataPtr->systemInfo, traceErrorMessage, 80 ); + RecorderDataPtr->internalErrorOccurred = 1; + } + } + } + + void vTraceSetFilterMask( uint16_t filterMask ) + { + CurrentFilterMask = filterMask; + } + + void vTraceSetFilterGroup( uint16_t filterGroup ) + { + CurrentFilterGroup = filterGroup; + } + +/****************************************************************************** + * prvCheckDataToBeOverwrittenForMultiEntryEvents + * + * This checks if the next event to be overwritten is a multi-entry user event, + * i.e., a USER_EVENT followed by data entries. + * Such data entries do not have an event code at byte 0, as other events. + * All 4 bytes are user data, so the first byte of such data events must + * not be interpreted as type field. The number of data entries following + * a USER_EVENT is given in the event code of the USER_EVENT. + * Therefore, when overwriting a USER_EVENT (when using in ring-buffer mode) + * any data entries following must be replaced with NULL events (code 0). + * + * This is assumed to execute within a critical section... + *****************************************************************************/ + + #if ( TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER ) + void prvCheckDataToBeOverwrittenForMultiEntryEvents( uint8_t nofEntriesToCheck ) + { + /* Generic "int" type is desired - should be 16 bit variable on 16 bit HW */ + unsigned int i = 0; + unsigned int e = 0; + + TRACE_ASSERT( nofEntriesToCheck != 0, + "prvCheckDataToBeOverwrittenForMultiEntryEvents: nofEntriesToCheck == 0", TRC_UNUSED ); + + while( i < nofEntriesToCheck ) + { + e = RecorderDataPtr->nextFreeIndex + i; + + if( ( RecorderDataPtr->eventData[ e * 4 ] > USER_EVENT ) && + ( RecorderDataPtr->eventData[ e * 4 ] < USER_EVENT + 16 ) ) + { + uint8_t nDataEvents = ( uint8_t ) ( RecorderDataPtr->eventData[ e * 4 ] - USER_EVENT ); + + if( ( e + nDataEvents ) < RecorderDataPtr->maxEvents ) + { + ( void ) memset( &RecorderDataPtr->eventData[ e * 4 ], 0, ( size_t ) ( 4 + 4 * nDataEvents ) ); + } + } + else if( RecorderDataPtr->eventData[ e * 4 ] == DIV_XPS ) + { + if( ( e + 1 ) < RecorderDataPtr->maxEvents ) + { + /* Clear 8 bytes */ + ( void ) memset( &RecorderDataPtr->eventData[ e * 4 ], 0, 4 + 4 ); + } + else + { + /* Clear 8 bytes, 4 first and 4 last */ + ( void ) memset( &RecorderDataPtr->eventData[ 0 ], 0, 4 ); + ( void ) memset( &RecorderDataPtr->eventData[ e * 4 ], 0, 4 ); + } + } + + i++; + } + } + #endif /* if ( TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER ) */ + +/******************************************************************************* + * prvTraceUpdateCounters + * + * Updates the index of the event buffer. + ******************************************************************************/ + void prvTraceUpdateCounters( void ) + { + if( RecorderDataPtr->recorderActive == 0 ) + { + return; + } + + RecorderDataPtr->numEvents++; + + RecorderDataPtr->nextFreeIndex++; + + if( RecorderDataPtr->nextFreeIndex >= ( TRC_CFG_EVENT_BUFFER_SIZE ) ) + { + #if ( TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER ) + RecorderDataPtr->bufferIsFull = 1; + RecorderDataPtr->nextFreeIndex = 0; + #else + vTraceStop(); + #endif + } + + #if ( TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER ) + prvCheckDataToBeOverwrittenForMultiEntryEvents( 1 ); + #endif + } + +/****************************************************************************** + * prvTraceGetDTS + * + * Returns a differential timestamp (DTS), i.e., the time since + * last event, and creates an XTS event if the DTS does not fit in the + * number of bits given. The XTS event holds the MSB bytes of the DTS. + * + * The parameter param_maxDTS should be 0xFF for 8-bit dts or 0xFFFF for + * events with 16-bit dts fields. + *****************************************************************************/ + uint16_t prvTraceGetDTS( uint16_t param_maxDTS ) + { + static uint32_t old_timestamp = 0; + XTSEvent * xts = 0; + uint32_t dts = 0; + uint32_t timestamp = 0; + + TRACE_ASSERT( param_maxDTS == 0xFF || param_maxDTS == 0xFFFF, "prvTraceGetDTS: Invalid value for param_maxDTS", 0 ); + + if( RecorderDataPtr->frequency == 0 ) + { + if( timestampFrequency != 0 ) + { + /* If to override default TRC_HWTC_FREQ_HZ value with value set by vTraceSetFrequency */ + RecorderDataPtr->frequency = timestampFrequency / ( TRC_HWTC_DIVISOR ); + } + else if( init_hwtc_count != ( TRC_HWTC_COUNT ) ) + { + /* If using default value and timer has been started. + * Note: If the default frequency value set here would be incorrect, e.g., + * if the timer has actually not been configured yet, override this + * with vTraceSetFrequency. + */ + RecorderDataPtr->frequency = ( TRC_HWTC_FREQ_HZ ) / ( TRC_HWTC_DIVISOR ); + } + + /* If no override (vTraceSetFrequency) and timer inactive -> no action */ + } + + /************************************************************************** + * The below statements read the timestamp from the timer port module. + * If necessary, whole seconds are extracted using division while the rest + * comes from the modulo operation. + **************************************************************************/ + + prvTracePortGetTimeStamp( ×tamp ); + + /*************************************************************************** + * Since dts is unsigned the result will be correct even if timestamp has + * wrapped around. + ***************************************************************************/ + dts = timestamp - old_timestamp; + old_timestamp = timestamp; + + if( RecorderDataPtr->frequency > 0 ) + { + /* Check if dts > 1 second */ + if( dts > RecorderDataPtr->frequency ) + { + /* More than 1 second has passed */ + RecorderDataPtr->absTimeLastEventSecond += dts / RecorderDataPtr->frequency; + /* The part that is not an entire second is added to absTimeLastEvent */ + RecorderDataPtr->absTimeLastEvent += dts % RecorderDataPtr->frequency; + } + else + { + RecorderDataPtr->absTimeLastEvent += dts; + } + + /* Check if absTimeLastEvent >= 1 second */ + if( RecorderDataPtr->absTimeLastEvent >= RecorderDataPtr->frequency ) + { + /* RecorderDataPtr->absTimeLastEvent is more than or equal to 1 second, but always less than 2 seconds */ + RecorderDataPtr->absTimeLastEventSecond++; + RecorderDataPtr->absTimeLastEvent -= RecorderDataPtr->frequency; + /* RecorderDataPtr->absTimeLastEvent is now less than 1 second */ + } + } + else + { + /* Special case if the recorder has not yet started (frequency may be uninitialized, i.e., zero) */ + RecorderDataPtr->absTimeLastEvent = timestamp; + } + + /* If the dts (time since last event) does not fit in event->dts (only 8 or 16 bits) */ + if( dts > param_maxDTS ) + { + /* Create an XTS event (eXtended TimeStamp) containing the higher dts bits*/ + xts = ( XTSEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( xts != 0 ) + { + if( param_maxDTS == 0xFFFF ) + { + xts->type = XTS16; + xts->xts_16 = ( uint16_t ) ( ( dts / 0x10000 ) & 0xFFFF ); + xts->xts_8 = 0; + } + else if( param_maxDTS == 0xFF ) + { + xts->type = XTS8; + xts->xts_16 = ( uint16_t ) ( ( dts / 0x100 ) & 0xFFFF ); + xts->xts_8 = ( uint8_t ) ( ( dts / 0x1000000 ) & 0xFF ); + } + else + { + prvTraceError( "Bad param_maxDTS in prvTraceGetDTS" ); + } + + prvTraceUpdateCounters(); + } + } + + return ( uint16_t ) dts & param_maxDTS; + } + +/******************************************************************************* + * prvTraceLookupSymbolTableEntry + * + * Find an entry in the symbol table, return 0 if not present. + * + * The strings are stored in a byte pool, with four bytes of "meta-data" for + * every string. + * byte 0-1: index of next entry with same checksum (for fast lookup). + * byte 2-3: reference to a symbol table entry, a label for xTracePrintF + * format strings only (the handle of the destination channel). + * byte 4..(4 + length): the string (object name or user event label), with + * zero-termination + ******************************************************************************/ + TraceStringHandle_t prvTraceLookupSymbolTableEntry( const char * name, + uint8_t crc6, + uint8_t len, + TraceStringHandle_t chn ) + { + uint16_t i = RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ]; + + TRACE_ASSERT( name != 0, "prvTraceLookupSymbolTableEntry: name == NULL", ( TraceStringHandle_t ) 0 ); + TRACE_ASSERT( len != 0, "prvTraceLookupSymbolTableEntry: len == 0", ( TraceStringHandle_t ) 0 ); + + while( i != 0 ) + { + if( RecorderDataPtr->SymbolTable.symbytes[ i + 2 ] == ( chn & 0x00FF ) ) + { + if( RecorderDataPtr->SymbolTable.symbytes[ i + 3 ] == ( chn / 0x100 ) ) + { + if( RecorderDataPtr->SymbolTable.symbytes[ i + 4 + len ] == '\0' ) + { + if( strncmp( ( char * ) ( &RecorderDataPtr->SymbolTable.symbytes[ i + 4 ] ), name, len ) == 0 ) + { + break; /* found */ + } + } + } + } + + i = ( uint16_t ) ( RecorderDataPtr->SymbolTable.symbytes[ i ] + ( RecorderDataPtr->SymbolTable.symbytes[ i + 1 ] * 0x100 ) ); + } + + return i; + } + +/******************************************************************************* + * prvTraceCreateSymbolTableEntry + * + * Creates an entry in the symbol table, independent if it exists already. + * + * The strings are stored in a byte pool, with four bytes of "meta-data" for + * every string. + * byte 0-1: index of next entry with same checksum (for fast lookup). + * byte 2-3: reference to a symbol table entry, a label for xTracePrintF + * format strings only (the handle of the destination channel). + * byte 4..(4 + length): the string (object name or user event label), with + * zero-termination + ******************************************************************************/ + TraceStringHandle_t prvTraceCreateSymbolTableEntry( const char * name, + uint8_t crc6, + uint8_t len, + TraceStringHandle_t channel ) + { + TraceStringHandle_t ret = 0; + + TRACE_ASSERT( name != 0, "prvTraceCreateSymbolTableEntry: name == NULL", 0 ); + TRACE_ASSERT( len != 0, "prvTraceCreateSymbolTableEntry: len == 0", 0 ); + + if( RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + len + 4 >= ( TRC_CFG_SYMBOL_TABLE_SIZE ) ) + { + prvTraceError( "Symbol table full. Increase TRC_CFG_SYMBOL_TABLE_SIZE in trcConfig.h" ); + ret = 0; + } + else + { + RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex ] = + ( uint8_t ) ( RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] & 0x00FF ); + + RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 1 ] = + ( uint8_t ) ( RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] / 0x100 ); + + RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 2 ] = + ( uint8_t ) ( channel & 0x00FF ); + + RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 3 ] = + ( uint8_t ) ( channel / 0x100 ); + + /* set name (bytes 4...4+len-1) */ + prvStrncpy( ( char * ) &( RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4 ] ), name, len ); + + /* Set zero termination (at offset 4+len) */ + RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4 + len ] = '\0'; + + /* store index of entry (for return value, and as head of LL[crc6]) */ + RecorderDataPtr->SymbolTable.latestEntryOfChecksum + [ crc6 ] = ( uint16_t ) RecorderDataPtr->SymbolTable.nextFreeSymbolIndex; + + RecorderDataPtr->SymbolTable.nextFreeSymbolIndex += ( uint32_t ) ( len + 5 ); + + ret = ( uint16_t ) ( RecorderDataPtr->SymbolTable.nextFreeSymbolIndex - ( uint8_t ) ( len + 5 ) ); + } + + return ret; + } + + +/******************************************************************************* + * prvTraceGetChecksum + * + * Calculates a simple 6-bit checksum from a string, used to index the string + * for fast symbol table lookup. + ******************************************************************************/ + void prvTraceGetChecksum( const char * pname, + uint8_t * pcrc, + uint8_t * plength ) + { + unsigned char c; + int length = 1; /* Should be 1 to account for '\0' */ + int crc = 0; + + TRACE_ASSERT( pname != 0, "prvTraceGetChecksum: pname == NULL", TRC_UNUSED ); + TRACE_ASSERT( pcrc != 0, "prvTraceGetChecksum: pcrc == NULL", TRC_UNUSED ); + TRACE_ASSERT( plength != 0, "prvTraceGetChecksum: plength == NULL", TRC_UNUSED ); + + if( pname != ( const char * ) 0 ) + { + for( ; ( c = ( unsigned char ) *pname++ ) != '\0'; ) + { + crc += c; + length++; + } + } + + *pcrc = ( uint8_t ) ( crc & 0x3F ); + *plength = ( uint8_t ) length; + } + + #if ( TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1 ) + + static void prvTraceStoreXID( traceHandle handle ); + +/****************************************************************************** + * prvTraceStoreXID + * + * Stores an XID (eXtended IDentifier) event. + * This is used if an object/task handle is larger than 255. + * The parameter "handle" is the full (16 bit) handle, assumed to be 256 or + * larger. Handles below 256 should not use this function. + * + * NOTE: this function MUST be called from within a critical section. + *****************************************************************************/ + static void prvTraceStoreXID( traceHandle handle ) + { + XPSEvent * xid; + + TRACE_ASSERT( handle >= 256, "prvTraceStoreXID: Handle < 256", TRC_UNUSED ); + + xid = ( XPSEvent * ) prvTraceNextFreeEventBufferSlot(); + + if( xid != 0 ) + { + xid->type = XID; + + /* This function is (only) used when traceHandle is 16 bit... */ + xid->xps_16 = handle; + + prvTraceUpdateCounters(); + } + } + + static uint8_t prvTraceGet8BitHandle( traceHandle handle ) + { + if( handle > 255 ) + { + prvTraceStoreXID( handle ); + + /* The full handle (16 bit) is stored in the XID event. + * This code (255) is used instead of zero (which is an error code).*/ + return 255; + } + + return ( uint8_t ) ( handle & 0xFF ); + } + #endif /*(TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)*/ + + +/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */ + #ifndef TRC_CFG_ARM_CM_USE_SYSTICK + #if ( ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M ) && ( defined( __CORTEX_M ) && ( __CORTEX_M >= 0x03 ) ) ) + void xTraceHardwarePortInitCortexM() + { + /* Ensure that the DWT registers are unlocked and can be modified. */ + TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK; + + /* Make sure DWT is enabled, if supported */ + TRC_REG_DEMCR |= TRC_DEMCR_TRCENA; + + do + { + /* Verify that DWT is supported */ + if( TRC_REG_DEMCR == 0 ) + { + /* This function is called on Cortex-M3, M4 and M7 devices to initialize + * the DWT unit, assumed present. The DWT cycle counter is used for timestamping. + * + * If the below error is produced, the DWT unit does not seem to be available. + * + * In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build + * to use SysTick timestamping instead, or define your own timestamping by + * setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED + * and make the necessary definitions, as explained in trcHardwarePort.h.*/ + + prvTraceError( "DWT unit not available, see code comment." ); + break; + } + + /* Verify that DWT_CYCCNT is supported */ + if( TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT ) + { + /* This function is called on Cortex-M3, M4 and M7 devices to initialize + * the DWT unit, assumed present. The DWT cycle counter is used for timestamping. + * + * If the below error is produced, the cycle counter does not seem to be available. + * + * In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build + * to use SysTick timestamping instead, or define your own timestamping by + * setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED + * and make the necessary definitions, as explained in trcHardwarePort.h.*/ + + prvTraceError( "DWT_CYCCNT not available, see code comment." ); + break; + } + + /* Reset the cycle counter */ + TRC_REG_DWT_CYCCNT = 0; + + /* Enable the cycle counter */ + TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA; + } while( 0 ); /* breaks above jump here */ + } + #endif /* if ( ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M ) && ( defined( __CORTEX_M ) && ( __CORTEX_M >= 0x03 ) ) ) */ + #endif /* ifndef TRC_CFG_ARM_CM_USE_SYSTICK */ + +/****************************************************************************** +* prvTracePortGetTimeStamp +* +* Returns the current time based on the HWTC macros which provide a hardware +* isolation layer towards the hardware timer/counter. +* +* The HWTC macros and prvTracePortGetTimeStamp is the main porting issue +* or the trace recorder library. Typically you should not need to change +* the code of prvTracePortGetTimeStamp if using the HWTC macros. +* +******************************************************************************/ + void prvTracePortGetTimeStamp( uint32_t * pTimestamp ) + { + static uint32_t last_hwtc_count = 0; + uint32_t hwtc_count = 0; + + #if TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR + /* systick based timer */ + static uint32_t last_traceTickCount = 0; + uint32_t traceTickCount = 0; + #else /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/ + /* Free running timer */ + static uint32_t last_hwtc_rest = 0; + uint32_t diff = 0; + uint32_t diff_scaled = 0; + #endif /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/ + + if( trace_disable_timestamp == 1 ) + { + if( pTimestamp ) + { + *pTimestamp = last_timestamp; + } + + return; + } + + /* Retrieve TRC_HWTC_COUNT only once since the same value should be used all throughout this function. */ + #if ( TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR ) + /* Get the increasing tick count */ + hwtc_count = ( TRC_HWTC_COUNT ); + #elif ( TRC_HWTC_TYPE == TRC_OS_TIMER_DECR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR ) + /* Convert decreasing tick count into increasing tick count */ + hwtc_count = ( TRC_HWTC_PERIOD ) -( TRC_HWTC_COUNT ); + #else + #error "TRC_HWTC_TYPE has unexpected value" + #endif + + #if ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32 ) + + /* The Win32 port uses ulGetRunTimeCounterValue for timestamping, which in turn + * uses QueryPerformanceCounter. That function is not always reliable when used over + * multiple threads. We must therefore handle rare cases where the timestamp is less + * than the previous. In practice, this should "never" roll over since the + * performance counter is 64 bit wide. */ + + if( last_hwtc_count > hwtc_count ) + { + hwtc_count = last_hwtc_count; + } + #endif + + #if ( TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR ) + /* Timestamping is based on a timer that wraps at TRC_HWTC_PERIOD */ + if( last_traceTickCount - uiTraceTickCount - 1 < 0x80000000 ) + { + /* This means last_traceTickCount is higher than uiTraceTickCount, + * so we have previously compensated for a missed tick. + * Therefore we use the last stored value because that is more accurate. */ + traceTickCount = last_traceTickCount; + } + else + { + /* Business as usual */ + traceTickCount = uiTraceTickCount; + } + + /* Check for overflow. May occur if the update of uiTraceTickCount has been + * delayed due to disabled interrupts. */ + if( ( traceTickCount == last_traceTickCount ) && ( hwtc_count < last_hwtc_count ) ) + { + /* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */ + traceTickCount++; + } + + /* Check if the return address is OK, then we perform the calculation. */ + if( pTimestamp ) + { + /* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */ + last_timestamp = traceTickCount * ( ( TRC_HWTC_PERIOD ) / ( TRC_HWTC_DIVISOR ) ); + /* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / TRC_HWTC_DIVISOR. */ + last_timestamp += ( hwtc_count + traceTickCount * ( ( TRC_HWTC_PERIOD ) % ( TRC_HWTC_DIVISOR ) ) ) / ( TRC_HWTC_DIVISOR ); + } + + /* Store the previous value */ + last_traceTickCount = traceTickCount; + #else /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/ + /* Timestamping is based on a free running timer */ + + /* This part handles free running clocks that can be scaled down to avoid too large DTS values. + * Without this, the scaled timestamp will incorrectly wrap at (2^32 / TRC_HWTC_DIVISOR) ticks. + * The scaled timestamp returned from this function is supposed to go from 0 -> 2^32, which in real time would represent (0 -> 2^32 * TRC_HWTC_DIVISOR) ticks. */ + + /* First we see how long time has passed since the last timestamp call, and we also add the ticks that was lost when we scaled down the last time. */ + diff = ( hwtc_count - last_hwtc_count ) + last_hwtc_rest; + + /* Scale down the diff */ + diff_scaled = diff / ( TRC_HWTC_DIVISOR ); + + /* Find out how many ticks were lost when scaling down, so we can add them the next time */ + last_hwtc_rest = diff % ( TRC_HWTC_DIVISOR ); + + /* We increase the scaled timestamp by the scaled amount */ + last_timestamp += diff_scaled; + #endif /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/ + + /* Is anyone interested in the results? */ + if( pTimestamp ) + { + *pTimestamp = last_timestamp; + } + + /* Store the previous value */ + last_hwtc_count = hwtc_count; + } + + #if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) + + void prvAddTaskToStackMonitor( void * task ) + { + int i; + int foundEmptySlot = 0; + + /* find an empty slot */ + for( i = 0; i < TRC_CFG_STACK_MONITOR_MAX_TASKS; i++ ) + { + if( tasksInStackMonitor[ i ].tcb == 0 ) + { + tasksInStackMonitor[ i ].tcb = task; + tasksInStackMonitor[ i ].uiPreviousLowMark = 0xFFFFFFFF; + foundEmptySlot = 1; + break; + } + } + + if( foundEmptySlot == 0 ) + { + tasksNotIncluded++; + } + } + + void prvRemoveTaskFromStackMonitor( void * task ) + { + int i; + + for( i = 0; i < TRC_CFG_STACK_MONITOR_MAX_TASKS; i++ ) + { + if( tasksInStackMonitor[ i ].tcb == task ) + { + tasksInStackMonitor[ i ].tcb = 0; + tasksInStackMonitor[ i ].uiPreviousLowMark = 0; + } + } + } + + void prvReportStackUsage() + { + static int i = 0; /* Static index used to loop over the monitored tasks */ + int count = 0; /* The number of generated reports */ + int initial = i; /* Used to make sure we break if we are back at the inital value */ + + do + { + /* Check the current spot */ + if( tasksInStackMonitor[ i ].tcb != 0 ) + { + /* Get the amount of unused stack */ + TraceUnsignedBaseType_t unusedStackSpace; + xTraceKernelPortGetUnusedStack( tasksInStackMonitor[ i ].tcb, &unusedStackSpace ); + + /* Store for later use */ + if( tasksInStackMonitor[ i ].uiPreviousLowMark > unusedStackSpace ) + { + tasksInStackMonitor[ i ].uiPreviousLowMark = unusedStackSpace; + } + + prvTraceStoreKernelCallWithParam( TRACE_UNUSED_STACK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( tasksInStackMonitor[ i ].tcb ), tasksInStackMonitor[ i ].uiPreviousLowMark ); + + count++; + } + + i = ( i + 1 ) % TRC_CFG_STACK_MONITOR_MAX_TASKS; /* Move i beyond this task */ + } while( count < TRC_CFG_STACK_MONITOR_MAX_REPORTS && i != initial ); + } + #endif /* defined(TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */ + + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStackMonitor.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStackMonitor.c index ea8ceba0c..e52e132a7 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStackMonitor.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStackMonitor.c @@ -1,218 +1,220 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for the stack monitor. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#if (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0)) - -typedef struct TraceStackMonitorEntry -{ - void *pvTask; - TraceUnsignedBaseType_t uxPreviousLowWaterMark; -} TraceStackMonitorEntry_t; - -typedef struct TraceStackMonitor -{ - TraceStackMonitorEntry_t xEntries[TRC_CFG_STACK_MONITOR_MAX_TASKS]; - - uint32_t uiEntryCount; -} TraceStackMonitor_t; - -static TraceStackMonitor_t* pxStackMonitor; - -traceResult xTraceStackMonitorInitialize(TraceStackMonitorBuffer_t *pxBuffer) -{ - uint32_t i; - - TRC_ASSERT_EQUAL_SIZE(TraceStackMonitorBuffer_t, TraceStackMonitor_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - pxStackMonitor = (TraceStackMonitor_t*)pxBuffer; - - pxStackMonitor->uiEntryCount = 0; - - for (i = 0; i < (TRC_CFG_STACK_MONITOR_MAX_TASKS); i++) - { - pxStackMonitor->xEntries[i].pvTask = 0; - } - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR); - - return TRC_SUCCESS; -} - -traceResult xTraceStackMonitorAdd(void *pvTask) -{ - TraceUnsignedBaseType_t uxLowMark; - - TRACE_ALLOC_CRITICAL_SECTION(); - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR)); - - if (pvTask == 0) - { - /* We don't add null addresses */ - return TRC_FAIL; - } - - TRACE_ENTER_CRITICAL_SECTION(); - - if (pxStackMonitor->uiEntryCount >= (TRC_CFG_STACK_MONITOR_MAX_TASKS)) - { - xTraceDiagnosticsIncrease(TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS); - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; - } - - if (xTraceKernelPortGetUnusedStack(pvTask, &uxLowMark) == TRC_SUCCESS) - { - pxStackMonitor->xEntries[pxStackMonitor->uiEntryCount].pvTask = pvTask; - pxStackMonitor->xEntries[pxStackMonitor->uiEntryCount].uxPreviousLowWaterMark = uxLowMark; - - pxStackMonitor->uiEntryCount++; - } - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_SUCCESS; -} - -traceResult xTraceStackMonitorRemove(void* pvTask) -{ - uint32_t i; - - TRACE_ALLOC_CRITICAL_SECTION(); - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR)); - - if (pvTask == 0) - { - /* We don't add null addresses */ - return TRC_FAIL; - } - - TRACE_ENTER_CRITICAL_SECTION(); - - for (i = 0; i < pxStackMonitor->uiEntryCount; i++) - { - if (pxStackMonitor->xEntries[i].pvTask == pvTask) - { - if (pxStackMonitor->uiEntryCount > 1 && i != (pxStackMonitor->uiEntryCount - 1)) - { - /* There are more entries and this is NOT the last entry. Move last entry to this slot. */ - pxStackMonitor->xEntries[i].pvTask = pxStackMonitor->xEntries[pxStackMonitor->uiEntryCount - 1].pvTask; - pxStackMonitor->xEntries[i].uxPreviousLowWaterMark = pxStackMonitor->xEntries[pxStackMonitor->uiEntryCount - 1].uxPreviousLowWaterMark; - - /* Clear old entry that was moved */ - pxStackMonitor->xEntries[pxStackMonitor->uiEntryCount - 1].pvTask = 0; - pxStackMonitor->xEntries[pxStackMonitor->uiEntryCount - 1].uxPreviousLowWaterMark = 0; - } - else - { - /* No other entries or last entry. */ - pxStackMonitor->xEntries[i].pvTask = 0; - pxStackMonitor->xEntries[i].uxPreviousLowWaterMark = 0; - } - - pxStackMonitor->uiEntryCount--; - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_SUCCESS; - } - } - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_FAIL; -} - -traceResult xTraceStackMonitorGetAtIndex(uint32_t uiIndex, void **ppvTask, TraceUnsignedBaseType_t *puxLowWaterMark) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR)); - - /* This should never fail */ - TRC_ASSERT(ppvTask != 0); - - /* This should never fail */ - TRC_ASSERT(puxLowWaterMark != 0); - - /* This should never fail */ - TRC_ASSERT(uiIndex < (TRC_CFG_STACK_MONITOR_MAX_TASKS)); - - *ppvTask = pxStackMonitor->xEntries[uiIndex].pvTask; - *puxLowWaterMark = pxStackMonitor->xEntries[uiIndex].uxPreviousLowWaterMark; - - return TRC_SUCCESS; -} - -traceResult xTraceStackMonitorReport(void) -{ - TraceUnsignedBaseType_t uxLowWaterMark; - TraceEventHandle_t xEventHandle = 0; - TraceStackMonitorEntry_t *pxStackMonitorEntry; - uint32_t uiToReport; - uint32_t i; - static uint32_t uiCurrentIndex = 0; - - TRACE_ALLOC_CRITICAL_SECTION(); - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STACK_MONITOR)); - - TRACE_ENTER_CRITICAL_SECTION(); - - /* Never report more than there are entries */ - uiToReport = TRC_CFG_STACK_MONITOR_MAX_REPORTS <= pxStackMonitor->uiEntryCount ? TRC_CFG_STACK_MONITOR_MAX_REPORTS : pxStackMonitor->uiEntryCount; - - for (i = 0; i < uiToReport; i++) - { - /* If uiCurrentIndex is too large, reset it */ - uiCurrentIndex = uiCurrentIndex < pxStackMonitor->uiEntryCount ? uiCurrentIndex : 0; - - pxStackMonitorEntry = &pxStackMonitor->xEntries[uiCurrentIndex]; - - xTraceKernelPortGetUnusedStack(pxStackMonitorEntry->pvTask, &uxLowWaterMark); - - if (uxLowWaterMark < pxStackMonitorEntry->uxPreviousLowWaterMark) - { - pxStackMonitorEntry->uxPreviousLowWaterMark = uxLowWaterMark; - } - - if (xTraceEventBegin(PSF_EVENT_UNUSED_STACK, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pxStackMonitorEntry->pvTask); - xTraceEventAdd32(xEventHandle, (uint32_t)pxStackMonitorEntry->uxPreviousLowWaterMark); - xTraceEventEnd(xEventHandle); - } - - uiCurrentIndex++; - } - - TRACE_EXIT_CRITICAL_SECTION(); - - return TRC_SUCCESS; -} -#endif /* (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0)) */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for the stack monitor. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #if ( ( ( TRC_CFG_ENABLE_STACK_MONITOR ) == 1 ) && ( ( TRC_CFG_SCHEDULING_ONLY ) == 0 ) ) + + typedef struct TraceStackMonitorEntry + { + void * pvTask; + TraceUnsignedBaseType_t uxPreviousLowWaterMark; + } TraceStackMonitorEntry_t; + + typedef struct TraceStackMonitor + { + TraceStackMonitorEntry_t xEntries[ TRC_CFG_STACK_MONITOR_MAX_TASKS ]; + + uint32_t uiEntryCount; + } TraceStackMonitor_t; + + static TraceStackMonitor_t * pxStackMonitor; + + traceResult xTraceStackMonitorInitialize( TraceStackMonitorBuffer_t * pxBuffer ) + { + uint32_t i; + + TRC_ASSERT_EQUAL_SIZE( TraceStackMonitorBuffer_t, TraceStackMonitor_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + pxStackMonitor = ( TraceStackMonitor_t * ) pxBuffer; + + pxStackMonitor->uiEntryCount = 0; + + for( i = 0; i < ( TRC_CFG_STACK_MONITOR_MAX_TASKS ); i++ ) + { + pxStackMonitor->xEntries[ i ].pvTask = 0; + } + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_STACK_MONITOR ); + + return TRC_SUCCESS; + } + + traceResult xTraceStackMonitorAdd( void * pvTask ) + { + TraceUnsignedBaseType_t uxLowMark; + + TRACE_ALLOC_CRITICAL_SECTION(); + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_STACK_MONITOR ) ); + + if( pvTask == 0 ) + { + /* We don't add null addresses */ + return TRC_FAIL; + } + + TRACE_ENTER_CRITICAL_SECTION(); + + if( pxStackMonitor->uiEntryCount >= ( TRC_CFG_STACK_MONITOR_MAX_TASKS ) ) + { + xTraceDiagnosticsIncrease( TRC_DIAGNOSTICS_STACK_MONITOR_NO_SLOTS ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + + if( xTraceKernelPortGetUnusedStack( pvTask, &uxLowMark ) == TRC_SUCCESS ) + { + pxStackMonitor->xEntries[ pxStackMonitor->uiEntryCount ].pvTask = pvTask; + pxStackMonitor->xEntries[ pxStackMonitor->uiEntryCount ].uxPreviousLowWaterMark = uxLowMark; + + pxStackMonitor->uiEntryCount++; + } + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_SUCCESS; + } + + traceResult xTraceStackMonitorRemove( void * pvTask ) + { + uint32_t i; + + TRACE_ALLOC_CRITICAL_SECTION(); + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_STACK_MONITOR ) ); + + if( pvTask == 0 ) + { + /* We don't add null addresses */ + return TRC_FAIL; + } + + TRACE_ENTER_CRITICAL_SECTION(); + + for( i = 0; i < pxStackMonitor->uiEntryCount; i++ ) + { + if( pxStackMonitor->xEntries[ i ].pvTask == pvTask ) + { + if( ( pxStackMonitor->uiEntryCount > 1 ) && ( i != ( pxStackMonitor->uiEntryCount - 1 ) ) ) + { + /* There are more entries and this is NOT the last entry. Move last entry to this slot. */ + pxStackMonitor->xEntries[ i ].pvTask = pxStackMonitor->xEntries[ pxStackMonitor->uiEntryCount - 1 ].pvTask; + pxStackMonitor->xEntries[ i ].uxPreviousLowWaterMark = pxStackMonitor->xEntries[ pxStackMonitor->uiEntryCount - 1 ].uxPreviousLowWaterMark; + + /* Clear old entry that was moved */ + pxStackMonitor->xEntries[ pxStackMonitor->uiEntryCount - 1 ].pvTask = 0; + pxStackMonitor->xEntries[ pxStackMonitor->uiEntryCount - 1 ].uxPreviousLowWaterMark = 0; + } + else + { + /* No other entries or last entry. */ + pxStackMonitor->xEntries[ i ].pvTask = 0; + pxStackMonitor->xEntries[ i ].uxPreviousLowWaterMark = 0; + } + + pxStackMonitor->uiEntryCount--; + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_SUCCESS; + } + } + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_FAIL; + } + + traceResult xTraceStackMonitorGetAtIndex( uint32_t uiIndex, + void ** ppvTask, + TraceUnsignedBaseType_t * puxLowWaterMark ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_STACK_MONITOR ) ); + + /* This should never fail */ + TRC_ASSERT( ppvTask != 0 ); + + /* This should never fail */ + TRC_ASSERT( puxLowWaterMark != 0 ); + + /* This should never fail */ + TRC_ASSERT( uiIndex < ( TRC_CFG_STACK_MONITOR_MAX_TASKS ) ); + + *ppvTask = pxStackMonitor->xEntries[ uiIndex ].pvTask; + *puxLowWaterMark = pxStackMonitor->xEntries[ uiIndex ].uxPreviousLowWaterMark; + + return TRC_SUCCESS; + } + + traceResult xTraceStackMonitorReport( void ) + { + TraceUnsignedBaseType_t uxLowWaterMark; + TraceEventHandle_t xEventHandle = 0; + TraceStackMonitorEntry_t * pxStackMonitorEntry; + uint32_t uiToReport; + uint32_t i; + static uint32_t uiCurrentIndex = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_STACK_MONITOR ) ); + + TRACE_ENTER_CRITICAL_SECTION(); + + /* Never report more than there are entries */ + uiToReport = TRC_CFG_STACK_MONITOR_MAX_REPORTS <= pxStackMonitor->uiEntryCount ? TRC_CFG_STACK_MONITOR_MAX_REPORTS : pxStackMonitor->uiEntryCount; + + for( i = 0; i < uiToReport; i++ ) + { + /* If uiCurrentIndex is too large, reset it */ + uiCurrentIndex = uiCurrentIndex < pxStackMonitor->uiEntryCount ? uiCurrentIndex : 0; + + pxStackMonitorEntry = &pxStackMonitor->xEntries[ uiCurrentIndex ]; + + xTraceKernelPortGetUnusedStack( pxStackMonitorEntry->pvTask, &uxLowWaterMark ); + + if( uxLowWaterMark < pxStackMonitorEntry->uxPreviousLowWaterMark ) + { + pxStackMonitorEntry->uxPreviousLowWaterMark = uxLowWaterMark; + } + + if( xTraceEventBegin( PSF_EVENT_UNUSED_STACK, sizeof( void * ) + sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pxStackMonitorEntry->pvTask ); + xTraceEventAdd32( xEventHandle, ( uint32_t ) pxStackMonitorEntry->uxPreviousLowWaterMark ); + xTraceEventEnd( xEventHandle ); + } + + uiCurrentIndex++; + } + + TRACE_EXIT_CRITICAL_SECTION(); + + return TRC_SUCCESS; + } + #endif /* (((TRC_CFG_ENABLE_STACK_MONITOR) == 1) && ((TRC_CFG_SCHEDULING_ONLY) == 0)) */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStateMachine.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStateMachine.c index 7504746a3..57d5e860a 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStateMachine.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStateMachine.c @@ -1,99 +1,103 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation of state machines. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#define TRC_STATE_MACHINE_STATE_INDEX 0 -#define TRC_STATE_MACHINE_INDEX 0 - -traceResult xTraceStateMachineCreate(const char *szName, TraceStateMachineHandle_t *pxStateMachineHandle) -{ - TraceObjectHandle_t xObjectHandle; - - /* This should never fail */ - TRC_ASSERT(pxStateMachineHandle != 0); - - /* We need to check this */ - if (xTraceObjectRegister(PSF_EVENT_STATEMACHINE_CREATE , 0, szName, 0, &xObjectHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions((TraceEntryHandle_t)xObjectHandle, (uint32_t)TRC_ENTRY_OPTION_STATE_MACHINE) == TRC_SUCCESS); - - *pxStateMachineHandle = (TraceStateMachineHandle_t)xObjectHandle; - - return TRC_SUCCESS; -} - -traceResult xTraceStateMachineStateCreate(TraceStateMachineHandle_t xStateMachineHandle, const char* szName, TraceStateMachineStateHandle_t* pxStateHandle) -{ - TraceObjectHandle_t xObjectHandle; - - /* This should never fail */ - TRC_ASSERT(xStateMachineHandle != 0); - - /* This should never fail */ - TRC_ASSERT(pxStateHandle != 0); - - /* We need to check this */ - if (xTraceObjectRegister(PSF_EVENT_STATEMACHINE_STATE_CREATE, 0, szName, (TraceUnsignedBaseType_t)xStateMachineHandle, &xObjectHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions((TraceEntryHandle_t)xObjectHandle, (uint32_t)TRC_ENTRY_OPTION_STATE_MACHINE_STATE) == TRC_SUCCESS); - - *pxStateHandle = (TraceStateMachineHandle_t)xObjectHandle; - - return TRC_SUCCESS; -} - -traceResult xTraceStateMachineSetState(TraceStateMachineHandle_t xStateMachineHandle, TraceStateMachineStateHandle_t xStateHandle) -{ - TraceEventHandle_t xEventHandle = 0; - TraceUnsignedBaseType_t uxStateMachine; - - /* This should never fail */ - TRC_ASSERT(xStateMachineHandle != 0); - - /* This should never fail */ - TRC_ASSERT(xStateHandle != 0); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState((TraceEntryHandle_t)xStateHandle, TRC_STATE_MACHINE_INDEX, &uxStateMachine) == TRC_SUCCESS); - - /* Verify that this state machine state was meant to be used with this state machine */ - /* This should never fail */ - TRC_ASSERT(xStateMachineHandle == (TraceStateMachineHandle_t)uxStateMachine); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState((TraceEntryHandle_t)xStateMachineHandle, TRC_STATE_MACHINE_STATE_INDEX, (TraceUnsignedBaseType_t)xStateHandle) == TRC_SUCCESS); - - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_STATEMACHINE_STATECHANGE, sizeof(void*) + sizeof(void*), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, (void*)xStateMachineHandle); - xTraceEventAddPointer(xEventHandle, (void*)xStateHandle); - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation of state machines. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #define TRC_STATE_MACHINE_STATE_INDEX 0 + #define TRC_STATE_MACHINE_INDEX 0 + + traceResult xTraceStateMachineCreate( const char * szName, + TraceStateMachineHandle_t * pxStateMachineHandle ) + { + TraceObjectHandle_t xObjectHandle; + + /* This should never fail */ + TRC_ASSERT( pxStateMachineHandle != 0 ); + + /* We need to check this */ + if( xTraceObjectRegister( PSF_EVENT_STATEMACHINE_CREATE, 0, szName, 0, &xObjectHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetOptions( ( TraceEntryHandle_t ) xObjectHandle, ( uint32_t ) TRC_ENTRY_OPTION_STATE_MACHINE ) == TRC_SUCCESS ); + + *pxStateMachineHandle = ( TraceStateMachineHandle_t ) xObjectHandle; + + return TRC_SUCCESS; + } + + traceResult xTraceStateMachineStateCreate( TraceStateMachineHandle_t xStateMachineHandle, + const char * szName, + TraceStateMachineStateHandle_t * pxStateHandle ) + { + TraceObjectHandle_t xObjectHandle; + + /* This should never fail */ + TRC_ASSERT( xStateMachineHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( pxStateHandle != 0 ); + + /* We need to check this */ + if( xTraceObjectRegister( PSF_EVENT_STATEMACHINE_STATE_CREATE, 0, szName, ( TraceUnsignedBaseType_t ) xStateMachineHandle, &xObjectHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetOptions( ( TraceEntryHandle_t ) xObjectHandle, ( uint32_t ) TRC_ENTRY_OPTION_STATE_MACHINE_STATE ) == TRC_SUCCESS ); + + *pxStateHandle = ( TraceStateMachineHandle_t ) xObjectHandle; + + return TRC_SUCCESS; + } + + traceResult xTraceStateMachineSetState( TraceStateMachineHandle_t xStateMachineHandle, + TraceStateMachineStateHandle_t xStateHandle ) + { + TraceEventHandle_t xEventHandle = 0; + TraceUnsignedBaseType_t uxStateMachine; + + /* This should never fail */ + TRC_ASSERT( xStateMachineHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT( xStateHandle != 0 ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetState( ( TraceEntryHandle_t ) xStateHandle, TRC_STATE_MACHINE_INDEX, &uxStateMachine ) == TRC_SUCCESS ); + + /* Verify that this state machine state was meant to be used with this state machine */ + /* This should never fail */ + TRC_ASSERT( xStateMachineHandle == ( TraceStateMachineHandle_t ) uxStateMachine ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetState( ( TraceEntryHandle_t ) xStateMachineHandle, TRC_STATE_MACHINE_STATE_INDEX, ( TraceUnsignedBaseType_t ) xStateHandle ) == TRC_SUCCESS ); + + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_STATEMACHINE_STATECHANGE, sizeof( void * ) + sizeof( void * ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, ( void * ) xStateMachineHandle ); + xTraceEventAddPointer( xEventHandle, ( void * ) xStateHandle ); + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStaticBuffer.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStaticBuffer.c index e6fbf5b7c..e781a43e1 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStaticBuffer.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStaticBuffer.c @@ -1,57 +1,57 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for the static buffer. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -TraceStaticBufferTable_t *pxTraceStaticBufferTable; - -traceResult xTraceStaticBufferInitialize(TraceStaticBufferBuffer_t *pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceStaticBufferBuffer_t, TraceStaticBufferTable_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - pxTraceStaticBufferTable = (TraceStaticBufferTable_t*)pxBuffer; - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_STATIC_BUFFER); - - return TRC_SUCCESS; -} - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -/* Returns a pointer to a maximum sized static buffer */ -traceResult xTraceStaticBufferGet(void **ppvBuffer) -{ - int32_t ISR_nesting; - - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_STATIC_BUFFER)); - - TRC_ASSERT(ppvBuffer != 0); - - TRC_ASSERT(xTraceISRGetCurrentNesting(&ISR_nesting) == TRC_SUCCESS); - - /* Task dummy events begin at 0, ISR dummy events begin at index 1 */ - *ppvBuffer = (void*)&pxTraceStaticBufferTable->coreDummyEvents[TRC_CFG_GET_CURRENT_CORE()].dummyEvents[ISR_nesting + 1]; - - return TRC_SUCCESS; -} - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for the static buffer. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + TraceStaticBufferTable_t * pxTraceStaticBufferTable; + + traceResult xTraceStaticBufferInitialize( TraceStaticBufferBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceStaticBufferBuffer_t, TraceStaticBufferTable_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + pxTraceStaticBufferTable = ( TraceStaticBufferTable_t * ) pxBuffer; + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_STATIC_BUFFER ); + + return TRC_SUCCESS; + } + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + +/* Returns a pointer to a maximum sized static buffer */ + traceResult xTraceStaticBufferGet( void ** ppvBuffer ) + { + int32_t ISR_nesting; + + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_STATIC_BUFFER ) ); + + TRC_ASSERT( ppvBuffer != 0 ); + + TRC_ASSERT( xTraceISRGetCurrentNesting( &ISR_nesting ) == TRC_SUCCESS ); + + /* Task dummy events begin at 0, ISR dummy events begin at index 1 */ + *ppvBuffer = ( void * ) &pxTraceStaticBufferTable->coreDummyEvents[ TRC_CFG_GET_CURRENT_CORE() ].dummyEvents[ ISR_nesting + 1 ]; + + return TRC_SUCCESS; + } + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c index e9f9a74b1..d174608a2 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c @@ -1,596 +1,610 @@ -/* - * Trace Recorder for Tracealyzer v4.6.0 - * Copyright 2021 Percepio AB - * www.percepio.com - * - * SPDX-License-Identifier: Apache-2.0 - * - * The generic core of the trace recorder's streaming mode. - */ - -#include - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -typedef struct TraceHeader -{ - uint32_t uiPSF; - uint16_t uiVersion; - uint16_t uiPlatform; - uint32_t uiOptions; - uint32_t uiNumCores; - uint32_t isrTailchainingThreshold; - char platformCfg[8]; - uint16_t uiPlatformCfgPatch; - uint8_t uiPlatformCfgMinor; - uint8_t uiPlatformCfgMajor; -} TraceHeader_t; - -/* The data structure for commands (a bit overkill) */ -typedef struct TraceCommandType_t -{ - unsigned char cmdCode; - unsigned char param1; - unsigned char param2; - unsigned char param3; - unsigned char param4; - unsigned char param5; - unsigned char checksumLSB; - unsigned char checksumMSB; -} TraceCommand_t; - -#ifndef TRC_CFG_RECORDER_DATA_INIT -#define TRC_CFG_RECORDER_DATA_INIT 1 -#endif - -/* Used to interpret the data format */ -#define TRACE_FORMAT_VERSION ((uint16_t)0x000A) - -/* Used to determine endian of data (big/little) */ -#define TRACE_PSF_ENDIANESS_IDENTIFIER ((uint32_t)0x50534600) - -#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC) -static TraceRecorderData_t xRecorderData TRC_CFG_RECORDER_DATA_ATTRIBUTE; -TraceRecorderData_t* pxTraceRecorderData = &xRecorderData; -#else -/* If using DYNAMIC or CUSTOM allocation */ -TraceRecorderData_t* pxTraceRecorderData TRC_CFG_RECORDER_DATA_ATTRIBUTE; -#endif - -static TraceHeader_t* pxHeader; - -/******************************************************************************* -* RecorderInitialized -* -* Makes sure the recorder data is only initialized once. -* -* NOTE: RecorderInitialized is only initialized to 0 if -* TRC_CFG_RECORDER_DATA_INIT is non-zero. -* This will avoid issues where the recorder must be started before main(), -* which can lead to RecorderInitialized be cleared by late initialization after -* xTraceEnable(TRC_INIT) was called and assigned RecorderInitialized its' -* value. -******************************************************************************/ -#if (TRC_CFG_RECORDER_DATA_INIT != 0) -uint32_t RecorderInitialized = 0; -#else /* (TRC_CFG_RECORDER_DATA_INIT != 0) */ -uint32_t RecorderInitialized TRC_CFG_RECORDER_DATA_ATTRIBUTE; -#endif /* (TRC_CFG_RECORDER_DATA_INIT != 0) */ - -#if (TRC_EXTERNAL_BUFFERS == 0) -/* Stores the header information on Start */ -static void prvTraceStoreHeader(void); - -/* Store the Timestamp info */ -static void prvTraceStoreTimestampInfo(void); - -/* Stores the entry table on Start */ -static void prvTraceStoreEntryTable(void); - -#else /* (TRC_EXTERNAL_BUFFERS == 0) */ - -#define prvTraceStoreHeader() -#define prvTraceStoreTimestampInfo() -#define prvTraceStoreEntryTable() - -#endif /* (TRC_EXTERNAL_BUFFERS == 0) */ - -/* Store start event. */ -static void prvTraceStoreStartEvent(void); - -/* Checks if the provided command is a valid command */ -static int prvIsValidCommand(TraceCommand_t* cmd); - -/* Executed the received command (Start or Stop) */ -static void prvProcessCommand(TraceCommand_t* cmd); - -/* Internal function for starting the recorder */ -static void prvSetRecorderEnabled(void); - -/* Internal function for stopping the recorder */ -static void prvSetRecorderDisabled(void); - -/****************************************************************************** -* xTraceInitialize -* -* Initializes the recorder data. -* This function will be called by xTraceEnable(...). -* Only needs to be called manually if traced objects are created before the -* trace recorder can be enabled, at which point make sure to call this function -* as early as possible. -* See TRC_CFG_RECORDER_DATA_INIT in trcConfig.h. -******************************************************************************/ -traceResult xTraceInitialize(void) -{ - TRC_ASSERT_EQUAL_SIZE(TraceRecorderDataBuffer_t, TraceRecorderData_t); - - if (RecorderInitialized != 0) - { - return TRC_SUCCESS; - } - -#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC) - pxRecorderData = TRC_MALLOC(sizeof(TraceRecorderData_t)); -#endif - - /* These are set on init so they aren't overwritten by late initialization values. */ - pxTraceRecorderData->uiSessionCounter = 0; - pxTraceRecorderData->uiRecorderEnabled = 0; - pxTraceRecorderData->uiTraceSystemState = TRC_STATE_IN_STARTUP; - -#if (TRC_EXTERNAL_BUFFERS == 0) - if (xTraceHeaderInitialize(&pxTraceRecorderData->xHeaderBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceEntryTableInitialize(&pxTraceRecorderData->xEntryTableBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceTimestampInitialize(&pxTraceRecorderData->xTimestampBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } -#endif - - if (xTraceStackMonitorInitialize(&pxTraceRecorderData->xStackMonitorBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceStreamPortInitialize(&pxTraceRecorderData->xStreamPortBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceAssertInitialize(&pxTraceRecorderData->xAssertBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceDiagnosticsInitialize(&pxTraceRecorderData->xDiagnosticsBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceStaticBufferInitialize(&pxTraceRecorderData->xStaticBufferBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceEventInitialize(&pxTraceRecorderData->xEventDataBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTracePrintInitialize(&pxTraceRecorderData->xPrintBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceErrorInitialize(&pxTraceRecorderData->xErrorBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceISRInitialize(&pxTraceRecorderData->xISRInfoBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceTaskInitialize(&pxTraceRecorderData->xTaskInfoBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - if (xTraceKernelPortInitialize(&pxTraceRecorderData->xKernelPortBuffer) == TRC_FAIL) - { - return TRC_FAIL; - } - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_CORE); - - return TRC_SUCCESS; -} - -traceResult xTraceHeaderInitialize(TraceHeaderBuffer_t *pxBuffer) -{ - uint32_t i; - char* platform_cfg = TRC_PLATFORM_CFG; - - TRC_ASSERT_EQUAL_SIZE(TraceHeaderBuffer_t, TraceHeader_t); - - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - pxHeader = (TraceHeader_t*)pxBuffer; - - pxHeader->uiPSF = TRACE_PSF_ENDIANESS_IDENTIFIER; - pxHeader->uiVersion = TRACE_FORMAT_VERSION; - pxHeader->uiPlatform = TRACE_KERNEL_VERSION; - - for (i = 0; i < TRC_PLATFORM_CFG_LENGTH; i++) - { - pxHeader->platformCfg[i] = platform_cfg[i]; - if (platform_cfg[i] == 0) - { - break; - } - } - pxHeader->uiPlatformCfgPatch = TRC_PLATFORM_CFG_PATCH; - pxHeader->uiPlatformCfgMinor = TRC_PLATFORM_CFG_MINOR; - pxHeader->uiPlatformCfgMajor = TRC_PLATFORM_CFG_MAJOR; - pxHeader->uiNumCores = TRC_CFG_CORE_COUNT; - pxHeader->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD; - - /* Lowest bit used for TRC_IRQ_PRIORITY_ORDER */ - pxHeader->uiOptions = ((TRC_IRQ_PRIORITY_ORDER) << 0); - - /* 3rd bit used for TRC_CFG_TEST_MODE */ - pxHeader->uiOptions |= ((TRC_CFG_TEST_MODE) << 2); - - return TRC_SUCCESS; -} - -traceResult xTraceEnable(uint32_t uiStartOption) -{ - TraceCommand_t xCommand; - int32_t iBytes = 0; - - if (xTraceInitialize() == TRC_FAIL) - { - return TRC_FAIL; - } - - xTraceStreamPortOnEnable(uiStartOption); - - if (xTraceKernelPortEnable() == TRC_FAIL) - { - return TRC_FAIL; - } - - if (uiStartOption == TRC_START_AWAIT_HOST) - { - /* We keep trying to read commands from host until the recorder has been started */ - do - { - iBytes = 0; - - if (xTraceStreamPortReadData(&xCommand, sizeof(TraceCommand_t), (int32_t*)&iBytes) == TRC_FAIL) - { - xTraceWarning(TRC_WARNING_STREAM_PORT_READ); - } - - if (iBytes == sizeof(TraceCommand_t)) - { - if (prvIsValidCommand(&xCommand)) - { - if (xCommand.cmdCode == CMD_SET_ACTIVE && xCommand.param1 == 1) - { - /* On start, init and reset the timestamping */ - TRC_PORT_SPECIFIC_INIT(); - } - - prvProcessCommand(&xCommand); - } - } - } while (pxTraceRecorderData->uiRecorderEnabled == 0); - } - else if (uiStartOption == TRC_START) - { - /* We start streaming directly - this assumes that the host interface is ready! */ - TRC_PORT_SPECIFIC_INIT(); - - xCommand.cmdCode = CMD_SET_ACTIVE; - xCommand.param1 = 1; - prvProcessCommand(&xCommand); - } - else if (uiStartOption == TRC_START_FROM_HOST) - { - /* We prepare the system to receive commands from host, but let system resume execution until that happens */ - TRC_PORT_SPECIFIC_INIT(); - } - - return TRC_SUCCESS; -} - -traceResult xTraceDisable(void) -{ - prvSetRecorderDisabled(); - - xTraceStreamPortOnDisable(); - - return TRC_SUCCESS; -} - -#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM) -traceResult xTraceSetBuffer(TraceRecorderDataBuffer_t* pxBuffer) -{ - if (pxBuffer == 0) - { - return TRC_FAIL; - } - - pxTraceRecorderData = (TraceRecorderData_t*)pxBuffer; - - return TRC_SUCCESS; -} -#endif - -traceResult xTraceGetEventBuffer(void **ppvBuffer, TraceUnsignedBaseType_t *puiSize) -{ - if (pxTraceRecorderData == 0 || ppvBuffer == 0 || puiSize == 0) - { - return TRC_FAIL; - } - - /* Returns the xStreamPortBuffer since that is the one containing trace data */ - *ppvBuffer = (void*)&pxTraceRecorderData->xStreamPortBuffer; - *puiSize = sizeof(pxTraceRecorderData->xStreamPortBuffer); - - return TRC_SUCCESS; -} - -traceResult xTraceTzCtrl(void) -{ - TraceCommand_t xCommand; - int32_t iBytes = 0; - - do - { - /* Listen for new commands */ - iBytes = 0; - if (xTraceStreamPortReadData(&xCommand, sizeof(TraceCommand_t), &iBytes) == TRC_FAIL) - { - /* The connection has failed, stop tracing */ - xTraceDisable(); - - return TRC_FAIL; - } - - if (iBytes == sizeof(TraceCommand_t)) - { - if (prvIsValidCommand(&xCommand)) - { - prvProcessCommand(&xCommand); /* Start or Stop currently... */ - } - } - -#if (TRC_USE_INTERNAL_BUFFER == 1) - xTraceInternalEventBufferTransfer(&iBytes); -#endif - - /* If there was data sent or received (bytes != 0), loop around and repeat, if there is more data to send or receive. - Otherwise, step out of this loop and sleep for a while. */ - - } while (iBytes != 0); - - if (xTraceIsRecorderEnabled()) - { - xTraceDiagnosticsCheckStatus(); - xTraceStackMonitorReport(); - } - - return TRC_SUCCESS; -} - -void vTraceSetFilterGroup(uint16_t filterGroup) -{ - (void)filterGroup; -} - -void vTraceSetFilterMask(uint16_t filterMask) -{ - (void)filterMask; -} - -/******************************************************************************/ -/*** INTERNAL FUNCTIONS *******************************************************/ -/******************************************************************************/ -/* Internal function for starting/stopping the recorder. */ -static void prvSetRecorderEnabled(void) -{ - uint32_t timestampFrequency = 0; - - TRACE_ALLOC_CRITICAL_SECTION(); - - if (pxTraceRecorderData->uiRecorderEnabled == 1) - { - return; - } - - xTraceTimestampGetFrequency(×tampFrequency); - /* If not overridden using xTraceTimestampSetFrequency(...), use default value */ - if (timestampFrequency == 0) - { - timestampFrequency = TRC_HWTC_FREQ_HZ; - xTraceTimestampSetFrequency(timestampFrequency); - } - - TRACE_ENTER_CRITICAL_SECTION(); - - /* If the internal event buffer is used, we must clear it */ - xTraceInternalEventBufferClear(); - - xTraceStreamPortOnTraceBegin(); - - prvTraceStoreHeader(); - prvTraceStoreTimestampInfo(); - prvTraceStoreEntryTable(); - prvTraceStoreStartEvent(); - - pxTraceRecorderData->uiSessionCounter++; - - pxTraceRecorderData->uiRecorderEnabled = 1; - - TRACE_EXIT_CRITICAL_SECTION(); -} - -static void prvSetRecorderDisabled(void) -{ - TRACE_ALLOC_CRITICAL_SECTION(); - - if (pxTraceRecorderData->uiRecorderEnabled == 0) - { - return; - } - - TRACE_ENTER_CRITICAL_SECTION(); - - pxTraceRecorderData->uiRecorderEnabled = 0; - - xTraceStreamPortOnTraceEnd(); - - TRACE_EXIT_CRITICAL_SECTION(); -} - -#if (TRC_EXTERNAL_BUFFERS == 0) -/* Stores the header information on Start */ -static void prvTraceStoreHeader(void) -{ - TraceEventHandle_t xEventHandle; - - if (xTraceEventBeginRawOfflineBlocking(sizeof(TraceHeader_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddData(xEventHandle, pxHeader, sizeof(TraceHeader_t)); - xTraceEventEndOfflineBlocking(xEventHandle); - } -} - -/* Store the Timestamp */ -static void prvTraceStoreTimestampInfo(void) -{ - TraceEventHandle_t xEventHandle; - uint32_t timestampFrequency = 0; - - xTraceTimestampGetFrequency(×tampFrequency); - - if (xTraceEventBeginRawOfflineBlocking(sizeof(TraceTimestampBuffer_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddData(xEventHandle, &pxTraceRecorderData->xTimestampBuffer, sizeof(TraceTimestampBuffer_t)); - xTraceEventEndOfflineBlocking(xEventHandle); - } -} - -/* Stores the entry table on Start */ -static void prvTraceStoreEntryTable(void) -{ - uint32_t i = 0; - TraceEventHandle_t xEventHandle; - TraceEntryHandle_t xEntryHandle; - uint32_t uiEntryCount; - void *pvEntryAddress; - - xTraceEntryGetCount(&uiEntryCount); - - if (xTraceEventBeginRawOfflineBlocking(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAdd32(xEventHandle, uiEntryCount); - xTraceEventAdd32(xEventHandle, TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE); - xTraceEventAdd32(xEventHandle, TRC_ENTRY_TABLE_STATE_COUNT); - xTraceEventEndOfflineBlocking(xEventHandle); - } - - for (i = 0; i < (TRC_ENTRY_TABLE_SLOTS); i++) - { - xTraceEntryGetAtIndex(i, &xEntryHandle); - xTraceEntryGetAddress(xEntryHandle, &pvEntryAddress); - /* We only send used entry slots */ - if (pvEntryAddress != 0) - { - /* Send entry */ - if (xTraceEventBeginRawOfflineBlocking(sizeof(TraceEntry_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddData(xEventHandle, (void*)xEntryHandle, sizeof(TraceEntry_t)); - xTraceEventEndOfflineBlocking(xEventHandle); - } - } - } -} -#endif /* (TRC_EXTERNAL_BUFFERS == 0) */ - -static void prvTraceStoreStartEvent() -{ - TraceEventHandle_t xEventHandle; - void* pvCurrentTask; - - xTraceTaskGetCurrent(&pvCurrentTask); - - if (xTraceEventBeginOffline(PSF_EVENT_TRACE_START, sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAdd32(xEventHandle, (uint32_t)pvCurrentTask); - xTraceEventEndOffline(xEventHandle); - } -} - -/* Checks if the provided command is a valid command */ -static int prvIsValidCommand(TraceCommand_t* cmd) -{ - uint16_t checksum = (uint16_t)(0xFFFF - ( cmd->cmdCode + - cmd->param1 + - cmd->param2 + - cmd->param3 + - cmd->param4 + - cmd->param5)); - - if (cmd->checksumMSB != (unsigned char)(checksum >> 8)) - return 0; - - if (cmd->checksumLSB != (unsigned char)(checksum & 0xFF)) - return 0; - - if (cmd->cmdCode > CMD_LAST_COMMAND) - return 0; - - return 1; -} - -/* Executed the received command (Start or Stop) */ -static void prvProcessCommand(TraceCommand_t* cmd) -{ - switch(cmd->cmdCode) - { - case CMD_SET_ACTIVE: - if (cmd->param1 == 1) - { - prvSetRecorderEnabled(); - } - else - { - prvSetRecorderDisabled(); - } - break; - default: - break; - } -} - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ - -#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The generic core of the trace recorder's streaming mode. + */ + +#include + +#if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + #if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + typedef struct TraceHeader + { + uint32_t uiPSF; + uint16_t uiVersion; + uint16_t uiPlatform; + uint32_t uiOptions; + uint32_t uiNumCores; + uint32_t isrTailchainingThreshold; + char platformCfg[ 8 ]; + uint16_t uiPlatformCfgPatch; + uint8_t uiPlatformCfgMinor; + uint8_t uiPlatformCfgMajor; + } TraceHeader_t; + +/* The data structure for commands (a bit overkill) */ + typedef struct TraceCommandType_t + { + unsigned char cmdCode; + unsigned char param1; + unsigned char param2; + unsigned char param3; + unsigned char param4; + unsigned char param5; + unsigned char checksumLSB; + unsigned char checksumMSB; + } TraceCommand_t; + + #ifndef TRC_CFG_RECORDER_DATA_INIT + #define TRC_CFG_RECORDER_DATA_INIT 1 + #endif + +/* Used to interpret the data format */ + #define TRACE_FORMAT_VERSION ( ( uint16_t ) 0x000A ) + +/* Used to determine endian of data (big/little) */ + #define TRACE_PSF_ENDIANESS_IDENTIFIER ( ( uint32_t ) 0x50534600 ) + + #if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC ) + static TraceRecorderData_t xRecorderData TRC_CFG_RECORDER_DATA_ATTRIBUTE; + TraceRecorderData_t * pxTraceRecorderData = &xRecorderData; + #else +/* If using DYNAMIC or CUSTOM allocation */ + TraceRecorderData_t * pxTraceRecorderData TRC_CFG_RECORDER_DATA_ATTRIBUTE; + #endif + + static TraceHeader_t * pxHeader; + +/******************************************************************************* + * RecorderInitialized + * + * Makes sure the recorder data is only initialized once. + * + * NOTE: RecorderInitialized is only initialized to 0 if + * TRC_CFG_RECORDER_DATA_INIT is non-zero. + * This will avoid issues where the recorder must be started before main(), + * which can lead to RecorderInitialized be cleared by late initialization after + * xTraceEnable(TRC_INIT) was called and assigned RecorderInitialized its' + * value. + ******************************************************************************/ + #if ( TRC_CFG_RECORDER_DATA_INIT != 0 ) + uint32_t RecorderInitialized = 0; + #else /* (TRC_CFG_RECORDER_DATA_INIT != 0) */ + uint32_t RecorderInitialized TRC_CFG_RECORDER_DATA_ATTRIBUTE; + #endif /* (TRC_CFG_RECORDER_DATA_INIT != 0) */ + + #if ( TRC_EXTERNAL_BUFFERS == 0 ) +/* Stores the header information on Start */ + static void prvTraceStoreHeader( void ); + +/* Store the Timestamp info */ + static void prvTraceStoreTimestampInfo( void ); + +/* Stores the entry table on Start */ + static void prvTraceStoreEntryTable( void ); + + #else /* (TRC_EXTERNAL_BUFFERS == 0) */ + + #define prvTraceStoreHeader() + #define prvTraceStoreTimestampInfo() + #define prvTraceStoreEntryTable() + + #endif /* (TRC_EXTERNAL_BUFFERS == 0) */ + +/* Store start event. */ + static void prvTraceStoreStartEvent( void ); + +/* Checks if the provided command is a valid command */ + static int prvIsValidCommand( TraceCommand_t * cmd ); + +/* Executed the received command (Start or Stop) */ + static void prvProcessCommand( TraceCommand_t * cmd ); + +/* Internal function for starting the recorder */ + static void prvSetRecorderEnabled( void ); + +/* Internal function for stopping the recorder */ + static void prvSetRecorderDisabled( void ); + +/****************************************************************************** +* xTraceInitialize +* +* Initializes the recorder data. +* This function will be called by xTraceEnable(...). +* Only needs to be called manually if traced objects are created before the +* trace recorder can be enabled, at which point make sure to call this function +* as early as possible. +* See TRC_CFG_RECORDER_DATA_INIT in trcConfig.h. +******************************************************************************/ + traceResult xTraceInitialize( void ) + { + TRC_ASSERT_EQUAL_SIZE( TraceRecorderDataBuffer_t, TraceRecorderData_t ); + + if( RecorderInitialized != 0 ) + { + return TRC_SUCCESS; + } + + #if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC ) + pxRecorderData = TRC_MALLOC( sizeof( TraceRecorderData_t ) ); + #endif + + /* These are set on init so they aren't overwritten by late initialization values. */ + pxTraceRecorderData->uiSessionCounter = 0; + pxTraceRecorderData->uiRecorderEnabled = 0; + pxTraceRecorderData->uiTraceSystemState = TRC_STATE_IN_STARTUP; + + #if ( TRC_EXTERNAL_BUFFERS == 0 ) + if( xTraceHeaderInitialize( &pxTraceRecorderData->xHeaderBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceEntryTableInitialize( &pxTraceRecorderData->xEntryTableBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceTimestampInitialize( &pxTraceRecorderData->xTimestampBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + #endif /* if ( TRC_EXTERNAL_BUFFERS == 0 ) */ + + if( xTraceStackMonitorInitialize( &pxTraceRecorderData->xStackMonitorBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceStreamPortInitialize( &pxTraceRecorderData->xStreamPortBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceAssertInitialize( &pxTraceRecorderData->xAssertBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceDiagnosticsInitialize( &pxTraceRecorderData->xDiagnosticsBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceStaticBufferInitialize( &pxTraceRecorderData->xStaticBufferBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceEventInitialize( &pxTraceRecorderData->xEventDataBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTracePrintInitialize( &pxTraceRecorderData->xPrintBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceErrorInitialize( &pxTraceRecorderData->xErrorBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceISRInitialize( &pxTraceRecorderData->xISRInfoBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceTaskInitialize( &pxTraceRecorderData->xTaskInfoBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( xTraceKernelPortInitialize( &pxTraceRecorderData->xKernelPortBuffer ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_CORE ); + + return TRC_SUCCESS; + } + + traceResult xTraceHeaderInitialize( TraceHeaderBuffer_t * pxBuffer ) + { + uint32_t i; + char * platform_cfg = TRC_PLATFORM_CFG; + + TRC_ASSERT_EQUAL_SIZE( TraceHeaderBuffer_t, TraceHeader_t ); + + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + pxHeader = ( TraceHeader_t * ) pxBuffer; + + pxHeader->uiPSF = TRACE_PSF_ENDIANESS_IDENTIFIER; + pxHeader->uiVersion = TRACE_FORMAT_VERSION; + pxHeader->uiPlatform = TRACE_KERNEL_VERSION; + + for( i = 0; i < TRC_PLATFORM_CFG_LENGTH; i++ ) + { + pxHeader->platformCfg[ i ] = platform_cfg[ i ]; + + if( platform_cfg[ i ] == 0 ) + { + break; + } + } + + pxHeader->uiPlatformCfgPatch = TRC_PLATFORM_CFG_PATCH; + pxHeader->uiPlatformCfgMinor = TRC_PLATFORM_CFG_MINOR; + pxHeader->uiPlatformCfgMajor = TRC_PLATFORM_CFG_MAJOR; + pxHeader->uiNumCores = TRC_CFG_CORE_COUNT; + pxHeader->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD; + + /* Lowest bit used for TRC_IRQ_PRIORITY_ORDER */ + pxHeader->uiOptions = ( ( TRC_IRQ_PRIORITY_ORDER ) << 0 ); + + /* 3rd bit used for TRC_CFG_TEST_MODE */ + pxHeader->uiOptions |= ( ( TRC_CFG_TEST_MODE ) << 2 ); + + return TRC_SUCCESS; + } + + traceResult xTraceEnable( uint32_t uiStartOption ) + { + TraceCommand_t xCommand; + int32_t iBytes = 0; + + if( xTraceInitialize() == TRC_FAIL ) + { + return TRC_FAIL; + } + + xTraceStreamPortOnEnable( uiStartOption ); + + if( xTraceKernelPortEnable() == TRC_FAIL ) + { + return TRC_FAIL; + } + + if( uiStartOption == TRC_START_AWAIT_HOST ) + { + /* We keep trying to read commands from host until the recorder has been started */ + do + { + iBytes = 0; + + if( xTraceStreamPortReadData( &xCommand, sizeof( TraceCommand_t ), ( int32_t * ) &iBytes ) == TRC_FAIL ) + { + xTraceWarning( TRC_WARNING_STREAM_PORT_READ ); + } + + if( iBytes == sizeof( TraceCommand_t ) ) + { + if( prvIsValidCommand( &xCommand ) ) + { + if( ( xCommand.cmdCode == CMD_SET_ACTIVE ) && ( xCommand.param1 == 1 ) ) + { + /* On start, init and reset the timestamping */ + TRC_PORT_SPECIFIC_INIT(); + } + + prvProcessCommand( &xCommand ); + } + } + } while( pxTraceRecorderData->uiRecorderEnabled == 0 ); + } + else if( uiStartOption == TRC_START ) + { + /* We start streaming directly - this assumes that the host interface is ready! */ + TRC_PORT_SPECIFIC_INIT(); + + xCommand.cmdCode = CMD_SET_ACTIVE; + xCommand.param1 = 1; + prvProcessCommand( &xCommand ); + } + else if( uiStartOption == TRC_START_FROM_HOST ) + { + /* We prepare the system to receive commands from host, but let system resume execution until that happens */ + TRC_PORT_SPECIFIC_INIT(); + } + + return TRC_SUCCESS; + } + + traceResult xTraceDisable( void ) + { + prvSetRecorderDisabled(); + + xTraceStreamPortOnDisable(); + + return TRC_SUCCESS; + } + + #if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM ) + traceResult xTraceSetBuffer( TraceRecorderDataBuffer_t * pxBuffer ) + { + if( pxBuffer == 0 ) + { + return TRC_FAIL; + } + + pxTraceRecorderData = ( TraceRecorderData_t * ) pxBuffer; + + return TRC_SUCCESS; + } + #endif /* if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM ) */ + + traceResult xTraceGetEventBuffer( void ** ppvBuffer, + TraceUnsignedBaseType_t * puiSize ) + { + if( ( pxTraceRecorderData == 0 ) || ( ppvBuffer == 0 ) || ( puiSize == 0 ) ) + { + return TRC_FAIL; + } + + /* Returns the xStreamPortBuffer since that is the one containing trace data */ + *ppvBuffer = ( void * ) &pxTraceRecorderData->xStreamPortBuffer; + *puiSize = sizeof( pxTraceRecorderData->xStreamPortBuffer ); + + return TRC_SUCCESS; + } + + traceResult xTraceTzCtrl( void ) + { + TraceCommand_t xCommand; + int32_t iBytes = 0; + + do + { + /* Listen for new commands */ + iBytes = 0; + + if( xTraceStreamPortReadData( &xCommand, sizeof( TraceCommand_t ), &iBytes ) == TRC_FAIL ) + { + /* The connection has failed, stop tracing */ + xTraceDisable(); + + return TRC_FAIL; + } + + if( iBytes == sizeof( TraceCommand_t ) ) + { + if( prvIsValidCommand( &xCommand ) ) + { + prvProcessCommand( &xCommand ); /* Start or Stop currently... */ + } + } + + #if ( TRC_USE_INTERNAL_BUFFER == 1 ) + xTraceInternalEventBufferTransfer( &iBytes ); + #endif + + /* If there was data sent or received (bytes != 0), loop around and repeat, if there is more data to send or receive. + * Otherwise, step out of this loop and sleep for a while. */ + } while( iBytes != 0 ); + + if( xTraceIsRecorderEnabled() ) + { + xTraceDiagnosticsCheckStatus(); + xTraceStackMonitorReport(); + } + + return TRC_SUCCESS; + } + + void vTraceSetFilterGroup( uint16_t filterGroup ) + { + ( void ) filterGroup; + } + + void vTraceSetFilterMask( uint16_t filterMask ) + { + ( void ) filterMask; + } + +/******************************************************************************/ +/*** INTERNAL FUNCTIONS *******************************************************/ +/******************************************************************************/ +/* Internal function for starting/stopping the recorder. */ + static void prvSetRecorderEnabled( void ) + { + uint32_t timestampFrequency = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + if( pxTraceRecorderData->uiRecorderEnabled == 1 ) + { + return; + } + + xTraceTimestampGetFrequency( ×tampFrequency ); + + /* If not overridden using xTraceTimestampSetFrequency(...), use default value */ + if( timestampFrequency == 0 ) + { + timestampFrequency = TRC_HWTC_FREQ_HZ; + xTraceTimestampSetFrequency( timestampFrequency ); + } + + TRACE_ENTER_CRITICAL_SECTION(); + + /* If the internal event buffer is used, we must clear it */ + xTraceInternalEventBufferClear(); + + xTraceStreamPortOnTraceBegin(); + + prvTraceStoreHeader(); + prvTraceStoreTimestampInfo(); + prvTraceStoreEntryTable(); + prvTraceStoreStartEvent(); + + pxTraceRecorderData->uiSessionCounter++; + + pxTraceRecorderData->uiRecorderEnabled = 1; + + TRACE_EXIT_CRITICAL_SECTION(); + } + + static void prvSetRecorderDisabled( void ) + { + TRACE_ALLOC_CRITICAL_SECTION(); + + if( pxTraceRecorderData->uiRecorderEnabled == 0 ) + { + return; + } + + TRACE_ENTER_CRITICAL_SECTION(); + + pxTraceRecorderData->uiRecorderEnabled = 0; + + xTraceStreamPortOnTraceEnd(); + + TRACE_EXIT_CRITICAL_SECTION(); + } + + #if ( TRC_EXTERNAL_BUFFERS == 0 ) +/* Stores the header information on Start */ + static void prvTraceStoreHeader( void ) + { + TraceEventHandle_t xEventHandle; + + if( xTraceEventBeginRawOfflineBlocking( sizeof( TraceHeader_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddData( xEventHandle, pxHeader, sizeof( TraceHeader_t ) ); + xTraceEventEndOfflineBlocking( xEventHandle ); + } + } + +/* Store the Timestamp */ + static void prvTraceStoreTimestampInfo( void ) + { + TraceEventHandle_t xEventHandle; + uint32_t timestampFrequency = 0; + + xTraceTimestampGetFrequency( ×tampFrequency ); + + if( xTraceEventBeginRawOfflineBlocking( sizeof( TraceTimestampBuffer_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddData( xEventHandle, &pxTraceRecorderData->xTimestampBuffer, sizeof( TraceTimestampBuffer_t ) ); + xTraceEventEndOfflineBlocking( xEventHandle ); + } + } + +/* Stores the entry table on Start */ + static void prvTraceStoreEntryTable( void ) + { + uint32_t i = 0; + TraceEventHandle_t xEventHandle; + TraceEntryHandle_t xEntryHandle; + uint32_t uiEntryCount; + void * pvEntryAddress; + + xTraceEntryGetCount( &uiEntryCount ); + + if( xTraceEventBeginRawOfflineBlocking( sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAdd32( xEventHandle, uiEntryCount ); + xTraceEventAdd32( xEventHandle, TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE ); + xTraceEventAdd32( xEventHandle, TRC_ENTRY_TABLE_STATE_COUNT ); + xTraceEventEndOfflineBlocking( xEventHandle ); + } + + for( i = 0; i < ( TRC_ENTRY_TABLE_SLOTS ); i++ ) + { + xTraceEntryGetAtIndex( i, &xEntryHandle ); + xTraceEntryGetAddress( xEntryHandle, &pvEntryAddress ); + + /* We only send used entry slots */ + if( pvEntryAddress != 0 ) + { + /* Send entry */ + if( xTraceEventBeginRawOfflineBlocking( sizeof( TraceEntry_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddData( xEventHandle, ( void * ) xEntryHandle, sizeof( TraceEntry_t ) ); + xTraceEventEndOfflineBlocking( xEventHandle ); + } + } + } + } + #endif /* (TRC_EXTERNAL_BUFFERS == 0) */ + + static void prvTraceStoreStartEvent() + { + TraceEventHandle_t xEventHandle; + void * pvCurrentTask; + + xTraceTaskGetCurrent( &pvCurrentTask ); + + if( xTraceEventBeginOffline( PSF_EVENT_TRACE_START, sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAdd32( xEventHandle, ( uint32_t ) pvCurrentTask ); + xTraceEventEndOffline( xEventHandle ); + } + } + +/* Checks if the provided command is a valid command */ + static int prvIsValidCommand( TraceCommand_t * cmd ) + { + uint16_t checksum = ( uint16_t ) ( 0xFFFF - ( cmd->cmdCode + + cmd->param1 + + cmd->param2 + + cmd->param3 + + cmd->param4 + + cmd->param5 ) ); + + if( cmd->checksumMSB != ( unsigned char ) ( checksum >> 8 ) ) + { + return 0; + } + + if( cmd->checksumLSB != ( unsigned char ) ( checksum & 0xFF ) ) + { + return 0; + } + + if( cmd->cmdCode > CMD_LAST_COMMAND ) + { + return 0; + } + + return 1; + } + +/* Executed the received command (Start or Stop) */ + static void prvProcessCommand( TraceCommand_t * cmd ) + { + switch( cmd->cmdCode ) + { + case CMD_SET_ACTIVE: + + if( cmd->param1 == 1 ) + { + prvSetRecorderEnabled(); + } + else + { + prvSetRecorderDisabled(); + } + + break; + + default: + break; + } + } + + #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcString.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcString.c index 6182d20af..601e16abb 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcString.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcString.c @@ -1,74 +1,79 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for strings. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -traceResult xTraceStringRegister(const char* szString, TraceStringHandle_t *pString) -{ - TraceEntryHandle_t xEntryHandle; - TraceEventHandle_t xEventHandle = 0; - uint32_t i = 0, uiLength = 0, uiValue = 0; - - /* This should never fail */ - TRC_ASSERT(szString != 0); - - /* This should never fail */ - TRC_ASSERT(pString != 0); - - /* We need to check this */ - if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - /* The address to the available symbol table slot is the address we use */ - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetSymbol(xEntryHandle, szString) == TRC_SUCCESS); - - *pString = (TraceStringHandle_t)xEntryHandle; - - for (i = 0; (szString[i] != 0) && (i < (TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE)); i++) {} - - uiLength = i; - - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_OBJ_NAME, sizeof(void*) + uiLength, &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, (void*)xEntryHandle); - xTraceEventAddData(xEventHandle, (void*)szString, uiLength); - - /* Check if we can truncate */ - xTraceEventPayloadRemaining(xEventHandle, &uiValue); - if (uiValue > 0) - { - xTraceEventAdd8(xEventHandle, 0); - } - - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -TraceStringHandle_t xTraceRegisterString(const char *name) -{ - TraceStringHandle_t trcStr = 0; - xTraceStringRegister(name, &trcStr); - - return trcStr; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for strings. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + traceResult xTraceStringRegister( const char * szString, + TraceStringHandle_t * pString ) + { + TraceEntryHandle_t xEntryHandle; + TraceEventHandle_t xEventHandle = 0; + uint32_t i = 0, uiLength = 0, uiValue = 0; + + /* This should never fail */ + TRC_ASSERT( szString != 0 ); + + /* This should never fail */ + TRC_ASSERT( pString != 0 ); + + /* We need to check this */ + if( xTraceEntryCreate( &xEntryHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + /* The address to the available symbol table slot is the address we use */ + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntrySetSymbol( xEntryHandle, szString ) == TRC_SUCCESS ); + + *pString = ( TraceStringHandle_t ) xEntryHandle; + + for( i = 0; ( szString[ i ] != 0 ) && ( i < ( TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE ) ); i++ ) + { + } + + uiLength = i; + + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_OBJ_NAME, sizeof( void * ) + uiLength, &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, ( void * ) xEntryHandle ); + xTraceEventAddData( xEventHandle, ( void * ) szString, uiLength ); + + /* Check if we can truncate */ + xTraceEventPayloadRemaining( xEventHandle, &uiValue ); + + if( uiValue > 0 ) + { + xTraceEventAdd8( xEventHandle, 0 ); + } + + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + TraceStringHandle_t xTraceRegisterString( const char * name ) + { + TraceStringHandle_t trcStr = 0; + + xTraceStringRegister( name, &trcStr ); + + return trcStr; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcTask.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcTask.c index ce8987252..723fa27fc 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcTask.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcTask.c @@ -1,193 +1,198 @@ -/* -* Percepio Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation for tasks. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -/* Code used for "task address" when no task has started, to indicate "(startup)". - * This value was used since NULL/0 was already reserved for the idle task. */ -#define TRACE_HANDLE_NO_TASK ((void*)2) - -#define TRC_TASK_STATE_INDEX_PRIORITY 0 -#define TRC_TASK_STATE_INDEX_UNUSED_STACK 1 - -TraceTaskInfo_t* pxTraceTaskInfo; - -traceResult xTraceTaskInitialize(TraceTaskInfoBuffer_t *pxBuffer) -{ - uint32_t i; - - TRC_ASSERT_EQUAL_SIZE(TraceTaskInfoBuffer_t, TraceTaskInfo_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - pxTraceTaskInfo = (TraceTaskInfo_t*)pxBuffer; - - for (i = 0; i < TRC_CFG_CORE_COUNT; i++) - { - pxTraceTaskInfo->coreTasks[i] = TRACE_HANDLE_NO_TASK; - } - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_TASK); - - return TRC_SUCCESS; -} - -traceResult xTraceTaskUnregister(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority) -{ - void* pvTask; - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xTaskHandle, &pvTask) == TRC_SUCCESS); - - xTraceStackMonitorRemove(pvTask); - - return xTraceObjectUnregister((TraceObjectHandle_t)xTaskHandle, PSF_EVENT_TASK_DELETE, uxPriority); -} - -traceResult xTraceTaskSetPriority(TraceTaskHandle_t xTaskHandle, TraceUnsignedBaseType_t uxPriority) -{ - TraceEventHandle_t xEventHandle = 0; - void *pvTask; - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetState((TraceObjectHandle_t)xTaskHandle, uxPriority) == TRC_SUCCESS); - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xTaskHandle, &pvTask) == TRC_SUCCESS); - - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_TASK_PRIORITY, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pvTask); - xTraceEventAdd32(xEventHandle, (uint32_t)uxPriority); - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -traceResult xTraceTaskSetPriorityWithoutHandle(void* pvTask, TraceUnsignedBaseType_t uxPriority) -{ - TraceEventHandle_t xEventHandle = 0; - TraceEntryHandle_t xEntryHandle; - - if (xTraceEntryFind(pvTask, &xEntryHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - /* This should never fail */ - TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetState((TraceObjectHandle_t)xEntryHandle, uxPriority) == TRC_SUCCESS); - - /* We need to check this */ - if (xTraceEventBegin(PSF_EVENT_TASK_PRIORITY, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pvTask); - xTraceEventAdd32(xEventHandle, (uint32_t)uxPriority); - xTraceEventEnd(xEventHandle); - } - - return TRC_SUCCESS; -} - -traceResult xTraceTaskSwitch(void *pvTask, TraceUnsignedBaseType_t uxPriority) -{ - traceResult xResult = TRC_FAIL; - TraceEventHandle_t xEventHandle = 0; - void* pvCurrent = 0; - - (void)pvTask; - (void)uxPriority; - - TRACE_ALLOC_CRITICAL_SECTION(); - - if (xTraceIsRecorderEnabled() == 0) - { - return xResult; - } - - TRACE_ENTER_CRITICAL_SECTION(); - - xTraceStateSet(TRC_STATE_IN_TASKSWITCH); - - xTraceTaskGetCurrent(&pvCurrent); - if (pvCurrent != pvTask) - { - xTraceTaskSetCurrent(pvTask); - - if (xTraceEventBegin(PSF_EVENT_TASK_ACTIVATE, sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pvTask); - xTraceEventAdd32(xEventHandle, (uint32_t)uxPriority); - xTraceEventEnd(xEventHandle); - xResult = TRC_SUCCESS; - } - } - - xTraceStateSet(TRC_STATE_IN_APPLICATION); - - TRACE_EXIT_CRITICAL_SECTION(); - - return xResult; -} - -#if (TRC_CFG_INCLUDE_READY_EVENTS == 1) -traceResult xTraceTaskReady(void *pvTask) -{ - traceResult xResult = TRC_FAIL; - TraceEventHandle_t xEventHandle = 0; - - if (xTraceEventBegin(PSF_EVENT_TASK_READY, sizeof(void*), &xEventHandle) == TRC_SUCCESS) - { - xTraceEventAddPointer(xEventHandle, pvTask); - xTraceEventEnd(xEventHandle); - xResult = TRC_SUCCESS; - } - - return xResult; -} -#endif /* (TRC_CFG_INCLUDE_READY_EVENTS == 1) */ - -traceResult xTraceTaskInstanceFinishedNow(void) -{ - TraceEventHandle_t xEventHandle = 0; - - if (xTraceEventBegin(PSF_EVENT_IFE_DIRECT, 0, &xEventHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - xTraceEventEnd(xEventHandle); - - return TRC_SUCCESS; -} - -traceResult xTraceTaskInstanceFinishedNext(void) -{ - TraceEventHandle_t xEventHandle = 0; - - if (xTraceEventBegin(PSF_EVENT_IFE_NEXT, 0, &xEventHandle) == TRC_FAIL) - { - return TRC_FAIL; - } - - xTraceEventEnd(xEventHandle); - - return TRC_SUCCESS; -} - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Percepio Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation for tasks. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + +/* Code used for "task address" when no task has started, to indicate "(startup)". + * This value was used since NULL/0 was already reserved for the idle task. */ + #define TRACE_HANDLE_NO_TASK ( ( void * ) 2 ) + + #define TRC_TASK_STATE_INDEX_PRIORITY 0 + #define TRC_TASK_STATE_INDEX_UNUSED_STACK 1 + + TraceTaskInfo_t * pxTraceTaskInfo; + + traceResult xTraceTaskInitialize( TraceTaskInfoBuffer_t * pxBuffer ) + { + uint32_t i; + + TRC_ASSERT_EQUAL_SIZE( TraceTaskInfoBuffer_t, TraceTaskInfo_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + pxTraceTaskInfo = ( TraceTaskInfo_t * ) pxBuffer; + + for( i = 0; i < TRC_CFG_CORE_COUNT; i++ ) + { + pxTraceTaskInfo->coreTasks[ i ] = TRACE_HANDLE_NO_TASK; + } + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_TASK ); + + return TRC_SUCCESS; + } + + traceResult xTraceTaskUnregister( TraceTaskHandle_t xTaskHandle, + TraceUnsignedBaseType_t uxPriority ) + { + void * pvTask; + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetAddress( ( TraceEntryHandle_t ) xTaskHandle, &pvTask ) == TRC_SUCCESS ); + + xTraceStackMonitorRemove( pvTask ); + + return xTraceObjectUnregister( ( TraceObjectHandle_t ) xTaskHandle, PSF_EVENT_TASK_DELETE, uxPriority ); + } + + traceResult xTraceTaskSetPriority( TraceTaskHandle_t xTaskHandle, + TraceUnsignedBaseType_t uxPriority ) + { + TraceEventHandle_t xEventHandle = 0; + void * pvTask; + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceObjectSetState( ( TraceObjectHandle_t ) xTaskHandle, uxPriority ) == TRC_SUCCESS ); + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceEntryGetAddress( ( TraceEntryHandle_t ) xTaskHandle, &pvTask ) == TRC_SUCCESS ); + + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_TASK_PRIORITY, sizeof( void * ) + sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pvTask ); + xTraceEventAdd32( xEventHandle, ( uint32_t ) uxPriority ); + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + traceResult xTraceTaskSetPriorityWithoutHandle( void * pvTask, + TraceUnsignedBaseType_t uxPriority ) + { + TraceEventHandle_t xEventHandle = 0; + TraceEntryHandle_t xEntryHandle; + + if( xTraceEntryFind( pvTask, &xEntryHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + /* This should never fail */ + TRC_ASSERT_ALWAYS_EVALUATE( xTraceObjectSetState( ( TraceObjectHandle_t ) xEntryHandle, uxPriority ) == TRC_SUCCESS ); + + /* We need to check this */ + if( xTraceEventBegin( PSF_EVENT_TASK_PRIORITY, sizeof( void * ) + sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pvTask ); + xTraceEventAdd32( xEventHandle, ( uint32_t ) uxPriority ); + xTraceEventEnd( xEventHandle ); + } + + return TRC_SUCCESS; + } + + traceResult xTraceTaskSwitch( void * pvTask, + TraceUnsignedBaseType_t uxPriority ) + { + traceResult xResult = TRC_FAIL; + TraceEventHandle_t xEventHandle = 0; + void * pvCurrent = 0; + + ( void ) pvTask; + ( void ) uxPriority; + + TRACE_ALLOC_CRITICAL_SECTION(); + + if( xTraceIsRecorderEnabled() == 0 ) + { + return xResult; + } + + TRACE_ENTER_CRITICAL_SECTION(); + + xTraceStateSet( TRC_STATE_IN_TASKSWITCH ); + + xTraceTaskGetCurrent( &pvCurrent ); + + if( pvCurrent != pvTask ) + { + xTraceTaskSetCurrent( pvTask ); + + if( xTraceEventBegin( PSF_EVENT_TASK_ACTIVATE, sizeof( void * ) + sizeof( uint32_t ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pvTask ); + xTraceEventAdd32( xEventHandle, ( uint32_t ) uxPriority ); + xTraceEventEnd( xEventHandle ); + xResult = TRC_SUCCESS; + } + } + + xTraceStateSet( TRC_STATE_IN_APPLICATION ); + + TRACE_EXIT_CRITICAL_SECTION(); + + return xResult; + } + + #if ( TRC_CFG_INCLUDE_READY_EVENTS == 1 ) + traceResult xTraceTaskReady( void * pvTask ) + { + traceResult xResult = TRC_FAIL; + TraceEventHandle_t xEventHandle = 0; + + if( xTraceEventBegin( PSF_EVENT_TASK_READY, sizeof( void * ), &xEventHandle ) == TRC_SUCCESS ) + { + xTraceEventAddPointer( xEventHandle, pvTask ); + xTraceEventEnd( xEventHandle ); + xResult = TRC_SUCCESS; + } + + return xResult; + } + #endif /* (TRC_CFG_INCLUDE_READY_EVENTS == 1) */ + + traceResult xTraceTaskInstanceFinishedNow( void ) + { + TraceEventHandle_t xEventHandle = 0; + + if( xTraceEventBegin( PSF_EVENT_IFE_DIRECT, 0, &xEventHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + xTraceEventEnd( xEventHandle ); + + return TRC_SUCCESS; + } + + traceResult xTraceTaskInstanceFinishedNext( void ) + { + TraceEventHandle_t xEventHandle = 0; + + if( xTraceEventBegin( PSF_EVENT_IFE_NEXT, 0, &xEventHandle ) == TRC_FAIL ) + { + return TRC_FAIL; + } + + xTraceEventEnd( xEventHandle ); + + return TRC_SUCCESS; + } + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcTimestamp.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcTimestamp.c index 488729848..8ae9d281c 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcTimestamp.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcTimestamp.c @@ -1,173 +1,180 @@ -/* -* Trace Recorder for Tracealyzer v4.6.0 -* Copyright 2021 Percepio AB -* www.percepio.com -* -* SPDX-License-Identifier: Apache-2.0 -* -* The implementation of timestamps. -*/ - -#include - -#if (TRC_USE_TRACEALYZER_RECORDER == 1) - -#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) - -TraceTimestamp_t *pxTraceTimestamp; - -traceResult xTraceTimestampInitialize(TraceTimestampBuffer_t *pxBuffer) -{ - TRC_ASSERT_EQUAL_SIZE(TraceTimestampBuffer_t, TraceTimestamp_t); - - /* This should never fail */ - TRC_ASSERT(pxBuffer != 0); - - pxTraceTimestamp = (TraceTimestamp_t*)pxBuffer; - pxTraceTimestamp->frequency = 0; - pxTraceTimestamp->period = TRC_HWTC_PERIOD; - pxTraceTimestamp->osTickHz = TRC_TICK_RATE_HZ; - pxTraceTimestamp->osTickCount = 0; - pxTraceTimestamp->wraparounds = 0; - pxTraceTimestamp->type = TRC_HWTC_TYPE; - -#if (TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_INCR) - pxTraceTimestamp->latestTimestamp = 0; -#elif (TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR) - pxTraceTimestamp->latestTimestamp = pxTraceTimestamp->period - 1; -#endif - - xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP); - - return TRC_SUCCESS; -} - -#if ((TRC_CFG_USE_TRACE_ASSERT) == 1) - -traceResult xTraceTimestampGet(uint32_t *puiTimestamp) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP)); - - /* This should never fail */ - TRC_ASSERT(puiTimestamp != 0); - - switch (pxTraceTimestamp->type) - { - case TRC_FREE_RUNNING_32BIT_INCR: - case TRC_CUSTOM_TIMER_INCR: - *puiTimestamp = TRC_HWTC_COUNT; - if (*puiTimestamp < pxTraceTimestamp->latestTimestamp) - { - pxTraceTimestamp->wraparounds++; - } - break; - case TRC_FREE_RUNNING_32BIT_DECR: - case TRC_CUSTOM_TIMER_DECR: - *puiTimestamp = TRC_HWTC_COUNT; - if (*puiTimestamp > pxTraceTimestamp->latestTimestamp) - { - pxTraceTimestamp->wraparounds++; - } - break; - case TRC_OS_TIMER_INCR: - case TRC_OS_TIMER_DECR: - *puiTimestamp = ((TRC_HWTC_COUNT) & 0x00FFFFFFU) + ((pxTraceTimestamp->osTickCount & 0x000000FFU) << 24); - pxTraceTimestamp->wraparounds = pxTraceTimestamp->osTickCount; - break; - default: - return TRC_FAIL; - } - - pxTraceTimestamp->latestTimestamp = *puiTimestamp; - - return TRC_SUCCESS; -} - -traceResult xTraceTimestampGetWraparounds(uint32_t* puiTimerWraparounds) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP)); - - /* This should never fail */ - TRC_ASSERT(puiTimerWraparounds != 0); - - *puiTimerWraparounds = pxTraceTimestamp->wraparounds; - - return TRC_SUCCESS; -} - -traceResult xTraceTimestampSetFrequency(TraceUnsignedBaseType_t uxFrequency) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP)); - - pxTraceTimestamp->frequency = uxFrequency; - - return TRC_SUCCESS; -} - -traceResult xTraceTimestampSetPeriod(uint32_t uiPeriod) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP)); - - pxTraceTimestamp->period = uiPeriod; - - return TRC_SUCCESS; -} - -traceResult xTraceTimestampSetOsTickCount(uint32_t uiOsTickCount) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP)); - - pxTraceTimestamp->osTickCount = uiOsTickCount; - - return TRC_SUCCESS; -} - -traceResult xTraceTimestampGetFrequency(TraceUnsignedBaseType_t *puxFrequency) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP)); - - /* This should never fail */ - TRC_ASSERT(puxFrequency != 0); - - *puxFrequency = pxTraceTimestamp->frequency; - - return TRC_SUCCESS; -} - -traceResult xTraceTimestampGetPeriod(uint32_t *puiPeriod) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP)); - - /* This should never fail */ - TRC_ASSERT(puiPeriod != 0); - - *puiPeriod = pxTraceTimestamp->period; - - return TRC_SUCCESS; -} - -traceResult xTraceTimestampGetOsTickCount(uint32_t* puiOsTickCount) -{ - /* This should never fail */ - TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_TIMESTAMP)); - - /* This should never fail */ - TRC_ASSERT(puiOsTickCount != 0); - - *puiOsTickCount = pxTraceTimestamp->osTickCount; - - return TRC_SUCCESS; -} - -#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ - -#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ - -#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * The implementation of timestamps. + */ + +#include + +#if ( TRC_USE_TRACEALYZER_RECORDER == 1 ) + + #if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) + + TraceTimestamp_t * pxTraceTimestamp; + + traceResult xTraceTimestampInitialize( TraceTimestampBuffer_t * pxBuffer ) + { + TRC_ASSERT_EQUAL_SIZE( TraceTimestampBuffer_t, TraceTimestamp_t ); + + /* This should never fail */ + TRC_ASSERT( pxBuffer != 0 ); + + pxTraceTimestamp = ( TraceTimestamp_t * ) pxBuffer; + pxTraceTimestamp->frequency = 0; + pxTraceTimestamp->period = TRC_HWTC_PERIOD; + pxTraceTimestamp->osTickHz = TRC_TICK_RATE_HZ; + pxTraceTimestamp->osTickCount = 0; + pxTraceTimestamp->wraparounds = 0; + pxTraceTimestamp->type = TRC_HWTC_TYPE; + + #if ( TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_INCR ) + pxTraceTimestamp->latestTimestamp = 0; + #elif ( TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR ) + pxTraceTimestamp->latestTimestamp = pxTraceTimestamp->period - 1; + #endif + + xTraceSetComponentInitialized( TRC_RECORDER_COMPONENT_TIMESTAMP ); + + return TRC_SUCCESS; + } + + #if ( ( TRC_CFG_USE_TRACE_ASSERT ) == 1 ) + + traceResult xTraceTimestampGet( uint32_t * puiTimestamp ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_TIMESTAMP ) ); + + /* This should never fail */ + TRC_ASSERT( puiTimestamp != 0 ); + + switch( pxTraceTimestamp->type ) + { + case TRC_FREE_RUNNING_32BIT_INCR: + case TRC_CUSTOM_TIMER_INCR: + *puiTimestamp = TRC_HWTC_COUNT; + + if( *puiTimestamp < pxTraceTimestamp->latestTimestamp ) + { + pxTraceTimestamp->wraparounds++; + } + + break; + + case TRC_FREE_RUNNING_32BIT_DECR: + case TRC_CUSTOM_TIMER_DECR: + *puiTimestamp = TRC_HWTC_COUNT; + + if( *puiTimestamp > pxTraceTimestamp->latestTimestamp ) + { + pxTraceTimestamp->wraparounds++; + } + + break; + + case TRC_OS_TIMER_INCR: + case TRC_OS_TIMER_DECR: + *puiTimestamp = ( ( TRC_HWTC_COUNT ) & 0x00FFFFFFU ) + ( ( pxTraceTimestamp->osTickCount & 0x000000FFU ) << 24 ); + pxTraceTimestamp->wraparounds = pxTraceTimestamp->osTickCount; + break; + + default: + return TRC_FAIL; + } + + pxTraceTimestamp->latestTimestamp = *puiTimestamp; + + return TRC_SUCCESS; + } + + traceResult xTraceTimestampGetWraparounds( uint32_t * puiTimerWraparounds ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_TIMESTAMP ) ); + + /* This should never fail */ + TRC_ASSERT( puiTimerWraparounds != 0 ); + + *puiTimerWraparounds = pxTraceTimestamp->wraparounds; + + return TRC_SUCCESS; + } + + traceResult xTraceTimestampSetFrequency( TraceUnsignedBaseType_t uxFrequency ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_TIMESTAMP ) ); + + pxTraceTimestamp->frequency = uxFrequency; + + return TRC_SUCCESS; + } + + traceResult xTraceTimestampSetPeriod( uint32_t uiPeriod ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_TIMESTAMP ) ); + + pxTraceTimestamp->period = uiPeriod; + + return TRC_SUCCESS; + } + + traceResult xTraceTimestampSetOsTickCount( uint32_t uiOsTickCount ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_TIMESTAMP ) ); + + pxTraceTimestamp->osTickCount = uiOsTickCount; + + return TRC_SUCCESS; + } + + traceResult xTraceTimestampGetFrequency( TraceUnsignedBaseType_t * puxFrequency ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_TIMESTAMP ) ); + + /* This should never fail */ + TRC_ASSERT( puxFrequency != 0 ); + + *puxFrequency = pxTraceTimestamp->frequency; + + return TRC_SUCCESS; + } + + traceResult xTraceTimestampGetPeriod( uint32_t * puiPeriod ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_TIMESTAMP ) ); + + /* This should never fail */ + TRC_ASSERT( puiPeriod != 0 ); + + *puiPeriod = pxTraceTimestamp->period; + + return TRC_SUCCESS; + } + + traceResult xTraceTimestampGetOsTickCount( uint32_t * puiOsTickCount ) + { + /* This should never fail */ + TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_TIMESTAMP ) ); + + /* This should never fail */ + TRC_ASSERT( puiOsTickCount != 0 ); + + *puiOsTickCount = pxTraceTimestamp->osTickCount; + + return TRC_SUCCESS; + } + + #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ + + #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/blockio.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/blockio.c index 897143de0..7aad60dc9 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/blockio.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/blockio.c @@ -1,198 +1,197 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Implements block device I/O using logical blocks as the units. - - The OS block device implementations operate on sectors. The core does I/O - in terms of logical blocks: this module translates from logical blocks to - sectors. - - If bBlockIoRetries is greater than 0 for the current volume, then this - module will retry block device calls on failure up to the configured number - of times. This behavior caters to the type of unreliable hardware and - drivers that are sometimes found in the IoT world, where one operation may - fail but the next may still succeed. -*/ + * @brief Implements block device I/O using logical blocks as the units. + * + * The OS block device implementations operate on sectors. The core does I/O + * in terms of logical blocks: this module translates from logical blocks to + * sectors. + * + * If bBlockIoRetries is greater than 0 for the current volume, then this + * module will retry block device calls on failure up to the configured number + * of times. This behavior caters to the type of unreliable hardware and + * drivers that are sometimes found in the IoT world, where one operation may + * fail but the next may still succeed. + */ #include #include /** @brief Read a range of logical blocks. - - @param bVolNum The volume whose block device is being read from. - @param ulBlockStart The first block to read. - @param ulBlockCount The number of blocks to read. - @param pBuffer The buffer to populate with the data read. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. -*/ -REDSTATUS RedIoRead( - uint8_t bVolNum, - uint32_t ulBlockStart, - uint32_t ulBlockCount, - void *pBuffer) + * + * @param bVolNum The volume whose block device is being read from. + * @param ulBlockStart The first block to read. + * @param ulBlockCount The number of blocks to read. + * @param pBuffer The buffer to populate with the data read. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + */ +REDSTATUS RedIoRead( uint8_t bVolNum, + uint32_t ulBlockStart, + uint32_t ulBlockCount, + void * pBuffer ) { - REDSTATUS ret = 0; + REDSTATUS ret = 0; - if( (bVolNum >= REDCONF_VOLUME_COUNT) - || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount) - || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount) - || (ulBlockCount == 0U) - || (pBuffer == NULL)) + if( ( bVolNum >= REDCONF_VOLUME_COUNT ) || + ( ulBlockStart >= gaRedVolume[ bVolNum ].ulBlockCount ) || + ( ( gaRedVolume[ bVolNum ].ulBlockCount - ulBlockStart ) < ulBlockCount ) || + ( ulBlockCount == 0U ) || + ( pBuffer == NULL ) ) { REDERROR(); ret = -RED_EINVAL; } else { - uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift; - uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift; + uint8_t bSectorShift = gaRedVolume[ bVolNum ].bBlockSectorShift; + uint64_t ullSectorStart = ( uint64_t ) ulBlockStart << bSectorShift; uint32_t ulSectorCount = ulBlockCount << bSectorShift; - uint8_t bRetryIdx; + uint8_t bRetryIdx; - REDASSERT(bSectorShift < 32U); - REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount); + REDASSERT( bSectorShift < 32U ); + REDASSERT( ( ulSectorCount >> bSectorShift ) == ulBlockCount ); - for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++) + for( bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++ ) { - ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + ret = RedOsBDevRead( bVolNum, ullSectorStart, ulSectorCount, pBuffer ); - if(ret == 0) + if( ret == 0 ) { break; } } } - CRITICAL_ASSERT(ret == 0); + CRITICAL_ASSERT( ret == 0 ); return ret; } #if REDCONF_READ_ONLY == 0 + /** @brief Write a range of logical blocks. - - @param bVolNum The volume whose block device is being written to. - @param ulBlockStart The first block to write. - @param ulBlockCount The number of blocks to write. - @param pBuffer The buffer containing the data to write. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. -*/ -REDSTATUS RedIoWrite( - uint8_t bVolNum, - uint32_t ulBlockStart, - uint32_t ulBlockCount, - const void *pBuffer) -{ - REDSTATUS ret = 0; - - if( (bVolNum >= REDCONF_VOLUME_COUNT) - || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount) - || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount) - || (ulBlockCount == 0U) - || (pBuffer == NULL)) + * + * @param bVolNum The volume whose block device is being written to. + * @param ulBlockStart The first block to write. + * @param ulBlockCount The number of blocks to write. + * @param pBuffer The buffer containing the data to write. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + */ + REDSTATUS RedIoWrite( uint8_t bVolNum, + uint32_t ulBlockStart, + uint32_t ulBlockCount, + const void * pBuffer ) { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift; - uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift; - uint32_t ulSectorCount = ulBlockCount << bSectorShift; - uint8_t bRetryIdx; + REDSTATUS ret = 0; - REDASSERT(bSectorShift < 32U); - REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount); - - for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++) + if( ( bVolNum >= REDCONF_VOLUME_COUNT ) || + ( ulBlockStart >= gaRedVolume[ bVolNum ].ulBlockCount ) || + ( ( gaRedVolume[ bVolNum ].ulBlockCount - ulBlockStart ) < ulBlockCount ) || + ( ulBlockCount == 0U ) || + ( pBuffer == NULL ) ) { - ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint8_t bSectorShift = gaRedVolume[ bVolNum ].bBlockSectorShift; + uint64_t ullSectorStart = ( uint64_t ) ulBlockStart << bSectorShift; + uint32_t ulSectorCount = ulBlockCount << bSectorShift; + uint8_t bRetryIdx; - if(ret == 0) + REDASSERT( bSectorShift < 32U ); + REDASSERT( ( ulSectorCount >> bSectorShift ) == ulBlockCount ); + + for( bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++ ) { - break; + ret = RedOsBDevWrite( bVolNum, ullSectorStart, ulSectorCount, pBuffer ); + + if( ret == 0 ) + { + break; + } } } + + CRITICAL_ASSERT( ret == 0 ); + + return ret; } - CRITICAL_ASSERT(ret == 0); - - return ret; -} - /** @brief Flush any caches beneath the file system. - - @param bVolNum The volume number of the volume whose block device is being - flushed. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedIoFlush( - uint8_t bVolNum) -{ - REDSTATUS ret = 0; - - if(bVolNum >= REDCONF_VOLUME_COUNT) + * + * @param bVolNum The volume number of the volume whose block device is being + * flushed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedIoFlush( uint8_t bVolNum ) { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint8_t bRetryIdx; + REDSTATUS ret = 0; - for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++) + if( bVolNum >= REDCONF_VOLUME_COUNT ) { - ret = RedOsBDevFlush(bVolNum); + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint8_t bRetryIdx; - if(ret == 0) + for( bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++ ) { - break; + ret = RedOsBDevFlush( bVolNum ); + + if( ret == 0 ) + { + break; + } } } + + CRITICAL_ASSERT( ret == 0 ); + + return ret; } - - CRITICAL_ASSERT(ret == 0); - - return ret; -} #endif /* REDCONF_READ_ONLY == 0 */ - diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/buffer.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/buffer.c index 17717e0f4..e26ebd4f7 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/buffer.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/buffer.c @@ -1,169 +1,180 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements the block device buffering system. + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ - This module implements the block buffer cache. It has a number of block - sized buffers which are used to store data from a given block (identified - by both block number and volume number: this cache is shared among all - volumes). Block buffers may be either dirty or clean. Most I/O passes - through this module. When a buffer is needed for a block which is not in - the cache, a "victim" is selected via a simple LRU scheme. -*/ +/** @file + * @brief Implements the block device buffering system. + * + * This module implements the block buffer cache. It has a number of block + * sized buffers which are used to store data from a given block (identified + * by both block number and volume number: this cache is shared among all + * volumes). Block buffers may be either dirty or clean. Most I/O passes + * through this module. When a buffer is needed for a block which is not in + * the cache, a "victim" is selected via a simple LRU scheme. + */ #include #include #if DINDIR_POINTERS > 0U - #define INODE_META_BUFFERS 3U /* Inode, double indirect, indirect */ + #define INODE_META_BUFFERS 3U /* Inode, double indirect, indirect */ #elif REDCONF_INDIRECT_POINTERS > 0U - #define INODE_META_BUFFERS 2U /* Inode, indirect */ + #define INODE_META_BUFFERS 2U /* Inode, indirect */ #elif REDCONF_DIRECT_POINTERS == INODE_ENTRIES - #define INODE_META_BUFFERS 1U /* Inode only */ + #define INODE_META_BUFFERS 1U /* Inode only */ #endif -#define INODE_BUFFERS (INODE_META_BUFFERS + 1U) /* Add data buffer */ +#define INODE_BUFFERS ( INODE_META_BUFFERS + 1U ) /* Add data buffer */ #if REDCONF_IMAP_EXTERNAL == 1 - #define IMAP_BUFFERS 1U + #define IMAP_BUFFERS 1U #else - #define IMAP_BUFFERS 0U + #define IMAP_BUFFERS 0U #endif -#if (REDCONF_READ_ONLY == 1) || (REDCONF_API_FSE == 1) - /* Read, write, truncate, lookup: One inode all the way down, plus imap. - */ - #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + IMAP_BUFFERS) +#if ( REDCONF_READ_ONLY == 1 ) || ( REDCONF_API_FSE == 1 ) + +/* Read, write, truncate, lookup: One inode all the way down, plus imap. + */ + #define MINIMUM_BUFFER_COUNT ( INODE_BUFFERS + IMAP_BUFFERS ) #elif REDCONF_API_POSIX == 1 - #if REDCONF_API_POSIX_RENAME == 1 - #if REDCONF_RENAME_ATOMIC == 1 - /* Two parent directories all the way down. Source and destination inode - buffer. One inode buffer for cyclic rename detection. Imap. The - parent inode buffers are released before deleting the destination - inode, so that does not increase the minimum. - */ - #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + INODE_BUFFERS + 3U + IMAP_BUFFERS) - #else - /* Two parent directories all the way down. Source inode buffer. One - inode buffer for cyclic rename detection. Imap. - */ - #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + INODE_BUFFERS + 2U + IMAP_BUFFERS) - #endif - #else - /* Link/create: Needs a parent inode all the way down, an extra inode - buffer, and an imap buffer. + #if REDCONF_API_POSIX_RENAME == 1 + #if REDCONF_RENAME_ATOMIC == 1 - Unlink is the same, since the parent inode buffers are released before - the inode is deleted. - */ - #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + 1U + IMAP_BUFFERS) - #endif -#endif +/* Two parent directories all the way down. Source and destination inode + * buffer. One inode buffer for cyclic rename detection. Imap. The + * parent inode buffers are released before deleting the destination + * inode, so that does not increase the minimum. + */ + #define MINIMUM_BUFFER_COUNT ( INODE_BUFFERS + INODE_BUFFERS + 3U + IMAP_BUFFERS ) + #else + +/* Two parent directories all the way down. Source inode buffer. One + * inode buffer for cyclic rename detection. Imap. + */ + #define MINIMUM_BUFFER_COUNT ( INODE_BUFFERS + INODE_BUFFERS + 2U + IMAP_BUFFERS ) + #endif + #else + +/* Link/create: Needs a parent inode all the way down, an extra inode + * buffer, and an imap buffer. + * + * Unlink is the same, since the parent inode buffers are released before + * the inode is deleted. + */ + #define MINIMUM_BUFFER_COUNT ( INODE_BUFFERS + 1U + IMAP_BUFFERS ) + #endif /* if REDCONF_API_POSIX_RENAME == 1 */ +#endif /* if ( REDCONF_READ_ONLY == 1 ) || ( REDCONF_API_FSE == 1 ) */ #if REDCONF_BUFFER_COUNT < MINIMUM_BUFFER_COUNT -#error "REDCONF_BUFFER_COUNT is too low for the configuration" + #error "REDCONF_BUFFER_COUNT is too low for the configuration" #endif /* A note on the typecasts in the below macros: Operands to bitwise operators - are subject to the "usual arithmetic conversions". This means that the - flags, which have uint16_t values, are promoted to int. MISRA-C:2012 R10.1 - forbids using signed integers in bitwise operations, so we cast to uint32_t - to avoid the integer promotion, then back to uint16_t to reflect the actual - type. -*/ -#define BFLAG_META_MASK (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_META_IMAP | BFLAG_META_INODE | BFLAG_META_INDIR | BFLAG_META_DINDIR) -#define BFLAG_MASK (uint16_t)((uint32_t)BFLAG_DIRTY | BFLAG_NEW | BFLAG_META_MASK) + * are subject to the "usual arithmetic conversions". This means that the + * flags, which have uint16_t values, are promoted to int. MISRA-C:2012 R10.1 + * forbids using signed integers in bitwise operations, so we cast to uint32_t + * to avoid the integer promotion, then back to uint16_t to reflect the actual + * type. + */ +#define BFLAG_META_MASK ( uint16_t ) ( ( uint32_t ) BFLAG_META_MASTER | BFLAG_META_IMAP | BFLAG_META_INODE | BFLAG_META_INDIR | BFLAG_META_DINDIR ) +#define BFLAG_MASK ( uint16_t ) ( ( uint32_t ) BFLAG_DIRTY | BFLAG_NEW | BFLAG_META_MASK ) /* An invalid block number. Used to indicate buffers which are not currently - in use. -*/ -#define BBLK_INVALID UINT32_MAX + * in use. + */ +#define BBLK_INVALID UINT32_MAX /** @brief Metadata stored for each block buffer. - - To make better use of CPU caching when searching the BUFFERHEAD array, this - structure should be kept small. -*/ + * + * To make better use of CPU caching when searching the BUFFERHEAD array, this + * structure should be kept small. + */ typedef struct { - uint32_t ulBlock; /**< Block number the buffer is associated with; BBLK_INVALID if unused. */ - uint8_t bVolNum; /**< Volume the block resides on. */ - uint8_t bRefCount; /**< Number of references. */ - uint16_t uFlags; /**< Buffer flags: mask of BFLAG_* values. */ + uint32_t ulBlock; /**< Block number the buffer is associated with; BBLK_INVALID if unused. */ + uint8_t bVolNum; /**< Volume the block resides on. */ + uint8_t bRefCount; /**< Number of references. */ + uint16_t uFlags; /**< Buffer flags: mask of BFLAG_* values. */ } BUFFERHEAD; /** @brief State information for the block buffer module. -*/ + */ typedef struct { /** Number of buffers which are referenced (have a bRefCount > 0). - */ - uint16_t uNumUsed; + */ + uint16_t uNumUsed; /** MRU array. Each element of the array stores a buffer index; each buffer - index appears in the array once and only once. The first element of the - array is the most-recently-used (MRU) buffer, followed by the next most - recently used, and so on, till the last element, which is the least- - recently-used (LRU) buffer. - */ - uint8_t abMRU[REDCONF_BUFFER_COUNT]; + * index appears in the array once and only once. The first element of the + * array is the most-recently-used (MRU) buffer, followed by the next most + * recently used, and so on, till the last element, which is the least- + * recently-used (LRU) buffer. + */ + uint8_t abMRU[ REDCONF_BUFFER_COUNT ]; /** Buffer heads, storing metadata for each buffer. - */ - BUFFERHEAD aHead[REDCONF_BUFFER_COUNT]; + */ + BUFFERHEAD aHead[ REDCONF_BUFFER_COUNT ]; /** Array of memory for the block buffers themselves. - - Force 64-bit alignment of the aabBuffer array to ensure that it is safe - to cast buffer pointers to node structure pointers. - */ - ALIGNED_2D_BYTE_ARRAY(b, aabBuffer, REDCONF_BUFFER_COUNT, REDCONF_BLOCK_SIZE); + * + * Force 64-bit alignment of the aabBuffer array to ensure that it is safe + * to cast buffer pointers to node structure pointers. + */ + ALIGNED_2D_BYTE_ARRAY( b, aabBuffer, REDCONF_BUFFER_COUNT, REDCONF_BLOCK_SIZE ); } BUFFERCTX; -static bool BufferIsValid(const uint8_t *pbBuffer, uint16_t uFlags); -static bool BufferToIdx(const void *pBuffer, uint8_t *pbIdx); +static bool BufferIsValid( const uint8_t * pbBuffer, + uint16_t uFlags ); +static bool BufferToIdx( const void * pBuffer, + uint8_t * pbIdx ); #if REDCONF_READ_ONLY == 0 -static REDSTATUS BufferWrite(uint8_t bIdx); -static REDSTATUS BufferFinalize(uint8_t *pbBuffer, uint16_t uFlags); + static REDSTATUS BufferWrite( uint8_t bIdx ); + static REDSTATUS BufferFinalize( uint8_t * pbBuffer, + uint16_t uFlags ); #endif -static void BufferMakeLRU(uint8_t bIdx); -static void BufferMakeMRU(uint8_t bIdx); -static bool BufferFind(uint32_t ulBlock, uint8_t *pbIdx); +static void BufferMakeLRU( uint8_t bIdx ); +static void BufferMakeMRU( uint8_t bIdx ); +static bool BufferFind( uint32_t ulBlock, + uint8_t * pbIdx ); #ifdef REDCONF_ENDIAN_SWAP -static void BufferEndianSwap(const void *pBuffer, uint16_t uFlags); -static void BufferEndianSwapHeader(NODEHEADER *pHeader); -static void BufferEndianSwapMaster(MASTERBLOCK *pMaster); -static void BufferEndianSwapMetaRoot(METAROOT *pMetaRoot); -static void BufferEndianSwapInode(INODE *pInode); -static void BufferEndianSwapIndir(INDIR *pIndir); + static void BufferEndianSwap( const void * pBuffer, + uint16_t uFlags ); + static void BufferEndianSwapHeader( NODEHEADER * pHeader ); + static void BufferEndianSwapMaster( MASTERBLOCK * pMaster ); + static void BufferEndianSwapMetaRoot( METAROOT * pMetaRoot ); + static void BufferEndianSwapInode( INODE * pInode ); + static void BufferEndianSwapIndir( INDIR * pIndir ); #endif @@ -171,165 +182,164 @@ static BUFFERCTX gBufCtx; /** @brief Initialize the buffers. -*/ -void RedBufferInit(void) + */ +void RedBufferInit( void ) { uint8_t bIdx; - RedMemSet(&gBufCtx, 0U, sizeof(gBufCtx)); + RedMemSet( &gBufCtx, 0U, sizeof( gBufCtx ) ); - for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + for( bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++ ) { /* When the buffers have been freshly initialized, acquire the buffers - in the order in which they appear in the array. - */ - gBufCtx.abMRU[bIdx] = (uint8_t)((REDCONF_BUFFER_COUNT - bIdx) - 1U); - gBufCtx.aHead[bIdx].ulBlock = BBLK_INVALID; + * in the order in which they appear in the array. + */ + gBufCtx.abMRU[ bIdx ] = ( uint8_t ) ( ( REDCONF_BUFFER_COUNT - bIdx ) - 1U ); + gBufCtx.aHead[ bIdx ].ulBlock = BBLK_INVALID; } } /** @brief Acquire a buffer. - - @param ulBlock Block number to acquire. - @param uFlags BFLAG_ values for the operation. - @param ppBuffer On success, populated with the acquired buffer. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. - @retval -RED_EBUSY All buffers are referenced. -*/ -REDSTATUS RedBufferGet( - uint32_t ulBlock, - uint16_t uFlags, - void **ppBuffer) + * + * @param ulBlock Block number to acquire. + * @param uFlags BFLAG_ values for the operation. + * @param ppBuffer On success, populated with the acquired buffer. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + * @retval -RED_EBUSY All buffers are referenced. + */ +REDSTATUS RedBufferGet( uint32_t ulBlock, + uint16_t uFlags, + void ** ppBuffer ) { - REDSTATUS ret = 0; - uint8_t bIdx; + REDSTATUS ret = 0; + uint8_t bIdx; - if((ulBlock >= gpRedVolume->ulBlockCount) || ((uFlags & BFLAG_MASK) != uFlags) || (ppBuffer == NULL)) + if( ( ulBlock >= gpRedVolume->ulBlockCount ) || ( ( uFlags & BFLAG_MASK ) != uFlags ) || ( ppBuffer == NULL ) ) { REDERROR(); ret = -RED_EINVAL; } else { - if(BufferFind(ulBlock, &bIdx)) + if( BufferFind( ulBlock, &bIdx ) ) { /* Error if the buffer exists and BFLAG_NEW was specified, since - the new flag is used when a block is newly allocated/created, so - the block was previously free and and there should never be an - existing buffer for a free block. - - Error if the buffer exists but does not have the same type as - was requested. - */ - if( ((uFlags & BFLAG_NEW) != 0U) - || ((uFlags & BFLAG_META_MASK) != (gBufCtx.aHead[bIdx].uFlags & BFLAG_META_MASK))) + * the new flag is used when a block is newly allocated/created, so + * the block was previously free and and there should never be an + * existing buffer for a free block. + * + * Error if the buffer exists but does not have the same type as + * was requested. + */ + if( ( ( uFlags & BFLAG_NEW ) != 0U ) || + ( ( uFlags & BFLAG_META_MASK ) != ( gBufCtx.aHead[ bIdx ].uFlags & BFLAG_META_MASK ) ) ) { CRITICAL_ERROR(); ret = -RED_EFUBAR; } } - else if(gBufCtx.uNumUsed == REDCONF_BUFFER_COUNT) + else if( gBufCtx.uNumUsed == REDCONF_BUFFER_COUNT ) { /* The MINIMUM_BUFFER_COUNT is supposed to ensure that no operation - ever runs out of buffers, so this should never happen. - */ + * ever runs out of buffers, so this should never happen. + */ CRITICAL_ERROR(); ret = -RED_EBUSY; } else { - BUFFERHEAD *pHead; + BUFFERHEAD * pHead; /* Search for the least recently used buffer which is not - referenced. - */ - for(bIdx = (uint8_t)(REDCONF_BUFFER_COUNT - 1U); bIdx > 0U; bIdx--) + * referenced. + */ + for( bIdx = ( uint8_t ) ( REDCONF_BUFFER_COUNT - 1U ); bIdx > 0U; bIdx-- ) { - if(gBufCtx.aHead[gBufCtx.abMRU[bIdx]].bRefCount == 0U) + if( gBufCtx.aHead[ gBufCtx.abMRU[ bIdx ] ].bRefCount == 0U ) { break; } } - bIdx = gBufCtx.abMRU[bIdx]; - pHead = &gBufCtx.aHead[bIdx]; + bIdx = gBufCtx.abMRU[ bIdx ]; + pHead = &gBufCtx.aHead[ bIdx ]; - if(pHead->bRefCount == 0U) + if( pHead->bRefCount == 0U ) { /* If the LRU buffer is valid and dirty, write it out before - repurposing it. - */ - if(((pHead->uFlags & BFLAG_DIRTY) != 0U) && (pHead->ulBlock != BBLK_INVALID)) + * repurposing it. + */ + if( ( ( pHead->uFlags & BFLAG_DIRTY ) != 0U ) && ( pHead->ulBlock != BBLK_INVALID ) ) { - #if REDCONF_READ_ONLY == 1 - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - #else - ret = BufferWrite(bIdx); - #endif + #if REDCONF_READ_ONLY == 1 + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + #else + ret = BufferWrite( bIdx ); + #endif } } else { /* All the buffers are used, which should have been caught by - checking gBufCtx.uNumUsed. - */ + * checking gBufCtx.uNumUsed. + */ CRITICAL_ERROR(); ret = -RED_EBUSY; } - if(ret == 0) + if( ret == 0 ) { - if((uFlags & BFLAG_NEW) == 0U) + if( ( uFlags & BFLAG_NEW ) == 0U ) { /* Invalidate the LRU buffer. If the read fails, we do not - want the buffer head to continue to refer to the old - block number, since the read, even if it fails, may have - partially overwritten the buffer data (consider the case - where block size exceeds sector size, and some but not - all of the sectors are read successfully), and if the - buffer were to be used subsequently with its partially - erroneous contents, bad things could happen. - */ + * want the buffer head to continue to refer to the old + * block number, since the read, even if it fails, may have + * partially overwritten the buffer data (consider the case + * where block size exceeds sector size, and some but not + * all of the sectors are read successfully), and if the + * buffer were to be used subsequently with its partially + * erroneous contents, bad things could happen. + */ pHead->ulBlock = BBLK_INVALID; - ret = RedIoRead(gbRedVolNum, ulBlock, 1U, gBufCtx.b.aabBuffer[bIdx]); + ret = RedIoRead( gbRedVolNum, ulBlock, 1U, gBufCtx.b.aabBuffer[ bIdx ] ); - if((ret == 0) && ((uFlags & BFLAG_META) != 0U)) + if( ( ret == 0 ) && ( ( uFlags & BFLAG_META ) != 0U ) ) { - if(!BufferIsValid(gBufCtx.b.aabBuffer[bIdx], uFlags)) + if( !BufferIsValid( gBufCtx.b.aabBuffer[ bIdx ], uFlags ) ) { /* A corrupt metadata node is usually a critical - error. The master block is an exception since - it might be invalid because the volume is not - mounted; that condition is expected and should - not result in an assertion. - */ - CRITICAL_ASSERT((uFlags & BFLAG_META_MASTER) == BFLAG_META_MASTER); + * error. The master block is an exception since + * it might be invalid because the volume is not + * mounted; that condition is expected and should + * not result in an assertion. + */ + CRITICAL_ASSERT( ( uFlags & BFLAG_META_MASTER ) == BFLAG_META_MASTER ); ret = -RED_EIO; } } - #ifdef REDCONF_ENDIAN_SWAP - if(ret == 0) - { - BufferEndianSwap(gBufCtx.b.aabBuffer[bIdx], uFlags); - } - #endif + #ifdef REDCONF_ENDIAN_SWAP + if( ret == 0 ) + { + BufferEndianSwap( gBufCtx.b.aabBuffer[ bIdx ], uFlags ); + } + #endif } else { - RedMemSet(gBufCtx.b.aabBuffer[bIdx], 0U, REDCONF_BLOCK_SIZE); + RedMemSet( gBufCtx.b.aabBuffer[ bIdx ], 0U, REDCONF_BLOCK_SIZE ); } } - if(ret == 0) + if( ret == 0 ) { pHead->bVolNum = gbRedVolNum; pHead->ulBlock = ulBlock; @@ -338,30 +348,30 @@ REDSTATUS RedBufferGet( } /* Reference the buffer, update its flags, and promote it to MRU. This - happens both when BufferFind() found an existing buffer for the - block and when the LRU buffer was repurposed to create a buffer for - the block. - */ - if(ret == 0) + * happens both when BufferFind() found an existing buffer for the + * block and when the LRU buffer was repurposed to create a buffer for + * the block. + */ + if( ret == 0 ) { - BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + BUFFERHEAD * pHead = &gBufCtx.aHead[ bIdx ]; pHead->bRefCount++; - if(pHead->bRefCount == 1U) + if( pHead->bRefCount == 1U ) { gBufCtx.uNumUsed++; } /* BFLAG_NEW tells this function to zero the buffer instead of - reading it from disk; it has no meaning later on, and thus is - not saved. - */ - pHead->uFlags |= (uFlags & (~BFLAG_NEW)); + * reading it from disk; it has no meaning later on, and thus is + * not saved. + */ + pHead->uFlags |= ( uFlags & ( ~BFLAG_NEW ) ); - BufferMakeMRU(bIdx); + BufferMakeMRU( bIdx ); - *ppBuffer = gBufCtx.b.aabBuffer[bIdx]; + *ppBuffer = gBufCtx.b.aabBuffer[ bIdx ]; } } @@ -370,26 +380,25 @@ REDSTATUS RedBufferGet( /** @brief Release a buffer. - - @param pBuffer The buffer to release. + * + * @param pBuffer The buffer to release. */ -void RedBufferPut( - const void *pBuffer) +void RedBufferPut( const void * pBuffer ) { - uint8_t bIdx; + uint8_t bIdx; - if(!BufferToIdx(pBuffer, &bIdx)) + if( !BufferToIdx( pBuffer, &bIdx ) ) { REDERROR(); } else { - REDASSERT(gBufCtx.aHead[bIdx].bRefCount > 0U); - gBufCtx.aHead[bIdx].bRefCount--; + REDASSERT( gBufCtx.aHead[ bIdx ].bRefCount > 0U ); + gBufCtx.aHead[ bIdx ].bRefCount--; - if(gBufCtx.aHead[bIdx].bRefCount == 0U) + if( gBufCtx.aHead[ bIdx ].bRefCount == 0U ) { - REDASSERT(gBufCtx.uNumUsed > 0U); + REDASSERT( gBufCtx.uNumUsed > 0U ); gBufCtx.uNumUsed--; } } @@ -397,166 +406,163 @@ void RedBufferPut( #if REDCONF_READ_ONLY == 0 + /** @brief Flush all buffers for the active volume in the given range of blocks. - - @param ulBlockStart Starting block number to flush. - @param ulBlockCount Count of blocks, starting at @p ulBlockStart, to flush. - Must not be zero. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. -*/ -REDSTATUS RedBufferFlush( - uint32_t ulBlockStart, - uint32_t ulBlockCount) -{ - REDSTATUS ret = 0; - - if( (ulBlockStart >= gpRedVolume->ulBlockCount) - || ((gpRedVolume->ulBlockCount - ulBlockStart) < ulBlockCount) - || (ulBlockCount == 0U)) + * + * @param ulBlockStart Starting block number to flush. + * @param ulBlockCount Count of blocks, starting at @p ulBlockStart, to flush. + * Must not be zero. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + */ + REDSTATUS RedBufferFlush( uint32_t ulBlockStart, + uint32_t ulBlockCount ) { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint8_t bIdx; + REDSTATUS ret = 0; - for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + if( ( ulBlockStart >= gpRedVolume->ulBlockCount ) || + ( ( gpRedVolume->ulBlockCount - ulBlockStart ) < ulBlockCount ) || + ( ulBlockCount == 0U ) ) { - BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint8_t bIdx; - if( (pHead->bVolNum == gbRedVolNum) - && (pHead->ulBlock != BBLK_INVALID) - && ((pHead->uFlags & BFLAG_DIRTY) != 0U) - && (pHead->ulBlock >= ulBlockStart) - && (pHead->ulBlock < (ulBlockStart + ulBlockCount))) + for( bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++ ) { - ret = BufferWrite(bIdx); + BUFFERHEAD * pHead = &gBufCtx.aHead[ bIdx ]; - if(ret == 0) + if( ( pHead->bVolNum == gbRedVolNum ) && + ( pHead->ulBlock != BBLK_INVALID ) && + ( ( pHead->uFlags & BFLAG_DIRTY ) != 0U ) && + ( pHead->ulBlock >= ulBlockStart ) && + ( pHead->ulBlock < ( ulBlockStart + ulBlockCount ) ) ) { - pHead->uFlags &= (~BFLAG_DIRTY); - } - else - { - break; + ret = BufferWrite( bIdx ); + + if( ret == 0 ) + { + pHead->uFlags &= ( ~BFLAG_DIRTY ); + } + else + { + break; + } } } } - } - return ret; -} + return ret; + } /** @brief Mark a buffer dirty - - @param pBuffer The buffer to mark dirty. -*/ -void RedBufferDirty( - const void *pBuffer) -{ - uint8_t bIdx; - - if(!BufferToIdx(pBuffer, &bIdx)) + * + * @param pBuffer The buffer to mark dirty. + */ + void RedBufferDirty( const void * pBuffer ) { - REDERROR(); - } - else - { - REDASSERT(gBufCtx.aHead[bIdx].bRefCount > 0U); + uint8_t bIdx; - gBufCtx.aHead[bIdx].uFlags |= BFLAG_DIRTY; + if( !BufferToIdx( pBuffer, &bIdx ) ) + { + REDERROR(); + } + else + { + REDASSERT( gBufCtx.aHead[ bIdx ].bRefCount > 0U ); + + gBufCtx.aHead[ bIdx ].uFlags |= BFLAG_DIRTY; + } } -} /** @brief Branch a buffer, marking it dirty and assigning a new block number. - - @param pBuffer The buffer to branch. - @param ulBlockNew The new block number for the buffer. -*/ -void RedBufferBranch( - const void *pBuffer, - uint32_t ulBlockNew) -{ - uint8_t bIdx; - - if( !BufferToIdx(pBuffer, &bIdx) - || (ulBlockNew >= gpRedVolume->ulBlockCount)) + * + * @param pBuffer The buffer to branch. + * @param ulBlockNew The new block number for the buffer. + */ + void RedBufferBranch( const void * pBuffer, + uint32_t ulBlockNew ) { - REDERROR(); + uint8_t bIdx; + + if( !BufferToIdx( pBuffer, &bIdx ) || + ( ulBlockNew >= gpRedVolume->ulBlockCount ) ) + { + REDERROR(); + } + else + { + BUFFERHEAD * pHead = &gBufCtx.aHead[ bIdx ]; + + REDASSERT( pHead->bRefCount > 0U ); + REDASSERT( ( pHead->uFlags & BFLAG_DIRTY ) == 0U ); + + pHead->uFlags |= BFLAG_DIRTY; + pHead->ulBlock = ulBlockNew; + } } - else - { - BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; - - REDASSERT(pHead->bRefCount > 0U); - REDASSERT((pHead->uFlags & BFLAG_DIRTY) == 0U); - - pHead->uFlags |= BFLAG_DIRTY; - pHead->ulBlock = ulBlockNew; - } -} -#if (REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED + #if ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED + /** @brief Discard a buffer, releasing it and marking it invalid. + * + * @param pBuffer The buffer to discard. + */ + void RedBufferDiscard( const void * pBuffer ) + { + uint8_t bIdx; - @param pBuffer The buffer to discard. -*/ -void RedBufferDiscard( - const void *pBuffer) -{ - uint8_t bIdx; + if( !BufferToIdx( pBuffer, &bIdx ) ) + { + REDERROR(); + } + else + { + REDASSERT( gBufCtx.aHead[ bIdx ].bRefCount == 1U ); + REDASSERT( gBufCtx.uNumUsed > 0U ); - if(!BufferToIdx(pBuffer, &bIdx)) - { - REDERROR(); - } - else - { - REDASSERT(gBufCtx.aHead[bIdx].bRefCount == 1U); - REDASSERT(gBufCtx.uNumUsed > 0U); + gBufCtx.aHead[ bIdx ].bRefCount = 0U; + gBufCtx.aHead[ bIdx ].ulBlock = BBLK_INVALID; - gBufCtx.aHead[bIdx].bRefCount = 0U; - gBufCtx.aHead[bIdx].ulBlock = BBLK_INVALID; + gBufCtx.uNumUsed--; - gBufCtx.uNumUsed--; - - BufferMakeLRU(bIdx); - } -} -#endif + BufferMakeLRU( bIdx ); + } + } + #endif /* if ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED */ #endif /* REDCONF_READ_ONLY == 0 */ /** @brief Discard a range of buffers, marking them invalid. - - @param ulBlockStart The starting block number to discard - @param ulBlockCount The number of blocks, starting at @p ulBlockStart, to - discard. Must not be zero. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL Invalid parameters. - @retval -RED_EBUSY A block in the desired range is referenced. -*/ -REDSTATUS RedBufferDiscardRange( - uint32_t ulBlockStart, - uint32_t ulBlockCount) + * + * @param ulBlockStart The starting block number to discard + * @param ulBlockCount The number of blocks, starting at @p ulBlockStart, to + * discard. Must not be zero. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL Invalid parameters. + * @retval -RED_EBUSY A block in the desired range is referenced. + */ +REDSTATUS RedBufferDiscardRange( uint32_t ulBlockStart, + uint32_t ulBlockCount ) { - REDSTATUS ret = 0; + REDSTATUS ret = 0; - if( (ulBlockStart >= gpRedVolume->ulBlockCount) - || ((gpRedVolume->ulBlockCount - ulBlockStart) < ulBlockCount) - || (ulBlockCount == 0U)) + if( ( ulBlockStart >= gpRedVolume->ulBlockCount ) || + ( ( gpRedVolume->ulBlockCount - ulBlockStart ) < ulBlockCount ) || + ( ulBlockCount == 0U ) ) { REDERROR(); ret = -RED_EINVAL; @@ -565,37 +571,37 @@ REDSTATUS RedBufferDiscardRange( { uint8_t bIdx; - for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + for( bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++ ) { - BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + BUFFERHEAD * pHead = &gBufCtx.aHead[ bIdx ]; - if( (pHead->bVolNum == gbRedVolNum) - && (pHead->ulBlock != BBLK_INVALID) - && (pHead->ulBlock >= ulBlockStart) - && (pHead->ulBlock < (ulBlockStart + ulBlockCount))) + if( ( pHead->bVolNum == gbRedVolNum ) && + ( pHead->ulBlock != BBLK_INVALID ) && + ( pHead->ulBlock >= ulBlockStart ) && + ( pHead->ulBlock < ( ulBlockStart + ulBlockCount ) ) ) { - if(pHead->bRefCount == 0U) + if( pHead->bRefCount == 0U ) { pHead->ulBlock = BBLK_INVALID; - BufferMakeLRU(bIdx); + BufferMakeLRU( bIdx ); } else { /* This should never happen. There are three general cases - when this function is used: - - 1) Discarding every block, as happens during unmount - and at the end of format. There should no longer be - any referenced buffers at those points. - 2) Discarding a block which has become free. All - buffers for such blocks should be put or branched - beforehand. - 3) Discarding of blocks that were just written straight - to disk, leaving stale data in the buffer. The write - code should never reference buffers for these blocks, - since they would not be needed or used. - */ + * when this function is used: + * + * 1) Discarding every block, as happens during unmount + * and at the end of format. There should no longer be + * any referenced buffers at those points. + * 2) Discarding a block which has become free. All + * buffers for such blocks should be put or branched + * beforehand. + * 3) Discarding of blocks that were just written straight + * to disk, leaving stale data in the buffer. The write + * code should never reference buffers for these blocks, + * since they would not be needed or used. + */ CRITICAL_ERROR(); ret = -RED_EBUSY; break; @@ -609,104 +615,106 @@ REDSTATUS RedBufferDiscardRange( /** Determine whether a metadata buffer is valid. - - This includes checking its signature, CRC, and sequence number. - - @param pbBuffer Pointer to the metadata buffer to validate. - @param uFlags The buffer flags provided by the caller. Used to determine - the expected signature. - - @return Whether the metadata buffer is valid. - - @retval true The metadata buffer is valid. - @retval false The metadata buffer is invalid. -*/ -static bool BufferIsValid( - const uint8_t *pbBuffer, - uint16_t uFlags) + * + * This includes checking its signature, CRC, and sequence number. + * + * @param pbBuffer Pointer to the metadata buffer to validate. + * @param uFlags The buffer flags provided by the caller. Used to determine + * the expected signature. + * + * @return Whether the metadata buffer is valid. + * + * @retval true The metadata buffer is valid. + * @retval false The metadata buffer is invalid. + */ +static bool BufferIsValid( const uint8_t * pbBuffer, + uint16_t uFlags ) { - bool fValid; + bool fValid; - if((pbBuffer == NULL) || ((uFlags & BFLAG_MASK) != uFlags)) + if( ( pbBuffer == NULL ) || ( ( uFlags & BFLAG_MASK ) != uFlags ) ) { REDERROR(); fValid = false; } else { - NODEHEADER buf; - uint16_t uMetaFlags = uFlags & BFLAG_META_MASK; + NODEHEADER buf; + uint16_t uMetaFlags = uFlags & BFLAG_META_MASK; /* Casting pbBuffer to (NODEHEADER *) would run afoul MISRA-C:2012 - R11.3, so instead copy the fields out. - */ - RedMemCpy(&buf.ulSignature, &pbBuffer[NODEHEADER_OFFSET_SIG], sizeof(buf.ulSignature)); - RedMemCpy(&buf.ulCRC, &pbBuffer[NODEHEADER_OFFSET_CRC], sizeof(buf.ulCRC)); - RedMemCpy(&buf.ullSequence, &pbBuffer[NODEHEADER_OFFSET_SEQ], sizeof(buf.ullSequence)); + * R11.3, so instead copy the fields out. + */ + RedMemCpy( &buf.ulSignature, &pbBuffer[ NODEHEADER_OFFSET_SIG ], sizeof( buf.ulSignature ) ); + RedMemCpy( &buf.ulCRC, &pbBuffer[ NODEHEADER_OFFSET_CRC ], sizeof( buf.ulCRC ) ); + RedMemCpy( &buf.ullSequence, &pbBuffer[ NODEHEADER_OFFSET_SEQ ], sizeof( buf.ullSequence ) ); - #ifdef REDCONF_ENDIAN_SWAP - buf.ulCRC = RedRev32(buf.ulCRC); - buf.ulSignature = RedRev32(buf.ulSignature); - buf.ullSequence = RedRev64(buf.ullSequence); - #endif + #ifdef REDCONF_ENDIAN_SWAP + buf.ulCRC = RedRev32( buf.ulCRC ); + buf.ulSignature = RedRev32( buf.ulSignature ); + buf.ullSequence = RedRev64( buf.ullSequence ); + #endif /* Make sure the signature is correct for the type of metadata block - requested by the caller. - */ - switch(buf.ulSignature) + * requested by the caller. + */ + switch( buf.ulSignature ) { case META_SIG_MASTER: - fValid = (uMetaFlags == BFLAG_META_MASTER); + fValid = ( uMetaFlags == BFLAG_META_MASTER ); break; - #if REDCONF_IMAP_EXTERNAL == 1 - case META_SIG_IMAP: - fValid = (uMetaFlags == BFLAG_META_IMAP); - break; - #endif + + #if REDCONF_IMAP_EXTERNAL == 1 + case META_SIG_IMAP: + fValid = ( uMetaFlags == BFLAG_META_IMAP ); + break; + #endif case META_SIG_INODE: - fValid = (uMetaFlags == BFLAG_META_INODE); + fValid = ( uMetaFlags == BFLAG_META_INODE ); break; - #if DINDIR_POINTERS > 0U - case META_SIG_DINDIR: - fValid = (uMetaFlags == BFLAG_META_DINDIR); - break; - #endif - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - case META_SIG_INDIR: - fValid = (uMetaFlags == BFLAG_META_INDIR); - break; - #endif + + #if DINDIR_POINTERS > 0U + case META_SIG_DINDIR: + fValid = ( uMetaFlags == BFLAG_META_DINDIR ); + break; + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + case META_SIG_INDIR: + fValid = ( uMetaFlags == BFLAG_META_INDIR ); + break; + #endif default: fValid = false; break; } - if(fValid) + if( fValid ) { uint32_t ulComputedCrc; /* Check for disk corruption by comparing the stored CRC with one - computed from the data. + * computed from the data. + * + * Also check the sequence number: if it is greater than the + * current sequence number, the block is from a previous format + * or the disk is writing blocks out of order. During mount, + * before the metaroots have been read, the sequence number will + * be unknown, and the check is skipped. + */ + ulComputedCrc = RedCrcNode( pbBuffer ); - Also check the sequence number: if it is greater than the - current sequence number, the block is from a previous format - or the disk is writing blocks out of order. During mount, - before the metaroots have been read, the sequence number will - be unknown, and the check is skipped. - */ - ulComputedCrc = RedCrcNode(pbBuffer); - if(buf.ulCRC != ulComputedCrc) + if( buf.ulCRC != ulComputedCrc ) { fValid = false; } - else if(gpRedVolume->fMounted && (buf.ullSequence >= gpRedVolume->ullSequence)) + else if( gpRedVolume->fMounted && ( buf.ullSequence >= gpRedVolume->ullSequence ) ) { fValid = false; } else { /* Buffer is valid. No action, fValid is already true. - */ + */ } } } @@ -716,44 +724,43 @@ static bool BufferIsValid( /** @brief Derive the index of the buffer. - - @param pBuffer The buffer to derive the index of. - @param pbIdx On success, populated with the index of the buffer. - - @return Boolean indicating result. - - @retval true Success. - @retval false Failure. @p pBuffer is not a valid buffer pointer. -*/ -static bool BufferToIdx( - const void *pBuffer, - uint8_t *pbIdx) + * + * @param pBuffer The buffer to derive the index of. + * @param pbIdx On success, populated with the index of the buffer. + * + * @return Boolean indicating result. + * + * @retval true Success. + * @retval false Failure. @p pBuffer is not a valid buffer pointer. + */ +static bool BufferToIdx( const void * pBuffer, + uint8_t * pbIdx ) { - bool fRet = false; + bool fRet = false; - if((pBuffer != NULL) && (pbIdx != NULL)) + if( ( pBuffer != NULL ) && ( pbIdx != NULL ) ) { uint8_t bIdx; /* pBuffer should be a pointer to one of the block buffers. - - A good compiler should optimize this loop into a bounds check and an - alignment check, although GCC has been observed to not do so; if the - number of buffers is small, it should not make much difference. The - alternative is to use pointer comparisons, but this both deviates - from MISRA-C:2012 and involves undefined behavior. - */ - for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + * + * A good compiler should optimize this loop into a bounds check and an + * alignment check, although GCC has been observed to not do so; if the + * number of buffers is small, it should not make much difference. The + * alternative is to use pointer comparisons, but this both deviates + * from MISRA-C:2012 and involves undefined behavior. + */ + for( bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++ ) { - if(pBuffer == &gBufCtx.b.aabBuffer[bIdx][0U]) + if( pBuffer == &gBufCtx.b.aabBuffer[ bIdx ][ 0U ] ) { break; } } - if( (bIdx < REDCONF_BUFFER_COUNT) - && (gBufCtx.aHead[bIdx].ulBlock != BBLK_INVALID) - && (gBufCtx.aHead[bIdx].bVolNum == gbRedVolNum)) + if( ( bIdx < REDCONF_BUFFER_COUNT ) && + ( gBufCtx.aHead[ bIdx ].ulBlock != BBLK_INVALID ) && + ( gBufCtx.aHead[ bIdx ].bVolNum == gbRedVolNum ) ) { *pbIdx = bIdx; fRet = true; @@ -765,347 +772,347 @@ static bool BufferToIdx( #if REDCONF_READ_ONLY == 0 + /** @brief Write out a dirty buffer. - - @param bIdx The index of the buffer to write. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS BufferWrite( - uint8_t bIdx) -{ - REDSTATUS ret = 0; - - if(bIdx < REDCONF_BUFFER_COUNT) + * + * @param bIdx The index of the buffer to write. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS BufferWrite( uint8_t bIdx ) { - const BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + REDSTATUS ret = 0; - REDASSERT((pHead->uFlags & BFLAG_DIRTY) != 0U); - - if((pHead->uFlags & BFLAG_META) != 0U) + if( bIdx < REDCONF_BUFFER_COUNT ) { - ret = BufferFinalize(gBufCtx.b.aabBuffer[bIdx], pHead->uFlags); + const BUFFERHEAD * pHead = &gBufCtx.aHead[ bIdx ]; + + REDASSERT( ( pHead->uFlags & BFLAG_DIRTY ) != 0U ); + + if( ( pHead->uFlags & BFLAG_META ) != 0U ) + { + ret = BufferFinalize( gBufCtx.b.aabBuffer[ bIdx ], pHead->uFlags ); + } + + if( ret == 0 ) + { + ret = RedIoWrite( pHead->bVolNum, pHead->ulBlock, 1U, gBufCtx.b.aabBuffer[ bIdx ] ); + + #ifdef REDCONF_ENDIAN_SWAP + BufferEndianSwap( gBufCtx.b.aabBuffer[ bIdx ], pHead->uFlags ); + #endif + } + } + else + { + REDERROR(); + ret = -RED_EINVAL; } - if(ret == 0) - { - ret = RedIoWrite(pHead->bVolNum, pHead->ulBlock, 1U, gBufCtx.b.aabBuffer[bIdx]); - - #ifdef REDCONF_ENDIAN_SWAP - BufferEndianSwap(gBufCtx.b.aabBuffer[bIdx], pHead->uFlags); - #endif - } + return ret; } - else - { - REDERROR(); - ret = -RED_EINVAL; - } - - return ret; -} /** @brief Finalize a metadata buffer. - - This updates the CRC and the sequence number. It also sets the signature, - though this is only truly needed if the buffer is new. - - @param pbBuffer Pointer to the metadata buffer to finalize. - @param uFlags The associated buffer flags. Used to determine the expected - signature. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL Invalid parameter; or maximum sequence number reached. -*/ -static REDSTATUS BufferFinalize( - uint8_t *pbBuffer, - uint16_t uFlags) -{ - REDSTATUS ret = 0; - - if((pbBuffer == NULL) || ((uFlags & BFLAG_MASK) != uFlags)) + * + * This updates the CRC and the sequence number. It also sets the signature, + * though this is only truly needed if the buffer is new. + * + * @param pbBuffer Pointer to the metadata buffer to finalize. + * @param uFlags The associated buffer flags. Used to determine the expected + * signature. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL Invalid parameter; or maximum sequence number reached. + */ + static REDSTATUS BufferFinalize( uint8_t * pbBuffer, + uint16_t uFlags ) { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint32_t ulSignature; + REDSTATUS ret = 0; - switch(uFlags & BFLAG_META_MASK) - { - case BFLAG_META_MASTER: - ulSignature = META_SIG_MASTER; - break; - #if REDCONF_IMAP_EXTERNAL == 1 - case BFLAG_META_IMAP: - ulSignature = META_SIG_IMAP; - break; - #endif - case BFLAG_META_INODE: - ulSignature = META_SIG_INODE; - break; - #if DINDIR_POINTERS > 0U - case BFLAG_META_DINDIR: - ulSignature = META_SIG_DINDIR; - break; - #endif - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - case BFLAG_META_INDIR: - ulSignature = META_SIG_INDIR; - break; - #endif - default: - ulSignature = 0U; - break; - } - - if(ulSignature == 0U) + if( ( pbBuffer == NULL ) || ( ( uFlags & BFLAG_MASK ) != uFlags ) ) { REDERROR(); ret = -RED_EINVAL; } else { - uint64_t ullSeqNum = gpRedVolume->ullSequence; + uint32_t ulSignature; - ret = RedVolSeqNumIncrement(); - if(ret == 0) + switch( uFlags & BFLAG_META_MASK ) { - uint32_t ulCrc; + case BFLAG_META_MASTER: + ulSignature = META_SIG_MASTER; + break; - RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_SIG], &ulSignature, sizeof(ulSignature)); - RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_SEQ], &ullSeqNum, sizeof(ullSeqNum)); + #if REDCONF_IMAP_EXTERNAL == 1 + case BFLAG_META_IMAP: + ulSignature = META_SIG_IMAP; + break; + #endif + case BFLAG_META_INODE: + ulSignature = META_SIG_INODE; + break; - #ifdef REDCONF_ENDIAN_SWAP - BufferEndianSwap(pbBuffer, uFlags); - #endif + #if DINDIR_POINTERS > 0U + case BFLAG_META_DINDIR: + ulSignature = META_SIG_DINDIR; + break; + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + case BFLAG_META_INDIR: + ulSignature = META_SIG_INDIR; + break; + #endif + default: + ulSignature = 0U; + break; + } - ulCrc = RedCrcNode(pbBuffer); - #ifdef REDCONF_ENDIAN_SWAP - ulCrc = RedRev32(ulCrc); - #endif - RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_CRC], &ulCrc, sizeof(ulCrc)); + if( ulSignature == 0U ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint64_t ullSeqNum = gpRedVolume->ullSequence; + + ret = RedVolSeqNumIncrement(); + + if( ret == 0 ) + { + uint32_t ulCrc; + + RedMemCpy( &pbBuffer[ NODEHEADER_OFFSET_SIG ], &ulSignature, sizeof( ulSignature ) ); + RedMemCpy( &pbBuffer[ NODEHEADER_OFFSET_SEQ ], &ullSeqNum, sizeof( ullSeqNum ) ); + + #ifdef REDCONF_ENDIAN_SWAP + BufferEndianSwap( pbBuffer, uFlags ); + #endif + + ulCrc = RedCrcNode( pbBuffer ); + #ifdef REDCONF_ENDIAN_SWAP + ulCrc = RedRev32( ulCrc ); + #endif + RedMemCpy( &pbBuffer[ NODEHEADER_OFFSET_CRC ], &ulCrc, sizeof( ulCrc ) ); + } } } - } - return ret; -} + return ret; + } #endif /* REDCONF_READ_ONLY == 0 */ #ifdef REDCONF_ENDIAN_SWAP + /** @brief Swap the byte order of a metadata buffer - - Does nothing if the buffer is not a metadata node. Also does nothing for - meta roots, which don't go through the buffers anyways. - - @param pBuffer Pointer to the metadata buffer to swap - @param uFlags The associated buffer flags. Used to determin the type of - metadata node. -*/ -static void BufferEndianSwap( - void *pBuffer, - uint16_t uFlags) -{ - if((pBuffer == NULL) || ((uFlags & BFLAG_MASK) != uFlags)) + * + * Does nothing if the buffer is not a metadata node. Also does nothing for + * meta roots, which don't go through the buffers anyways. + * + * @param pBuffer Pointer to the metadata buffer to swap + * @param uFlags The associated buffer flags. Used to determin the type of + * metadata node. + */ + static void BufferEndianSwap( void * pBuffer, + uint16_t uFlags ) { - REDERROR(); - } - else if((uFlags & BFLAG_META_MASK) != 0) - { - BufferEndianSwapHeader(pBuffer); - - switch(uFlags & BFLAG_META_MASK) + if( ( pBuffer == NULL ) || ( ( uFlags & BFLAG_MASK ) != uFlags ) ) { - case BFLAG_META_MASTER: - BufferEndianSwapMaster(pBuffer); - break; - case BFLAG_META_INODE: - BufferEndianSwapInode(pBuffer); - break; - #if DINDIR_POINTERS > 0U - case BFLAG_META_DINDIR: - BufferEndianSwapIndir(pBuffer); - break; - #endif - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - case BFLAG_META_INDIR: - BufferEndianSwapIndir(pBuffer); - break; - #endif - default: - break; + REDERROR(); + } + else if( ( uFlags & BFLAG_META_MASK ) != 0 ) + { + BufferEndianSwapHeader( pBuffer ); + + switch( uFlags & BFLAG_META_MASK ) + { + case BFLAG_META_MASTER: + BufferEndianSwapMaster( pBuffer ); + break; + + case BFLAG_META_INODE: + BufferEndianSwapInode( pBuffer ); + break; + + #if DINDIR_POINTERS > 0U + case BFLAG_META_DINDIR: + BufferEndianSwapIndir( pBuffer ); + break; + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + case BFLAG_META_INDIR: + BufferEndianSwapIndir( pBuffer ); + break; + #endif + default: + break; + } + } + else + { + /* File data buffers do not need to be swapped. + */ } } - else - { - /* File data buffers do not need to be swapped. - */ - } -} /** @brief Swap the byte order of a metadata node header - - @param pHeader Pointer to the metadata node header to swap -*/ -static void BufferEndianSwapHeader( - NODEHEADER *pHeader) -{ - if(pHeader == NULL) + * + * @param pHeader Pointer to the metadata node header to swap + */ + static void BufferEndianSwapHeader( NODEHEADER * pHeader ) { - REDERROR(); + if( pHeader == NULL ) + { + REDERROR(); + } + else + { + pHeader->ulSignature = RedRev32( pHeader->ulSignature ); + pHeader->ulCRC = RedRev32( pHeader->ulCRC ); + pHeader->ullSequence = RedRev64( pHeader->ullSequence ); + } } - else - { - pHeader->ulSignature = RedRev32(pHeader->ulSignature); - pHeader->ulCRC = RedRev32(pHeader->ulCRC); - pHeader->ullSequence = RedRev64(pHeader->ullSequence); - } -} /** @brief Swap the byte order of a master block - - @param pMaster Pointer to the master block to swap -*/ -static void BufferEndianSwapMaster( - MASTERBLOCK *pMaster) -{ - if(pMaster == NULL) + * + * @param pMaster Pointer to the master block to swap + */ + static void BufferEndianSwapMaster( MASTERBLOCK * pMaster ) { - REDERROR(); + if( pMaster == NULL ) + { + REDERROR(); + } + else + { + pMaster->ulVersion = RedRev32( pMaster->ulVersion ); + pMaster->ulFormatTime = RedRev32( pMaster->ulFormatTime ); + pMaster->ulInodeCount = RedRev32( pMaster->ulInodeCount ); + pMaster->ulBlockCount = RedRev32( pMaster->ulBlockCount ); + pMaster->uMaxNameLen = RedRev16( pMaster->uMaxNameLen ); + pMaster->uDirectPointers = RedRev16( pMaster->uDirectPointers ); + pMaster->uIndirectPointers = RedRev16( pMaster->uIndirectPointers ); + } } - else - { - pMaster->ulVersion = RedRev32(pMaster->ulVersion); - pMaster->ulFormatTime = RedRev32(pMaster->ulFormatTime); - pMaster->ulInodeCount = RedRev32(pMaster->ulInodeCount); - pMaster->ulBlockCount = RedRev32(pMaster->ulBlockCount); - pMaster->uMaxNameLen = RedRev16(pMaster->uMaxNameLen); - pMaster->uDirectPointers = RedRev16(pMaster->uDirectPointers); - pMaster->uIndirectPointers = RedRev16(pMaster->uIndirectPointers); - } -} /** @brief Swap the byte order of an inode - - @param pInode Pointer to the inode to swap -*/ -static void BufferEndianSwapInode( - INODE *pInode) -{ - if(pInode == NULL) + * + * @param pInode Pointer to the inode to swap + */ + static void BufferEndianSwapInode( INODE * pInode ) { - REDERROR(); - } - else - { - uint32_t ulIdx; - - pInode->ullSize = RedRev64(pInode->ullSize); - - #if REDCONF_INODE_BLOCKS == 1 - pInode->ulBlocks = RedRev32(pInode->ulBlocks); - #endif - - #if REDCONF_INODE_TIMESTAMPS == 1 - pInode->ulATime = RedRev32(pInode->ulATime); - pInode->ulMTime = RedRev32(pInode->ulMTime); - pInode->ulCTime = RedRev32(pInode->ulCTime); - #endif - - pInode->uMode = RedRev16(pInode->uMode); - - #if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) - pInode->uNLink = RedRev16(pInode->uNLink); - #endif - - #if REDCONF_API_POSIX == 1 - pInode->ulPInode = RedRev32(pInode->ulPInode); - #endif - - for(ulIdx = 0; ulIdx < INODE_ENTRIES; ulIdx++) + if( pInode == NULL ) { - pInode->aulEntries[ulIdx] = RedRev32(pInode->aulEntries[ulIdx]); + REDERROR(); + } + else + { + uint32_t ulIdx; + + pInode->ullSize = RedRev64( pInode->ullSize ); + + #if REDCONF_INODE_BLOCKS == 1 + pInode->ulBlocks = RedRev32( pInode->ulBlocks ); + #endif + + #if REDCONF_INODE_TIMESTAMPS == 1 + pInode->ulATime = RedRev32( pInode->ulATime ); + pInode->ulMTime = RedRev32( pInode->ulMTime ); + pInode->ulCTime = RedRev32( pInode->ulCTime ); + #endif + + pInode->uMode = RedRev16( pInode->uMode ); + + #if ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_LINK == 1 ) + pInode->uNLink = RedRev16( pInode->uNLink ); + #endif + + #if REDCONF_API_POSIX == 1 + pInode->ulPInode = RedRev32( pInode->ulPInode ); + #endif + + for( ulIdx = 0; ulIdx < INODE_ENTRIES; ulIdx++ ) + { + pInode->aulEntries[ ulIdx ] = RedRev32( pInode->aulEntries[ ulIdx ] ); + } } } -} -#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + /** @brief Swap the byte order of an indirect or double indirect node - - @param pIndir Pointer to the node to swap -*/ -static void BufferEndianSwapIndir( - INDIR *pIndir) -{ - if(pIndir == NULL) - { - REDERROR(); - } - else - { - uint32_t ulIdx; - - pIndir->ulInode = RedRev32(pIndir->ulInode); - - for(ulIdx = 0; ulIdx < INDIR_ENTRIES; ulIdx++) + * + * @param pIndir Pointer to the node to swap + */ + static void BufferEndianSwapIndir( INDIR * pIndir ) { - pIndir->aulEntries[ulIdx] = RedRev32(pIndir->aulEntries[ulIdx]); - } - } -} + if( pIndir == NULL ) + { + REDERROR(); + } + else + { + uint32_t ulIdx; -#endif /* REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ + pIndir->ulInode = RedRev32( pIndir->ulInode ); + + for( ulIdx = 0; ulIdx < INDIR_ENTRIES; ulIdx++ ) + { + pIndir->aulEntries[ ulIdx ] = RedRev32( pIndir->aulEntries[ ulIdx ] ); + } + } + } + + #endif /* REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ #endif /* #ifdef REDCONF_ENDIAN_SWAP */ /** @brief Mark a buffer as least recently used. - - @param bIdx The index of the buffer to make LRU. -*/ -static void BufferMakeLRU( - uint8_t bIdx) + * + * @param bIdx The index of the buffer to make LRU. + */ +static void BufferMakeLRU( uint8_t bIdx ) { - if(bIdx >= REDCONF_BUFFER_COUNT) + if( bIdx >= REDCONF_BUFFER_COUNT ) { REDERROR(); } - else if(bIdx != gBufCtx.abMRU[REDCONF_BUFFER_COUNT - 1U]) + else if( bIdx != gBufCtx.abMRU[ REDCONF_BUFFER_COUNT - 1U ] ) { uint8_t bMruIdx; /* Find the current position of the buffer in the MRU array. We do not - need to check the last slot, since we already know from the above - check that the index is not there. - */ - for(bMruIdx = 0U; bMruIdx < (REDCONF_BUFFER_COUNT - 1U); bMruIdx++) + * need to check the last slot, since we already know from the above + * check that the index is not there. + */ + for( bMruIdx = 0U; bMruIdx < ( REDCONF_BUFFER_COUNT - 1U ); bMruIdx++ ) { - if(bIdx == gBufCtx.abMRU[bMruIdx]) + if( bIdx == gBufCtx.abMRU[ bMruIdx ] ) { break; } } - if(bMruIdx < (REDCONF_BUFFER_COUNT - 1U)) + if( bMruIdx < ( REDCONF_BUFFER_COUNT - 1U ) ) { /* Move the buffer index to the back of the MRU array, making it - the LRU buffer. - */ - RedMemMove(&gBufCtx.abMRU[bMruIdx], &gBufCtx.abMRU[bMruIdx + 1U], REDCONF_BUFFER_COUNT - ((uint32_t)bMruIdx + 1U)); - gBufCtx.abMRU[REDCONF_BUFFER_COUNT - 1U] = bIdx; + * the LRU buffer. + */ + RedMemMove( &gBufCtx.abMRU[ bMruIdx ], &gBufCtx.abMRU[ bMruIdx + 1U ], REDCONF_BUFFER_COUNT - ( ( uint32_t ) bMruIdx + 1U ) ); + gBufCtx.abMRU[ REDCONF_BUFFER_COUNT - 1U ] = bIdx; } else { @@ -1115,45 +1122,44 @@ static void BufferMakeLRU( else { /* Buffer already LRU, nothing to do. - */ + */ } } /** @brief Mark a buffer as most recently used. - - @param bIdx The index of the buffer to make MRU. -*/ -static void BufferMakeMRU( - uint8_t bIdx) + * + * @param bIdx The index of the buffer to make MRU. + */ +static void BufferMakeMRU( uint8_t bIdx ) { - if(bIdx >= REDCONF_BUFFER_COUNT) + if( bIdx >= REDCONF_BUFFER_COUNT ) { REDERROR(); } - else if(bIdx != gBufCtx.abMRU[0U]) + else if( bIdx != gBufCtx.abMRU[ 0U ] ) { uint8_t bMruIdx; /* Find the current position of the buffer in the MRU array. We do not - need to check the first slot, since we already know from the above - check that the index is not there. - */ - for(bMruIdx = 1U; bMruIdx < REDCONF_BUFFER_COUNT; bMruIdx++) + * need to check the first slot, since we already know from the above + * check that the index is not there. + */ + for( bMruIdx = 1U; bMruIdx < REDCONF_BUFFER_COUNT; bMruIdx++ ) { - if(bIdx == gBufCtx.abMRU[bMruIdx]) + if( bIdx == gBufCtx.abMRU[ bMruIdx ] ) { break; } } - if(bMruIdx < REDCONF_BUFFER_COUNT) + if( bMruIdx < REDCONF_BUFFER_COUNT ) { /* Move the buffer index to the front of the MRU array, making it - the MRU buffer. - */ - RedMemMove(&gBufCtx.abMRU[1U], &gBufCtx.abMRU[0U], bMruIdx); - gBufCtx.abMRU[0U] = bIdx; + * the MRU buffer. + */ + RedMemMove( &gBufCtx.abMRU[ 1U ], &gBufCtx.abMRU[ 0U ], bMruIdx ); + gBufCtx.abMRU[ 0U ] = bIdx; } else { @@ -1163,30 +1169,29 @@ static void BufferMakeMRU( else { /* Buffer already MRU, nothing to do. - */ + */ } } /** @brief Find a block in the buffers. - - @param ulBlock The block number to find. - @param pbIdx If the block is buffered (true is returned), populated with - the index of the buffer. - - @return Boolean indicating whether or not the block is buffered. - - @retval true @p ulBlock is buffered, and its index has been stored in - @p pbIdx. - @retval false @p ulBlock is not buffered. -*/ -static bool BufferFind( - uint32_t ulBlock, - uint8_t *pbIdx) + * + * @param ulBlock The block number to find. + * @param pbIdx If the block is buffered (true is returned), populated with + * the index of the buffer. + * + * @return Boolean indicating whether or not the block is buffered. + * + * @retval true @p ulBlock is buffered, and its index has been stored in + * @p pbIdx. + * @retval false @p ulBlock is not buffered. + */ +static bool BufferFind( uint32_t ulBlock, + uint8_t * pbIdx ) { - bool ret = false; + bool ret = false; - if((ulBlock >= gpRedVolume->ulBlockCount) || (pbIdx == NULL)) + if( ( ulBlock >= gpRedVolume->ulBlockCount ) || ( pbIdx == NULL ) ) { REDERROR(); } @@ -1194,11 +1199,11 @@ static bool BufferFind( { uint8_t bIdx; - for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + for( bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++ ) { - const BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + const BUFFERHEAD * pHead = &gBufCtx.aHead[ bIdx ]; - if((pHead->bVolNum == gbRedVolNum) && (pHead->ulBlock == ulBlock)) + if( ( pHead->bVolNum == gbRedVolNum ) && ( pHead->ulBlock == ulBlock ) ) { *pbIdx = bIdx; ret = true; @@ -1209,4 +1214,3 @@ static bool BufferFind( return ret; } - diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/core.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/core.c index 06c3a23eb..480757a2f 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/core.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/core.c @@ -1,1921 +1,1938 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements the entry-points to the core file system. -*/ -#include -#include -#include - - -/* Minimum number of blocks needed for metadata on any volume: the master - block (1), the two metaroots (2), and one doubly-allocated inode (2), - resulting in 1 + 2 + 2 = 5. -*/ -#define MINIMUM_METADATA_BLOCKS (5U) - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) -static REDSTATUS CoreCreate(uint32_t ulPInode, const char *pszName, bool fDir, uint32_t *pulInode); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) -static REDSTATUS CoreLink(uint32_t ulPInode, const char *pszName, uint32_t ulInode); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) -static REDSTATUS CoreUnlink(uint32_t ulPInode, const char *pszName); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) -static REDSTATUS CoreRename(uint32_t ulSrcPInode, const char *pszSrcName, uint32_t ulDstPInode, const char *pszDstName); -#endif -#if REDCONF_READ_ONLY == 0 -static REDSTATUS CoreFileWrite(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer); -#endif -#if TRUNCATE_SUPPORTED -static REDSTATUS CoreFileTruncate(uint32_t ulInode, uint64_t ullSize); -#endif - - -VOLUME gaRedVolume[REDCONF_VOLUME_COUNT]; -static COREVOLUME gaCoreVol[REDCONF_VOLUME_COUNT]; - -const VOLCONF * CONST_IF_ONE_VOLUME gpRedVolConf = &gaRedVolConf[0U]; -VOLUME * CONST_IF_ONE_VOLUME gpRedVolume = &gaRedVolume[0U]; -COREVOLUME * CONST_IF_ONE_VOLUME gpRedCoreVol = &gaCoreVol[0U]; -METAROOT *gpRedMR = &gaCoreVol[0U].aMR[0U]; - -CONST_IF_ONE_VOLUME uint8_t gbRedVolNum = 0; - - -/** @brief Initialize the Reliance Edge file system driver. - - Prepares the Reliance Edge file system driver to be used. Must be the first - Reliance Edge function to be invoked: no volumes can be mounted until the - driver has been initialized. - - If this function is called when the Reliance Edge driver is already - initialized, the behavior is undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -REDSTATUS RedCoreInit(void) -{ - REDSTATUS ret = 0; - uint8_t bVolNum; - #if REDCONF_OUTPUT == 1 - static uint8_t bSignedOn = 0U; /* Whether the sign on has been printed. */ - - if(bSignedOn == 0U) - { - RedSignOn(); - bSignedOn = 1U; - } - #else - /* Call RedSignOn() even when output is disabled, to force the copyright - text to be referenced and pulled into the program data. - */ - RedSignOn(); - #endif - - RedMemSet(gaRedVolume, 0U, sizeof(gaRedVolume)); - RedMemSet(gaCoreVol, 0U, sizeof(gaCoreVol)); - - RedBufferInit(); - - for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++) - { - VOLUME *pVol = &gaRedVolume[bVolNum]; - COREVOLUME *pCoreVol = &gaCoreVol[bVolNum]; - const VOLCONF *pVolConf = &gaRedVolConf[bVolNum]; - - if( (pVolConf->ulSectorSize < SECTOR_SIZE_MIN) - || ((REDCONF_BLOCK_SIZE % pVolConf->ulSectorSize) != 0U) - || (pVolConf->ulInodeCount == 0U)) - { - ret = -RED_EINVAL; - } - #if REDCONF_API_POSIX == 1 - else if(pVolConf->pszPathPrefix == NULL) - { - ret = -RED_EINVAL; - } - else - { - #if REDCONF_VOLUME_COUNT > 1U - uint8_t bCmpVol; - - /* Ensure there are no duplicate path prefixes. Check against all - previous volumes, which are already verified. - */ - for(bCmpVol = 0U; bCmpVol < bVolNum; bCmpVol++) - { - const char *pszCmpPathPrefix = gaRedVolConf[bCmpVol].pszPathPrefix; - - if(RedStrCmp(pVolConf->pszPathPrefix, pszCmpPathPrefix) == 0) - { - ret = -RED_EINVAL; - break; - } - } - #endif - } - #endif - - if(ret == 0) - { - pVol->bBlockSectorShift = 0U; - while((pVolConf->ulSectorSize << pVol->bBlockSectorShift) < REDCONF_BLOCK_SIZE) - { - pVol->bBlockSectorShift++; - } - - /* This should always be true since the block size is confirmed to - be a power of two (checked at compile time) and above we ensured - that (REDCONF_BLOCK_SIZE % pVolConf->ulSectorSize) == 0. - */ - REDASSERT((pVolConf->ulSectorSize << pVol->bBlockSectorShift) == REDCONF_BLOCK_SIZE); - - pVol->ulBlockCount = (uint32_t)(pVolConf->ullSectorCount >> pVol->bBlockSectorShift); - - if(pVol->ulBlockCount < MINIMUM_METADATA_BLOCKS) - { - ret = -RED_EINVAL; - } - else - { - #if REDCONF_READ_ONLY == 0 - pVol->ulTransMask = REDCONF_TRANSACT_DEFAULT; - #endif - - pVol->ullMaxInodeSize = INODE_SIZE_MAX; - - /* To understand the following code, note that the fixed- - location metadata is located at the start of the disk, in - the following order: - - - Master block (1 block) - - Metaroots (2 blocks) - - External imap blocks (variable * 2 blocks) - - Inode blocks (pVolConf->ulInodeCount * 2 blocks) - */ - - /* The imap needs bits for all inode and allocable blocks. If - that bitmap will fit into the metaroot, the inline imap is - used and there are no imap nodes on disk. The minus 3 is - there since the imap does not include bits for the master - block or metaroots. - */ - pCoreVol->fImapInline = (pVol->ulBlockCount - 3U) <= METAROOT_ENTRIES; - - if(pCoreVol->fImapInline) - { - #if REDCONF_IMAP_INLINE == 1 - pCoreVol->ulInodeTableStartBN = 3U; - #else - ret = -RED_EINVAL; - #endif - } - else - { - #if REDCONF_IMAP_EXTERNAL == 1 - pCoreVol->ulImapStartBN = 3U; - - /* The imap does not include bits for itself, so add two to - the number of imap entries for the two blocks of each - imap node. This allows us to divide up the remaining - space, making sure to round up so all data blocks are - covered. - */ - pCoreVol->ulImapNodeCount = - ((pVol->ulBlockCount - 3U) + ((IMAPNODE_ENTRIES + 2U) - 1U)) / (IMAPNODE_ENTRIES + 2U); - - pCoreVol->ulInodeTableStartBN = pCoreVol->ulImapStartBN + (pCoreVol->ulImapNodeCount * 2U); - #else - ret = -RED_EINVAL; - #endif - } - } - } - - if(ret == 0) - { - pCoreVol->ulFirstAllocableBN = pCoreVol->ulInodeTableStartBN + (pVolConf->ulInodeCount * 2U); - - if(pCoreVol->ulFirstAllocableBN > pVol->ulBlockCount) - { - /* We can get here if there is not enough space for the number - of configured inodes. - */ - ret = -RED_EINVAL; - } - else - { - pVol->ulBlocksAllocable = pVol->ulBlockCount - pCoreVol->ulFirstAllocableBN; - } - } - - if(ret != 0) - { - break; - } - } - - /* Make sure the configured endianness is correct. - */ - if(ret == 0) - { - uint16_t uValue = 0xFF00U; - uint8_t abBytes[2U]; - - RedMemCpy(abBytes, &uValue, sizeof(abBytes)); - - #if REDCONF_ENDIAN_BIG == 1 - if(abBytes[0U] != 0xFFU) - #else - if(abBytes[0U] != 0x00U) - #endif - { - ret = -RED_EINVAL; - } - } - - if(ret == 0) - { - ret = RedOsClockInit(); - - #if REDCONF_TASK_COUNT > 1U - if(ret == 0) - { - ret = RedOsMutexInit(); - - if(ret != 0) - { - (void)RedOsClockUninit(); - } - } - #endif - } - - return ret; -} - - -/** @brief Uninitialize the Reliance Edge file system driver. - - Tears down the Reliance Edge file system driver. Cannot be used until all - Reliance Edge volumes are unmounted. A subsequent call to RedCoreInit() - will initialize the driver again. - - The behavior of calling this function when the core is already uninitialized - is undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBUSY At least one volume is still mounted. -*/ -REDSTATUS RedCoreUninit(void) -{ - REDSTATUS ret; - - #if REDCONF_TASK_COUNT > 1U - ret = RedOsMutexUninit(); - - if(ret == 0) - #endif - { - ret = RedOsClockUninit(); - } - - return ret; -} - - -/** @brief Set the current volume. - - All core APIs operate on the current volume. This call must precede all - core accesses. - - @param bVolNum The volume number to access. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number. -*/ -REDSTATUS RedCoreVolSetCurrent( - uint8_t bVolNum) -{ - REDSTATUS ret; - - if(bVolNum >= REDCONF_VOLUME_COUNT) - { - ret = -RED_EINVAL; - } - else - { - #if REDCONF_VOLUME_COUNT > 1U - gbRedVolNum = bVolNum; - gpRedVolConf = &gaRedVolConf[bVolNum]; - gpRedVolume = &gaRedVolume[bVolNum]; - gpRedCoreVol = &gaCoreVol[bVolNum]; - gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR]; - #endif - - ret = 0; - } - - return ret; -} - - -#if FORMAT_SUPPORTED -/** @brief Format a file system volume. - - Uses the statically defined volume configuration. After calling this - function, the volume needs to be mounted -- see RedCoreVolMount(). - - An error is returned if the volume is mounted. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBUSY Volume is mounted. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedCoreVolFormat(void) -{ - return RedVolFormat(); -} -#endif /* FORMAT_SUPPORTED */ - - -/** @brief Mount a file system volume. - - Prepares the file system volume to be accessed. Mount will fail if the - volume has never been formatted, or if the on-disk format is inconsistent - with the compile-time configuration. - - If the volume is already mounted, the behavior is undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt. -*/ -REDSTATUS RedCoreVolMount(void) -{ - return RedVolMount(); -} - - -/** @brief Unmount a file system volume. - - This function discards the in-memory state for the file system and marks it - as unmounted. Subsequent attempts to access the volume will fail until the - volume is mounted again. - - If unmount automatic transaction points are enabled, this function will - commit a transaction point prior to unmounting. If unmount automatic - transaction points are disabled, this function will unmount without - transacting, effectively discarding the working state. - - If the volume is already unmounted, the behavior is undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO I/O error during unmount automatic transaction point. -*/ -REDSTATUS RedCoreVolUnmount(void) -{ - REDSTATUS ret = 0; - - #if REDCONF_READ_ONLY == 0 - if(!gpRedVolume->fReadOnly && ((gpRedVolume->ulTransMask & RED_TRANSACT_UMOUNT) != 0U)) - { - ret = RedVolTransact(); - } - #endif - - if(ret == 0) - { - ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount); - } - - if(ret == 0) - { - ret = RedOsBDevClose(gbRedVolNum); - } - - if(ret == 0) - { - gpRedVolume->fMounted = false; - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Commit a transaction point. - - Reliance Edge is a transactional file system. All modifications, of both - metadata and filedata, are initially working state. A transaction point - is a process whereby the working state atomically becomes the committed - state, replacing the previous committed state. Whenever Reliance Edge is - mounted, including after power loss, the state of the file system after - mount is the most recent committed state. Nothing from the committed - state is ever missing, and nothing from the working state is ever included. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL The volume is not mounted. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EROFS The file system volume is read-only. -*/ -REDSTATUS RedCoreVolTransact(void) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted) - { - ret = -RED_EINVAL; - } - else if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - ret = RedVolTransact(); - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ - - -#if REDCONF_API_POSIX == 1 -/** @brief Query file system status information. - - @param pStatFS The buffer to populate with volume information. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval -RED_EINVAL Volume is not mounted; or @p pStatFS is `NULL`. -*/ -REDSTATUS RedCoreVolStat( - REDSTATFS *pStatFS) -{ - REDSTATUS ret; - - if((pStatFS == NULL) || (!gpRedVolume->fMounted)) - { - ret = -RED_EINVAL; - } - else - { - RedMemSet(pStatFS, 0U, sizeof(*pStatFS)); - - pStatFS->f_bsize = REDCONF_BLOCK_SIZE; - pStatFS->f_frsize = REDCONF_BLOCK_SIZE; - pStatFS->f_blocks = gpRedVolume->ulBlockCount; - #if RESERVED_BLOCKS > 0U - pStatFS->f_bfree = (gpRedMR->ulFreeBlocks > RESERVED_BLOCKS) ? (gpRedMR->ulFreeBlocks - RESERVED_BLOCKS) : 0U; - #else - pStatFS->f_bfree = gpRedMR->ulFreeBlocks; - #endif - pStatFS->f_bavail = pStatFS->f_bfree; - pStatFS->f_files = gpRedVolConf->ulInodeCount; - pStatFS->f_ffree = gpRedMR->ulFreeInodes; - pStatFS->f_favail = gpRedMR->ulFreeInodes; - - pStatFS->f_flag = RED_ST_NOSUID; - #if REDCONF_READ_ONLY == 0 - if(gpRedVolume->fReadOnly) - #endif - { - pStatFS->f_flag |= RED_ST_RDONLY; - } - - pStatFS->f_namemax = REDCONF_NAME_MAX; - pStatFS->f_maxfsize = INODE_SIZE_MAX; - pStatFS->f_dev = gbRedVolNum; - - ret = 0; - } - - return ret; -} -#endif /* REDCONF_API_POSIX == 1 */ - - -#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKSET == 1)) -/** @brief Update the transaction mask. - - The following events are available when using the FSE API: - - - #RED_TRANSACT_UMOUNT - - #RED_TRANSACT_WRITE - - #RED_TRANSACT_TRUNCATE - - #RED_TRANSACT_VOLFULL - - The following events are available when using the POSIX-like API: - - - #RED_TRANSACT_UMOUNT - - #RED_TRANSACT_CREAT - - #RED_TRANSACT_UNLINK - - #RED_TRANSACT_MKDIR - - #RED_TRANSACT_RENAME - - #RED_TRANSACT_LINK - - #RED_TRANSACT_CLOSE - - #RED_TRANSACT_WRITE - - #RED_TRANSACT_FSYNC - - #RED_TRANSACT_TRUNCATE - - #RED_TRANSACT_VOLFULL - - The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all - automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of - all transaction flags, excluding those representing excluded functionality. - - Attempting to enable events for excluded functionality will result in an - error. - - @param ulEventMask A bitwise-OR'd mask of automatic transaction events to - be set as the current transaction mode. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL The volume is not mounted; or @p ulEventMask contains - invalid bits. - @retval -RED_EROFS The file system volume is read-only. -*/ -REDSTATUS RedCoreTransMaskSet( - uint32_t ulEventMask) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted || ((ulEventMask & RED_TRANSACT_MASK) != ulEventMask)) - { - ret = -RED_EINVAL; - } - else if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - gpRedVolume->ulTransMask = ulEventMask; - ret = 0; - } - - return ret; -} -#endif - - -#if (REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKGET == 1) -/** @brief Read the transaction mask. - - If the volume is read-only, the returned event mask is always zero. - - @param pulEventMask Populated with a bitwise-OR'd mask of automatic - transaction events which represent the current - transaction mode for the volume. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL The volume is not mounted; or @p pulEventMask is `NULL`. -*/ -REDSTATUS RedCoreTransMaskGet( - uint32_t *pulEventMask) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted || (pulEventMask == NULL)) - { - ret = -RED_EINVAL; - } - else - { - #if REDCONF_READ_ONLY == 1 - *pulEventMask = 0U; - #else - *pulEventMask = gpRedVolume->ulTransMask; - #endif - ret = 0; - } - - return ret; -} -#endif - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) -/** @brief Create a file or directory. - - @param ulPInode The inode number of the parent directory. - @param pszName A null-terminated name for the new inode. - @param fDir Whether to create a directory (true) or file (false). - @param pulInode On successful return, populated with the inode number of the - new file or directory. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL The volume is not mounted; or @p pszName is not - a valid name; or @p pulInode is `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EROFS The file system volume is read-only. - @retval -RED_ENOTDIR @p ulPInode is not a directory. - @retval -RED_EBADF @p ulPInode is not a valid inode. - @retval -RED_ENOSPC There is not enough space on the volume to - createthe new directory entry; or the directory - is full. - @retval -RED_ENFILE No available inode slots. - @retval -RED_ENAMETOOLONG @p pszName is too long. - @retval -RED_EEXIST @p pszName already exists in @p ulPInode. -*/ -REDSTATUS RedCoreCreate( - uint32_t ulPInode, - const char *pszName, - bool fDir, - uint32_t *pulInode) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted) - { - ret = -RED_EINVAL; - } - else if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - ret = CoreCreate(ulPInode, pszName, fDir, pulInode); - - if( (ret == -RED_ENOSPC) - && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) - && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) - { - ret = RedVolTransact(); - - if(ret == 0) - { - ret = CoreCreate(ulPInode, pszName, fDir, pulInode); - } - } - - if(ret == 0) - { - if(fDir && ((gpRedVolume->ulTransMask & RED_TRANSACT_MKDIR) != 0U)) - { - ret = RedVolTransact(); - } - else if(!fDir && ((gpRedVolume->ulTransMask & RED_TRANSACT_CREAT) != 0U)) - { - ret = RedVolTransact(); - } - else - { - /* No automatic transaction for this operation. - */ - } - } - } - - return ret; -} - - -/** @brief Create a file or directory. - - @param ulPInode The inode number of the parent directory. - @param pszName A null-terminated name for the new inode. - @param fDir Whether to create a directory (true) or file (false). - @param pulInode On successful return, populated with the inode number of the - new file or directory. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EROFS The file system volume is read-only. - @retval -RED_ENOTDIR @p ulPInode is not a directory. - @retval -RED_EBADF @p ulPInode is not a valid inode. - @retval -RED_ENOSPC There is not enough space on the volume to - create the new directory entry; or the directory - is full. - @retval -RED_ENFILE No available inode slots. - @retval -RED_ENAMETOOLONG @p pszName is too long. - @retval -RED_EEXIST @p pszName already exists in @p ulPInode. -*/ -static REDSTATUS CoreCreate( - uint32_t ulPInode, - const char *pszName, - bool fDir, - uint32_t *pulInode) -{ - REDSTATUS ret; - - if(pulInode == NULL) - { - ret = -RED_EINVAL; - } - else if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - CINODE pino; - - pino.ulInode = ulPInode; - ret = RedInodeMount(&pino, FTYPE_DIR, false); - - if(ret == 0) - { - CINODE ino; - - ino.ulInode = INODE_INVALID; - ret = RedInodeCreate(&ino, ulPInode, fDir ? RED_S_IFDIR : RED_S_IFREG); - - if(ret == 0) - { - ret = RedInodeBranch(&pino); - - if(ret == 0) - { - ret = RedDirEntryCreate(&pino, pszName, ino.ulInode); - } - - if(ret == 0) - { - *pulInode = ino.ulInode; - } - else - { - REDSTATUS ret2; - - ret2 = RedInodeFree(&ino); - CRITICAL_ASSERT(ret2 == 0); - } - - RedInodePut(&ino, 0U); - } - - RedInodePut(&pino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); - } - } - - return ret; -} -#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) */ - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) -/** @brief Create a hard link. - - This creates an additional name (link) for @p ulInode. The new name refers - to the same file with the same contents. If a name is deleted, but the - underlying file has other names, the file continues to exist. The link - count (accessible via RedCoreStat()) indicates the number of names that a - file has. All of a file's names are on equal footing: there is nothing - special about the original name. - - If @p ulInode names a directory, the operation will fail. - - @param ulPInode The inode number of the parent directory. - @param pszName The null-terminated name for the new link. - @param ulInode The inode to create a hard link to. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulPInode is not a valid inode; or @p ulInode - is not a valid inode. - @retval -RED_EEXIST @p pszName resolves to an existing file. - @retval -RED_EINVAL The volume is not mounted; or @p pszName is - `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EMLINK Creating the link would exceed the maximum link - count of @p ulInode. - @retval -RED_ENAMETOOLONG Attempting to create a link with a name that - exceeds the maximum name length. - @retval -RED_ENOSPC There is insufficient free space to expand the - directory that would contain the link. - @retval -RED_ENOTDIR @p ulPInode is not a directory. - @retval -RED_EPERM @p ulInode is a directory. - @retval -RED_EROFS The requested link requires writing in a - directory on a read-only file system. -*/ -REDSTATUS RedCoreLink( - uint32_t ulPInode, - const char *pszName, - uint32_t ulInode) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted) - { - ret = -RED_EINVAL; - } - else if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - ret = CoreLink(ulPInode, pszName, ulInode); - - if( (ret == -RED_ENOSPC) - && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) - && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) - { - ret = RedVolTransact(); - - if(ret == 0) - { - ret = CoreLink(ulPInode, pszName, ulInode); - } - } - - if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_LINK) != 0U)) - { - ret = RedVolTransact(); - } - } - - return ret; -} - - -/** @brief Create a hard link. - - @param ulPInode The inode number of the parent directory. - @param pszName The null-terminated name for the new link. - @param ulInode The inode to create a hard link to. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulPInode is not a valid inode; or @p ulInode - is not a valid inode. - @retval -RED_EEXIST @p pszName resolves to an existing file. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EMLINK Creating the link would exceed the maximum link - count of @p ulInode. - @retval -RED_ENAMETOOLONG Attempting to create a link with a name that - exceeds the maximum name length. - @retval -RED_ENOSPC There is insufficient free space to expand the - directory that would contain the link. - @retval -RED_ENOTDIR @p ulPInode is not a directory. - @retval -RED_EPERM @p ulInode is a directory. - @retval -RED_EROFS The requested link requires writing in a - directory on a read-only file system. -*/ -static REDSTATUS CoreLink( - uint32_t ulPInode, - const char *pszName, - uint32_t ulInode) -{ - REDSTATUS ret; - - if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - CINODE pino; - - pino.ulInode = ulPInode; - ret = RedInodeMount(&pino, FTYPE_DIR, false); - - if(ret == 0) - { - CINODE ino; - - ino.ulInode = ulInode; - ret = RedInodeMount(&ino, FTYPE_FILE, false); - - /* POSIX specifies EPERM as the errno thrown when link() is given a - directory. Switch the errno returned if EISDIR was the return - value. - */ - if(ret == -RED_EISDIR) - { - ret = -RED_EPERM; - } - - if(ret == 0) - { - if(ino.pInodeBuf->uNLink == UINT16_MAX) - { - ret = -RED_EMLINK; - } - else - { - ret = RedInodeBranch(&pino); - } - - if(ret == 0) - { - ret = RedInodeBranch(&ino); - } - - if(ret == 0) - { - ret = RedDirEntryCreate(&pino, pszName, ino.ulInode); - } - - if(ret == 0) - { - ino.pInodeBuf->uNLink++; - } - - RedInodePut(&ino, (ret == 0) ? IPUT_UPDATE_CTIME : 0U); - } - - RedInodePut(&pino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); - } - } - - return ret; -} -#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) */ - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) -/** @brief Delete a file or directory. - - The given name is deleted and the link count of the corresponding inode is - decremented. If the link count falls to zero (no remaining hard links), - the inode will be deleted. - - If the path names a directory which is not empty, the unlink will fail. - - If the deletion frees data in the committed state, it will not return to - free space until after a transaction point. Similarly, if the inode was - part of the committed state, the inode slot will not be available until - after a transaction point. - - This function can fail when the disk is full. To fix this, transact and - try again: Reliance Edge guarantees that it is possible to delete at least - one file or directory after a transaction point. If disk full automatic - transactions are enabled, this will happen automatically. - - @param ulPInode The inode number of the parent directory. - @param pszName The null-terminated name of the file or directory to - delete. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulPInode is not a valid inode. - @retval -RED_EINVAL The volume is not mounted; or @p pszName is - `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENAMETOOLONG @p pszName is too long. - @retval -RED_ENOENT @p pszName does not name an existing file or - directory. - @retval -RED_ENOTDIR @p ulPInode is not a directory. - @retval -RED_ENOSPC The file system does not have enough space to - modify the parent directory to perform the - deletion. - @retval -RED_ENOTEMPTY The inode refered to by @p pszName is a - directory which is not empty. -*/ -REDSTATUS RedCoreUnlink( - uint32_t ulPInode, - const char *pszName) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted) - { - ret = -RED_EINVAL; - } - else if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - ret = CoreUnlink(ulPInode, pszName); - - if( (ret == -RED_ENOSPC) - && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) - && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) - { - ret = RedVolTransact(); - - if(ret == 0) - { - ret = CoreUnlink(ulPInode, pszName); - } - } - - if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_UNLINK) != 0U)) - { - ret = RedVolTransact(); - } - } - - return ret; -} - - -/** @brief Delete a file or directory. - - @param ulPInode The inode number of the parent directory. - @param pszName The null-terminated name of the file or directory to - delete. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulPInode is not a valid inode. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENAMETOOLONG @p pszName is too long. - @retval -RED_ENOENT @p pszName does not name an existing file or - directory. - @retval -RED_ENOTDIR @p ulPInode is not a directory. - @retval -RED_ENOSPC The file system does not have enough space to - modify the parent directory to perform the - deletion. - @retval -RED_ENOTEMPTY The inode refered to by @p pszName is a - directory which is not empty. -*/ -static REDSTATUS CoreUnlink( - uint32_t ulPInode, - const char *pszName) -{ - REDSTATUS ret; - - if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - CINODE pino; - - pino.ulInode = ulPInode; - ret = RedInodeMount(&pino, FTYPE_DIR, false); - - if(ret == 0) - { - uint32_t ulDeleteIdx; - uint32_t ulInode; - - ret = RedDirEntryLookup(&pino, pszName, &ulDeleteIdx, &ulInode); - - if(ret == 0) - { - ret = RedInodeBranch(&pino); - } - - if(ret == 0) - { - CINODE ino; - - ino.ulInode = ulInode; - ret = RedInodeMount(&ino, FTYPE_EITHER, false); - - if(ret == 0) - { - if(ino.fDirectory && (ino.pInodeBuf->ullSize > 0U)) - { - ret = -RED_ENOTEMPTY; - } - else - { - #if RESERVED_BLOCKS > 0U - gpRedCoreVol->fUseReservedBlocks = true; - #endif - - ret = RedDirEntryDelete(&pino, ulDeleteIdx); - - #if RESERVED_BLOCKS > 0U - gpRedCoreVol->fUseReservedBlocks = false; - #endif - - if(ret == 0) - { - /* If the inode is deleted, buffers are needed to - read all of the indirects and free the data - blocks. Before doing that, to reduce the - minimum number of buffers needed to complete the - unlink, release the parent directory inode - buffers which are no longer needed. - */ - RedInodePutCoord(&pino); - - ret = RedInodeLinkDec(&ino); - CRITICAL_ASSERT(ret == 0); - } - } - - RedInodePut(&ino, (ret == 0) ? IPUT_UPDATE_CTIME : 0U); - } - } - - RedInodePut(&pino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); - } - } - - return ret; -} -#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) */ - - -#if REDCONF_API_POSIX == 1 -/** @brief Look up the inode number of a file or directory. - - @param ulPInode The inode number of the parent directory. - @param pszName The null-terminated name of the file or directory to look - up. - @param pulInode On successful return, populated with the inode number named - by @p pszName. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulPInode is not a valid inode. - @retval -RED_EINVAL The volume is not mounted; @p pszName is `NULL`; or - @p pulInode is `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOENT @p pszName does not name an existing file or directory. - @retval -RED_ENOTDIR @p ulPInode is not a directory. -*/ -REDSTATUS RedCoreLookup( - uint32_t ulPInode, - const char *pszName, - uint32_t *pulInode) -{ - REDSTATUS ret; - - if((pulInode == NULL) || !gpRedVolume->fMounted) - { - ret = -RED_EINVAL; - } - else - { - CINODE ino; - - ino.ulInode = ulPInode; - ret = RedInodeMount(&ino, FTYPE_DIR, false); - - if(ret == 0) - { - ret = RedDirEntryLookup(&ino, pszName, NULL, pulInode); - - RedInodePut(&ino, 0U); - } - } - - return ret; -} -#endif /* REDCONF_API_POSIX == 1 */ - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) -/** @brief Rename a file or directory. - - If @p pszDstName names an existing file or directory, the behavior depends - on the configuration. If #REDCONF_RENAME_ATOMIC is false, and if the - destination name exists, this function always fails with -RED_EEXIST. - - If #REDCONF_RENAME_ATOMIC is true, and if the new name exists, then in one - atomic operation, the destination name is unlinked and the source name is - renamed to the destination name. Both names must be of the same type (both - files or both directories). As with RedCoreUnlink(), if the destination - name is a directory, it must be empty. The major exception to this - behavior is that if both names are links to the same inode, then the rename - does nothing and both names continue to exist. - - If the rename deletes the old destination, it may free data in the - committed state, which will not return to free space until after a - transaction point. Similarly, if the deleted inode was part of the - committed state, the inode slot will not be available until after a - transaction point. - - @param ulSrcPInode The inode number of the parent directory of the file or - directory to rename. - @param pszSrcName The name of the file or directory to rename. - @param ulDstPInode The new parent directory inode number of the file or - directory after the rename. - @param pszDstName The new name of the file or directory after the rename. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulSrcPInode is not a valid inode number; or - @p ulDstPInode is not a valid inode number. - @retval -RED_EEXIST #REDCONF_RENAME_POSIX is false and the - destination name exists. - @retval -RED_EINVAL The volume is not mounted; @p pszSrcName is - `NULL`; or @p pszDstName is `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR The destination name exists and is a directory, - and the source name is a non-directory. - @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer - than #REDCONF_NAME_MAX. - @retval -RED_ENOENT The source name is not an existing entry; or - either @p pszSrcName or @p pszDstName point to - an empty string. - @retval -RED_ENOTDIR @p ulSrcPInode is not a directory; or - @p ulDstPInode is not a directory; or the source - name is a directory and the destination name is - a file. - @retval -RED_ENOTEMPTY The destination name is a directory which is not - empty. - @retval -RED_ENOSPC The file system does not have enough space to - extend the @p ulDstPInode directory. - @retval -RED_EROFS The directory to be removed resides on a - read-only file system. -*/ -REDSTATUS RedCoreRename( - uint32_t ulSrcPInode, - const char *pszSrcName, - uint32_t ulDstPInode, - const char *pszDstName) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted) - { - ret = -RED_EINVAL; - } - else if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - ret = CoreRename(ulSrcPInode, pszSrcName, ulDstPInode, pszDstName); - - if( (ret == -RED_ENOSPC) - && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) - && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) - { - ret = RedVolTransact(); - - if(ret == 0) - { - ret = CoreRename(ulSrcPInode, pszSrcName, ulDstPInode, pszDstName); - } - } - - if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_RENAME) != 0U)) - { - ret = RedVolTransact(); - } - } - - return ret; -} - - -/** @brief Rename a file or directory. - - @param ulSrcPInode The inode number of the parent directory of the file or - directory to rename. - @param pszSrcName The name of the file or directory to rename. - @param ulDstPInode The new parent directory inode number of the file or - directory after the rename. - @param pszDstName The new name of the file or directory after the rename. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulSrcPInode is not a valid inode number; or - @p ulDstPInode is not a valid inode number. - @retval -RED_EEXIST #REDCONF_RENAME_POSIX is false and the - destination name exists. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR The destination name exists and is a directory, - and the source name is a non-directory. - @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer - than #REDCONF_NAME_MAX. - @retval -RED_ENOENT The source name is not an existing entry; or - either @p pszSrcName or @p pszDstName point to - an empty string. - @retval -RED_ENOTDIR @p ulSrcPInode is not a directory; or - @p ulDstPInode is not a directory; or the source - name is a directory and the destination name is - a file. - @retval -RED_ENOTEMPTY The destination name is a directory which is not - empty. - @retval -RED_ENOSPC The file system does not have enough space to - extend the @p ulDstPInode directory. - @retval -RED_EROFS The directory to be removed resides on a - read-only file system. -*/ -static REDSTATUS CoreRename( - uint32_t ulSrcPInode, - const char *pszSrcName, - uint32_t ulDstPInode, - const char *pszDstName) -{ - REDSTATUS ret; - - if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - bool fUpdateTimestamps = false; - CINODE SrcPInode; - - SrcPInode.ulInode = ulSrcPInode; - ret = RedInodeMount(&SrcPInode, FTYPE_DIR, true); - - if(ret == 0) - { - CINODE DstPInode; - CINODE *pDstPInode; - - if(ulSrcPInode == ulDstPInode) - { - pDstPInode = &SrcPInode; - } - else - { - pDstPInode = &DstPInode; - DstPInode.ulInode = ulDstPInode; - ret = RedInodeMount(pDstPInode, FTYPE_DIR, true); - } - - if(ret == 0) - { - /* Initialize these to zero so we can unconditionally put them, - even if RedDirEntryRename() fails before mounting them. - */ - CINODE SrcInode = {0U}; - CINODE DstInode = {0U}; - - ret = RedDirEntryRename(&SrcPInode, pszSrcName, &SrcInode, pDstPInode, pszDstName, &DstInode); - - #if REDCONF_RENAME_ATOMIC == 1 - if((ret == 0) && (DstInode.ulInode != INODE_INVALID) && (DstInode.ulInode != SrcInode.ulInode)) - { - /* If the inode is deleted, buffers are needed to read all - of the indirects and free the data blocks. Before doing - that, to reduce the minimum number of buffers needed to - complete the rename, release parent directory inode - buffers which are no longer needed. - */ - RedInodePutCoord(&SrcPInode); - RedInodePutCoord(pDstPInode); - - ret = RedInodeLinkDec(&DstInode); - CRITICAL_ASSERT(ret == 0); - } - - if((ret == 0) && (DstInode.ulInode != SrcInode.ulInode)) - #else - if(ret == 0) - #endif - { - fUpdateTimestamps = true; - } - - #if REDCONF_RENAME_ATOMIC == 1 - RedInodePut(&DstInode, 0U); - #endif - - /* POSIX says updating ctime for the source inode is optional, - but searching around it looks like this is common for Linux - and other Unix file systems. - */ - RedInodePut(&SrcInode, fUpdateTimestamps ? IPUT_UPDATE_CTIME : 0U); - RedInodePut(pDstPInode, fUpdateTimestamps ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); - } - } - - RedInodePut(&SrcPInode, fUpdateTimestamps ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); - } - - return ret; -} -#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) */ - - -#if REDCONF_API_POSIX == 1 -/** @brief Get the status of a file or directory. - - See the ::REDSTAT type for the details of the information returned. - - @param ulInode The inode number of the file or directory whose information - is to be retrieved. - @param pStat Pointer to a ::REDSTAT buffer to populate. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is not a valid inode. - @retval -RED_EINVAL The volume is not mounted; @p pStat is `NULL`. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedCoreStat( - uint32_t ulInode, - REDSTAT *pStat) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted || (pStat == NULL)) - { - ret = -RED_EINVAL; - } - else - { - CINODE ino; - - ino.ulInode = ulInode; - ret = RedInodeMount(&ino, FTYPE_EITHER, false); - if(ret == 0) - { - RedMemSet(pStat, 0U, sizeof(*pStat)); - - pStat->st_dev = gbRedVolNum; - pStat->st_ino = ulInode; - pStat->st_mode = ino.pInodeBuf->uMode; - #if REDCONF_API_POSIX_LINK == 1 - pStat->st_nlink = ino.pInodeBuf->uNLink; - #else - pStat->st_nlink = 1U; - #endif - pStat->st_size = ino.pInodeBuf->ullSize; - #if REDCONF_INODE_TIMESTAMPS == 1 - pStat->st_atime = ino.pInodeBuf->ulATime; - pStat->st_mtime = ino.pInodeBuf->ulMTime; - pStat->st_ctime = ino.pInodeBuf->ulCTime; - #endif - #if REDCONF_INODE_BLOCKS == 1 - pStat->st_blocks = ino.pInodeBuf->ulBlocks; - #endif - - RedInodePut(&ino, 0U); - } - } - - return ret; -} -#endif /* REDCONF_API_POSIX == 1 */ - - -#if REDCONF_API_FSE == 1 -/** @brief Get the size of a file. - - @param ulInode The inode number of the file whose size is to be retrieved. - @param pullSize On successful exit, populated with the file size. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is not a valid inode. - @retval -RED_EINVAL The volume is not mounted; @p pullSize is `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR @p ulInode is a directory inode. -*/ -REDSTATUS RedCoreFileSizeGet( - uint32_t ulInode, - uint64_t *pullSize) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted || (pullSize == NULL)) - { - ret = -RED_EINVAL; - } - else - { - CINODE ino; - - ino.ulInode = ulInode; - ret = RedInodeMount(&ino, FTYPE_FILE, false); - if(ret == 0) - { - *pullSize = ino.pInodeBuf->ullSize; - - RedInodePut(&ino, 0U); - } - } - - return ret; -} -#endif /* REDCONF_API_FSE == 1 */ - - -/** @brief Read from a file. - - Data which has not yet been written, but which is before the end-of-file - (sparse data), shall read as zeroes. A short read -- where the number of - bytes read is less than requested -- indicates that the requested read was - partially or, if zero bytes were read, entirely beyond the end-of-file. - - If @p ullStart is at or beyond the maximum file size, it is treated like - any other read entirely beyond the end-of-file: no data is read and - @p pulLen is populated with zero. - - @param ulInode The inode number of the file to read. - @param ullStart The file offset to read from. - @param pulLen On entry, contains the number of bytes to read; on - successful exit, contains the number of bytes actually - read. - @param pBuffer The buffer to populate with the data read. Must be big - enough for the read request. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is not a valid inode number. - @retval -RED_EINVAL The volume is not mounted; or @p pBuffer is `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR The inode is a directory inode. -*/ -REDSTATUS RedCoreFileRead( - uint32_t ulInode, - uint64_t ullStart, - uint32_t *pulLen, - void *pBuffer) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted || (pulLen == NULL)) - { - ret = -RED_EINVAL; - } - else - { - #if (REDCONF_ATIME == 1) && (REDCONF_READ_ONLY == 0) - bool fUpdateAtime = (*pulLen > 0U) && !gpRedVolume->fReadOnly; - #else - bool fUpdateAtime = false; - #endif - CINODE ino; - - ino.ulInode = ulInode; - ret = RedInodeMount(&ino, FTYPE_FILE, fUpdateAtime); - if(ret == 0) - { - ret = RedInodeDataRead(&ino, ullStart, pulLen, pBuffer); - - #if (REDCONF_ATIME == 1) && (REDCONF_READ_ONLY == 0) - RedInodePut(&ino, ((ret == 0) && fUpdateAtime) ? IPUT_UPDATE_ATIME : 0U); - #else - RedInodePut(&ino, 0U); - #endif - } - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Write to a file. - - If the write extends beyond the end-of-file, the file size will be - increased. - - A short write -- where the number of bytes written is less than requested - -- indicates either that the file system ran out of space but was still - able to write some of the request; or that the request would have caused - the file to exceed the maximum file size, but some of the data could be - written prior to the file size limit. - - If an error is returned, either none of the data was written or a critical - error occurred (like an I/O error) and the file system volume will be - read-only. - - @param ulInode The file number of the file to write. - @param ullStart The file offset to write at. - @param pulLen On entry, the number of bytes to write; on successful exit, - the number of bytes actually written. - @param pBuffer The buffer containing the data to be written. Must big - enough for the write request. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is not a valid file number. - @retval -RED_EFBIG No data can be written to the given file offset since - the resulting file size would exceed the maximum file - size. - @retval -RED_EINVAL The volume is not mounted; or @p pBuffer is `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR The inode is a directory inode. - @retval -RED_ENOSPC No data can be written because there is insufficient - free space. - @retval -RED_EROFS The file system volume is read-only. -*/ -REDSTATUS RedCoreFileWrite( - uint32_t ulInode, - uint64_t ullStart, - uint32_t *pulLen, - const void *pBuffer) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted) - { - ret = -RED_EINVAL; - } - else if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - ret = CoreFileWrite(ulInode, ullStart, pulLen, pBuffer); - - if( (ret == -RED_ENOSPC) - && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) - && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) - { - ret = RedVolTransact(); - - if(ret == 0) - { - ret = CoreFileWrite(ulInode, ullStart, pulLen, pBuffer); - } - } - - if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_WRITE) != 0U)) - { - ret = RedVolTransact(); - } - } - - return ret; -} - - -/** @brief Write to a file. - - @param ulInode The file number of the file to write. - @param ullStart The file offset to write at. - @param pulLen On entry, the number of bytes to write; on successful exit, - the number of bytes actually written. - @param pBuffer The buffer containing the data to be written. Must big - enough for the write request. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is not a valid file number. - @retval -RED_EFBIG No data can be written to the given file offset since - the resulting file size would exceed the maximum file - size. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR The inode is a directory inode. - @retval -RED_ENOSPC No data can be written because there is insufficient - free space. - @retval -RED_EROFS The file system volume is read-only. -*/ -static REDSTATUS CoreFileWrite( - uint32_t ulInode, - uint64_t ullStart, - uint32_t *pulLen, - const void *pBuffer) -{ - REDSTATUS ret; - - if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - CINODE ino; - - ino.ulInode = ulInode; - ret = RedInodeMount(&ino, FTYPE_FILE, true); - if(ret == 0) - { - ret = RedInodeDataWrite(&ino, ullStart, pulLen, pBuffer); - - RedInodePut(&ino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); - } - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ - - -#if TRUNCATE_SUPPORTED -/** @brief Set the file size. - - Allows the file size to be increased, decreased, or to remain the same. If - the file size is increased, the new area is sparse (will read as zeroes). - If the file size is decreased, the data beyond the new end-of-file will - return to free space once it is no longer part of the committed state - (either immediately or after the next transaction point). - - @param ulInode The inode of the file to truncate. - @param ullSize The new file size, in bytes. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is not a valid inode number. - @retval -RED_EFBIG @p ullSize exceeds the maximum file size. - @retval -RED_EINVAL The volume is not mounted. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR The inode is a directory inode. - @retval -RED_ENOSPC Insufficient free space to perform the truncate. - @retval -RED_EROFS The file system volume is read-only. -*/ -REDSTATUS RedCoreFileTruncate( - uint32_t ulInode, - uint64_t ullSize) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted) - { - ret = -RED_EINVAL; - } - else if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - ret = CoreFileTruncate(ulInode, ullSize); - - if( (ret == -RED_ENOSPC) - && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) - && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) - { - ret = RedVolTransact(); - - if(ret == 0) - { - ret = CoreFileTruncate(ulInode, ullSize); - } - } - - if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_TRUNCATE) != 0U)) - { - ret = RedVolTransact(); - } - } - - return ret; -} - - -/** @brief Set the file size. - - @param ulInode The inode of the file to truncate. - @param ullSize The new file size, in bytes. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is not a valid inode number. - @retval -RED_EFBIG @p ullSize exceeds the maximum file size. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR The inode is a directory inode. - @retval -RED_ENOSPC Insufficient free space to perform the truncate. - @retval -RED_EROFS The file system volume is read-only. -*/ -static REDSTATUS CoreFileTruncate( - uint32_t ulInode, - uint64_t ullSize) -{ - REDSTATUS ret; - - if(gpRedVolume->fReadOnly) - { - ret = -RED_EROFS; - } - else - { - CINODE ino; - - ino.ulInode = ulInode; - ret = RedInodeMount(&ino, FTYPE_FILE, true); - if(ret == 0) - { - #if RESERVED_BLOCKS > 0U - gpRedCoreVol->fUseReservedBlocks = (ullSize < ino.pInodeBuf->ullSize); - #endif - - ret = RedInodeDataTruncate(&ino, ullSize); - - #if RESERVED_BLOCKS > 0U - gpRedCoreVol->fUseReservedBlocks = false; - #endif - - RedInodePut(&ino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); - } - } - - return ret; -} -#endif /* TRUNCATE_SUPPORTED */ - - -#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1) -/** @brief Read from a directory. - - If files are added to the directory after it is opened, the new files may - or may not be returned by this function. If files are deleted, the deleted - files will not be returned. - - @param ulInode The directory inode to read from. - @param pulPos A token which stores the position within the directory. To - read from the beginning of the directory, populate with - zero. - @param pszName Pointer to a buffer which must be big enough to store a - maximum size name, including a null terminator. On - successful exit, populated with the name of the next - directory entry. - @param pulInode On successful return, populated with the inode number of the - next directory entry. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is not a valid inode number. - @retval -RED_EINVAL The volume is not mounted. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOENT There are no more entries in the directory. - @retval -RED_ENOTDIR @p ulInode refers to a file. -*/ -REDSTATUS RedCoreDirRead( - uint32_t ulInode, - uint32_t *pulPos, - char *pszName, - uint32_t *pulInode) -{ - REDSTATUS ret; - - if(!gpRedVolume->fMounted) - { - ret = -RED_EINVAL; - } - else - { - CINODE ino; - - ino.ulInode = ulInode; - ret = RedInodeMount(&ino, FTYPE_DIR, false); - - if(ret == 0) - { - ret = RedDirEntryRead(&ino, pulPos, pszName, pulInode); - - #if (REDCONF_ATIME == 1) && (REDCONF_READ_ONLY == 0) - if((ret == 0) && !gpRedVolume->fReadOnly) - { - ret = RedInodeBranch(&ino); - } - - RedInodePut(&ino, ((ret == 0) && !gpRedVolume->fReadOnly) ? IPUT_UPDATE_ATIME : 0U); - #else - RedInodePut(&ino, 0U); - #endif - } - } - - return ret; -} -#endif /* (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1) */ - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements the entry-points to the core file system. + */ +#include +#include +#include + + +/* Minimum number of blocks needed for metadata on any volume: the master + * block (1), the two metaroots (2), and one doubly-allocated inode (2), + * resulting in 1 + 2 + 2 = 5. + */ +#define MINIMUM_METADATA_BLOCKS ( 5U ) + + +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) + static REDSTATUS CoreCreate( uint32_t ulPInode, + const char * pszName, + bool fDir, + uint32_t * pulInode ); +#endif +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_LINK == 1 ) + static REDSTATUS CoreLink( uint32_t ulPInode, + const char * pszName, + uint32_t ulInode ); +#endif +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) && ( ( REDCONF_API_POSIX_UNLINK == 1 ) || ( REDCONF_API_POSIX_RMDIR == 1 ) ) + static REDSTATUS CoreUnlink( uint32_t ulPInode, + const char * pszName ); +#endif +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_RENAME == 1 ) + static REDSTATUS CoreRename( uint32_t ulSrcPInode, + const char * pszSrcName, + uint32_t ulDstPInode, + const char * pszDstName ); +#endif +#if REDCONF_READ_ONLY == 0 + static REDSTATUS CoreFileWrite( uint32_t ulInode, + uint64_t ullStart, + uint32_t * pulLen, + const void * pBuffer ); +#endif +#if TRUNCATE_SUPPORTED + static REDSTATUS CoreFileTruncate( uint32_t ulInode, + uint64_t ullSize ); +#endif + + +VOLUME gaRedVolume[ REDCONF_VOLUME_COUNT ]; +static COREVOLUME gaCoreVol[ REDCONF_VOLUME_COUNT ]; + +const VOLCONF * CONST_IF_ONE_VOLUME gpRedVolConf = &gaRedVolConf[ 0U ]; +VOLUME * CONST_IF_ONE_VOLUME gpRedVolume = &gaRedVolume[ 0U ]; +COREVOLUME * CONST_IF_ONE_VOLUME gpRedCoreVol = &gaCoreVol[ 0U ]; +METAROOT * gpRedMR = &gaCoreVol[ 0U ].aMR[ 0U ]; + +CONST_IF_ONE_VOLUME uint8_t gbRedVolNum = 0; + + +/** @brief Initialize the Reliance Edge file system driver. + * + * Prepares the Reliance Edge file system driver to be used. Must be the first + * Reliance Edge function to be invoked: no volumes can be mounted until the + * driver has been initialized. + * + * If this function is called when the Reliance Edge driver is already + * initialized, the behavior is undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ +REDSTATUS RedCoreInit( void ) +{ + REDSTATUS ret = 0; + uint8_t bVolNum; + + #if REDCONF_OUTPUT == 1 + static uint8_t bSignedOn = 0U; /* Whether the sign on has been printed. */ + + if( bSignedOn == 0U ) + { + RedSignOn(); + bSignedOn = 1U; + } + #else + + /* Call RedSignOn() even when output is disabled, to force the copyright + * text to be referenced and pulled into the program data. + */ + RedSignOn(); + #endif + + RedMemSet( gaRedVolume, 0U, sizeof( gaRedVolume ) ); + RedMemSet( gaCoreVol, 0U, sizeof( gaCoreVol ) ); + + RedBufferInit(); + + for( bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++ ) + { + VOLUME * pVol = &gaRedVolume[ bVolNum ]; + COREVOLUME * pCoreVol = &gaCoreVol[ bVolNum ]; + const VOLCONF * pVolConf = &gaRedVolConf[ bVolNum ]; + + if( ( pVolConf->ulSectorSize < SECTOR_SIZE_MIN ) || + ( ( REDCONF_BLOCK_SIZE % pVolConf->ulSectorSize ) != 0U ) || + ( pVolConf->ulInodeCount == 0U ) ) + { + ret = -RED_EINVAL; + } + + #if REDCONF_API_POSIX == 1 + else if( pVolConf->pszPathPrefix == NULL ) + { + ret = -RED_EINVAL; + } + else + { + #if REDCONF_VOLUME_COUNT > 1U + uint8_t bCmpVol; + + /* Ensure there are no duplicate path prefixes. Check against all + * previous volumes, which are already verified. + */ + for( bCmpVol = 0U; bCmpVol < bVolNum; bCmpVol++ ) + { + const char * pszCmpPathPrefix = gaRedVolConf[ bCmpVol ].pszPathPrefix; + + if( RedStrCmp( pVolConf->pszPathPrefix, pszCmpPathPrefix ) == 0 ) + { + ret = -RED_EINVAL; + break; + } + } + #endif /* if REDCONF_VOLUME_COUNT > 1U */ + } + #endif /* if REDCONF_API_POSIX == 1 */ + + if( ret == 0 ) + { + pVol->bBlockSectorShift = 0U; + + while( ( pVolConf->ulSectorSize << pVol->bBlockSectorShift ) < REDCONF_BLOCK_SIZE ) + { + pVol->bBlockSectorShift++; + } + + /* This should always be true since the block size is confirmed to + * be a power of two (checked at compile time) and above we ensured + * that (REDCONF_BLOCK_SIZE % pVolConf->ulSectorSize) == 0. + */ + REDASSERT( ( pVolConf->ulSectorSize << pVol->bBlockSectorShift ) == REDCONF_BLOCK_SIZE ); + + pVol->ulBlockCount = ( uint32_t ) ( pVolConf->ullSectorCount >> pVol->bBlockSectorShift ); + + if( pVol->ulBlockCount < MINIMUM_METADATA_BLOCKS ) + { + ret = -RED_EINVAL; + } + else + { + #if REDCONF_READ_ONLY == 0 + pVol->ulTransMask = REDCONF_TRANSACT_DEFAULT; + #endif + + pVol->ullMaxInodeSize = INODE_SIZE_MAX; + + /* To understand the following code, note that the fixed- + * location metadata is located at the start of the disk, in + * the following order: + * + * - Master block (1 block) + * - Metaroots (2 blocks) + * - External imap blocks (variable * 2 blocks) + * - Inode blocks (pVolConf->ulInodeCount * 2 blocks) + */ + + /* The imap needs bits for all inode and allocable blocks. If + * that bitmap will fit into the metaroot, the inline imap is + * used and there are no imap nodes on disk. The minus 3 is + * there since the imap does not include bits for the master + * block or metaroots. + */ + pCoreVol->fImapInline = ( pVol->ulBlockCount - 3U ) <= METAROOT_ENTRIES; + + if( pCoreVol->fImapInline ) + { + #if REDCONF_IMAP_INLINE == 1 + pCoreVol->ulInodeTableStartBN = 3U; + #else + ret = -RED_EINVAL; + #endif + } + else + { + #if REDCONF_IMAP_EXTERNAL == 1 + pCoreVol->ulImapStartBN = 3U; + + /* The imap does not include bits for itself, so add two to + * the number of imap entries for the two blocks of each + * imap node. This allows us to divide up the remaining + * space, making sure to round up so all data blocks are + * covered. + */ + pCoreVol->ulImapNodeCount = + ( ( pVol->ulBlockCount - 3U ) + ( ( IMAPNODE_ENTRIES + 2U ) - 1U ) ) / ( IMAPNODE_ENTRIES + 2U ); + + pCoreVol->ulInodeTableStartBN = pCoreVol->ulImapStartBN + ( pCoreVol->ulImapNodeCount * 2U ); + #else + ret = -RED_EINVAL; + #endif + } + } + } + + if( ret == 0 ) + { + pCoreVol->ulFirstAllocableBN = pCoreVol->ulInodeTableStartBN + ( pVolConf->ulInodeCount * 2U ); + + if( pCoreVol->ulFirstAllocableBN > pVol->ulBlockCount ) + { + /* We can get here if there is not enough space for the number + * of configured inodes. + */ + ret = -RED_EINVAL; + } + else + { + pVol->ulBlocksAllocable = pVol->ulBlockCount - pCoreVol->ulFirstAllocableBN; + } + } + + if( ret != 0 ) + { + break; + } + } + + /* Make sure the configured endianness is correct. + */ + if( ret == 0 ) + { + uint16_t uValue = 0xFF00U; + uint8_t abBytes[ 2U ]; + + RedMemCpy( abBytes, &uValue, sizeof( abBytes ) ); + + #if REDCONF_ENDIAN_BIG == 1 + if( abBytes[ 0U ] != 0xFFU ) + #else + if( abBytes[ 0U ] != 0x00U ) + #endif + { + ret = -RED_EINVAL; + } + } + + if( ret == 0 ) + { + ret = RedOsClockInit(); + + #if REDCONF_TASK_COUNT > 1U + if( ret == 0 ) + { + ret = RedOsMutexInit(); + + if( ret != 0 ) + { + ( void ) RedOsClockUninit(); + } + } + #endif + } + + return ret; +} + + +/** @brief Uninitialize the Reliance Edge file system driver. + * + * Tears down the Reliance Edge file system driver. Cannot be used until all + * Reliance Edge volumes are unmounted. A subsequent call to RedCoreInit() + * will initialize the driver again. + * + * The behavior of calling this function when the core is already uninitialized + * is undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBUSY At least one volume is still mounted. + */ +REDSTATUS RedCoreUninit( void ) +{ + REDSTATUS ret; + + #if REDCONF_TASK_COUNT > 1U + ret = RedOsMutexUninit(); + + if( ret == 0 ) + #endif + { + ret = RedOsClockUninit(); + } + + return ret; +} + + +/** @brief Set the current volume. + * + * All core APIs operate on the current volume. This call must precede all + * core accesses. + * + * @param bVolNum The volume number to access. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number. + */ +REDSTATUS RedCoreVolSetCurrent( uint8_t bVolNum ) +{ + REDSTATUS ret; + + if( bVolNum >= REDCONF_VOLUME_COUNT ) + { + ret = -RED_EINVAL; + } + else + { + #if REDCONF_VOLUME_COUNT > 1U + gbRedVolNum = bVolNum; + gpRedVolConf = &gaRedVolConf[ bVolNum ]; + gpRedVolume = &gaRedVolume[ bVolNum ]; + gpRedCoreVol = &gaCoreVol[ bVolNum ]; + gpRedMR = &gpRedCoreVol->aMR[ gpRedCoreVol->bCurMR ]; + #endif + + ret = 0; + } + + return ret; +} + + +#if FORMAT_SUPPORTED + +/** @brief Format a file system volume. + * + * Uses the statically defined volume configuration. After calling this + * function, the volume needs to be mounted -- see RedCoreVolMount(). + * + * An error is returned if the volume is mounted. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBUSY Volume is mounted. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedCoreVolFormat( void ) + { + return RedVolFormat(); + } +#endif /* FORMAT_SUPPORTED */ + + +/** @brief Mount a file system volume. + * + * Prepares the file system volume to be accessed. Mount will fail if the + * volume has never been formatted, or if the on-disk format is inconsistent + * with the compile-time configuration. + * + * If the volume is already mounted, the behavior is undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt. + */ +REDSTATUS RedCoreVolMount( void ) +{ + return RedVolMount(); +} + + +/** @brief Unmount a file system volume. + * + * This function discards the in-memory state for the file system and marks it + * as unmounted. Subsequent attempts to access the volume will fail until the + * volume is mounted again. + * + * If unmount automatic transaction points are enabled, this function will + * commit a transaction point prior to unmounting. If unmount automatic + * transaction points are disabled, this function will unmount without + * transacting, effectively discarding the working state. + * + * If the volume is already unmounted, the behavior is undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO I/O error during unmount automatic transaction point. + */ +REDSTATUS RedCoreVolUnmount( void ) +{ + REDSTATUS ret = 0; + + #if REDCONF_READ_ONLY == 0 + if( !gpRedVolume->fReadOnly && ( ( gpRedVolume->ulTransMask & RED_TRANSACT_UMOUNT ) != 0U ) ) + { + ret = RedVolTransact(); + } + #endif + + if( ret == 0 ) + { + ret = RedBufferDiscardRange( 0U, gpRedVolume->ulBlockCount ); + } + + if( ret == 0 ) + { + ret = RedOsBDevClose( gbRedVolNum ); + } + + if( ret == 0 ) + { + gpRedVolume->fMounted = false; + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Commit a transaction point. + * + * Reliance Edge is a transactional file system. All modifications, of both + * metadata and filedata, are initially working state. A transaction point + * is a process whereby the working state atomically becomes the committed + * state, replacing the previous committed state. Whenever Reliance Edge is + * mounted, including after power loss, the state of the file system after + * mount is the most recent committed state. Nothing from the committed + * state is ever missing, and nothing from the working state is ever included. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL The volume is not mounted. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EROFS The file system volume is read-only. + */ + REDSTATUS RedCoreVolTransact( void ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted ) + { + ret = -RED_EINVAL; + } + else if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + ret = RedVolTransact(); + } + + return ret; + } +#endif /* REDCONF_READ_ONLY == 0 */ + + +#if REDCONF_API_POSIX == 1 + +/** @brief Query file system status information. + * + * @param pStatFS The buffer to populate with volume information. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval -RED_EINVAL Volume is not mounted; or @p pStatFS is `NULL`. + */ + REDSTATUS RedCoreVolStat( REDSTATFS * pStatFS ) + { + REDSTATUS ret; + + if( ( pStatFS == NULL ) || ( !gpRedVolume->fMounted ) ) + { + ret = -RED_EINVAL; + } + else + { + RedMemSet( pStatFS, 0U, sizeof( *pStatFS ) ); + + pStatFS->f_bsize = REDCONF_BLOCK_SIZE; + pStatFS->f_frsize = REDCONF_BLOCK_SIZE; + pStatFS->f_blocks = gpRedVolume->ulBlockCount; + #if RESERVED_BLOCKS > 0U + pStatFS->f_bfree = ( gpRedMR->ulFreeBlocks > RESERVED_BLOCKS ) ? ( gpRedMR->ulFreeBlocks - RESERVED_BLOCKS ) : 0U; + #else + pStatFS->f_bfree = gpRedMR->ulFreeBlocks; + #endif + pStatFS->f_bavail = pStatFS->f_bfree; + pStatFS->f_files = gpRedVolConf->ulInodeCount; + pStatFS->f_ffree = gpRedMR->ulFreeInodes; + pStatFS->f_favail = gpRedMR->ulFreeInodes; + + pStatFS->f_flag = RED_ST_NOSUID; + #if REDCONF_READ_ONLY == 0 + if( gpRedVolume->fReadOnly ) + #endif + { + pStatFS->f_flag |= RED_ST_RDONLY; + } + + pStatFS->f_namemax = REDCONF_NAME_MAX; + pStatFS->f_maxfsize = INODE_SIZE_MAX; + pStatFS->f_dev = gbRedVolNum; + + ret = 0; + } + + return ret; + } +#endif /* REDCONF_API_POSIX == 1 */ + + +#if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || ( REDCONF_API_FSE_TRANSMASKSET == 1 ) ) + +/** @brief Update the transaction mask. + * + * The following events are available when using the FSE API: + * + * - #RED_TRANSACT_UMOUNT + * - #RED_TRANSACT_WRITE + * - #RED_TRANSACT_TRUNCATE + * - #RED_TRANSACT_VOLFULL + * + * The following events are available when using the POSIX-like API: + * + * - #RED_TRANSACT_UMOUNT + * - #RED_TRANSACT_CREAT + * - #RED_TRANSACT_UNLINK + * - #RED_TRANSACT_MKDIR + * - #RED_TRANSACT_RENAME + * - #RED_TRANSACT_LINK + * - #RED_TRANSACT_CLOSE + * - #RED_TRANSACT_WRITE + * - #RED_TRANSACT_FSYNC + * - #RED_TRANSACT_TRUNCATE + * - #RED_TRANSACT_VOLFULL + * + * The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all + * automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of + * all transaction flags, excluding those representing excluded functionality. + * + * Attempting to enable events for excluded functionality will result in an + * error. + * + * @param ulEventMask A bitwise-OR'd mask of automatic transaction events to + * be set as the current transaction mode. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL The volume is not mounted; or @p ulEventMask contains + * invalid bits. + * @retval -RED_EROFS The file system volume is read-only. + */ + REDSTATUS RedCoreTransMaskSet( uint32_t ulEventMask ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted || ( ( ulEventMask & RED_TRANSACT_MASK ) != ulEventMask ) ) + { + ret = -RED_EINVAL; + } + else if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + gpRedVolume->ulTransMask = ulEventMask; + ret = 0; + } + + return ret; + } +#endif /* if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || ( REDCONF_API_FSE_TRANSMASKSET == 1 ) ) */ + + +#if ( REDCONF_API_POSIX == 1 ) || ( REDCONF_API_FSE_TRANSMASKGET == 1 ) + +/** @brief Read the transaction mask. + * + * If the volume is read-only, the returned event mask is always zero. + * + * @param pulEventMask Populated with a bitwise-OR'd mask of automatic + * transaction events which represent the current + * transaction mode for the volume. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL The volume is not mounted; or @p pulEventMask is `NULL`. + */ + REDSTATUS RedCoreTransMaskGet( uint32_t * pulEventMask ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted || ( pulEventMask == NULL ) ) + { + ret = -RED_EINVAL; + } + else + { + #if REDCONF_READ_ONLY == 1 + *pulEventMask = 0U; + #else + *pulEventMask = gpRedVolume->ulTransMask; + #endif + ret = 0; + } + + return ret; + } +#endif /* if ( REDCONF_API_POSIX == 1 ) || ( REDCONF_API_FSE_TRANSMASKGET == 1 ) */ + + +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) + +/** @brief Create a file or directory. + * + * @param ulPInode The inode number of the parent directory. + * @param pszName A null-terminated name for the new inode. + * @param fDir Whether to create a directory (true) or file (false). + * @param pulInode On successful return, populated with the inode number of the + * new file or directory. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL The volume is not mounted; or @p pszName is not + * a valid name; or @p pulInode is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EROFS The file system volume is read-only. + * @retval -RED_ENOTDIR @p ulPInode is not a directory. + * @retval -RED_EBADF @p ulPInode is not a valid inode. + * @retval -RED_ENOSPC There is not enough space on the volume to + * createthe new directory entry; or the directory + * is full. + * @retval -RED_ENFILE No available inode slots. + * @retval -RED_ENAMETOOLONG @p pszName is too long. + * @retval -RED_EEXIST @p pszName already exists in @p ulPInode. + */ + REDSTATUS RedCoreCreate( uint32_t ulPInode, + const char * pszName, + bool fDir, + uint32_t * pulInode ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted ) + { + ret = -RED_EINVAL; + } + else if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + ret = CoreCreate( ulPInode, pszName, fDir, pulInode ); + + if( ( ret == -RED_ENOSPC ) && + ( ( gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL ) != 0U ) && + ( gpRedCoreVol->ulAlmostFreeBlocks > 0U ) ) + { + ret = RedVolTransact(); + + if( ret == 0 ) + { + ret = CoreCreate( ulPInode, pszName, fDir, pulInode ); + } + } + + if( ret == 0 ) + { + if( fDir && ( ( gpRedVolume->ulTransMask & RED_TRANSACT_MKDIR ) != 0U ) ) + { + ret = RedVolTransact(); + } + else if( !fDir && ( ( gpRedVolume->ulTransMask & RED_TRANSACT_CREAT ) != 0U ) ) + { + ret = RedVolTransact(); + } + else + { + /* No automatic transaction for this operation. + */ + } + } + } + + return ret; + } + + +/** @brief Create a file or directory. + * + * @param ulPInode The inode number of the parent directory. + * @param pszName A null-terminated name for the new inode. + * @param fDir Whether to create a directory (true) or file (false). + * @param pulInode On successful return, populated with the inode number of the + * new file or directory. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EROFS The file system volume is read-only. + * @retval -RED_ENOTDIR @p ulPInode is not a directory. + * @retval -RED_EBADF @p ulPInode is not a valid inode. + * @retval -RED_ENOSPC There is not enough space on the volume to + * create the new directory entry; or the directory + * is full. + * @retval -RED_ENFILE No available inode slots. + * @retval -RED_ENAMETOOLONG @p pszName is too long. + * @retval -RED_EEXIST @p pszName already exists in @p ulPInode. + */ + static REDSTATUS CoreCreate( uint32_t ulPInode, + const char * pszName, + bool fDir, + uint32_t * pulInode ) + { + REDSTATUS ret; + + if( pulInode == NULL ) + { + ret = -RED_EINVAL; + } + else if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + CINODE pino; + + pino.ulInode = ulPInode; + ret = RedInodeMount( &pino, FTYPE_DIR, false ); + + if( ret == 0 ) + { + CINODE ino; + + ino.ulInode = INODE_INVALID; + ret = RedInodeCreate( &ino, ulPInode, fDir ? RED_S_IFDIR : RED_S_IFREG ); + + if( ret == 0 ) + { + ret = RedInodeBranch( &pino ); + + if( ret == 0 ) + { + ret = RedDirEntryCreate( &pino, pszName, ino.ulInode ); + } + + if( ret == 0 ) + { + *pulInode = ino.ulInode; + } + else + { + REDSTATUS ret2; + + ret2 = RedInodeFree( &ino ); + CRITICAL_ASSERT( ret2 == 0 ); + } + + RedInodePut( &ino, 0U ); + } + + RedInodePut( &pino, ( ret == 0 ) ? ( uint8_t ) ( IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME ) : 0U ); + } + } + + return ret; + } +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) */ + + +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_LINK == 1 ) + +/** @brief Create a hard link. + * + * This creates an additional name (link) for @p ulInode. The new name refers + * to the same file with the same contents. If a name is deleted, but the + * underlying file has other names, the file continues to exist. The link + * count (accessible via RedCoreStat()) indicates the number of names that a + * file has. All of a file's names are on equal footing: there is nothing + * special about the original name. + * + * If @p ulInode names a directory, the operation will fail. + * + * @param ulPInode The inode number of the parent directory. + * @param pszName The null-terminated name for the new link. + * @param ulInode The inode to create a hard link to. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulPInode is not a valid inode; or @p ulInode + * is not a valid inode. + * @retval -RED_EEXIST @p pszName resolves to an existing file. + * @retval -RED_EINVAL The volume is not mounted; or @p pszName is + * `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EMLINK Creating the link would exceed the maximum link + * count of @p ulInode. + * @retval -RED_ENAMETOOLONG Attempting to create a link with a name that + * exceeds the maximum name length. + * @retval -RED_ENOSPC There is insufficient free space to expand the + * directory that would contain the link. + * @retval -RED_ENOTDIR @p ulPInode is not a directory. + * @retval -RED_EPERM @p ulInode is a directory. + * @retval -RED_EROFS The requested link requires writing in a + * directory on a read-only file system. + */ + REDSTATUS RedCoreLink( uint32_t ulPInode, + const char * pszName, + uint32_t ulInode ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted ) + { + ret = -RED_EINVAL; + } + else if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + ret = CoreLink( ulPInode, pszName, ulInode ); + + if( ( ret == -RED_ENOSPC ) && + ( ( gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL ) != 0U ) && + ( gpRedCoreVol->ulAlmostFreeBlocks > 0U ) ) + { + ret = RedVolTransact(); + + if( ret == 0 ) + { + ret = CoreLink( ulPInode, pszName, ulInode ); + } + } + + if( ( ret == 0 ) && ( ( gpRedVolume->ulTransMask & RED_TRANSACT_LINK ) != 0U ) ) + { + ret = RedVolTransact(); + } + } + + return ret; + } + + +/** @brief Create a hard link. + * + * @param ulPInode The inode number of the parent directory. + * @param pszName The null-terminated name for the new link. + * @param ulInode The inode to create a hard link to. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulPInode is not a valid inode; or @p ulInode + * is not a valid inode. + * @retval -RED_EEXIST @p pszName resolves to an existing file. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EMLINK Creating the link would exceed the maximum link + * count of @p ulInode. + * @retval -RED_ENAMETOOLONG Attempting to create a link with a name that + * exceeds the maximum name length. + * @retval -RED_ENOSPC There is insufficient free space to expand the + * directory that would contain the link. + * @retval -RED_ENOTDIR @p ulPInode is not a directory. + * @retval -RED_EPERM @p ulInode is a directory. + * @retval -RED_EROFS The requested link requires writing in a + * directory on a read-only file system. + */ + static REDSTATUS CoreLink( uint32_t ulPInode, + const char * pszName, + uint32_t ulInode ) + { + REDSTATUS ret; + + if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + CINODE pino; + + pino.ulInode = ulPInode; + ret = RedInodeMount( &pino, FTYPE_DIR, false ); + + if( ret == 0 ) + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount( &ino, FTYPE_FILE, false ); + + /* POSIX specifies EPERM as the errno thrown when link() is given a + * directory. Switch the errno returned if EISDIR was the return + * value. + */ + if( ret == -RED_EISDIR ) + { + ret = -RED_EPERM; + } + + if( ret == 0 ) + { + if( ino.pInodeBuf->uNLink == UINT16_MAX ) + { + ret = -RED_EMLINK; + } + else + { + ret = RedInodeBranch( &pino ); + } + + if( ret == 0 ) + { + ret = RedInodeBranch( &ino ); + } + + if( ret == 0 ) + { + ret = RedDirEntryCreate( &pino, pszName, ino.ulInode ); + } + + if( ret == 0 ) + { + ino.pInodeBuf->uNLink++; + } + + RedInodePut( &ino, ( ret == 0 ) ? IPUT_UPDATE_CTIME : 0U ); + } + + RedInodePut( &pino, ( ret == 0 ) ? ( uint8_t ) ( IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME ) : 0U ); + } + } + + return ret; + } +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) */ + + +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) && ( ( REDCONF_API_POSIX_UNLINK == 1 ) || ( REDCONF_API_POSIX_RMDIR == 1 ) ) + +/** @brief Delete a file or directory. + * + * The given name is deleted and the link count of the corresponding inode is + * decremented. If the link count falls to zero (no remaining hard links), + * the inode will be deleted. + * + * If the path names a directory which is not empty, the unlink will fail. + * + * If the deletion frees data in the committed state, it will not return to + * free space until after a transaction point. Similarly, if the inode was + * part of the committed state, the inode slot will not be available until + * after a transaction point. + * + * This function can fail when the disk is full. To fix this, transact and + * try again: Reliance Edge guarantees that it is possible to delete at least + * one file or directory after a transaction point. If disk full automatic + * transactions are enabled, this will happen automatically. + * + * @param ulPInode The inode number of the parent directory. + * @param pszName The null-terminated name of the file or directory to + * delete. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulPInode is not a valid inode. + * @retval -RED_EINVAL The volume is not mounted; or @p pszName is + * `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENAMETOOLONG @p pszName is too long. + * @retval -RED_ENOENT @p pszName does not name an existing file or + * directory. + * @retval -RED_ENOTDIR @p ulPInode is not a directory. + * @retval -RED_ENOSPC The file system does not have enough space to + * modify the parent directory to perform the + * deletion. + * @retval -RED_ENOTEMPTY The inode referred to by @p pszName is a + * directory which is not empty. + */ + REDSTATUS RedCoreUnlink( uint32_t ulPInode, + const char * pszName ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted ) + { + ret = -RED_EINVAL; + } + else if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + ret = CoreUnlink( ulPInode, pszName ); + + if( ( ret == -RED_ENOSPC ) && + ( ( gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL ) != 0U ) && + ( gpRedCoreVol->ulAlmostFreeBlocks > 0U ) ) + { + ret = RedVolTransact(); + + if( ret == 0 ) + { + ret = CoreUnlink( ulPInode, pszName ); + } + } + + if( ( ret == 0 ) && ( ( gpRedVolume->ulTransMask & RED_TRANSACT_UNLINK ) != 0U ) ) + { + ret = RedVolTransact(); + } + } + + return ret; + } + + +/** @brief Delete a file or directory. + * + * @param ulPInode The inode number of the parent directory. + * @param pszName The null-terminated name of the file or directory to + * delete. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulPInode is not a valid inode. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENAMETOOLONG @p pszName is too long. + * @retval -RED_ENOENT @p pszName does not name an existing file or + * directory. + * @retval -RED_ENOTDIR @p ulPInode is not a directory. + * @retval -RED_ENOSPC The file system does not have enough space to + * modify the parent directory to perform the + * deletion. + * @retval -RED_ENOTEMPTY The inode referred to by @p pszName is a + * directory which is not empty. + */ + static REDSTATUS CoreUnlink( uint32_t ulPInode, + const char * pszName ) + { + REDSTATUS ret; + + if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + CINODE pino; + + pino.ulInode = ulPInode; + ret = RedInodeMount( &pino, FTYPE_DIR, false ); + + if( ret == 0 ) + { + uint32_t ulDeleteIdx; + uint32_t ulInode; + + ret = RedDirEntryLookup( &pino, pszName, &ulDeleteIdx, &ulInode ); + + if( ret == 0 ) + { + ret = RedInodeBranch( &pino ); + } + + if( ret == 0 ) + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount( &ino, FTYPE_EITHER, false ); + + if( ret == 0 ) + { + if( ino.fDirectory && ( ino.pInodeBuf->ullSize > 0U ) ) + { + ret = -RED_ENOTEMPTY; + } + else + { + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = true; + #endif + + ret = RedDirEntryDelete( &pino, ulDeleteIdx ); + + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = false; + #endif + + if( ret == 0 ) + { + /* If the inode is deleted, buffers are needed to + * read all of the indirects and free the data + * blocks. Before doing that, to reduce the + * minimum number of buffers needed to complete the + * unlink, release the parent directory inode + * buffers which are no longer needed. + */ + RedInodePutCoord( &pino ); + + ret = RedInodeLinkDec( &ino ); + CRITICAL_ASSERT( ret == 0 ); + } + } + + RedInodePut( &ino, ( ret == 0 ) ? IPUT_UPDATE_CTIME : 0U ); + } + } + + RedInodePut( &pino, ( ret == 0 ) ? ( uint8_t ) ( IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME ) : 0U ); + } + } + + return ret; + } +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) */ + + +#if REDCONF_API_POSIX == 1 + +/** @brief Look up the inode number of a file or directory. + * + * @param ulPInode The inode number of the parent directory. + * @param pszName The null-terminated name of the file or directory to look + * up. + * @param pulInode On successful return, populated with the inode number named + * by @p pszName. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulPInode is not a valid inode. + * @retval -RED_EINVAL The volume is not mounted; @p pszName is `NULL`; or + * @p pulInode is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOENT @p pszName does not name an existing file or directory. + * @retval -RED_ENOTDIR @p ulPInode is not a directory. + */ + REDSTATUS RedCoreLookup( uint32_t ulPInode, + const char * pszName, + uint32_t * pulInode ) + { + REDSTATUS ret; + + if( ( pulInode == NULL ) || !gpRedVolume->fMounted ) + { + ret = -RED_EINVAL; + } + else + { + CINODE ino; + + ino.ulInode = ulPInode; + ret = RedInodeMount( &ino, FTYPE_DIR, false ); + + if( ret == 0 ) + { + ret = RedDirEntryLookup( &ino, pszName, NULL, pulInode ); + + RedInodePut( &ino, 0U ); + } + } + + return ret; + } +#endif /* REDCONF_API_POSIX == 1 */ + + +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_RENAME == 1 ) + +/** @brief Rename a file or directory. + * + * If @p pszDstName names an existing file or directory, the behavior depends + * on the configuration. If #REDCONF_RENAME_ATOMIC is false, and if the + * destination name exists, this function always fails with -RED_EEXIST. + * + * If #REDCONF_RENAME_ATOMIC is true, and if the new name exists, then in one + * atomic operation, the destination name is unlinked and the source name is + * renamed to the destination name. Both names must be of the same type (both + * files or both directories). As with RedCoreUnlink(), if the destination + * name is a directory, it must be empty. The major exception to this + * behavior is that if both names are links to the same inode, then the rename + * does nothing and both names continue to exist. + * + * If the rename deletes the old destination, it may free data in the + * committed state, which will not return to free space until after a + * transaction point. Similarly, if the deleted inode was part of the + * committed state, the inode slot will not be available until after a + * transaction point. + * + * @param ulSrcPInode The inode number of the parent directory of the file or + * directory to rename. + * @param pszSrcName The name of the file or directory to rename. + * @param ulDstPInode The new parent directory inode number of the file or + * directory after the rename. + * @param pszDstName The new name of the file or directory after the rename. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulSrcPInode is not a valid inode number; or + * @p ulDstPInode is not a valid inode number. + * @retval -RED_EEXIST #REDCONF_RENAME_POSIX is false and the + * destination name exists. + * @retval -RED_EINVAL The volume is not mounted; @p pszSrcName is + * `NULL`; or @p pszDstName is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR The destination name exists and is a directory, + * and the source name is a non-directory. + * @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer + * than #REDCONF_NAME_MAX. + * @retval -RED_ENOENT The source name is not an existing entry; or + * either @p pszSrcName or @p pszDstName point to + * an empty string. + * @retval -RED_ENOTDIR @p ulSrcPInode is not a directory; or + * @p ulDstPInode is not a directory; or the source + * name is a directory and the destination name is + * a file. + * @retval -RED_ENOTEMPTY The destination name is a directory which is not + * empty. + * @retval -RED_ENOSPC The file system does not have enough space to + * extend the @p ulDstPInode directory. + * @retval -RED_EROFS The directory to be removed resides on a + * read-only file system. + */ + REDSTATUS RedCoreRename( uint32_t ulSrcPInode, + const char * pszSrcName, + uint32_t ulDstPInode, + const char * pszDstName ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted ) + { + ret = -RED_EINVAL; + } + else if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + ret = CoreRename( ulSrcPInode, pszSrcName, ulDstPInode, pszDstName ); + + if( ( ret == -RED_ENOSPC ) && + ( ( gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL ) != 0U ) && + ( gpRedCoreVol->ulAlmostFreeBlocks > 0U ) ) + { + ret = RedVolTransact(); + + if( ret == 0 ) + { + ret = CoreRename( ulSrcPInode, pszSrcName, ulDstPInode, pszDstName ); + } + } + + if( ( ret == 0 ) && ( ( gpRedVolume->ulTransMask & RED_TRANSACT_RENAME ) != 0U ) ) + { + ret = RedVolTransact(); + } + } + + return ret; + } + + +/** @brief Rename a file or directory. + * + * @param ulSrcPInode The inode number of the parent directory of the file or + * directory to rename. + * @param pszSrcName The name of the file or directory to rename. + * @param ulDstPInode The new parent directory inode number of the file or + * directory after the rename. + * @param pszDstName The new name of the file or directory after the rename. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulSrcPInode is not a valid inode number; or + * @p ulDstPInode is not a valid inode number. + * @retval -RED_EEXIST #REDCONF_RENAME_POSIX is false and the + * destination name exists. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR The destination name exists and is a directory, + * and the source name is a non-directory. + * @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer + * than #REDCONF_NAME_MAX. + * @retval -RED_ENOENT The source name is not an existing entry; or + * either @p pszSrcName or @p pszDstName point to + * an empty string. + * @retval -RED_ENOTDIR @p ulSrcPInode is not a directory; or + * @p ulDstPInode is not a directory; or the source + * name is a directory and the destination name is + * a file. + * @retval -RED_ENOTEMPTY The destination name is a directory which is not + * empty. + * @retval -RED_ENOSPC The file system does not have enough space to + * extend the @p ulDstPInode directory. + * @retval -RED_EROFS The directory to be removed resides on a + * read-only file system. + */ + static REDSTATUS CoreRename( uint32_t ulSrcPInode, + const char * pszSrcName, + uint32_t ulDstPInode, + const char * pszDstName ) + { + REDSTATUS ret; + + if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + bool fUpdateTimestamps = false; + CINODE SrcPInode; + + SrcPInode.ulInode = ulSrcPInode; + ret = RedInodeMount( &SrcPInode, FTYPE_DIR, true ); + + if( ret == 0 ) + { + CINODE DstPInode; + CINODE * pDstPInode; + + if( ulSrcPInode == ulDstPInode ) + { + pDstPInode = &SrcPInode; + } + else + { + pDstPInode = &DstPInode; + DstPInode.ulInode = ulDstPInode; + ret = RedInodeMount( pDstPInode, FTYPE_DIR, true ); + } + + if( ret == 0 ) + { + /* Initialize these to zero so we can unconditionally put them, + * even if RedDirEntryRename() fails before mounting them. + */ + CINODE SrcInode = { 0U }; + CINODE DstInode = { 0U }; + + ret = RedDirEntryRename( &SrcPInode, pszSrcName, &SrcInode, pDstPInode, pszDstName, &DstInode ); + + #if REDCONF_RENAME_ATOMIC == 1 + if( ( ret == 0 ) && ( DstInode.ulInode != INODE_INVALID ) && ( DstInode.ulInode != SrcInode.ulInode ) ) + { + /* If the inode is deleted, buffers are needed to read all + * of the indirects and free the data blocks. Before doing + * that, to reduce the minimum number of buffers needed to + * complete the rename, release parent directory inode + * buffers which are no longer needed. + */ + RedInodePutCoord( &SrcPInode ); + RedInodePutCoord( pDstPInode ); + + ret = RedInodeLinkDec( &DstInode ); + CRITICAL_ASSERT( ret == 0 ); + } + + if( ( ret == 0 ) && ( DstInode.ulInode != SrcInode.ulInode ) ) + #else /* if REDCONF_RENAME_ATOMIC == 1 */ + if( ret == 0 ) + #endif /* if REDCONF_RENAME_ATOMIC == 1 */ + { + fUpdateTimestamps = true; + } + + #if REDCONF_RENAME_ATOMIC == 1 + RedInodePut( &DstInode, 0U ); + #endif + + /* POSIX says updating ctime for the source inode is optional, + * but searching around it looks like this is common for Linux + * and other Unix file systems. + */ + RedInodePut( &SrcInode, fUpdateTimestamps ? IPUT_UPDATE_CTIME : 0U ); + RedInodePut( pDstPInode, fUpdateTimestamps ? ( uint8_t ) ( IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME ) : 0U ); + } + } + + RedInodePut( &SrcPInode, fUpdateTimestamps ? ( uint8_t ) ( IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME ) : 0U ); + } + + return ret; + } +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) */ + + +#if REDCONF_API_POSIX == 1 + +/** @brief Get the status of a file or directory. + * + * See the ::REDSTAT type for the details of the information returned. + * + * @param ulInode The inode number of the file or directory whose information + * is to be retrieved. + * @param pStat Pointer to a ::REDSTAT buffer to populate. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is not a valid inode. + * @retval -RED_EINVAL The volume is not mounted; @p pStat is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedCoreStat( uint32_t ulInode, + REDSTAT * pStat ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted || ( pStat == NULL ) ) + { + ret = -RED_EINVAL; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount( &ino, FTYPE_EITHER, false ); + + if( ret == 0 ) + { + RedMemSet( pStat, 0U, sizeof( *pStat ) ); + + pStat->st_dev = gbRedVolNum; + pStat->st_ino = ulInode; + pStat->st_mode = ino.pInodeBuf->uMode; + #if REDCONF_API_POSIX_LINK == 1 + pStat->st_nlink = ino.pInodeBuf->uNLink; + #else + pStat->st_nlink = 1U; + #endif + pStat->st_size = ino.pInodeBuf->ullSize; + #if REDCONF_INODE_TIMESTAMPS == 1 + pStat->st_atime = ino.pInodeBuf->ulATime; + pStat->st_mtime = ino.pInodeBuf->ulMTime; + pStat->st_ctime = ino.pInodeBuf->ulCTime; + #endif + #if REDCONF_INODE_BLOCKS == 1 + pStat->st_blocks = ino.pInodeBuf->ulBlocks; + #endif + + RedInodePut( &ino, 0U ); + } + } + + return ret; + } +#endif /* REDCONF_API_POSIX == 1 */ + + +#if REDCONF_API_FSE == 1 + +/** @brief Get the size of a file. + * + * @param ulInode The inode number of the file whose size is to be retrieved. + * @param pullSize On successful exit, populated with the file size. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is not a valid inode. + * @retval -RED_EINVAL The volume is not mounted; @p pullSize is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR @p ulInode is a directory inode. + */ + REDSTATUS RedCoreFileSizeGet( uint32_t ulInode, + uint64_t * pullSize ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted || ( pullSize == NULL ) ) + { + ret = -RED_EINVAL; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount( &ino, FTYPE_FILE, false ); + + if( ret == 0 ) + { + *pullSize = ino.pInodeBuf->ullSize; + + RedInodePut( &ino, 0U ); + } + } + + return ret; + } +#endif /* REDCONF_API_FSE == 1 */ + + +/** @brief Read from a file. + * + * Data which has not yet been written, but which is before the end-of-file + * (sparse data), shall read as zeroes. A short read -- where the number of + * bytes read is less than requested -- indicates that the requested read was + * partially or, if zero bytes were read, entirely beyond the end-of-file. + * + * If @p ullStart is at or beyond the maximum file size, it is treated like + * any other read entirely beyond the end-of-file: no data is read and + * @p pulLen is populated with zero. + * + * @param ulInode The inode number of the file to read. + * @param ullStart The file offset to read from. + * @param pulLen On entry, contains the number of bytes to read; on + * successful exit, contains the number of bytes actually + * read. + * @param pBuffer The buffer to populate with the data read. Must be big + * enough for the read request. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is not a valid inode number. + * @retval -RED_EINVAL The volume is not mounted; or @p pBuffer is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR The inode is a directory inode. + */ +REDSTATUS RedCoreFileRead( uint32_t ulInode, + uint64_t ullStart, + uint32_t * pulLen, + void * pBuffer ) +{ + REDSTATUS ret; + + if( !gpRedVolume->fMounted || ( pulLen == NULL ) ) + { + ret = -RED_EINVAL; + } + else + { + #if ( REDCONF_ATIME == 1 ) && ( REDCONF_READ_ONLY == 0 ) + bool fUpdateAtime = ( *pulLen > 0U ) && !gpRedVolume->fReadOnly; + #else + bool fUpdateAtime = false; + #endif + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount( &ino, FTYPE_FILE, fUpdateAtime ); + + if( ret == 0 ) + { + ret = RedInodeDataRead( &ino, ullStart, pulLen, pBuffer ); + + #if ( REDCONF_ATIME == 1 ) && ( REDCONF_READ_ONLY == 0 ) + RedInodePut( &ino, ( ( ret == 0 ) && fUpdateAtime ) ? IPUT_UPDATE_ATIME : 0U ); + #else + RedInodePut( &ino, 0U ); + #endif + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Write to a file. + * + * If the write extends beyond the end-of-file, the file size will be + * increased. + * + * A short write -- where the number of bytes written is less than requested + * -- indicates either that the file system ran out of space but was still + * able to write some of the request; or that the request would have caused + * the file to exceed the maximum file size, but some of the data could be + * written prior to the file size limit. + * + * If an error is returned, either none of the data was written or a critical + * error occurred (like an I/O error) and the file system volume will be + * read-only. + * + * @param ulInode The file number of the file to write. + * @param ullStart The file offset to write at. + * @param pulLen On entry, the number of bytes to write; on successful exit, + * the number of bytes actually written. + * @param pBuffer The buffer containing the data to be written. Must big + * enough for the write request. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is not a valid file number. + * @retval -RED_EFBIG No data can be written to the given file offset since + * the resulting file size would exceed the maximum file + * size. + * @retval -RED_EINVAL The volume is not mounted; or @p pBuffer is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR The inode is a directory inode. + * @retval -RED_ENOSPC No data can be written because there is insufficient + * free space. + * @retval -RED_EROFS The file system volume is read-only. + */ + REDSTATUS RedCoreFileWrite( uint32_t ulInode, + uint64_t ullStart, + uint32_t * pulLen, + const void * pBuffer ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted ) + { + ret = -RED_EINVAL; + } + else if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + ret = CoreFileWrite( ulInode, ullStart, pulLen, pBuffer ); + + if( ( ret == -RED_ENOSPC ) && + ( ( gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL ) != 0U ) && + ( gpRedCoreVol->ulAlmostFreeBlocks > 0U ) ) + { + ret = RedVolTransact(); + + if( ret == 0 ) + { + ret = CoreFileWrite( ulInode, ullStart, pulLen, pBuffer ); + } + } + + if( ( ret == 0 ) && ( ( gpRedVolume->ulTransMask & RED_TRANSACT_WRITE ) != 0U ) ) + { + ret = RedVolTransact(); + } + } + + return ret; + } + + +/** @brief Write to a file. + * + * @param ulInode The file number of the file to write. + * @param ullStart The file offset to write at. + * @param pulLen On entry, the number of bytes to write; on successful exit, + * the number of bytes actually written. + * @param pBuffer The buffer containing the data to be written. Must big + * enough for the write request. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is not a valid file number. + * @retval -RED_EFBIG No data can be written to the given file offset since + * the resulting file size would exceed the maximum file + * size. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR The inode is a directory inode. + * @retval -RED_ENOSPC No data can be written because there is insufficient + * free space. + * @retval -RED_EROFS The file system volume is read-only. + */ + static REDSTATUS CoreFileWrite( uint32_t ulInode, + uint64_t ullStart, + uint32_t * pulLen, + const void * pBuffer ) + { + REDSTATUS ret; + + if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount( &ino, FTYPE_FILE, true ); + + if( ret == 0 ) + { + ret = RedInodeDataWrite( &ino, ullStart, pulLen, pBuffer ); + + RedInodePut( &ino, ( ret == 0 ) ? ( uint8_t ) ( IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME ) : 0U ); + } + } + + return ret; + } +#endif /* REDCONF_READ_ONLY == 0 */ + + +#if TRUNCATE_SUPPORTED + +/** @brief Set the file size. + * + * Allows the file size to be increased, decreased, or to remain the same. If + * the file size is increased, the new area is sparse (will read as zeroes). + * If the file size is decreased, the data beyond the new end-of-file will + * return to free space once it is no longer part of the committed state + * (either immediately or after the next transaction point). + * + * @param ulInode The inode of the file to truncate. + * @param ullSize The new file size, in bytes. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is not a valid inode number. + * @retval -RED_EFBIG @p ullSize exceeds the maximum file size. + * @retval -RED_EINVAL The volume is not mounted. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR The inode is a directory inode. + * @retval -RED_ENOSPC Insufficient free space to perform the truncate. + * @retval -RED_EROFS The file system volume is read-only. + */ + REDSTATUS RedCoreFileTruncate( uint32_t ulInode, + uint64_t ullSize ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted ) + { + ret = -RED_EINVAL; + } + else if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + ret = CoreFileTruncate( ulInode, ullSize ); + + if( ( ret == -RED_ENOSPC ) && + ( ( gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL ) != 0U ) && + ( gpRedCoreVol->ulAlmostFreeBlocks > 0U ) ) + { + ret = RedVolTransact(); + + if( ret == 0 ) + { + ret = CoreFileTruncate( ulInode, ullSize ); + } + } + + if( ( ret == 0 ) && ( ( gpRedVolume->ulTransMask & RED_TRANSACT_TRUNCATE ) != 0U ) ) + { + ret = RedVolTransact(); + } + } + + return ret; + } + + +/** @brief Set the file size. + * + * @param ulInode The inode of the file to truncate. + * @param ullSize The new file size, in bytes. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is not a valid inode number. + * @retval -RED_EFBIG @p ullSize exceeds the maximum file size. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR The inode is a directory inode. + * @retval -RED_ENOSPC Insufficient free space to perform the truncate. + * @retval -RED_EROFS The file system volume is read-only. + */ + static REDSTATUS CoreFileTruncate( uint32_t ulInode, + uint64_t ullSize ) + { + REDSTATUS ret; + + if( gpRedVolume->fReadOnly ) + { + ret = -RED_EROFS; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount( &ino, FTYPE_FILE, true ); + + if( ret == 0 ) + { + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = ( ullSize < ino.pInodeBuf->ullSize ); + #endif + + ret = RedInodeDataTruncate( &ino, ullSize ); + + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = false; + #endif + + RedInodePut( &ino, ( ret == 0 ) ? ( uint8_t ) ( IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME ) : 0U ); + } + } + + return ret; + } +#endif /* TRUNCATE_SUPPORTED */ + + +#if ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_READDIR == 1 ) + +/** @brief Read from a directory. + * + * If files are added to the directory after it is opened, the new files may + * or may not be returned by this function. If files are deleted, the deleted + * files will not be returned. + * + * @param ulInode The directory inode to read from. + * @param pulPos A token which stores the position within the directory. To + * read from the beginning of the directory, populate with + * zero. + * @param pszName Pointer to a buffer which must be big enough to store a + * maximum size name, including a null terminator. On + * successful exit, populated with the name of the next + * directory entry. + * @param pulInode On successful return, populated with the inode number of the + * next directory entry. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is not a valid inode number. + * @retval -RED_EINVAL The volume is not mounted. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOENT There are no more entries in the directory. + * @retval -RED_ENOTDIR @p ulInode refers to a file. + */ + REDSTATUS RedCoreDirRead( uint32_t ulInode, + uint32_t * pulPos, + char * pszName, + uint32_t * pulInode ) + { + REDSTATUS ret; + + if( !gpRedVolume->fMounted ) + { + ret = -RED_EINVAL; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount( &ino, FTYPE_DIR, false ); + + if( ret == 0 ) + { + ret = RedDirEntryRead( &ino, pulPos, pszName, pulInode ); + + #if ( REDCONF_ATIME == 1 ) && ( REDCONF_READ_ONLY == 0 ) + if( ( ret == 0 ) && !gpRedVolume->fReadOnly ) + { + ret = RedInodeBranch( &ino ); + } + + RedInodePut( &ino, ( ( ret == 0 ) && !gpRedVolume->fReadOnly ) ? IPUT_UPDATE_ATIME : 0U ); + #else + RedInodePut( &ino, 0U ); + #endif + } + } + + return ret; + } +#endif /* (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1) */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/dir.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/dir.c index cfda1c1aa..4ba7e67cc 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/dir.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/dir.c @@ -1,958 +1,966 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements directory operations. -*/ -#include - -#if REDCONF_API_POSIX == 1 - -#include - - -#define DIR_INDEX_INVALID UINT32_MAX - -#if (REDCONF_NAME_MAX % 4U) != 0U -#define DIRENT_PADDING (4U - (REDCONF_NAME_MAX % 4U)) -#else -#define DIRENT_PADDING (0U) -#endif -#define DIRENT_SIZE (4U + REDCONF_NAME_MAX + DIRENT_PADDING) -#define DIRENTS_PER_BLOCK (REDCONF_BLOCK_SIZE / DIRENT_SIZE) -#define DIRENTS_MAX (uint32_t)REDMIN(UINT32_MAX, UINT64_SUFFIX(1) * INODE_DATA_BLOCKS * DIRENTS_PER_BLOCK) - - -/** @brief On-disk directory entry. -*/ -typedef struct -{ - /** The inode number that the directory entry points at. If the directory - entry is available, this holds INODE_INVALID. - */ - uint32_t ulInode; - - /** The name of the directory entry. For names shorter than - REDCONF_NAME_MAX, unused bytes in the array are zeroed. For names of - the maximum length, the string is not null terminated. - */ - char acName[REDCONF_NAME_MAX]; - - #if DIRENT_PADDING > 0U - /** Unused padding so that ulInode is always aligned on a four-byte - boundary. - */ - uint8_t abPadding[DIRENT_PADDING]; - #endif -} DIRENT; - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) -static REDSTATUS DirCyclicRenameCheck(uint32_t ulSrcInode, const CINODE *pDstPInode); -#endif -#if REDCONF_READ_ONLY == 0 -static REDSTATUS DirEntryWrite(CINODE *pPInode, uint32_t ulIdx, uint32_t ulInode, const char *pszName, uint32_t ulNameLen); -static uint64_t DirEntryIndexToOffset(uint32_t ulIdx); -#endif -static uint32_t DirOffsetToEntryIndex(uint64_t ullOffset); - - -#if REDCONF_READ_ONLY == 0 -/** @brief Create a new entry in a directory. - - @param pPInode A pointer to the cached inode structure of the directory - to which the new entry will be added. - @param pszName The name to be given to the new entry, terminated by a - null or a path separator. - @param ulInode The inode number the new name will point at. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC There is not enough space on the volume to - create the new directory entry; or the directory - is full. - @retval -RED_ENOTDIR @p pPInode is not a directory. - @retval -RED_ENAMETOOLONG @p pszName is too long. - @retval -RED_EEXIST @p pszName already exists in @p ulPInode. - @retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode - structure; or @p pszName is not a valid name. -*/ -REDSTATUS RedDirEntryCreate( - CINODE *pPInode, - const char *pszName, - uint32_t ulInode) -{ - REDSTATUS ret; - - if(!CINODE_IS_DIRTY(pPInode) || (pszName == NULL) || !INODE_IS_VALID(ulInode)) - { - ret = -RED_EINVAL; - } - else if(!pPInode->fDirectory) - { - ret = -RED_ENOTDIR; - } - else - { - uint32_t ulNameLen = RedNameLen(pszName); - - if(ulNameLen == 0U) - { - ret = -RED_EINVAL; - } - else if(ulNameLen > REDCONF_NAME_MAX) - { - ret = -RED_ENAMETOOLONG; - } - else - { - uint32_t ulEntryIdx; - - ret = RedDirEntryLookup(pPInode, pszName, &ulEntryIdx, NULL); - if(ret == 0) - { - ret = -RED_EEXIST; - } - else if(ret == -RED_ENOENT) - { - if(ulEntryIdx == DIR_INDEX_INVALID) - { - ret = -RED_ENOSPC; - } - else - { - ret = 0; - } - } - else - { - /* Unexpected error, no action. - */ - } - - if(ret == 0) - { - ret = DirEntryWrite(pPInode, ulEntryIdx, ulInode, pszName, ulNameLen); - } - } - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ - - -#if DELETE_SUPPORTED -/** @brief Delete an existing directory entry. - - @param pPInode A pointer to the cached inode structure of the directory - containing the entry to be deleted. - @param ulDeleteIdx Position within the directory of the entry to be - deleted. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC The file system does not have enough space to modify - the parent directory to perform the deletion. - @retval -RED_ENOTDIR @p pPInode is not a directory. - @retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode - structure; or @p ulIdx is out of range. -*/ -REDSTATUS RedDirEntryDelete( - CINODE *pPInode, - uint32_t ulDeleteIdx) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_DIRTY(pPInode) || (ulDeleteIdx >= DIRENTS_MAX)) - { - ret = -RED_EINVAL; - } - else if(!pPInode->fDirectory) - { - ret = -RED_ENOTDIR; - } - else if((DirEntryIndexToOffset(ulDeleteIdx) + DIRENT_SIZE) == pPInode->pInodeBuf->ullSize) - { - /* Start searching one behind the index to be deleted. - */ - uint32_t ulTruncIdx = ulDeleteIdx - 1U; - bool fDone = false; - - /* We are deleting the last dirent in the directory, so search - backwards to find the last populated dirent, allowing us to truncate - the directory to that point. - */ - while((ret == 0) && (ulTruncIdx != UINT32_MAX) && !fDone) - { - ret = RedInodeDataSeekAndRead(pPInode, ulTruncIdx / DIRENTS_PER_BLOCK); - - if(ret == 0) - { - const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData); - uint32_t ulBlockIdx = ulTruncIdx % DIRENTS_PER_BLOCK; - - do - { - if(pDirents[ulBlockIdx].ulInode != INODE_INVALID) - { - fDone = true; - break; - } - - ulTruncIdx--; - ulBlockIdx--; - } while(ulBlockIdx != UINT32_MAX); - } - else if(ret == -RED_ENODATA) - { - ret = 0; - - REDASSERT((ulTruncIdx % DIRENTS_PER_BLOCK) == 0U); - ulTruncIdx -= DIRENTS_PER_BLOCK; - } - else - { - /* Unexpected error, loop will terminate; nothing else - to be done. - */ - } - } - - /* Currently ulTruncIdx represents the last valid dirent index, or - UINT32_MAX if the directory is now empty. Increment it so that it - represents the first invalid entry, which will be truncated. - */ - ulTruncIdx++; - - /* Truncate the directory, deleting the requested entry and any empty - dirents at the end of the directory. - */ - if(ret == 0) - { - ret = RedInodeDataTruncate(pPInode, DirEntryIndexToOffset(ulTruncIdx)); - } - } - else - { - /* The dirent to delete is not the last entry in the directory, so just - zero it. - */ - ret = DirEntryWrite(pPInode, ulDeleteIdx, INODE_INVALID, "", 0U); - } - - return ret; -} -#endif /* DELETE_SUPPORTED */ - - -/** @brief Perform a case-sensitive search of a directory for a given name. - - If found, then position of the entry within the directory and the inode - number it points to are returned. As an optimization for directory entry - creation, in the case where the requested entry does not exist, the position - of the first available (unused) entry is returned. - - @param pPInode A pointer to the cached inode structure of the directory - to search. - @param pszName The name of the desired entry, terminated by either a - null or a path separator. - @param pulEntryIdx On successful return, meaning that the desired entry - exists, populated with the position of the entry. If - returning an -RED_ENOENT error, populated with the - position of the first available entry, or set to - DIR_INDEX_INVALID if the directory is full. Optional. - @param pulInode On successful return, populated with the inode number - that the name points to. Optional; may be `NULL`. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOENT @p pszName does not name an existing file or - directory. - @retval -RED_ENOTDIR @p pPInode is not a directory. - @retval -RED_EINVAL @p pPInode is not a mounted cached inode - structure; or @p pszName is not a valid name; or - @p pulEntryIdx is `NULL`. - @retval -RED_ENAMETOOLONG @p pszName is too long. -*/ -REDSTATUS RedDirEntryLookup( - CINODE *pPInode, - const char *pszName, - uint32_t *pulEntryIdx, - uint32_t *pulInode) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_MOUNTED(pPInode) || (pszName == NULL)) - { - ret = -RED_EINVAL; - } - else if(!pPInode->fDirectory) - { - ret = -RED_ENOTDIR; - } - else - { - uint32_t ulNameLen = RedNameLen(pszName); - - if(ulNameLen == 0U) - { - ret = -RED_EINVAL; - } - else if(ulNameLen > REDCONF_NAME_MAX) - { - ret = -RED_ENAMETOOLONG; - } - else - { - uint32_t ulIdx = 0U; - uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize); - uint32_t ulFreeIdx = DIR_INDEX_INVALID; /* Index of first free dirent. */ - - /* Loop over the directory blocks, searching each block for a - dirent that matches the given name. - */ - while((ret == 0) && (ulIdx < ulDirentCount)) - { - ret = RedInodeDataSeekAndRead(pPInode, ulIdx / DIRENTS_PER_BLOCK); - - if(ret == 0) - { - const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData); - uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - ulIdx); - uint32_t ulBlockIdx; - - for(ulBlockIdx = 0U; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++) - { - const DIRENT *pDirent = &pDirents[ulBlockIdx]; - - if(pDirent->ulInode != INODE_INVALID) - { - /* The name in the dirent will not be null - terminated if it is of the maximum length, so - use a bounded string compare and then make sure - there is nothing more to the name. - */ - if( (RedStrNCmp(pDirent->acName, pszName, ulNameLen) == 0) - && ((ulNameLen == REDCONF_NAME_MAX) || (pDirent->acName[ulNameLen] == '\0'))) - { - /* Found a matching dirent, stop and return its - information. - */ - if(pulInode != NULL) - { - *pulInode = pDirent->ulInode; - - #ifdef REDCONF_ENDIAN_SWAP - *pulInode = RedRev32(*pulInode); - #endif - } - - ulIdx += ulBlockIdx; - break; - } - } - else if(ulFreeIdx == DIR_INDEX_INVALID) - { - ulFreeIdx = ulIdx + ulBlockIdx; - } - else - { - /* The directory entry is free, but we already found a free one, so there's - nothing to do here. - */ - } - } - - if(ulBlockIdx < ulBlockLastIdx) - { - /* If we broke out of the for loop, we found a matching - dirent and can stop the search. - */ - break; - } - - ulIdx += ulBlockLastIdx; - } - else if(ret == -RED_ENODATA) - { - if(ulFreeIdx == DIR_INDEX_INVALID) - { - ulFreeIdx = ulIdx; - } - - ret = 0; - ulIdx += DIRENTS_PER_BLOCK; - } - else - { - /* Unexpected error, let the loop terminate, no action - here. - */ - } - } - - if(ret == 0) - { - /* If we made it all the way to the end of the directory - without stopping, then the given name does not exist in the - directory. - */ - if(ulIdx == ulDirentCount) - { - /* If the directory had no sparse dirents, then the first - free dirent is beyond the end of the directory. If the - directory is already the maximum size, then there is no - free dirent. - */ - if((ulFreeIdx == DIR_INDEX_INVALID) && (ulDirentCount < DIRENTS_MAX)) - { - ulFreeIdx = ulDirentCount; - } - - ulIdx = ulFreeIdx; - - ret = -RED_ENOENT; - } - - if(pulEntryIdx != NULL) - { - *pulEntryIdx = ulIdx; - } - } - } - } - - return ret; -} - - -#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1) -/** @brief Read the next entry from a directory, given a starting index. - - @param pPInode A pointer to the cached inode structure of the directory to - read from. - @param pulIdx On entry, the directory index to start reading from. On - successful return, populated with the directory index to use - for subsequent reads. On -RED_ENOENT return, populated with - the directory index immediately following the last valid - one. - @param pszName On successful return, populated with the name of the next - directory entry. Buffer must be at least - REDCONF_NAME_MAX + 1 in size, to store the maximum name - length plus a null terminator. - @param pulInode On successful return, populated with the inode number - pointed at by the next directory entry. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOENT There are no more entries in the directory. - @retval -RED_ENOTDIR @p pPInode is not a directory. - @retval -RED_EINVAL @p pPInode is not a mounted cached inode structure; - or @p pszName is `NULL`; or @p pulIdx is `NULL`; or - @p pulInode is `NULL`. -*/ -REDSTATUS RedDirEntryRead( - CINODE *pPInode, - uint32_t *pulIdx, - char *pszName, - uint32_t *pulInode) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_MOUNTED(pPInode) || (pulIdx == NULL) || (pszName == NULL) || (pulInode == NULL)) - { - ret = -RED_EINVAL; - } - else if(!pPInode->fDirectory) - { - ret = -RED_ENOTDIR; - } - else - { - uint32_t ulIdx = *pulIdx; - uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize); - - /* Starting either at the beginning of the directory or where we left - off, loop over the directory blocks, searching each block for a - non-sparse dirent to return as the next entry in the directory. - */ - while((ret == 0) && (ulIdx < ulDirentCount)) - { - uint32_t ulBlockOffset = ulIdx / DIRENTS_PER_BLOCK; - - ret = RedInodeDataSeekAndRead(pPInode, ulBlockOffset); - - if(ret == 0) - { - const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData); - uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - (ulBlockOffset * DIRENTS_PER_BLOCK)); - uint32_t ulBlockIdx; - - for(ulBlockIdx = ulIdx % DIRENTS_PER_BLOCK; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++) - { - if(pDirents[ulBlockIdx].ulInode != INODE_INVALID) - { - *pulIdx = ulIdx + 1U; - RedStrNCpy(pszName, pDirents[ulBlockIdx].acName, REDCONF_NAME_MAX); - pszName[REDCONF_NAME_MAX] = '\0'; - - *pulInode = pDirents[ulBlockIdx].ulInode; - - #ifdef REDCONF_ENDIAN_SWAP - *pulInode = RedRev32(*pulInode); - #endif - break; - } - - ulIdx++; - } - - if(ulBlockIdx < ulBlockLastIdx) - { - REDASSERT(ulIdx <= ulDirentCount); - break; - } - } - else if(ret == -RED_ENODATA) - { - ulIdx += DIRENTS_PER_BLOCK - (ulIdx % DIRENTS_PER_BLOCK); - ret = 0; - } - else - { - /* Unexpected error, loop will terminate; nothing else to do. - */ - } - - REDASSERT(ulIdx <= ulDirentCount); - } - - if((ret == 0) && (ulIdx >= ulDirentCount)) - { - *pulIdx = ulDirentCount; - ret = -RED_ENOENT; - } - } - - return ret; -} -#endif - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) -/** Rename a directory entry. - - @param pSrcPInode The inode of the directory containing @p pszSrcName. - @param pszSrcName The name of the directory entry to be renamed. - @param pSrcInode On successful return, populated with the inode of the - source entry. - @param pDstPInode The inode of the directory in which @p pszDstName will - be created or replaced. - @param pszDstName The name of the directory entry to be created or - replaced. - @param pDstInode On successful return, if the destination previously - existed, populated with the inode previously pointed to - by the destination. This may be the same as the source - inode. If the destination did not exist, populated with - INODE_INVALID. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EEXIST #REDCONF_RENAME_ATOMIC is false and the - destination name exists. - @retval -RED_EINVAL @p pSrcPInode is not a mounted dirty cached - inode structure; or @p pSrcInode is `NULL`; or - @p pszSrcName is not a valid name; or - @p pDstPInode is not a mounted dirty cached - inode structure; or @p pDstInode is `NULL`; or - @p pszDstName is not a valid name. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR The destination name exists and is a directory, - and the source name is a non-directory. - @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer - than #REDCONF_NAME_MAX. - @retval -RED_ENOENT The source name is not an existing entry; or - either @p pszSrcName or @p pszDstName point to - an empty string. - @retval -RED_ENOTDIR @p pSrcPInode is not a directory; or - @p pDstPInode is not a directory; or the source - name is a directory and the destination name is - a file. - @retval -RED_ENOTEMPTY The destination name is a directory which is not - empty. - @retval -RED_ENOSPC The file system does not have enough space to - extend the @p ulDstPInode directory. - @retval -RED_EROFS The directory to be removed resides on a - read-only file system. -*/ -REDSTATUS RedDirEntryRename( - CINODE *pSrcPInode, - const char *pszSrcName, - CINODE *pSrcInode, - CINODE *pDstPInode, - const char *pszDstName, - CINODE *pDstInode) -{ - REDSTATUS ret; - - if( !CINODE_IS_DIRTY(pSrcPInode) - || (pszSrcName == NULL) - || (pSrcInode == NULL) - || !CINODE_IS_DIRTY(pDstPInode) - || (pszDstName == NULL) - || (pDstInode == NULL)) - { - ret = -RED_EINVAL; - } - else if(!pSrcPInode->fDirectory || !pDstPInode->fDirectory) - { - ret = -RED_ENOTDIR; - } - else - { - uint32_t ulDstIdx = 0U; /* Init'd to quiet warnings. */ - uint32_t ulSrcIdx; - - /* Look up the source and destination names. - */ - ret = RedDirEntryLookup(pSrcPInode, pszSrcName, &ulSrcIdx, &pSrcInode->ulInode); - - if(ret == 0) - { - ret = RedDirEntryLookup(pDstPInode, pszDstName, &ulDstIdx, &pDstInode->ulInode); - - if(ret == -RED_ENOENT) - { - if(ulDstIdx == DIR_INDEX_INVALID) - { - ret = -RED_ENOSPC; - } - else - { - #if REDCONF_RENAME_ATOMIC == 1 - pDstInode->ulInode = INODE_INVALID; - #endif - ret = 0; - } - } - #if REDCONF_RENAME_ATOMIC == 0 - else if(ret == 0) - { - ret = -RED_EEXIST; - } - else - { - /* Nothing to do here, just propagate the error. - */ - } - #endif - } - - #if REDCONF_RENAME_ATOMIC == 1 - /* If both names point to the same inode, POSIX says to do nothing to - either name. - */ - if((ret == 0) && (pSrcInode->ulInode != pDstInode->ulInode)) - #else - if(ret == 0) - #endif - { - ret = RedInodeMount(pSrcInode, FTYPE_EITHER, true); - - #if REDCONF_RENAME_ATOMIC == 1 - if((ret == 0) && (pDstInode->ulInode != INODE_INVALID)) - { - /* Source and destination must be the same type (file/dir). - */ - ret = RedInodeMount(pDstInode, pSrcInode->fDirectory ? FTYPE_DIR : FTYPE_FILE, true); - - /* If renaming directories, the destination must be empty. - */ - if((ret == 0) && pDstInode->fDirectory && (pDstInode->pInodeBuf->ullSize > 0U)) - { - ret = -RED_ENOTEMPTY; - } - } - #endif - - /* If we are renaming a directory, make sure the rename isn't - cyclic (e.g., renaming "foo" into "foo/bar"). - */ - if((ret == 0) && pSrcInode->fDirectory) - { - ret = DirCyclicRenameCheck(pSrcInode->ulInode, pDstPInode); - } - - if(ret == 0) - { - ret = DirEntryWrite(pDstPInode, ulDstIdx, pSrcInode->ulInode, pszDstName, RedNameLen(pszDstName)); - } - - if(ret == 0) - { - ret = RedDirEntryDelete(pSrcPInode, ulSrcIdx); - - if(ret == -RED_ENOSPC) - { - REDSTATUS ret2; - - /* If there was not enough space to branch the parent - directory inode and data block containin the source - entry, revert destination directory entry to its - previous state. - */ - #if REDCONF_RENAME_ATOMIC == 1 - if(pDstInode->ulInode != INODE_INVALID) - { - ret2 = DirEntryWrite(pDstPInode, ulDstIdx, pDstInode->ulInode, pszDstName, RedNameLen(pszDstName)); - } - else - #endif - { - ret2 = RedDirEntryDelete(pDstPInode, ulDstIdx); - } - - if(ret2 != 0) - { - ret = ret2; - CRITICAL_ERROR(); - } - } - } - - if(ret == 0) - { - pSrcInode->pInodeBuf->ulPInode = pDstPInode->ulInode; - } - } - } - - return ret; -} - - -/** @brief Check for a cyclic rename. - - A cyclic rename is renaming a directory into a subdirectory of itself. For - example, renaming "a" into "a/b/c/d" is cyclic. These renames must not be - allowed since they would corrupt the directory tree. - - @param ulSrcInode The inode number of the directory being renamed. - @param pDstPInode A pointer to the cached inode structure of the directory - into which the source is being renamed. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL The rename is cyclic; or invalid parameters. - @retval -RED_ENOTDIR @p pDstPInode is not a directory. -*/ -static REDSTATUS DirCyclicRenameCheck( - uint32_t ulSrcInode, - const CINODE *pDstPInode) -{ - REDSTATUS ret = 0; - - if(!INODE_IS_VALID(ulSrcInode) || !CINODE_IS_MOUNTED(pDstPInode)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(ulSrcInode == pDstPInode->ulInode) - { - ret = -RED_EINVAL; - } - else if(!pDstPInode->fDirectory) - { - ret = -RED_ENOTDIR; - } - else - { - CINODE NextParent; - /* Used to prevent infinite loop in case of corrupted directory - structure. - */ - uint32_t ulIteration = 0U; - - NextParent.ulInode = pDstPInode->pInodeBuf->ulPInode; - - while( (NextParent.ulInode != ulSrcInode) - && (NextParent.ulInode != INODE_ROOTDIR) - && (NextParent.ulInode != INODE_INVALID) - && (ulIteration < gpRedVolConf->ulInodeCount)) - { - ret = RedInodeMount(&NextParent, FTYPE_DIR, false); - if(ret != 0) - { - break; - } - - NextParent.ulInode = NextParent.pInodeBuf->ulPInode; - - RedInodePut(&NextParent, 0U); - - ulIteration++; - } - - if((ret == 0) && (ulIteration == gpRedVolConf->ulInodeCount)) - { - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - - if((ret == 0) && (ulSrcInode == NextParent.ulInode)) - { - ret = -RED_EINVAL; - } - } - - return ret; -} -#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) */ - - -#if REDCONF_READ_ONLY == 0 -/** @brief Update the contents of a directory entry. - - @param pPInode A pointer to the cached inode structure of the directory - whose entry is being written. - @param ulIdx The index of the directory entry to write. - @param ulInode The inode number the directory entry is to point at. - @param pszName The name of the directory entry. - @param ulNameLen The length of @p pszName. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC There is not enough space on the volume to write the - directory entry. - @retval -RED_ENOTDIR @p pPInode is not a directory. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS DirEntryWrite( - CINODE *pPInode, - uint32_t ulIdx, - uint32_t ulInode, - const char *pszName, - uint32_t ulNameLen) -{ - REDSTATUS ret; - - if( !CINODE_IS_DIRTY(pPInode) - || (ulIdx >= DIRENTS_MAX) - || (!INODE_IS_VALID(ulInode) && (ulInode != INODE_INVALID)) - || (pszName == NULL) - || (ulNameLen > REDCONF_NAME_MAX) - || ((ulNameLen == 0U) != (ulInode == INODE_INVALID))) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(!pPInode->fDirectory) - { - ret = -RED_ENOTDIR; - } - else - { - uint64_t ullOffset = DirEntryIndexToOffset(ulIdx); - uint32_t ulLen = DIRENT_SIZE; - static DIRENT de; - - RedMemSet(&de, 0U, sizeof(de)); - - de.ulInode = ulInode; - - #ifdef REDCONF_ENDIAN_SWAP - de.ulInode = RedRev32(de.ulInode); - #endif - - RedStrNCpy(de.acName, pszName, ulNameLen); - - ret = RedInodeDataWrite(pPInode, ullOffset, &ulLen, &de); - } - - return ret; -} - - -/** @brief Convert a directory entry index to a byte offset. - - @param ulIdx Directory entry index. - - @return Byte offset in the directory corresponding with ulIdx. -*/ -static uint64_t DirEntryIndexToOffset( - uint32_t ulIdx) -{ - uint32_t ulBlock = ulIdx / DIRENTS_PER_BLOCK; - uint32_t ulOffsetInBlock = ulIdx % DIRENTS_PER_BLOCK; - uint64_t ullOffset; - - REDASSERT(ulIdx < DIRENTS_MAX); - - ullOffset = (uint64_t)ulBlock << BLOCK_SIZE_P2; - ullOffset += (uint64_t)ulOffsetInBlock * DIRENT_SIZE; - - return ullOffset; -} -#endif /* REDCONF_READ_ONLY == 0 */ - - -/** @brief Convert a byte offset to a directory entry index. - - @param ullOffset Byte offset in the directory. - - @return Directory entry index corresponding with @p ullOffset. -*/ -static uint32_t DirOffsetToEntryIndex( - uint64_t ullOffset) -{ - uint32_t ulIdx; - - REDASSERT(ullOffset < INODE_SIZE_MAX); - REDASSERT(((uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) % DIRENT_SIZE) == 0U); - - /* Avoid doing any 64-bit divides. - */ - ulIdx = (uint32_t)(ullOffset >> BLOCK_SIZE_P2) * DIRENTS_PER_BLOCK; - ulIdx += (uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) / DIRENT_SIZE; - - return ulIdx; -} - - -#endif /* REDCONF_API_POSIX == 1 */ - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements directory operations. + */ +#include + +#if REDCONF_API_POSIX == 1 + + #include + + + #define DIR_INDEX_INVALID UINT32_MAX + + #if ( REDCONF_NAME_MAX % 4U ) != 0U + #define DIRENT_PADDING ( 4U - ( REDCONF_NAME_MAX % 4U ) ) + #else + #define DIRENT_PADDING ( 0U ) + #endif + #define DIRENT_SIZE ( 4U + REDCONF_NAME_MAX + DIRENT_PADDING ) + #define DIRENTS_PER_BLOCK ( REDCONF_BLOCK_SIZE / DIRENT_SIZE ) + #define DIRENTS_MAX ( uint32_t ) REDMIN( UINT32_MAX, UINT64_SUFFIX( 1 ) * INODE_DATA_BLOCKS * DIRENTS_PER_BLOCK ) + + +/** @brief On-disk directory entry. + */ + typedef struct + { + /** The inode number that the directory entry points at. If the directory + * entry is available, this holds INODE_INVALID. + */ + uint32_t ulInode; + + /** The name of the directory entry. For names shorter than + * REDCONF_NAME_MAX, unused bytes in the array are zeroed. For names of + * the maximum length, the string is not null terminated. + */ + char acName[ REDCONF_NAME_MAX ]; + + #if DIRENT_PADDING > 0U + + /** Unused padding so that ulInode is always aligned on a four-byte + * boundary. + */ + uint8_t abPadding[ DIRENT_PADDING ]; + #endif + } DIRENT; + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RENAME == 1 ) + static REDSTATUS DirCyclicRenameCheck( uint32_t ulSrcInode, + const CINODE * pDstPInode ); + #endif + #if REDCONF_READ_ONLY == 0 + static REDSTATUS DirEntryWrite( CINODE * pPInode, + uint32_t ulIdx, + uint32_t ulInode, + const char * pszName, + uint32_t ulNameLen ); + static uint64_t DirEntryIndexToOffset( uint32_t ulIdx ); + #endif + static uint32_t DirOffsetToEntryIndex( uint64_t ullOffset ); + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Create a new entry in a directory. + * + * @param pPInode A pointer to the cached inode structure of the directory + * to which the new entry will be added. + * @param pszName The name to be given to the new entry, terminated by a + * null or a path separator. + * @param ulInode The inode number the new name will point at. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC There is not enough space on the volume to + * create the new directory entry; or the directory + * is full. + * @retval -RED_ENOTDIR @p pPInode is not a directory. + * @retval -RED_ENAMETOOLONG @p pszName is too long. + * @retval -RED_EEXIST @p pszName already exists in @p ulPInode. + * @retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode + * structure; or @p pszName is not a valid name. + */ + REDSTATUS RedDirEntryCreate( CINODE * pPInode, + const char * pszName, + uint32_t ulInode ) + { + REDSTATUS ret; + + if( !CINODE_IS_DIRTY( pPInode ) || ( pszName == NULL ) || !INODE_IS_VALID( ulInode ) ) + { + ret = -RED_EINVAL; + } + else if( !pPInode->fDirectory ) + { + ret = -RED_ENOTDIR; + } + else + { + uint32_t ulNameLen = RedNameLen( pszName ); + + if( ulNameLen == 0U ) + { + ret = -RED_EINVAL; + } + else if( ulNameLen > REDCONF_NAME_MAX ) + { + ret = -RED_ENAMETOOLONG; + } + else + { + uint32_t ulEntryIdx; + + ret = RedDirEntryLookup( pPInode, pszName, &ulEntryIdx, NULL ); + + if( ret == 0 ) + { + ret = -RED_EEXIST; + } + else if( ret == -RED_ENOENT ) + { + if( ulEntryIdx == DIR_INDEX_INVALID ) + { + ret = -RED_ENOSPC; + } + else + { + ret = 0; + } + } + else + { + /* Unexpected error, no action. + */ + } + + if( ret == 0 ) + { + ret = DirEntryWrite( pPInode, ulEntryIdx, ulInode, pszName, ulNameLen ); + } + } + } + + return ret; + } + #endif /* REDCONF_READ_ONLY == 0 */ + + + #if DELETE_SUPPORTED + +/** @brief Delete an existing directory entry. + * + * @param pPInode A pointer to the cached inode structure of the directory + * containing the entry to be deleted. + * @param ulDeleteIdx Position within the directory of the entry to be + * deleted. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC The file system does not have enough space to modify + * the parent directory to perform the deletion. + * @retval -RED_ENOTDIR @p pPInode is not a directory. + * @retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode + * structure; or @p ulIdx is out of range. + */ + REDSTATUS RedDirEntryDelete( CINODE * pPInode, + uint32_t ulDeleteIdx ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_DIRTY( pPInode ) || ( ulDeleteIdx >= DIRENTS_MAX ) ) + { + ret = -RED_EINVAL; + } + else if( !pPInode->fDirectory ) + { + ret = -RED_ENOTDIR; + } + else if( ( DirEntryIndexToOffset( ulDeleteIdx ) + DIRENT_SIZE ) == pPInode->pInodeBuf->ullSize ) + { + /* Start searching one behind the index to be deleted. + */ + uint32_t ulTruncIdx = ulDeleteIdx - 1U; + bool fDone = false; + + /* We are deleting the last dirent in the directory, so search + * backwards to find the last populated dirent, allowing us to truncate + * the directory to that point. + */ + while( ( ret == 0 ) && ( ulTruncIdx != UINT32_MAX ) && !fDone ) + { + ret = RedInodeDataSeekAndRead( pPInode, ulTruncIdx / DIRENTS_PER_BLOCK ); + + if( ret == 0 ) + { + const DIRENT * pDirents = CAST_CONST_DIRENT_PTR( pPInode->pbData ); + uint32_t ulBlockIdx = ulTruncIdx % DIRENTS_PER_BLOCK; + + do + { + if( pDirents[ ulBlockIdx ].ulInode != INODE_INVALID ) + { + fDone = true; + break; + } + + ulTruncIdx--; + ulBlockIdx--; + } while( ulBlockIdx != UINT32_MAX ); + } + else if( ret == -RED_ENODATA ) + { + ret = 0; + + REDASSERT( ( ulTruncIdx % DIRENTS_PER_BLOCK ) == 0U ); + ulTruncIdx -= DIRENTS_PER_BLOCK; + } + else + { + /* Unexpected error, loop will terminate; nothing else + * to be done. + */ + } + } + + /* Currently ulTruncIdx represents the last valid dirent index, or + * UINT32_MAX if the directory is now empty. Increment it so that it + * represents the first invalid entry, which will be truncated. + */ + ulTruncIdx++; + + /* Truncate the directory, deleting the requested entry and any empty + * dirents at the end of the directory. + */ + if( ret == 0 ) + { + ret = RedInodeDataTruncate( pPInode, DirEntryIndexToOffset( ulTruncIdx ) ); + } + } + else + { + /* The dirent to delete is not the last entry in the directory, so just + * zero it. + */ + ret = DirEntryWrite( pPInode, ulDeleteIdx, INODE_INVALID, "", 0U ); + } + + return ret; + } + #endif /* DELETE_SUPPORTED */ + + +/** @brief Perform a case-sensitive search of a directory for a given name. + * + * If found, then position of the entry within the directory and the inode + * number it points to are returned. As an optimization for directory entry + * creation, in the case where the requested entry does not exist, the position + * of the first available (unused) entry is returned. + * + * @param pPInode A pointer to the cached inode structure of the directory + * to search. + * @param pszName The name of the desired entry, terminated by either a + * null or a path separator. + * @param pulEntryIdx On successful return, meaning that the desired entry + * exists, populated with the position of the entry. If + * returning an -RED_ENOENT error, populated with the + * position of the first available entry, or set to + * DIR_INDEX_INVALID if the directory is full. Optional. + * @param pulInode On successful return, populated with the inode number + * that the name points to. Optional; may be `NULL`. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOENT @p pszName does not name an existing file or + * directory. + * @retval -RED_ENOTDIR @p pPInode is not a directory. + * @retval -RED_EINVAL @p pPInode is not a mounted cached inode + * structure; or @p pszName is not a valid name; or + * @p pulEntryIdx is `NULL`. + * @retval -RED_ENAMETOOLONG @p pszName is too long. + */ + REDSTATUS RedDirEntryLookup( CINODE * pPInode, + const char * pszName, + uint32_t * pulEntryIdx, + uint32_t * pulInode ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_MOUNTED( pPInode ) || ( pszName == NULL ) ) + { + ret = -RED_EINVAL; + } + else if( !pPInode->fDirectory ) + { + ret = -RED_ENOTDIR; + } + else + { + uint32_t ulNameLen = RedNameLen( pszName ); + + if( ulNameLen == 0U ) + { + ret = -RED_EINVAL; + } + else if( ulNameLen > REDCONF_NAME_MAX ) + { + ret = -RED_ENAMETOOLONG; + } + else + { + uint32_t ulIdx = 0U; + uint32_t ulDirentCount = DirOffsetToEntryIndex( pPInode->pInodeBuf->ullSize ); + uint32_t ulFreeIdx = DIR_INDEX_INVALID; /* Index of first free dirent. */ + + /* Loop over the directory blocks, searching each block for a + * dirent that matches the given name. + */ + while( ( ret == 0 ) && ( ulIdx < ulDirentCount ) ) + { + ret = RedInodeDataSeekAndRead( pPInode, ulIdx / DIRENTS_PER_BLOCK ); + + if( ret == 0 ) + { + const DIRENT * pDirents = CAST_CONST_DIRENT_PTR( pPInode->pbData ); + uint32_t ulBlockLastIdx = REDMIN( DIRENTS_PER_BLOCK, ulDirentCount - ulIdx ); + uint32_t ulBlockIdx; + + for( ulBlockIdx = 0U; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++ ) + { + const DIRENT * pDirent = &pDirents[ ulBlockIdx ]; + + if( pDirent->ulInode != INODE_INVALID ) + { + /* The name in the dirent will not be null + * terminated if it is of the maximum length, so + * use a bounded string compare and then make sure + * there is nothing more to the name. + */ + if( ( RedStrNCmp( pDirent->acName, pszName, ulNameLen ) == 0 ) && + ( ( ulNameLen == REDCONF_NAME_MAX ) || ( pDirent->acName[ ulNameLen ] == '\0' ) ) ) + { + /* Found a matching dirent, stop and return its + * information. + */ + if( pulInode != NULL ) + { + *pulInode = pDirent->ulInode; + + #ifdef REDCONF_ENDIAN_SWAP + *pulInode = RedRev32( *pulInode ); + #endif + } + + ulIdx += ulBlockIdx; + break; + } + } + else if( ulFreeIdx == DIR_INDEX_INVALID ) + { + ulFreeIdx = ulIdx + ulBlockIdx; + } + else + { + /* The directory entry is free, but we already found a free one, so there's + * nothing to do here. + */ + } + } + + if( ulBlockIdx < ulBlockLastIdx ) + { + /* If we broke out of the for loop, we found a matching + * dirent and can stop the search. + */ + break; + } + + ulIdx += ulBlockLastIdx; + } + else if( ret == -RED_ENODATA ) + { + if( ulFreeIdx == DIR_INDEX_INVALID ) + { + ulFreeIdx = ulIdx; + } + + ret = 0; + ulIdx += DIRENTS_PER_BLOCK; + } + else + { + /* Unexpected error, let the loop terminate, no action + * here. + */ + } + } + + if( ret == 0 ) + { + /* If we made it all the way to the end of the directory + * without stopping, then the given name does not exist in the + * directory. + */ + if( ulIdx == ulDirentCount ) + { + /* If the directory had no sparse dirents, then the first + * free dirent is beyond the end of the directory. If the + * directory is already the maximum size, then there is no + * free dirent. + */ + if( ( ulFreeIdx == DIR_INDEX_INVALID ) && ( ulDirentCount < DIRENTS_MAX ) ) + { + ulFreeIdx = ulDirentCount; + } + + ulIdx = ulFreeIdx; + + ret = -RED_ENOENT; + } + + if( pulEntryIdx != NULL ) + { + *pulEntryIdx = ulIdx; + } + } + } + } + + return ret; + } + + + #if ( REDCONF_API_POSIX_READDIR == 1 ) || ( REDCONF_CHECKER == 1 ) + +/** @brief Read the next entry from a directory, given a starting index. + * + * @param pPInode A pointer to the cached inode structure of the directory to + * read from. + * @param pulIdx On entry, the directory index to start reading from. On + * successful return, populated with the directory index to use + * for subsequent reads. On -RED_ENOENT return, populated with + * the directory index immediately following the last valid + * one. + * @param pszName On successful return, populated with the name of the next + * directory entry. Buffer must be at least + * REDCONF_NAME_MAX + 1 in size, to store the maximum name + * length plus a null terminator. + * @param pulInode On successful return, populated with the inode number + * pointed at by the next directory entry. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOENT There are no more entries in the directory. + * @retval -RED_ENOTDIR @p pPInode is not a directory. + * @retval -RED_EINVAL @p pPInode is not a mounted cached inode structure; + * or @p pszName is `NULL`; or @p pulIdx is `NULL`; or + * @p pulInode is `NULL`. + */ + REDSTATUS RedDirEntryRead( CINODE * pPInode, + uint32_t * pulIdx, + char * pszName, + uint32_t * pulInode ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_MOUNTED( pPInode ) || ( pulIdx == NULL ) || ( pszName == NULL ) || ( pulInode == NULL ) ) + { + ret = -RED_EINVAL; + } + else if( !pPInode->fDirectory ) + { + ret = -RED_ENOTDIR; + } + else + { + uint32_t ulIdx = *pulIdx; + uint32_t ulDirentCount = DirOffsetToEntryIndex( pPInode->pInodeBuf->ullSize ); + + /* Starting either at the beginning of the directory or where we left + * off, loop over the directory blocks, searching each block for a + * non-sparse dirent to return as the next entry in the directory. + */ + while( ( ret == 0 ) && ( ulIdx < ulDirentCount ) ) + { + uint32_t ulBlockOffset = ulIdx / DIRENTS_PER_BLOCK; + + ret = RedInodeDataSeekAndRead( pPInode, ulBlockOffset ); + + if( ret == 0 ) + { + const DIRENT * pDirents = CAST_CONST_DIRENT_PTR( pPInode->pbData ); + uint32_t ulBlockLastIdx = REDMIN( DIRENTS_PER_BLOCK, ulDirentCount - ( ulBlockOffset * DIRENTS_PER_BLOCK ) ); + uint32_t ulBlockIdx; + + for( ulBlockIdx = ulIdx % DIRENTS_PER_BLOCK; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++ ) + { + if( pDirents[ ulBlockIdx ].ulInode != INODE_INVALID ) + { + *pulIdx = ulIdx + 1U; + RedStrNCpy( pszName, pDirents[ ulBlockIdx ].acName, REDCONF_NAME_MAX ); + pszName[ REDCONF_NAME_MAX ] = '\0'; + + *pulInode = pDirents[ ulBlockIdx ].ulInode; + + #ifdef REDCONF_ENDIAN_SWAP + *pulInode = RedRev32( *pulInode ); + #endif + break; + } + + ulIdx++; + } + + if( ulBlockIdx < ulBlockLastIdx ) + { + REDASSERT( ulIdx <= ulDirentCount ); + break; + } + } + else if( ret == -RED_ENODATA ) + { + ulIdx += DIRENTS_PER_BLOCK - ( ulIdx % DIRENTS_PER_BLOCK ); + ret = 0; + } + else + { + /* Unexpected error, loop will terminate; nothing else to do. + */ + } + + REDASSERT( ulIdx <= ulDirentCount ); + } + + if( ( ret == 0 ) && ( ulIdx >= ulDirentCount ) ) + { + *pulIdx = ulDirentCount; + ret = -RED_ENOENT; + } + } + + return ret; + } + #endif /* if ( REDCONF_API_POSIX_READDIR == 1 ) || ( REDCONF_CHECKER == 1 ) */ + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RENAME == 1 ) + +/** Rename a directory entry. + * + * @param pSrcPInode The inode of the directory containing @p pszSrcName. + * @param pszSrcName The name of the directory entry to be renamed. + * @param pSrcInode On successful return, populated with the inode of the + * source entry. + * @param pDstPInode The inode of the directory in which @p pszDstName will + * be created or replaced. + * @param pszDstName The name of the directory entry to be created or + * replaced. + * @param pDstInode On successful return, if the destination previously + * existed, populated with the inode previously pointed to + * by the destination. This may be the same as the source + * inode. If the destination did not exist, populated with + * INODE_INVALID. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EEXIST #REDCONF_RENAME_ATOMIC is false and the + * destination name exists. + * @retval -RED_EINVAL @p pSrcPInode is not a mounted dirty cached + * inode structure; or @p pSrcInode is `NULL`; or + * @p pszSrcName is not a valid name; or + * @p pDstPInode is not a mounted dirty cached + * inode structure; or @p pDstInode is `NULL`; or + * @p pszDstName is not a valid name. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR The destination name exists and is a directory, + * and the source name is a non-directory. + * @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer + * than #REDCONF_NAME_MAX. + * @retval -RED_ENOENT The source name is not an existing entry; or + * either @p pszSrcName or @p pszDstName point to + * an empty string. + * @retval -RED_ENOTDIR @p pSrcPInode is not a directory; or + * @p pDstPInode is not a directory; or the source + * name is a directory and the destination name is + * a file. + * @retval -RED_ENOTEMPTY The destination name is a directory which is not + * empty. + * @retval -RED_ENOSPC The file system does not have enough space to + * extend the @p ulDstPInode directory. + * @retval -RED_EROFS The directory to be removed resides on a + * read-only file system. + */ + REDSTATUS RedDirEntryRename( CINODE * pSrcPInode, + const char * pszSrcName, + CINODE * pSrcInode, + CINODE * pDstPInode, + const char * pszDstName, + CINODE * pDstInode ) + { + REDSTATUS ret; + + if( !CINODE_IS_DIRTY( pSrcPInode ) || + ( pszSrcName == NULL ) || + ( pSrcInode == NULL ) || + !CINODE_IS_DIRTY( pDstPInode ) || + ( pszDstName == NULL ) || + ( pDstInode == NULL ) ) + { + ret = -RED_EINVAL; + } + else if( !pSrcPInode->fDirectory || !pDstPInode->fDirectory ) + { + ret = -RED_ENOTDIR; + } + else + { + uint32_t ulDstIdx = 0U; /* Init'd to quiet warnings. */ + uint32_t ulSrcIdx; + + /* Look up the source and destination names. + */ + ret = RedDirEntryLookup( pSrcPInode, pszSrcName, &ulSrcIdx, &pSrcInode->ulInode ); + + if( ret == 0 ) + { + ret = RedDirEntryLookup( pDstPInode, pszDstName, &ulDstIdx, &pDstInode->ulInode ); + + if( ret == -RED_ENOENT ) + { + if( ulDstIdx == DIR_INDEX_INVALID ) + { + ret = -RED_ENOSPC; + } + else + { + #if REDCONF_RENAME_ATOMIC == 1 + pDstInode->ulInode = INODE_INVALID; + #endif + ret = 0; + } + } + + #if REDCONF_RENAME_ATOMIC == 0 + else if( ret == 0 ) + { + ret = -RED_EEXIST; + } + else + { + /* Nothing to do here, just propagate the error. + */ + } + #endif + } + + #if REDCONF_RENAME_ATOMIC == 1 + + /* If both names point to the same inode, POSIX says to do nothing to + * either name. + */ + if( ( ret == 0 ) && ( pSrcInode->ulInode != pDstInode->ulInode ) ) + #else + if( ret == 0 ) + #endif + { + ret = RedInodeMount( pSrcInode, FTYPE_EITHER, true ); + + #if REDCONF_RENAME_ATOMIC == 1 + if( ( ret == 0 ) && ( pDstInode->ulInode != INODE_INVALID ) ) + { + /* Source and destination must be the same type (file/dir). + */ + ret = RedInodeMount( pDstInode, pSrcInode->fDirectory ? FTYPE_DIR : FTYPE_FILE, true ); + + /* If renaming directories, the destination must be empty. + */ + if( ( ret == 0 ) && pDstInode->fDirectory && ( pDstInode->pInodeBuf->ullSize > 0U ) ) + { + ret = -RED_ENOTEMPTY; + } + } + #endif /* if REDCONF_RENAME_ATOMIC == 1 */ + + /* If we are renaming a directory, make sure the rename isn't + * cyclic (e.g., renaming "foo" into "foo/bar"). + */ + if( ( ret == 0 ) && pSrcInode->fDirectory ) + { + ret = DirCyclicRenameCheck( pSrcInode->ulInode, pDstPInode ); + } + + if( ret == 0 ) + { + ret = DirEntryWrite( pDstPInode, ulDstIdx, pSrcInode->ulInode, pszDstName, RedNameLen( pszDstName ) ); + } + + if( ret == 0 ) + { + ret = RedDirEntryDelete( pSrcPInode, ulSrcIdx ); + + if( ret == -RED_ENOSPC ) + { + REDSTATUS ret2; + + /* If there was not enough space to branch the parent + * directory inode and data block containing the source + * entry, revert destination directory entry to its + * previous state. + */ + #if REDCONF_RENAME_ATOMIC == 1 + if( pDstInode->ulInode != INODE_INVALID ) + { + ret2 = DirEntryWrite( pDstPInode, ulDstIdx, pDstInode->ulInode, pszDstName, RedNameLen( pszDstName ) ); + } + else + #endif + { + ret2 = RedDirEntryDelete( pDstPInode, ulDstIdx ); + } + + if( ret2 != 0 ) + { + ret = ret2; + CRITICAL_ERROR(); + } + } + } + + if( ret == 0 ) + { + pSrcInode->pInodeBuf->ulPInode = pDstPInode->ulInode; + } + } + } + + return ret; + } + + +/** @brief Check for a cyclic rename. + * + * A cyclic rename is renaming a directory into a subdirectory of itself. For + * example, renaming "a" into "a/b/c/d" is cyclic. These renames must not be + * allowed since they would corrupt the directory tree. + * + * @param ulSrcInode The inode number of the directory being renamed. + * @param pDstPInode A pointer to the cached inode structure of the directory + * into which the source is being renamed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL The rename is cyclic; or invalid parameters. + * @retval -RED_ENOTDIR @p pDstPInode is not a directory. + */ + static REDSTATUS DirCyclicRenameCheck( uint32_t ulSrcInode, + const CINODE * pDstPInode ) + { + REDSTATUS ret = 0; + + if( !INODE_IS_VALID( ulSrcInode ) || !CINODE_IS_MOUNTED( pDstPInode ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( ulSrcInode == pDstPInode->ulInode ) + { + ret = -RED_EINVAL; + } + else if( !pDstPInode->fDirectory ) + { + ret = -RED_ENOTDIR; + } + else + { + CINODE NextParent; + + /* Used to prevent infinite loop in case of corrupted directory + * structure. + */ + uint32_t ulIteration = 0U; + + NextParent.ulInode = pDstPInode->pInodeBuf->ulPInode; + + while( ( NextParent.ulInode != ulSrcInode ) && + ( NextParent.ulInode != INODE_ROOTDIR ) && + ( NextParent.ulInode != INODE_INVALID ) && + ( ulIteration < gpRedVolConf->ulInodeCount ) ) + { + ret = RedInodeMount( &NextParent, FTYPE_DIR, false ); + + if( ret != 0 ) + { + break; + } + + NextParent.ulInode = NextParent.pInodeBuf->ulPInode; + + RedInodePut( &NextParent, 0U ); + + ulIteration++; + } + + if( ( ret == 0 ) && ( ulIteration == gpRedVolConf->ulInodeCount ) ) + { + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + + if( ( ret == 0 ) && ( ulSrcInode == NextParent.ulInode ) ) + { + ret = -RED_EINVAL; + } + } + + return ret; + } + #endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) */ + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Update the contents of a directory entry. + * + * @param pPInode A pointer to the cached inode structure of the directory + * whose entry is being written. + * @param ulIdx The index of the directory entry to write. + * @param ulInode The inode number the directory entry is to point at. + * @param pszName The name of the directory entry. + * @param ulNameLen The length of @p pszName. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC There is not enough space on the volume to write the + * directory entry. + * @retval -RED_ENOTDIR @p pPInode is not a directory. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS DirEntryWrite( CINODE * pPInode, + uint32_t ulIdx, + uint32_t ulInode, + const char * pszName, + uint32_t ulNameLen ) + { + REDSTATUS ret; + + if( !CINODE_IS_DIRTY( pPInode ) || + ( ulIdx >= DIRENTS_MAX ) || + ( !INODE_IS_VALID( ulInode ) && ( ulInode != INODE_INVALID ) ) || + ( pszName == NULL ) || + ( ulNameLen > REDCONF_NAME_MAX ) || + ( ( ulNameLen == 0U ) != ( ulInode == INODE_INVALID ) ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( !pPInode->fDirectory ) + { + ret = -RED_ENOTDIR; + } + else + { + uint64_t ullOffset = DirEntryIndexToOffset( ulIdx ); + uint32_t ulLen = DIRENT_SIZE; + static DIRENT de; + + RedMemSet( &de, 0U, sizeof( de ) ); + + de.ulInode = ulInode; + + #ifdef REDCONF_ENDIAN_SWAP + de.ulInode = RedRev32( de.ulInode ); + #endif + + RedStrNCpy( de.acName, pszName, ulNameLen ); + + ret = RedInodeDataWrite( pPInode, ullOffset, &ulLen, &de ); + } + + return ret; + } + + +/** @brief Convert a directory entry index to a byte offset. + * + * @param ulIdx Directory entry index. + * + * @return Byte offset in the directory corresponding with ulIdx. + */ + static uint64_t DirEntryIndexToOffset( uint32_t ulIdx ) + { + uint32_t ulBlock = ulIdx / DIRENTS_PER_BLOCK; + uint32_t ulOffsetInBlock = ulIdx % DIRENTS_PER_BLOCK; + uint64_t ullOffset; + + REDASSERT( ulIdx < DIRENTS_MAX ); + + ullOffset = ( uint64_t ) ulBlock << BLOCK_SIZE_P2; + ullOffset += ( uint64_t ) ulOffsetInBlock * DIRENT_SIZE; + + return ullOffset; + } + #endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Convert a byte offset to a directory entry index. + * + * @param ullOffset Byte offset in the directory. + * + * @return Directory entry index corresponding with @p ullOffset. + */ + static uint32_t DirOffsetToEntryIndex( uint64_t ullOffset ) + { + uint32_t ulIdx; + + REDASSERT( ullOffset < INODE_SIZE_MAX ); + REDASSERT( ( ( uint32_t ) ( ullOffset & ( REDCONF_BLOCK_SIZE - 1U ) ) % DIRENT_SIZE ) == 0U ); + + /* Avoid doing any 64-bit divides. + */ + ulIdx = ( uint32_t ) ( ullOffset >> BLOCK_SIZE_P2 ) * DIRENTS_PER_BLOCK; + ulIdx += ( uint32_t ) ( ullOffset & ( REDCONF_BLOCK_SIZE - 1U ) ) / DIRENT_SIZE; + + return ulIdx; + } + + +#endif /* REDCONF_API_POSIX == 1 */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/format.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/format.c index 8fe8f14a8..c5a6934c5 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/format.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/format.c @@ -1,235 +1,240 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements the Reliance Edge file system formatter. -*/ -#include -#include -#include - -#if FORMAT_SUPPORTED - - -/** @brief Format a file system volume. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBUSY Volume is mounted. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedVolFormat(void) -{ - REDSTATUS ret; - - if(gpRedVolume->fMounted) - { - ret = -RED_EBUSY; - } - else - { - ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR); - } - - if(ret == 0) - { - MASTERBLOCK *pMB; - REDSTATUS ret2; - - /* Overwrite the master block with zeroes, so that if formatting is - interrupted, the volume will not be mountable. - */ - ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_NEW | BFLAG_DIRTY, CAST_VOID_PTR_PTR(&pMB)); - - if(ret == 0) - { - ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U); - - RedBufferDiscard(pMB); - } - - if(ret == 0) - { - ret = RedIoFlush(gbRedVolNum); - } - - #if REDCONF_IMAP_EXTERNAL == 1 - if((ret == 0) && !gpRedCoreVol->fImapInline) - { - uint32_t ulImapBlock; - uint32_t ulImapBlockLimit = gpRedCoreVol->ulImapStartBN + (gpRedCoreVol->ulImapNodeCount * 2U); - uint16_t uImapFlags = (uint16_t)((uint32_t)BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY); - - /* Technically it is only necessary to create one copy of each imap - node (the copy the metaroot points at), but creating them both - avoids headaches during disk image analysis from stale imaps - left over from previous formats. - */ - for(ulImapBlock = gpRedCoreVol->ulImapStartBN; ulImapBlock < ulImapBlockLimit; ulImapBlock++) - { - IMAPNODE *pImap; - - ret = RedBufferGet(ulImapBlock, uImapFlags, CAST_VOID_PTR_PTR(&pImap)); - if(ret != 0) - { - break; - } - - RedBufferPut(pImap); - } - } - #endif - - /* Write the first metaroot. - */ - if(ret == 0) - { - RedMemSet(gpRedMR, 0U, sizeof(*gpRedMR)); - - gpRedMR->ulFreeBlocks = gpRedVolume->ulBlocksAllocable; - #if REDCONF_API_POSIX == 1 - gpRedMR->ulFreeInodes = gpRedVolConf->ulInodeCount; - #endif - gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN; - - /* The branched flag is typically set automatically when bits in - the imap change. It is set here explicitly because the imap has - only been initialized, not changed. - */ - gpRedCoreVol->fBranched = true; - - ret = RedVolTransact(); - } - - #if REDCONF_API_POSIX == 1 - /* Create the root directory. - */ - if(ret == 0) - { - CINODE rootdir; - - rootdir.ulInode = INODE_ROOTDIR; - ret = RedInodeCreate(&rootdir, INODE_INVALID, RED_S_IFDIR); - - if(ret == 0) - { - RedInodePut(&rootdir, 0U); - } - } - #endif - - #if REDCONF_API_FSE == 1 - /* The FSE API does not support creating or deletes files, so all the - inodes are created during setup. - */ - if(ret == 0) - { - uint32_t ulInodeIdx; - - for(ulInodeIdx = 0U; ulInodeIdx < gpRedVolConf->ulInodeCount; ulInodeIdx++) - { - CINODE ino; - - ino.ulInode = INODE_FIRST_FREE + ulInodeIdx; - ret = RedInodeCreate(&ino, INODE_INVALID, RED_S_IFREG); - - if(ret == 0) - { - RedInodePut(&ino, 0U); - } - } - } - #endif - - /* Write the second metaroot. - */ - if(ret == 0) - { - ret = RedVolTransact(); - } - - /* Populate and write out the master block. - */ - if(ret == 0) - { - ret = RedBufferGet(BLOCK_NUM_MASTER, (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY), CAST_VOID_PTR_PTR(&pMB)); - } - - if(ret == 0) - { - pMB->ulVersion = RED_DISK_LAYOUT_VERSION; - RedStrNCpy(pMB->acBuildNum, RED_BUILD_NUMBER, sizeof(pMB->acBuildNum)); - pMB->ulFormatTime = RedOsClockGetTime(); - pMB->ulInodeCount = gpRedVolConf->ulInodeCount; - pMB->ulBlockCount = gpRedVolume->ulBlockCount; - pMB->uMaxNameLen = REDCONF_NAME_MAX; - pMB->uDirectPointers = REDCONF_DIRECT_POINTERS; - pMB->uIndirectPointers = REDCONF_INDIRECT_POINTERS; - pMB->bBlockSizeP2 = BLOCK_SIZE_P2; - - #if REDCONF_API_POSIX == 1 - pMB->bFlags |= MBFLAG_API_POSIX; - #endif - #if REDCONF_INODE_TIMESTAMPS == 1 - pMB->bFlags |= MBFLAG_INODE_TIMESTAMPS; - #endif - #if REDCONF_INODE_BLOCKS == 1 - pMB->bFlags |= MBFLAG_INODE_BLOCKS; - #endif - #if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) - pMB->bFlags |= MBFLAG_INODE_NLINK; - #endif - - ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U); - - RedBufferPut(pMB); - } - - if(ret == 0) - { - ret = RedIoFlush(gbRedVolNum); - } - - ret2 = RedOsBDevClose(gbRedVolNum); - if(ret == 0) - { - ret = ret2; - } - } - - /* Discard the buffers so a subsequent format will not run into blocks it - does not expect. - */ - if(ret == 0) - { - ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount); - } - - return ret; -} - - -#endif /* FORMAT_SUPPORTED */ - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements the Reliance Edge file system formatter. + */ +#include +#include +#include + +#if FORMAT_SUPPORTED + + +/** @brief Format a file system volume. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBUSY Volume is mounted. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedVolFormat( void ) + { + REDSTATUS ret; + + if( gpRedVolume->fMounted ) + { + ret = -RED_EBUSY; + } + else + { + ret = RedOsBDevOpen( gbRedVolNum, BDEV_O_RDWR ); + } + + if( ret == 0 ) + { + MASTERBLOCK * pMB; + REDSTATUS ret2; + + /* Overwrite the master block with zeroes, so that if formatting is + * interrupted, the volume will not be mountable. + */ + ret = RedBufferGet( BLOCK_NUM_MASTER, BFLAG_NEW | BFLAG_DIRTY, CAST_VOID_PTR_PTR( &pMB ) ); + + if( ret == 0 ) + { + ret = RedBufferFlush( BLOCK_NUM_MASTER, 1U ); + + RedBufferDiscard( pMB ); + } + + if( ret == 0 ) + { + ret = RedIoFlush( gbRedVolNum ); + } + + #if REDCONF_IMAP_EXTERNAL == 1 + if( ( ret == 0 ) && !gpRedCoreVol->fImapInline ) + { + uint32_t ulImapBlock; + uint32_t ulImapBlockLimit = gpRedCoreVol->ulImapStartBN + ( gpRedCoreVol->ulImapNodeCount * 2U ); + uint16_t uImapFlags = ( uint16_t ) ( ( uint32_t ) BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY ); + + /* Technically it is only necessary to create one copy of each imap + * node (the copy the metaroot points at), but creating them both + * avoids headaches during disk image analysis from stale imaps + * left over from previous formats. + */ + for( ulImapBlock = gpRedCoreVol->ulImapStartBN; ulImapBlock < ulImapBlockLimit; ulImapBlock++ ) + { + IMAPNODE * pImap; + + ret = RedBufferGet( ulImapBlock, uImapFlags, CAST_VOID_PTR_PTR( &pImap ) ); + + if( ret != 0 ) + { + break; + } + + RedBufferPut( pImap ); + } + } + #endif /* if REDCONF_IMAP_EXTERNAL == 1 */ + + /* Write the first metaroot. + */ + if( ret == 0 ) + { + RedMemSet( gpRedMR, 0U, sizeof( *gpRedMR ) ); + + gpRedMR->ulFreeBlocks = gpRedVolume->ulBlocksAllocable; + #if REDCONF_API_POSIX == 1 + gpRedMR->ulFreeInodes = gpRedVolConf->ulInodeCount; + #endif + gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN; + + /* The branched flag is typically set automatically when bits in + * the imap change. It is set here explicitly because the imap has + * only been initialized, not changed. + */ + gpRedCoreVol->fBranched = true; + + ret = RedVolTransact(); + } + + #if REDCONF_API_POSIX == 1 + + /* Create the root directory. + */ + if( ret == 0 ) + { + CINODE rootdir; + + rootdir.ulInode = INODE_ROOTDIR; + ret = RedInodeCreate( &rootdir, INODE_INVALID, RED_S_IFDIR ); + + if( ret == 0 ) + { + RedInodePut( &rootdir, 0U ); + } + } + #endif /* if REDCONF_API_POSIX == 1 */ + + #if REDCONF_API_FSE == 1 + + /* The FSE API does not support creating or deletes files, so all the + * inodes are created during setup. + */ + if( ret == 0 ) + { + uint32_t ulInodeIdx; + + for( ulInodeIdx = 0U; ulInodeIdx < gpRedVolConf->ulInodeCount; ulInodeIdx++ ) + { + CINODE ino; + + ino.ulInode = INODE_FIRST_FREE + ulInodeIdx; + ret = RedInodeCreate( &ino, INODE_INVALID, RED_S_IFREG ); + + if( ret == 0 ) + { + RedInodePut( &ino, 0U ); + } + } + } + #endif /* if REDCONF_API_FSE == 1 */ + + /* Write the second metaroot. + */ + if( ret == 0 ) + { + ret = RedVolTransact(); + } + + /* Populate and write out the master block. + */ + if( ret == 0 ) + { + ret = RedBufferGet( BLOCK_NUM_MASTER, ( uint16_t ) ( ( uint32_t ) BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY ), CAST_VOID_PTR_PTR( &pMB ) ); + } + + if( ret == 0 ) + { + pMB->ulVersion = RED_DISK_LAYOUT_VERSION; + RedStrNCpy( pMB->acBuildNum, RED_BUILD_NUMBER, sizeof( pMB->acBuildNum ) ); + pMB->ulFormatTime = RedOsClockGetTime(); + pMB->ulInodeCount = gpRedVolConf->ulInodeCount; + pMB->ulBlockCount = gpRedVolume->ulBlockCount; + pMB->uMaxNameLen = REDCONF_NAME_MAX; + pMB->uDirectPointers = REDCONF_DIRECT_POINTERS; + pMB->uIndirectPointers = REDCONF_INDIRECT_POINTERS; + pMB->bBlockSizeP2 = BLOCK_SIZE_P2; + + #if REDCONF_API_POSIX == 1 + pMB->bFlags |= MBFLAG_API_POSIX; + #endif + #if REDCONF_INODE_TIMESTAMPS == 1 + pMB->bFlags |= MBFLAG_INODE_TIMESTAMPS; + #endif + #if REDCONF_INODE_BLOCKS == 1 + pMB->bFlags |= MBFLAG_INODE_BLOCKS; + #endif + #if ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_LINK == 1 ) + pMB->bFlags |= MBFLAG_INODE_NLINK; + #endif + + ret = RedBufferFlush( BLOCK_NUM_MASTER, 1U ); + + RedBufferPut( pMB ); + } + + if( ret == 0 ) + { + ret = RedIoFlush( gbRedVolNum ); + } + + ret2 = RedOsBDevClose( gbRedVolNum ); + + if( ret == 0 ) + { + ret = ret2; + } + } + + /* Discard the buffers so a subsequent format will not run into blocks it + * does not expect. + */ + if( ret == 0 ) + { + ret = RedBufferDiscardRange( 0U, gpRedVolume->ulBlockCount ); + } + + return ret; + } + + +#endif /* FORMAT_SUPPORTED */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imap.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imap.c index 87664d12d..34cb85f4a 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imap.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imap.c @@ -1,349 +1,348 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements allocation routines. - - This module implements routines for working with the imap, a bitmap which - tracks which blocks are allocated or free. Some of the functionality is - delegated to imapinline.c and imapextern.c. -*/ -#include -#include - - -/** @brief Get the allocation bit of a block from either metaroot. - - Will pass the call down either to the inline imap or to the external imap - implementation, whichever is appropriate for the current volume. - - @param bMR The metaroot index: either 0 or 1. - @param ulBlock The block number to query. - @param pfAllocated On successful return, populated with the allocation bit - of the block. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; - or @p pfAllocated is `NULL`. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedImapBlockGet( - uint8_t bMR, - uint32_t ulBlock, - bool *pfAllocated) -{ - REDSTATUS ret; - - if( (bMR > 1U) - || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) - || (ulBlock >= gpRedVolume->ulBlockCount) - || (pfAllocated == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - #if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1) - if(gpRedCoreVol->fImapInline) - { - ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated); - } - else - { - ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated); - } - #elif REDCONF_IMAP_INLINE == 1 - ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated); - #else - ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated); - #endif - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Set the allocation bit of a block in the working metaroot. - - Will pass the call down either to the inline imap or to the external imap - implementation, whichever is appropriate for the current volume. - - @param ulBlock The block number to allocate or free. - @param fAllocated Whether to allocate the block (true) or free it (false). - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p ulBlock is out of range; or @p ulBlock is allocable - and @p fAllocated is 1. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedImapBlockSet( - uint32_t ulBlock, - bool fAllocated) -{ - REDSTATUS ret; - - if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN) - || (ulBlock >= gpRedVolume->ulBlockCount)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if( (ulBlock >= gpRedCoreVol->ulFirstAllocableBN) - && ( (fAllocated && (gpRedMR->ulFreeBlocks == 0U)) - || ((!fAllocated) && (gpRedMR->ulFreeBlocks >= gpRedVolume->ulBlocksAllocable)))) - { - /* Attempting either to free more blocks than are allocable, or - allocate a block when there are none available. This could indicate - metadata corruption. - */ - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - else - { - #if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1) - if(gpRedCoreVol->fImapInline) - { - ret = RedImapIBlockSet(ulBlock, fAllocated); - } - else - { - ret = RedImapEBlockSet(ulBlock, fAllocated); - } - #elif REDCONF_IMAP_INLINE == 1 - ret = RedImapIBlockSet(ulBlock, fAllocated); - #else - ret = RedImapEBlockSet(ulBlock, fAllocated); - #endif - - /* Any change to the allocation state of a block indicates that the - volume is now branched. - */ - gpRedCoreVol->fBranched = true; - } - - /* If a block was marked as no longer in use, discard it from the buffers. - */ - if((ret == 0) && (!fAllocated)) - { - ret = RedBufferDiscardRange(ulBlock, 1U); - CRITICAL_ASSERT(ret == 0); - } - - /* Adjust the free/almost free block count if the block was allocable. - Discard the block if required. - */ - if((ret == 0) && (ulBlock >= gpRedCoreVol->ulFirstAllocableBN)) - { - if(fAllocated) - { - gpRedMR->ulFreeBlocks--; - } - else - { - bool fWasAllocated; - - /* Whether the block became free or almost free depends on its - previous allocation state. If it was used, then it is now - almost free. Otherwise, it was new and is now free. - */ - ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fWasAllocated); - CRITICAL_ASSERT(ret == 0); - - if(ret == 0) - { - if(fWasAllocated) - { - gpRedCoreVol->ulAlmostFreeBlocks++; - } - else - { - gpRedMR->ulFreeBlocks++; - } - } - } - } - - return ret; -} - - -/** @brief Allocate one block. - - @param pulBlock On successful return, populated with the allocated block - number. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p pulBlock is `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC Insufficient free space to perform the allocation. -*/ -REDSTATUS RedImapAllocBlock( - uint32_t *pulBlock) -{ - REDSTATUS ret; - - if(pulBlock == NULL) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(gpRedMR->ulFreeBlocks == 0U) - { - ret = -RED_ENOSPC; - } - else - { - uint32_t ulStopBlock = gpRedMR->ulAllocNextBlock; - bool fAllocated = false; - - do - { - ALLOCSTATE state; - - ret = RedImapBlockState(gpRedMR->ulAllocNextBlock, &state); - CRITICAL_ASSERT(ret == 0); - - if(ret == 0) - { - if(state == ALLOCSTATE_FREE) - { - ret = RedImapBlockSet(gpRedMR->ulAllocNextBlock, true); - CRITICAL_ASSERT(ret == 0); - - *pulBlock = gpRedMR->ulAllocNextBlock; - fAllocated = true; - } - - /* Increment the next block number, wrapping it when the end of - the volume is reached. - */ - gpRedMR->ulAllocNextBlock++; - if(gpRedMR->ulAllocNextBlock == gpRedVolume->ulBlockCount) - { - gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN; - } - } - } - while((ret == 0) && !fAllocated && (gpRedMR->ulAllocNextBlock != ulStopBlock)); - - if((ret == 0) && !fAllocated) - { - /* The free block count was already determined to be non-zero, no - error occurred while looking for free blocks, but no free blocks - were found. This indicates metadata corruption. - */ - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ - - -/** @brief Get the allocation state of a block. - - Takes into account the allocation bits from both metaroots, and returns one - of four possible allocation state values: - - - ::ALLOCSTATE_FREE Free and may be allocated; writeable. - - ::ALLOCSTATE_USED In-use and transacted; not writeable. - - ::ALLOCSTATE_NEW In-use but not transacted; writeable. - - ::ALLOCSTATE_AFREE Will become free after a transaction; not writeable. - - @param ulBlock The block number to query. - @param pState On successful return, populated with the state of the block. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p ulBlock is out of range; or @p pState is `NULL`. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedImapBlockState( - uint32_t ulBlock, - ALLOCSTATE *pState) -{ - REDSTATUS ret; - - if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN) - || (ulBlock >= gpRedVolume->ulBlockCount) - || (pState == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - bool fBitCurrent; - - ret = RedImapBlockGet(gpRedCoreVol->bCurMR, ulBlock, &fBitCurrent); - - if(ret == 0) - { - bool fBitOld; - - ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fBitOld); - - if(ret == 0) - { - if(fBitCurrent) - { - if(fBitOld) - { - *pState = ALLOCSTATE_USED; - } - else - { - *pState = ALLOCSTATE_NEW; - } - } - else - { - if(fBitOld) - { - *pState = ALLOCSTATE_AFREE; - } - else - { - *pState = ALLOCSTATE_FREE; - } - } - } - } - } - - return ret; -} - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements allocation routines. + * + * This module implements routines for working with the imap, a bitmap which + * tracks which blocks are allocated or free. Some of the functionality is + * delegated to imapinline.c and imapextern.c. + */ +#include +#include + + +/** @brief Get the allocation bit of a block from either metaroot. + * + * Will pass the call down either to the inline imap or to the external imap + * implementation, whichever is appropriate for the current volume. + * + * @param bMR The metaroot index: either 0 or 1. + * @param ulBlock The block number to query. + * @param pfAllocated On successful return, populated with the allocation bit + * of the block. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; + * or @p pfAllocated is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + */ +REDSTATUS RedImapBlockGet( uint8_t bMR, + uint32_t ulBlock, + bool * pfAllocated ) +{ + REDSTATUS ret; + + if( ( bMR > 1U ) || + ( ulBlock < gpRedCoreVol->ulInodeTableStartBN ) || + ( ulBlock >= gpRedVolume->ulBlockCount ) || + ( pfAllocated == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + #if ( REDCONF_IMAP_INLINE == 1 ) && ( REDCONF_IMAP_EXTERNAL == 1 ) + if( gpRedCoreVol->fImapInline ) + { + ret = RedImapIBlockGet( bMR, ulBlock, pfAllocated ); + } + else + { + ret = RedImapEBlockGet( bMR, ulBlock, pfAllocated ); + } + #elif REDCONF_IMAP_INLINE == 1 + ret = RedImapIBlockGet( bMR, ulBlock, pfAllocated ); + #else /* if ( REDCONF_IMAP_INLINE == 1 ) && ( REDCONF_IMAP_EXTERNAL == 1 ) */ + ret = RedImapEBlockGet( bMR, ulBlock, pfAllocated ); + #endif /* if ( REDCONF_IMAP_INLINE == 1 ) && ( REDCONF_IMAP_EXTERNAL == 1 ) */ + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Set the allocation bit of a block in the working metaroot. + * + * Will pass the call down either to the inline imap or to the external imap + * implementation, whichever is appropriate for the current volume. + * + * @param ulBlock The block number to allocate or free. + * @param fAllocated Whether to allocate the block (true) or free it (false). + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p ulBlock is out of range; or @p ulBlock is allocable + * and @p fAllocated is 1. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedImapBlockSet( uint32_t ulBlock, + bool fAllocated ) + { + REDSTATUS ret; + + if( ( ulBlock < gpRedCoreVol->ulInodeTableStartBN ) || + ( ulBlock >= gpRedVolume->ulBlockCount ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( ( ulBlock >= gpRedCoreVol->ulFirstAllocableBN ) && + ( ( fAllocated && ( gpRedMR->ulFreeBlocks == 0U ) ) || + ( ( !fAllocated ) && ( gpRedMR->ulFreeBlocks >= gpRedVolume->ulBlocksAllocable ) ) ) ) + { + /* Attempting either to free more blocks than are allocable, or + * allocate a block when there are none available. This could indicate + * metadata corruption. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else + { + #if ( REDCONF_IMAP_INLINE == 1 ) && ( REDCONF_IMAP_EXTERNAL == 1 ) + if( gpRedCoreVol->fImapInline ) + { + ret = RedImapIBlockSet( ulBlock, fAllocated ); + } + else + { + ret = RedImapEBlockSet( ulBlock, fAllocated ); + } + #elif REDCONF_IMAP_INLINE == 1 + ret = RedImapIBlockSet( ulBlock, fAllocated ); + #else /* if ( REDCONF_IMAP_INLINE == 1 ) && ( REDCONF_IMAP_EXTERNAL == 1 ) */ + ret = RedImapEBlockSet( ulBlock, fAllocated ); + #endif /* if ( REDCONF_IMAP_INLINE == 1 ) && ( REDCONF_IMAP_EXTERNAL == 1 ) */ + + /* Any change to the allocation state of a block indicates that the + * volume is now branched. + */ + gpRedCoreVol->fBranched = true; + } + + /* If a block was marked as no longer in use, discard it from the buffers. + */ + if( ( ret == 0 ) && ( !fAllocated ) ) + { + ret = RedBufferDiscardRange( ulBlock, 1U ); + CRITICAL_ASSERT( ret == 0 ); + } + + /* Adjust the free/almost free block count if the block was allocable. + * Discard the block if required. + */ + if( ( ret == 0 ) && ( ulBlock >= gpRedCoreVol->ulFirstAllocableBN ) ) + { + if( fAllocated ) + { + gpRedMR->ulFreeBlocks--; + } + else + { + bool fWasAllocated; + + /* Whether the block became free or almost free depends on its + * previous allocation state. If it was used, then it is now + * almost free. Otherwise, it was new and is now free. + */ + ret = RedImapBlockGet( 1U - gpRedCoreVol->bCurMR, ulBlock, &fWasAllocated ); + CRITICAL_ASSERT( ret == 0 ); + + if( ret == 0 ) + { + if( fWasAllocated ) + { + gpRedCoreVol->ulAlmostFreeBlocks++; + } + else + { + gpRedMR->ulFreeBlocks++; + } + } + } + } + + return ret; + } + + +/** @brief Allocate one block. + * + * @param pulBlock On successful return, populated with the allocated block + * number. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p pulBlock is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC Insufficient free space to perform the allocation. + */ + REDSTATUS RedImapAllocBlock( uint32_t * pulBlock ) + { + REDSTATUS ret; + + if( pulBlock == NULL ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( gpRedMR->ulFreeBlocks == 0U ) + { + ret = -RED_ENOSPC; + } + else + { + uint32_t ulStopBlock = gpRedMR->ulAllocNextBlock; + bool fAllocated = false; + + do + { + ALLOCSTATE state; + + ret = RedImapBlockState( gpRedMR->ulAllocNextBlock, &state ); + CRITICAL_ASSERT( ret == 0 ); + + if( ret == 0 ) + { + if( state == ALLOCSTATE_FREE ) + { + ret = RedImapBlockSet( gpRedMR->ulAllocNextBlock, true ); + CRITICAL_ASSERT( ret == 0 ); + + *pulBlock = gpRedMR->ulAllocNextBlock; + fAllocated = true; + } + + /* Increment the next block number, wrapping it when the end of + * the volume is reached. + */ + gpRedMR->ulAllocNextBlock++; + + if( gpRedMR->ulAllocNextBlock == gpRedVolume->ulBlockCount ) + { + gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN; + } + } + } + while( ( ret == 0 ) && !fAllocated && ( gpRedMR->ulAllocNextBlock != ulStopBlock ) ); + + if( ( ret == 0 ) && !fAllocated ) + { + /* The free block count was already determined to be non-zero, no + * error occurred while looking for free blocks, but no free blocks + * were found. This indicates metadata corruption. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + } + + return ret; + } +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Get the allocation state of a block. + * + * Takes into account the allocation bits from both metaroots, and returns one + * of four possible allocation state values: + * + * - ::ALLOCSTATE_FREE Free and may be allocated; writeable. + * - ::ALLOCSTATE_USED In-use and transacted; not writeable. + * - ::ALLOCSTATE_NEW In-use but not transacted; writeable. + * - ::ALLOCSTATE_AFREE Will become free after a transaction; not writeable. + * + * @param ulBlock The block number to query. + * @param pState On successful return, populated with the state of the block. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p ulBlock is out of range; or @p pState is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + */ +REDSTATUS RedImapBlockState( uint32_t ulBlock, + ALLOCSTATE * pState ) +{ + REDSTATUS ret; + + if( ( ulBlock < gpRedCoreVol->ulInodeTableStartBN ) || + ( ulBlock >= gpRedVolume->ulBlockCount ) || + ( pState == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + bool fBitCurrent; + + ret = RedImapBlockGet( gpRedCoreVol->bCurMR, ulBlock, &fBitCurrent ); + + if( ret == 0 ) + { + bool fBitOld; + + ret = RedImapBlockGet( 1U - gpRedCoreVol->bCurMR, ulBlock, &fBitOld ); + + if( ret == 0 ) + { + if( fBitCurrent ) + { + if( fBitOld ) + { + *pState = ALLOCSTATE_USED; + } + else + { + *pState = ALLOCSTATE_NEW; + } + } + else + { + if( fBitOld ) + { + *pState = ALLOCSTATE_AFREE; + } + else + { + *pState = ALLOCSTATE_FREE; + } + } + } + } + } + + return ret; +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapextern.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapextern.c index 67fab47c1..47b54f4e3 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapextern.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapextern.c @@ -1,316 +1,315 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements routines for the external imap. - - The external imap is used on volumes that are too big for the imap bitmap - to be stored entirely in the metaroot, so instead the bitmap is stored in - imap nodes on disk, and the metaroot bitmap is used to toggle between imap - nodes. -*/ -#include - -#if REDCONF_IMAP_EXTERNAL == 1 - -#include - - -#if REDCONF_READ_ONLY == 0 -static REDSTATUS ImapNodeBranch(uint32_t ulImapNode, IMAPNODE **ppImap); -static bool ImapNodeIsBranched(uint32_t ulImapNode); -#endif - - -/** @brief Get the allocation bit of a block from the imap as it exists in - either metaroot. - - @param bMR The metaroot index: either 0 or 1. - @param ulBlock The block number to query. - @param pfAllocated On successful exit, populated with the allocation bit - of the block. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; - or @p pfAllocated is `NULL`. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedImapEBlockGet( - uint8_t bMR, - uint32_t ulBlock, - bool *pfAllocated) -{ - REDSTATUS ret; - - if( gpRedCoreVol->fImapInline - || (bMR > 1U) - || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) - || (ulBlock >= gpRedVolume->ulBlockCount) - || (pfAllocated == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; - uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES; - uint8_t bMRToRead = bMR; - IMAPNODE *pImap; - - #if REDCONF_READ_ONLY == 0 - /* If the imap node is not branched, then both copies of the imap are - identical. If the old metaroot copy is requested, use the current - copy instead, since it is more likely to be buffered. - */ - if(bMR == (1U - gpRedCoreVol->bCurMR)) - { - if(!ImapNodeIsBranched(ulImapNode)) - { - bMRToRead = 1U - bMR; - } - } - #endif - - ret = RedBufferGet(RedImapNodeBlock(bMRToRead, ulImapNode), BFLAG_META_IMAP, CAST_VOID_PTR_PTR(&pImap)); - - if(ret == 0) - { - *pfAllocated = RedBitGet(pImap->abEntries, ulOffset % IMAPNODE_ENTRIES); - - RedBufferPut(pImap); - } - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Set the allocation bit of a block in the working-state imap. - - @param ulBlock The block number to allocate or free. - @param fAllocated Whether to allocate the block (true) or free it (false). - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p ulBlock is out of range. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedImapEBlockSet( - uint32_t ulBlock, - bool fAllocated) -{ - REDSTATUS ret; - - if( gpRedCoreVol->fImapInline - || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) - || (ulBlock >= gpRedVolume->ulBlockCount)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; - uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES; - IMAPNODE *pImap; - - ret = ImapNodeBranch(ulImapNode, &pImap); - - if(ret == 0) - { - uint32_t ulImapEntry = ulOffset % IMAPNODE_ENTRIES; - - if(RedBitGet(pImap->abEntries, ulImapEntry) == fAllocated) - { - /* The driver shouldn't ever set a bit in the imap to its - current value. That shouldn't ever be needed, and it - indicates that the driver is doing unnecessary I/O, or - that the imap is corrupt. - */ - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - else if(fAllocated) - { - RedBitSet(pImap->abEntries, ulImapEntry); - } - else - { - RedBitClear(pImap->abEntries, ulImapEntry); - } - - RedBufferPut(pImap); - } - } - - return ret; -} - - -/** @brief Branch an imap node and get a buffer for it. - - If the imap node is already branched, it can be overwritten in its current - location, and this function just gets it buffered dirty. If the node is not - already branched, the metaroot must be updated to toggle the imap node to - its alternate location, thereby preserving the committed state copy of the - imap node. - - @param ulImapNode The imap node to branch and buffer. - @param ppImap On successful return, populated with the imap node - buffer, which will be marked dirty. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p ulImapNode is out of range; or @p ppImap is `NULL`. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS ImapNodeBranch( - uint32_t ulImapNode, - IMAPNODE **ppImap) -{ - REDSTATUS ret; - - if((ulImapNode >= gpRedCoreVol->ulImapNodeCount) || (ppImap == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(ImapNodeIsBranched(ulImapNode)) - { - /* Imap node is already branched, so just get it buffered dirty. - */ - ret = RedBufferGet(RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode), BFLAG_META_IMAP | BFLAG_DIRTY, CAST_VOID_PTR_PTR(ppImap)); - } - else - { - uint32_t ulBlockCurrent; - uint32_t ulBlockOld; - - /* The metaroot currently points to the committed state imap node. - Toggle the metaroot to point at the alternate, writeable location. - */ - if(RedBitGet(gpRedMR->abEntries, ulImapNode)) - { - RedBitClear(gpRedMR->abEntries, ulImapNode); - } - else - { - RedBitSet(gpRedMR->abEntries, ulImapNode); - } - - ulBlockCurrent = RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode); - ulBlockOld = RedImapNodeBlock(1U - gpRedCoreVol->bCurMR, ulImapNode); - - ret = RedBufferDiscardRange(ulBlockCurrent, 1U); - - /* Buffer the committed copy then reassign the block number to the - writeable location. This also dirties the buffer. - */ - if(ret == 0) - { - ret = RedBufferGet(ulBlockOld, BFLAG_META_IMAP, CAST_VOID_PTR_PTR(ppImap)); - - if(ret == 0) - { - RedBufferBranch(*ppImap, ulBlockCurrent); - } - } - } - - return ret; -} - - -/** @brief Determine whether an imap node is branched. - - If the imap node is branched, it can be overwritten in its current location. - - @param ulImapNode The imap node to examine. - - @return Whether the imap node is branched. -*/ -static bool ImapNodeIsBranched( - uint32_t ulImapNode) -{ - bool fNodeBitSetInMetaroot0 = RedBitGet(gpRedCoreVol->aMR[0U].abEntries, ulImapNode); - bool fNodeBitSetInMetaroot1 = RedBitGet(gpRedCoreVol->aMR[1U].abEntries, ulImapNode); - - /* If the imap node is not branched, both metaroots will point to the same - copy of the node. - */ - return fNodeBitSetInMetaroot0 != fNodeBitSetInMetaroot1; -} -#endif /* REDCONF_READ_ONLY == 0 */ - - -/** @brief Calculate the block number of the imap node location indicated by the - given metaroot. - - An imap node has two locations on disk. A bit in the metaroot bitmap - indicates which location is the valid one, according to that metaroot. This - function returns the block number of the imap node which is valid in the - given metaroot. - - @param bMR Which metaroot to examine. - @param ulImapNode The imap node for which to calculate the block number. - - @return Block number of the imap node, as indicated by the given metaroot. -*/ -uint32_t RedImapNodeBlock( - uint8_t bMR, - uint32_t ulImapNode) -{ - uint32_t ulBlock; - - REDASSERT(ulImapNode < gpRedCoreVol->ulImapNodeCount); - - ulBlock = gpRedCoreVol->ulImapStartBN + (ulImapNode * 2U); - - if(bMR > 1U) - { - REDERROR(); - } - else if(RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulImapNode)) - { - /* Bit is set, so point ulBlock at the second copy of the node. - */ - ulBlock++; - } - else - { - /* ulBlock already points at the first copy of the node. - */ - } - - return ulBlock; -} - -#endif /* REDCONF_IMAP_EXTERNAL == 1 */ - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements routines for the external imap. + * + * The external imap is used on volumes that are too big for the imap bitmap + * to be stored entirely in the metaroot, so instead the bitmap is stored in + * imap nodes on disk, and the metaroot bitmap is used to toggle between imap + * nodes. + */ +#include + +#if REDCONF_IMAP_EXTERNAL == 1 + + #include + + + #if REDCONF_READ_ONLY == 0 + static REDSTATUS ImapNodeBranch( uint32_t ulImapNode, + IMAPNODE ** ppImap ); + static bool ImapNodeIsBranched( uint32_t ulImapNode ); + #endif + + +/** @brief Get the allocation bit of a block from the imap as it exists in + * either metaroot. + * + * @param bMR The metaroot index: either 0 or 1. + * @param ulBlock The block number to query. + * @param pfAllocated On successful exit, populated with the allocation bit + * of the block. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; + * or @p pfAllocated is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedImapEBlockGet( uint8_t bMR, + uint32_t ulBlock, + bool * pfAllocated ) + { + REDSTATUS ret; + + if( gpRedCoreVol->fImapInline || + ( bMR > 1U ) || + ( ulBlock < gpRedCoreVol->ulInodeTableStartBN ) || + ( ulBlock >= gpRedVolume->ulBlockCount ) || + ( pfAllocated == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; + uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES; + uint8_t bMRToRead = bMR; + IMAPNODE * pImap; + + #if REDCONF_READ_ONLY == 0 + + /* If the imap node is not branched, then both copies of the imap are + * identical. If the old metaroot copy is requested, use the current + * copy instead, since it is more likely to be buffered. + */ + if( bMR == ( 1U - gpRedCoreVol->bCurMR ) ) + { + if( !ImapNodeIsBranched( ulImapNode ) ) + { + bMRToRead = 1U - bMR; + } + } + #endif + + ret = RedBufferGet( RedImapNodeBlock( bMRToRead, ulImapNode ), BFLAG_META_IMAP, CAST_VOID_PTR_PTR( &pImap ) ); + + if( ret == 0 ) + { + *pfAllocated = RedBitGet( pImap->abEntries, ulOffset % IMAPNODE_ENTRIES ); + + RedBufferPut( pImap ); + } + } + + return ret; + } + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Set the allocation bit of a block in the working-state imap. + * + * @param ulBlock The block number to allocate or free. + * @param fAllocated Whether to allocate the block (true) or free it (false). + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p ulBlock is out of range. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedImapEBlockSet( uint32_t ulBlock, + bool fAllocated ) + { + REDSTATUS ret; + + if( gpRedCoreVol->fImapInline || + ( ulBlock < gpRedCoreVol->ulInodeTableStartBN ) || + ( ulBlock >= gpRedVolume->ulBlockCount ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; + uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES; + IMAPNODE * pImap; + + ret = ImapNodeBranch( ulImapNode, &pImap ); + + if( ret == 0 ) + { + uint32_t ulImapEntry = ulOffset % IMAPNODE_ENTRIES; + + if( RedBitGet( pImap->abEntries, ulImapEntry ) == fAllocated ) + { + /* The driver shouldn't ever set a bit in the imap to its + * current value. That shouldn't ever be needed, and it + * indicates that the driver is doing unnecessary I/O, or + * that the imap is corrupt. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else if( fAllocated ) + { + RedBitSet( pImap->abEntries, ulImapEntry ); + } + else + { + RedBitClear( pImap->abEntries, ulImapEntry ); + } + + RedBufferPut( pImap ); + } + } + + return ret; + } + + +/** @brief Branch an imap node and get a buffer for it. + * + * If the imap node is already branched, it can be overwritten in its current + * location, and this function just gets it buffered dirty. If the node is not + * already branched, the metaroot must be updated to toggle the imap node to + * its alternate location, thereby preserving the committed state copy of the + * imap node. + * + * @param ulImapNode The imap node to branch and buffer. + * @param ppImap On successful return, populated with the imap node + * buffer, which will be marked dirty. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p ulImapNode is out of range; or @p ppImap is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS ImapNodeBranch( uint32_t ulImapNode, + IMAPNODE ** ppImap ) + { + REDSTATUS ret; + + if( ( ulImapNode >= gpRedCoreVol->ulImapNodeCount ) || ( ppImap == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( ImapNodeIsBranched( ulImapNode ) ) + { + /* Imap node is already branched, so just get it buffered dirty. + */ + ret = RedBufferGet( RedImapNodeBlock( gpRedCoreVol->bCurMR, ulImapNode ), BFLAG_META_IMAP | BFLAG_DIRTY, CAST_VOID_PTR_PTR( ppImap ) ); + } + else + { + uint32_t ulBlockCurrent; + uint32_t ulBlockOld; + + /* The metaroot currently points to the committed state imap node. + * Toggle the metaroot to point at the alternate, writeable location. + */ + if( RedBitGet( gpRedMR->abEntries, ulImapNode ) ) + { + RedBitClear( gpRedMR->abEntries, ulImapNode ); + } + else + { + RedBitSet( gpRedMR->abEntries, ulImapNode ); + } + + ulBlockCurrent = RedImapNodeBlock( gpRedCoreVol->bCurMR, ulImapNode ); + ulBlockOld = RedImapNodeBlock( 1U - gpRedCoreVol->bCurMR, ulImapNode ); + + ret = RedBufferDiscardRange( ulBlockCurrent, 1U ); + + /* Buffer the committed copy then reassign the block number to the + * writeable location. This also dirties the buffer. + */ + if( ret == 0 ) + { + ret = RedBufferGet( ulBlockOld, BFLAG_META_IMAP, CAST_VOID_PTR_PTR( ppImap ) ); + + if( ret == 0 ) + { + RedBufferBranch( *ppImap, ulBlockCurrent ); + } + } + } + + return ret; + } + + +/** @brief Determine whether an imap node is branched. + * + * If the imap node is branched, it can be overwritten in its current location. + * + * @param ulImapNode The imap node to examine. + * + * @return Whether the imap node is branched. + */ + static bool ImapNodeIsBranched( uint32_t ulImapNode ) + { + bool fNodeBitSetInMetaroot0 = RedBitGet( gpRedCoreVol->aMR[ 0U ].abEntries, ulImapNode ); + bool fNodeBitSetInMetaroot1 = RedBitGet( gpRedCoreVol->aMR[ 1U ].abEntries, ulImapNode ); + + /* If the imap node is not branched, both metaroots will point to the same + * copy of the node. + */ + return fNodeBitSetInMetaroot0 != fNodeBitSetInMetaroot1; + } + #endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Calculate the block number of the imap node location indicated by the + * given metaroot. + * + * An imap node has two locations on disk. A bit in the metaroot bitmap + * indicates which location is the valid one, according to that metaroot. This + * function returns the block number of the imap node which is valid in the + * given metaroot. + * + * @param bMR Which metaroot to examine. + * @param ulImapNode The imap node for which to calculate the block number. + * + * @return Block number of the imap node, as indicated by the given metaroot. + */ + uint32_t RedImapNodeBlock( uint8_t bMR, + uint32_t ulImapNode ) + { + uint32_t ulBlock; + + REDASSERT( ulImapNode < gpRedCoreVol->ulImapNodeCount ); + + ulBlock = gpRedCoreVol->ulImapStartBN + ( ulImapNode * 2U ); + + if( bMR > 1U ) + { + REDERROR(); + } + else if( RedBitGet( gpRedCoreVol->aMR[ bMR ].abEntries, ulImapNode ) ) + { + /* Bit is set, so point ulBlock at the second copy of the node. + */ + ulBlock++; + } + else + { + /* ulBlock already points at the first copy of the node. + */ + } + + return ulBlock; + } + +#endif /* REDCONF_IMAP_EXTERNAL == 1 */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapinline.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapinline.c index 0171ae79b..950ed4484 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapinline.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapinline.c @@ -1,133 +1,133 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements routines for the inline imap. - - The inline imap is used on volumes that are small enough for the imap bitmap - to be entirely contained within the metaroot. -*/ -#include - -#if REDCONF_IMAP_INLINE == 1 - -#include - - -/** @brief Get the allocation bit of a block from either metaroot. - - @param bMR The metaroot index: either 0 or 1. - @param ulBlock The block number to query. - @param pfAllocated On successful return, populated with the allocation bit - of the block. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; - @p pfAllocated is `NULL`; or the current volume does not - use the inline imap. -*/ -REDSTATUS RedImapIBlockGet( - uint8_t bMR, - uint32_t ulBlock, - bool *pfAllocated) -{ - REDSTATUS ret; - - if( (!gpRedCoreVol->fImapInline) - || (bMR > 1U) - || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) - || (ulBlock >= gpRedVolume->ulBlockCount) - || (pfAllocated == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - *pfAllocated = RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulBlock - gpRedCoreVol->ulInodeTableStartBN); - ret = 0; - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Set the allocation bit of a block in the working metaroot. - - @param ulBlock The block number to allocate or free. - @param fAllocated Whether to allocate the block (true) or free it (false). - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p ulBlock is out of range; or the current volume does - not use the inline imap. -*/ -REDSTATUS RedImapIBlockSet( - uint32_t ulBlock, - bool fAllocated) -{ - REDSTATUS ret; - - if( (!gpRedCoreVol->fImapInline) - || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) - || (ulBlock >= gpRedVolume->ulBlockCount)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; - - if(RedBitGet(gpRedMR->abEntries, ulOffset) == fAllocated) - { - /* The driver shouldn't ever set a bit in the imap to its current - value. This is more of a problem with the external imap, but it - is checked here for consistency. - */ - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - else if(fAllocated) - { - RedBitSet(gpRedMR->abEntries, ulOffset); - ret = 0; - } - else - { - RedBitClear(gpRedMR->abEntries, ulOffset); - ret = 0; - } - } - - return ret; -} -#endif - -#endif /* REDCONF_IMAP_INLINE == 1 */ - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements routines for the inline imap. + * + * The inline imap is used on volumes that are small enough for the imap bitmap + * to be entirely contained within the metaroot. + */ +#include + +#if REDCONF_IMAP_INLINE == 1 + + #include + + +/** @brief Get the allocation bit of a block from either metaroot. + * + * @param bMR The metaroot index: either 0 or 1. + * @param ulBlock The block number to query. + * @param pfAllocated On successful return, populated with the allocation bit + * of the block. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; + * @p pfAllocated is `NULL`; or the current volume does not + * use the inline imap. + */ + REDSTATUS RedImapIBlockGet( uint8_t bMR, + uint32_t ulBlock, + bool * pfAllocated ) + { + REDSTATUS ret; + + if( ( !gpRedCoreVol->fImapInline ) || + ( bMR > 1U ) || + ( ulBlock < gpRedCoreVol->ulInodeTableStartBN ) || + ( ulBlock >= gpRedVolume->ulBlockCount ) || + ( pfAllocated == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + *pfAllocated = RedBitGet( gpRedCoreVol->aMR[ bMR ].abEntries, ulBlock - gpRedCoreVol->ulInodeTableStartBN ); + ret = 0; + } + + return ret; + } + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Set the allocation bit of a block in the working metaroot. + * + * @param ulBlock The block number to allocate or free. + * @param fAllocated Whether to allocate the block (true) or free it (false). + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p ulBlock is out of range; or the current volume does + * not use the inline imap. + */ + REDSTATUS RedImapIBlockSet( uint32_t ulBlock, + bool fAllocated ) + { + REDSTATUS ret; + + if( ( !gpRedCoreVol->fImapInline ) || + ( ulBlock < gpRedCoreVol->ulInodeTableStartBN ) || + ( ulBlock >= gpRedVolume->ulBlockCount ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; + + if( RedBitGet( gpRedMR->abEntries, ulOffset ) == fAllocated ) + { + /* The driver shouldn't ever set a bit in the imap to its current + * value. This is more of a problem with the external imap, but it + * is checked here for consistency. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else if( fAllocated ) + { + RedBitSet( gpRedMR->abEntries, ulOffset ); + ret = 0; + } + else + { + RedBitClear( gpRedMR->abEntries, ulOffset ); + ret = 0; + } + } + + return ret; + } + #endif /* if REDCONF_READ_ONLY == 0 */ + +#endif /* REDCONF_IMAP_INLINE == 1 */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inode.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inode.c index c8c768265..a2b41e561 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inode.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inode.c @@ -1,1120 +1,1127 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements inode functions. -*/ -#include -#include - - -#if REDCONF_READ_ONLY == 0 -static REDSTATUS InodeIsBranched(uint32_t ulInode, bool *pfIsBranched); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) -static REDSTATUS InodeFindFree(uint32_t *pulInode); -#endif -#if REDCONF_READ_ONLY == 0 -static REDSTATUS InodeGetWriteableCopy(uint32_t ulInode, uint8_t *pbWhich); -#endif -static REDSTATUS InodeGetCurrentCopy(uint32_t ulInode, uint8_t *pbWhich); -#if REDCONF_READ_ONLY == 0 -static REDSTATUS InodeBitSet(uint32_t ulInode, uint8_t bWhich, bool fAllocated); -#endif -static uint32_t InodeBlock(uint32_t ulInode, uint8_t bWhich); - - -/** @brief Mount an existing inode. - - Will populate all fields of the cached inode structure, except those which - are populated during seek. - - @param pInode A pointer to the cached inode structure. The - pInode->ulInode field must already be initialized with the - inode number to mount. All other fields will be discarded. - @param type The expected inode type. - @param fBranch Whether to branch the inode. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL Invalid parameters. - @retval -RED_EROFS @p fBranch is true but the driver is read-only. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EBADF The inode number is free; or the inode number is not - valid. - @retval -RED_EISDIR @p type is ::FTYPE_FILE and the inode is a directory. - @retval -RED_ENOTDIR @p type is ::FTYPE_DIR and the inode is a file. -*/ -REDSTATUS RedInodeMount( - CINODE *pInode, - FTYPE type, - bool fBranch) -{ - REDSTATUS ret = 0; - - if(pInode == NULL) - { - ret = -RED_EINVAL; - } - else if(!INODE_IS_VALID(pInode->ulInode)) - { - ret = -RED_EBADF; - } - #if REDCONF_API_FSE == 1 - else if(type == FTYPE_DIR) - { - REDERROR(); - ret = -RED_EINVAL; - } - #endif - #if REDCONF_READ_ONLY == 1 - else if(fBranch) - { - REDERROR(); - ret = -RED_EROFS; - } - #endif - else - { - uint32_t ulInode = pInode->ulInode; - uint8_t bWhich = 0U; /* Init'd to quiet warnings. */ - - RedMemSet(pInode, 0U, sizeof(*pInode)); - pInode->ulInode = ulInode; - - ret = InodeGetCurrentCopy(pInode->ulInode, &bWhich); - - if(ret == 0) - { - ret = RedBufferGet(InodeBlock(pInode->ulInode, bWhich), BFLAG_META_INODE, CAST_VOID_PTR_PTR(&pInode->pInodeBuf)); - } - - #if REDCONF_READ_ONLY == 0 - if(ret == 0) - { - ret = InodeIsBranched(pInode->ulInode, &pInode->fBranched); - } - #endif - - if(ret == 0) - { - if(RED_S_ISREG(pInode->pInodeBuf->uMode)) - { - #if REDCONF_API_POSIX == 1 - pInode->fDirectory = false; - - if(type == FTYPE_DIR) - { - ret = -RED_ENOTDIR; - } - #endif - } - #if REDCONF_API_POSIX == 1 - else if(RED_S_ISDIR(pInode->pInodeBuf->uMode)) - { - pInode->fDirectory = true; - - if(type == FTYPE_FILE) - { - ret = -RED_EISDIR; - } - } - #endif - else - { - /* Missing or unsupported inode type. - */ - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - } - - #if REDCONF_READ_ONLY == 0 - if((ret == 0) && fBranch) - { - ret = RedInodeBranch(pInode); - } - #endif - - if(ret != 0) - { - RedInodePut(pInode, 0U); - } - } - - return ret; -} - - -#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED) -/** @brief Create an inode. - - @param pInode Pointer to the cached inode structure. If pInode->ulInode - is #INODE_INVALID, a free inode will be found; otherwise, - pInode->ulInode will be the inode number (an error will be - returned if it is not free). - @param ulPInode The parent inode number. - @param uMode The inode mode. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF pInode->ulInode is an invalid inode number other than - #INODE_INVALID. - @retval -RED_EINVAL Invalid parameters. - @retval -RED_EEXIST Tried to create an inode with an inode number that is - already in use. - @retval -RED_ENFILE All inode slots are already in use. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedInodeCreate( - CINODE *pInode, - uint32_t ulPInode, - uint16_t uMode) -{ - REDSTATUS ret; - - #if REDCONF_API_POSIX == 1 - /* ulPInode must be a valid inode number, unless we are creating the root - directory, in which case ulPInode must be INODE_INVALID (the root - directory has no parent). - */ - if( (pInode == NULL) - || (!INODE_IS_VALID(ulPInode) && ((ulPInode != INODE_INVALID) || (pInode->ulInode != INODE_ROOTDIR)))) - #else - if(pInode == NULL) - #endif - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint32_t ulInode = pInode->ulInode; - - RedMemSet(pInode, 0U, sizeof(*pInode)); - - #if REDCONF_API_POSIX == 1 - if(ulInode == INODE_INVALID) - { - /* Caller requested that an inode number be allocated. Search for - an unused inode number, error if there isn't one. - */ - ret = InodeFindFree(&pInode->ulInode); - } - else - #endif - { - /* Caller requested creation of a specific inode number. Make sure - it's valid and doesn't already exist. - */ - if(INODE_IS_VALID(ulInode)) - { - bool fFree; - - ret = RedInodeIsFree(ulInode, &fFree); - if(ret == 0) - { - if(fFree) - { - pInode->ulInode = ulInode; - } - else - { - ret = -RED_EEXIST; - } - } - } - else - { - ret = -RED_EBADF; - } - } - - if(ret == 0) - { - uint8_t bWriteableWhich; - - ret = InodeGetWriteableCopy(pInode->ulInode, &bWriteableWhich); - - if(ret == 0) - { - ret = RedBufferGet(InodeBlock(pInode->ulInode, bWriteableWhich), - (uint16_t)((uint32_t)BFLAG_META_INODE | BFLAG_DIRTY | BFLAG_NEW), CAST_VOID_PTR_PTR(&pInode->pInodeBuf)); - - if(ret == 0) - { - /* Mark the inode block as allocated. - */ - ret = InodeBitSet(pInode->ulInode, bWriteableWhich, true); - - if(ret != 0) - { - RedBufferPut(pInode->pInodeBuf); - } - } - } - } - - if(ret == 0) - { - #if REDCONF_INODE_TIMESTAMPS == 1 - uint32_t ulNow = RedOsClockGetTime(); - - pInode->pInodeBuf->ulATime = ulNow; - pInode->pInodeBuf->ulMTime = ulNow; - pInode->pInodeBuf->ulCTime = ulNow; - #endif - - pInode->pInodeBuf->uMode = uMode; - - #if REDCONF_API_POSIX == 1 - #if REDCONF_API_POSIX_LINK == 1 - pInode->pInodeBuf->uNLink = 1U; - #endif - pInode->pInodeBuf->ulPInode = ulPInode; - #else - (void)ulPInode; - #endif - - pInode->fBranched = true; - pInode->fDirty = true; - - #if REDCONF_API_POSIX == 1 - gpRedMR->ulFreeInodes--; - #endif - } - } - - return ret; -} -#endif /* (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED) */ - - -#if DELETE_SUPPORTED -/** @brief Delete an inode. - - @param pInode Pointer to the cached inode structure. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF The inode is free. - @retval -RED_EINVAL @p pInode is `NULL`; or pInode->pBuffer is `NULL`. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedInodeDelete( - CINODE *pInode) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_MOUNTED(pInode)) - { - ret = -RED_EINVAL; - } - else - { - if(pInode->pInodeBuf->ullSize != 0U) - { - ret = RedInodeDataTruncate(pInode, UINT64_SUFFIX(0)); - } - - if(ret == 0) - { - ret = RedInodeFree(pInode); - } - } - - return ret; -} - - -/** @brief Decrement an inode link count and delete the inode if the link count - falls to zero. - - @param pInode A pointer to the cached inode structure. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p pInode is not a mounted cachde inode. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedInodeLinkDec( - CINODE *pInode) -{ - REDSTATUS ret; - - if(!CINODE_IS_MOUNTED(pInode)) - { - ret = -RED_EINVAL; - } - #if REDCONF_API_POSIX_LINK == 1 - else if(pInode->pInodeBuf->uNLink > 1U) - { - ret = RedInodeBranch(pInode); - - if(ret == 0) - { - pInode->pInodeBuf->uNLink--; - } - } - #endif - else - { - ret = RedInodeDelete(pInode); - } - - return ret; -} -#endif /* DELETE_SUPPORTED */ - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) -/** @brief Free an inode. - - @param pInode Pointer to the cached inode structure. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF The inode is free. - @retval -RED_EINVAL @p pInode is `NULL`; or pInode->pBuffer is `NULL`. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedInodeFree( - CINODE *pInode) -{ - REDSTATUS ret; - - if(!CINODE_IS_MOUNTED(pInode)) - { - ret = -RED_EINVAL; - } - else - { - bool fSlot0Allocated; - - RedBufferDiscard(pInode->pInodeBuf); - pInode->pInodeBuf = NULL; - - /* Determine which of the two slots for the inode is currently - allocated, and free that slot. - */ - ret = RedInodeBitGet(gpRedCoreVol->bCurMR, pInode->ulInode, 0U, &fSlot0Allocated); - - if(ret == 0) - { - bool fSlot1Allocated; - - ret = RedInodeBitGet(gpRedCoreVol->bCurMR, pInode->ulInode, 1U, &fSlot1Allocated); - - if(ret == 0) - { - if(fSlot0Allocated) - { - if(fSlot1Allocated) - { - /* Both inode slots should never be allocated at - the same time. - */ - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - else - { - ret = InodeBitSet(pInode->ulInode, 0U, false); - } - } - else - { - if(!fSlot1Allocated) - { - /* The inode in unallocated, which should have been - caught when it was mounted. - */ - CRITICAL_ERROR(); - ret = -RED_EBADF; - } - else - { - ret = InodeBitSet(pInode->ulInode, 1U, false); - } - } - } - } - - pInode->ulInode = INODE_INVALID; - - if(ret == 0) - { - if(gpRedMR->ulFreeInodes >= gpRedVolConf->ulInodeCount) - { - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - else - { - gpRedMR->ulFreeInodes++; - } - } - } - - return ret; -} -#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) */ - - -/** @brief Put the cached inode structure. - - This puts all of the buffers in the ::CINODE structure. Also updates inode - timestamp fields if requested. - - @param pInode The cached inode structure. - @param bTimeFields The inode timestamp fields to update. -*/ -void RedInodePut( - CINODE *pInode, - uint8_t bTimeFields) -{ - if(pInode == NULL) - { - REDERROR(); - } - else - { - RedInodePutCoord(pInode); - - if(pInode->pInodeBuf != NULL) - { - #if (REDCONF_READ_ONLY == 0) && (REDCONF_INODE_TIMESTAMPS == 1) - if((bTimeFields & IPUT_UPDATE_MASK) != 0U) - { - if(!pInode->fBranched || !pInode->fDirty) - { - REDERROR(); - } - else - { - uint32_t ulNow = RedOsClockGetTime(); - - #if REDCONF_ATIME == 1 - if((bTimeFields & IPUT_UPDATE_ATIME) != 0U) - { - pInode->pInodeBuf->ulATime = ulNow; - } - #endif - - if((bTimeFields & IPUT_UPDATE_MTIME) != 0U) - { - pInode->pInodeBuf->ulMTime = ulNow; - } - - if((bTimeFields & IPUT_UPDATE_CTIME) != 0U) - { - pInode->pInodeBuf->ulCTime = ulNow; - } - } - } - #else - (void)bTimeFields; - #endif - - RedBufferPut(pInode->pInodeBuf); - pInode->pInodeBuf = NULL; - } - } -} - - -/** @brief Put all buffers in the cached inode structure except for the inode - node buffer. - - @param pInode A pointer to the cached inode structure. -*/ -void RedInodePutCoord( - CINODE *pInode) -{ - if(pInode == NULL) - { - REDERROR(); - } - else - { - RedInodePutData(pInode); - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - RedInodePutIndir(pInode); - #endif - #if DINDIR_POINTERS > 0U - RedInodePutDindir(pInode); - #endif - } -} - - -#if DINDIR_POINTERS > 0U -/** @brief Put the double indirect buffer. - - @param pInode A pointer to the cached inode structure. -*/ -void RedInodePutDindir( - CINODE *pInode) -{ - if(pInode == NULL) - { - REDERROR(); - } - else if(pInode->pDindir != NULL) - { - RedBufferPut(pInode->pDindir); - pInode->pDindir = NULL; - } - else - { - /* No double indirect buffer, nothing to put. - */ - } -} -#endif - - -#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES -/** @brief Put the indirect buffer. - - @param pInode A pointer to the cached inode structure. -*/ -void RedInodePutIndir( - CINODE *pInode) -{ - if(pInode == NULL) - { - REDERROR(); - } - else if(pInode->pIndir != NULL) - { - RedBufferPut(pInode->pIndir); - pInode->pIndir = NULL; - } - else - { - /* No indirect buffer, nothing to put. - */ - } -} -#endif - - -/** @brief Put the inode data buffer. - - @param pInode A pointer to the cached inode structure. -*/ -void RedInodePutData( - CINODE *pInode) -{ - if(pInode == NULL) - { - REDERROR(); - } - else if(pInode->pbData != NULL) - { - RedBufferPut(pInode->pbData); - pInode->pbData = NULL; - } - else - { - /* No data buffer, nothing to put. - */ - } -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Determine if an inode is branched. - - @param ulInode The inode number to examine. - @param pfIsBranched On successful return, populated with whether the inode - is branched. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p pInode is `NULL`; or @p ulInode is not a valid inode - number. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS InodeIsBranched( - uint32_t ulInode, - bool *pfIsBranched) -{ - REDSTATUS ret; - - if(!INODE_IS_VALID(ulInode) || (pfIsBranched == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - ALLOCSTATE state; - - ret = RedImapBlockState(InodeBlock(ulInode, 0U), &state); - - if(ret == 0) - { - if(state == ALLOCSTATE_NEW) - { - *pfIsBranched = true; - } - else - { - ret = RedImapBlockState(InodeBlock(ulInode, 1U), &state); - - if(ret == 0) - { - if(state == ALLOCSTATE_NEW) - { - *pfIsBranched = true; - } - else - { - *pfIsBranched = false; - } - } - } - } - } - - return ret; -} - - -/** @brief Branch an inode. - - A branched inode is one in which the allocation state for one copy is free - or almost free, and the other copy is in the new state. The copy which is - in the new state is the writeable copy, which is also buffered and dirty. - - @param pInode Pointer to the cached inode structure which has already been - mounted. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL Invalid parameters. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedInodeBranch( - CINODE *pInode) -{ - REDSTATUS ret; - - if(!CINODE_IS_MOUNTED(pInode)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(!pInode->fBranched) - { - uint8_t bWhich; - - ret = InodeGetWriteableCopy(pInode->ulInode, &bWhich); - - if(ret == 0) - { - RedBufferBranch(pInode->pInodeBuf, InodeBlock(pInode->ulInode, bWhich)); - pInode->fBranched = true; - pInode->fDirty = true; - } - - /* Toggle the inode slots: the old slot block becomes almost free - (still used by the committed state) and the new slot block becomes - new. - */ - if(ret == 0) - { - ret = InodeBitSet(pInode->ulInode, 1U - bWhich, false); - } - - if(ret == 0) - { - ret = InodeBitSet(pInode->ulInode, bWhich, true); - } - - CRITICAL_ASSERT(ret == 0); - } - else - { - RedBufferDirty(pInode->pInodeBuf); - pInode->fDirty = true; - ret = 0; - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) -/** @brief Find a free inode number. - - @param pulInode On successful return, populated with a free inode number. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p pulInode is `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENFILE No available inode numbers. -*/ -static REDSTATUS InodeFindFree( - uint32_t *pulInode) -{ - REDSTATUS ret; - - if(pulInode == NULL) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(gpRedMR->ulFreeInodes == 0U) - { - ret = -RED_ENFILE; - } - else - { - uint32_t ulInode; - - ret = 0; - - for(ulInode = INODE_FIRST_FREE; ulInode < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount); ulInode++) - { - bool fFree; - - ret = RedInodeIsFree(ulInode, &fFree); - - if((ret != 0) || fFree) - { - break; - } - } - - if(ret == 0) - { - if(ulInode < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount)) - { - *pulInode = ulInode; - } - else - { - /* If gpRedMR->ulFreeInodes > 0, we should have found an inode. - */ - CRITICAL_ERROR(); - ret = -RED_ENFILE; - } - } - } - - return ret; -} -#endif - - -#if ((REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)) || (REDCONF_CHECKER == 1) -/** @brief Determine whether an inode number is available. - - @param ulInode The node number to examine. - @param pfFree On successful return, populated with whether the inode - number is available (true) or in use (false). - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p pfFree is `NULL`; or @p ulInode is not a valid inode - number. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedInodeIsFree( - uint32_t ulInode, - bool *pfFree) -{ - REDSTATUS ret; - - if(pfFree == NULL) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - bool fSlot0Allocated; - - *pfFree = false; - - ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated); - if((ret == 0) && !fSlot0Allocated) - { - bool fSlot1Allocated; - - ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated); - if((ret == 0) && !fSlot1Allocated) - { - *pfFree = true; - } - } - } - - return ret; -} -#endif - - -#if REDCONF_READ_ONLY == 0 -/** @brief Determine which copy of the inode is currently writeable. - - @param ulInode The inode number to examine. - @param pbWhich On successful return, populated with which copy of the inode - (either 0 or 1) is writeable. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p pbWhich is `NULL`; or ulInode is not a valid inode - number. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS InodeGetWriteableCopy( - uint32_t ulInode, - uint8_t *pbWhich) -{ - REDSTATUS ret; - - if(pbWhich == NULL) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - bool fSlot0Allocated; - - /* The writeable inode slot is the one which is free in the committed - state, so query the committed state metaroot. - */ - ret = RedInodeBitGet(1U - gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated); - - if(ret == 0) - { - if(!fSlot0Allocated) - { - *pbWhich = 0U; - } - else - { - bool fSlot1Allocated; - - ret = RedInodeBitGet(1U - gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated); - - if(ret == 0) - { - if(!fSlot1Allocated) - { - *pbWhich = 1U; - } - else - { - /* Both inode slots were allocated, which should never - happen. - */ - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - } - } - } - } - - return ret; -} -#endif - - -/** @brief Determine which copy of the inode is current. - - @param ulInode The inode number to examine. - @param pbWhich On successful return, populated with which copy of the inode - (either 0 or 1) is current. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is an unallocated inode number. - @retval -RED_EINVAL @p pbWhich is `NULL`; or ulInode is not a valid inode - number. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS InodeGetCurrentCopy( - uint32_t ulInode, - uint8_t *pbWhich) -{ - REDSTATUS ret; - - if(pbWhich == NULL) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - bool fSlot0Allocated; - - /* The current inode slot is the one which is allocated in the working - state metaroot. - */ - ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated); - if(ret == 0) - { - if(fSlot0Allocated) - { - *pbWhich = 0U; - } - else - { - bool fSlot1Allocated; - - ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated); - if(ret == 0) - { - if(fSlot1Allocated) - { - *pbWhich = 1U; - } - else - { - /* Neither slot for this inode was allocated, so the - inode is actually free. - */ - ret = -RED_EBADF; - } - } - } - } - } - - return ret; -} - - -/** @brief Get whether a copy of an inode is allocated. - - @param bMR The metaroot index: either 0 or 1. - @param ulInode The inode number. - @param bWhich Which copy of the inode to get. - @param pfAllocated On successful return, populated with whether the given - copy of the inode is allocated. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bMR is not 1 or 0; @p ulInode is not a valid inode - number; or @p bWhich is not 1 or 0; or @p pfAllocated is - `NULL`. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedInodeBitGet( - uint8_t bMR, - uint32_t ulInode, - uint8_t bWhich, - bool *pfAllocated) -{ - REDSTATUS ret; - - if(!INODE_IS_VALID(ulInode) || (bWhich > 1U)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - ret = RedImapBlockGet(bMR, InodeBlock(ulInode, bWhich), pfAllocated); - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Set whether a copy of an inode is allocated. - - @param ulInode The inode number. - @param bWhich Which copy of the inode to set. - @param fAllocated If true, the inode is set to allocated; if false, the - inode is set to free. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p ulInode is not a valid inode number; or @p bWhich is - not 1 or 0. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS InodeBitSet( - uint32_t ulInode, - uint8_t bWhich, - bool fAllocated) -{ - REDSTATUS ret; - - if(!INODE_IS_VALID(ulInode) || (bWhich > 1U)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - ret = RedImapBlockSet(InodeBlock(ulInode, bWhich), fAllocated); - } - - return ret; -} -#endif - - -/** @brief Determine the block number of an inode. - - @param ulInode The inode number. - @param bWhich Which copy of the inode. - - @return The block number of the inode. -*/ -static uint32_t InodeBlock( - uint32_t ulInode, - uint8_t bWhich) -{ - REDASSERT(INODE_IS_VALID(ulInode)); - REDASSERT(bWhich <= 1U); - - return gpRedCoreVol->ulInodeTableStartBN + ((ulInode - INODE_FIRST_VALID) * 2U) + bWhich; -} - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements inode functions. + */ +#include +#include + + +#if REDCONF_READ_ONLY == 0 + static REDSTATUS InodeIsBranched( uint32_t ulInode, + bool * pfIsBranched ); +#endif +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) + static REDSTATUS InodeFindFree( uint32_t * pulInode ); +#endif +#if REDCONF_READ_ONLY == 0 + static REDSTATUS InodeGetWriteableCopy( uint32_t ulInode, + uint8_t * pbWhich ); +#endif +static REDSTATUS InodeGetCurrentCopy( uint32_t ulInode, + uint8_t * pbWhich ); +#if REDCONF_READ_ONLY == 0 + static REDSTATUS InodeBitSet( uint32_t ulInode, + uint8_t bWhich, + bool fAllocated ); +#endif +static uint32_t InodeBlock( uint32_t ulInode, + uint8_t bWhich ); + + +/** @brief Mount an existing inode. + * + * Will populate all fields of the cached inode structure, except those which + * are populated during seek. + * + * @param pInode A pointer to the cached inode structure. The + * pInode->ulInode field must already be initialized with the + * inode number to mount. All other fields will be discarded. + * @param type The expected inode type. + * @param fBranch Whether to branch the inode. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL Invalid parameters. + * @retval -RED_EROFS @p fBranch is true but the driver is read-only. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EBADF The inode number is free; or the inode number is not + * valid. + * @retval -RED_EISDIR @p type is ::FTYPE_FILE and the inode is a directory. + * @retval -RED_ENOTDIR @p type is ::FTYPE_DIR and the inode is a file. + */ +REDSTATUS RedInodeMount( CINODE * pInode, + FTYPE type, + bool fBranch ) +{ + REDSTATUS ret = 0; + + if( pInode == NULL ) + { + ret = -RED_EINVAL; + } + else if( !INODE_IS_VALID( pInode->ulInode ) ) + { + ret = -RED_EBADF; + } + + #if REDCONF_API_FSE == 1 + else if( type == FTYPE_DIR ) + { + REDERROR(); + ret = -RED_EINVAL; + } + #endif + #if REDCONF_READ_ONLY == 1 + else if( fBranch ) + { + REDERROR(); + ret = -RED_EROFS; + } + #endif + else + { + uint32_t ulInode = pInode->ulInode; + uint8_t bWhich = 0U; /* Init'd to quiet warnings. */ + + RedMemSet( pInode, 0U, sizeof( *pInode ) ); + pInode->ulInode = ulInode; + + ret = InodeGetCurrentCopy( pInode->ulInode, &bWhich ); + + if( ret == 0 ) + { + ret = RedBufferGet( InodeBlock( pInode->ulInode, bWhich ), BFLAG_META_INODE, CAST_VOID_PTR_PTR( &pInode->pInodeBuf ) ); + } + + #if REDCONF_READ_ONLY == 0 + if( ret == 0 ) + { + ret = InodeIsBranched( pInode->ulInode, &pInode->fBranched ); + } + #endif + + if( ret == 0 ) + { + if( RED_S_ISREG( pInode->pInodeBuf->uMode ) ) + { + #if REDCONF_API_POSIX == 1 + pInode->fDirectory = false; + + if( type == FTYPE_DIR ) + { + ret = -RED_ENOTDIR; + } + #endif + } + + #if REDCONF_API_POSIX == 1 + else if( RED_S_ISDIR( pInode->pInodeBuf->uMode ) ) + { + pInode->fDirectory = true; + + if( type == FTYPE_FILE ) + { + ret = -RED_EISDIR; + } + } + #endif + else + { + /* Missing or unsupported inode type. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + } + + #if REDCONF_READ_ONLY == 0 + if( ( ret == 0 ) && fBranch ) + { + ret = RedInodeBranch( pInode ); + } + #endif + + if( ret != 0 ) + { + RedInodePut( pInode, 0U ); + } + } + + return ret; +} + + +#if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED ) + +/** @brief Create an inode. + * + * @param pInode Pointer to the cached inode structure. If pInode->ulInode + * is #INODE_INVALID, a free inode will be found; otherwise, + * pInode->ulInode will be the inode number (an error will be + * returned if it is not free). + * @param ulPInode The parent inode number. + * @param uMode The inode mode. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF pInode->ulInode is an invalid inode number other than + #INODE_INVALID. + * @retval -RED_EINVAL Invalid parameters. + * @retval -RED_EEXIST Tried to create an inode with an inode number that is + * already in use. + * @retval -RED_ENFILE All inode slots are already in use. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedInodeCreate( CINODE * pInode, + uint32_t ulPInode, + uint16_t uMode ) + { + REDSTATUS ret; + + #if REDCONF_API_POSIX == 1 + + /* ulPInode must be a valid inode number, unless we are creating the root + * directory, in which case ulPInode must be INODE_INVALID (the root + * directory has no parent). + */ + if( ( pInode == NULL ) || + ( !INODE_IS_VALID( ulPInode ) && ( ( ulPInode != INODE_INVALID ) || ( pInode->ulInode != INODE_ROOTDIR ) ) ) ) + #else + if( pInode == NULL ) + #endif + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulInode = pInode->ulInode; + + RedMemSet( pInode, 0U, sizeof( *pInode ) ); + + #if REDCONF_API_POSIX == 1 + if( ulInode == INODE_INVALID ) + { + /* Caller requested that an inode number be allocated. Search for + * an unused inode number, error if there isn't one. + */ + ret = InodeFindFree( &pInode->ulInode ); + } + else + #endif + { + /* Caller requested creation of a specific inode number. Make sure + * it's valid and doesn't already exist. + */ + if( INODE_IS_VALID( ulInode ) ) + { + bool fFree; + + ret = RedInodeIsFree( ulInode, &fFree ); + + if( ret == 0 ) + { + if( fFree ) + { + pInode->ulInode = ulInode; + } + else + { + ret = -RED_EEXIST; + } + } + } + else + { + ret = -RED_EBADF; + } + } + + if( ret == 0 ) + { + uint8_t bWriteableWhich; + + ret = InodeGetWriteableCopy( pInode->ulInode, &bWriteableWhich ); + + if( ret == 0 ) + { + ret = RedBufferGet( InodeBlock( pInode->ulInode, bWriteableWhich ), + ( uint16_t ) ( ( uint32_t ) BFLAG_META_INODE | BFLAG_DIRTY | BFLAG_NEW ), CAST_VOID_PTR_PTR( &pInode->pInodeBuf ) ); + + if( ret == 0 ) + { + /* Mark the inode block as allocated. + */ + ret = InodeBitSet( pInode->ulInode, bWriteableWhich, true ); + + if( ret != 0 ) + { + RedBufferPut( pInode->pInodeBuf ); + } + } + } + } + + if( ret == 0 ) + { + #if REDCONF_INODE_TIMESTAMPS == 1 + uint32_t ulNow = RedOsClockGetTime(); + + pInode->pInodeBuf->ulATime = ulNow; + pInode->pInodeBuf->ulMTime = ulNow; + pInode->pInodeBuf->ulCTime = ulNow; + #endif + + pInode->pInodeBuf->uMode = uMode; + + #if REDCONF_API_POSIX == 1 + #if REDCONF_API_POSIX_LINK == 1 + pInode->pInodeBuf->uNLink = 1U; + #endif + pInode->pInodeBuf->ulPInode = ulPInode; + #else + ( void ) ulPInode; + #endif + + pInode->fBranched = true; + pInode->fDirty = true; + + #if REDCONF_API_POSIX == 1 + gpRedMR->ulFreeInodes--; + #endif + } + } + + return ret; + } +#endif /* (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED) */ + + +#if DELETE_SUPPORTED + +/** @brief Delete an inode. + * + * @param pInode Pointer to the cached inode structure. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF The inode is free. + * @retval -RED_EINVAL @p pInode is `NULL`; or pInode->pBuffer is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedInodeDelete( CINODE * pInode ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_MOUNTED( pInode ) ) + { + ret = -RED_EINVAL; + } + else + { + if( pInode->pInodeBuf->ullSize != 0U ) + { + ret = RedInodeDataTruncate( pInode, UINT64_SUFFIX( 0 ) ); + } + + if( ret == 0 ) + { + ret = RedInodeFree( pInode ); + } + } + + return ret; + } + + +/** @brief Decrement an inode link count and delete the inode if the link count + * falls to zero. + * + * @param pInode A pointer to the cached inode structure. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p pInode is not a mounted cached inode. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedInodeLinkDec( CINODE * pInode ) + { + REDSTATUS ret; + + if( !CINODE_IS_MOUNTED( pInode ) ) + { + ret = -RED_EINVAL; + } + + #if REDCONF_API_POSIX_LINK == 1 + else if( pInode->pInodeBuf->uNLink > 1U ) + { + ret = RedInodeBranch( pInode ); + + if( ret == 0 ) + { + pInode->pInodeBuf->uNLink--; + } + } + #endif + else + { + ret = RedInodeDelete( pInode ); + } + + return ret; + } +#endif /* DELETE_SUPPORTED */ + + +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) + +/** @brief Free an inode. + * + * @param pInode Pointer to the cached inode structure. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF The inode is free. + * @retval -RED_EINVAL @p pInode is `NULL`; or pInode->pBuffer is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedInodeFree( CINODE * pInode ) + { + REDSTATUS ret; + + if( !CINODE_IS_MOUNTED( pInode ) ) + { + ret = -RED_EINVAL; + } + else + { + bool fSlot0Allocated; + + RedBufferDiscard( pInode->pInodeBuf ); + pInode->pInodeBuf = NULL; + + /* Determine which of the two slots for the inode is currently + * allocated, and free that slot. + */ + ret = RedInodeBitGet( gpRedCoreVol->bCurMR, pInode->ulInode, 0U, &fSlot0Allocated ); + + if( ret == 0 ) + { + bool fSlot1Allocated; + + ret = RedInodeBitGet( gpRedCoreVol->bCurMR, pInode->ulInode, 1U, &fSlot1Allocated ); + + if( ret == 0 ) + { + if( fSlot0Allocated ) + { + if( fSlot1Allocated ) + { + /* Both inode slots should never be allocated at + * the same time. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else + { + ret = InodeBitSet( pInode->ulInode, 0U, false ); + } + } + else + { + if( !fSlot1Allocated ) + { + /* The inode in unallocated, which should have been + * caught when it was mounted. + */ + CRITICAL_ERROR(); + ret = -RED_EBADF; + } + else + { + ret = InodeBitSet( pInode->ulInode, 1U, false ); + } + } + } + } + + pInode->ulInode = INODE_INVALID; + + if( ret == 0 ) + { + if( gpRedMR->ulFreeInodes >= gpRedVolConf->ulInodeCount ) + { + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else + { + gpRedMR->ulFreeInodes++; + } + } + } + + return ret; + } +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) */ + + +/** @brief Put the cached inode structure. + * + * This puts all of the buffers in the ::CINODE structure. Also updates inode + * timestamp fields if requested. + * + * @param pInode The cached inode structure. + * @param bTimeFields The inode timestamp fields to update. + */ +void RedInodePut( CINODE * pInode, + uint8_t bTimeFields ) +{ + if( pInode == NULL ) + { + REDERROR(); + } + else + { + RedInodePutCoord( pInode ); + + if( pInode->pInodeBuf != NULL ) + { + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_INODE_TIMESTAMPS == 1 ) + if( ( bTimeFields & IPUT_UPDATE_MASK ) != 0U ) + { + if( !pInode->fBranched || !pInode->fDirty ) + { + REDERROR(); + } + else + { + uint32_t ulNow = RedOsClockGetTime(); + + #if REDCONF_ATIME == 1 + if( ( bTimeFields & IPUT_UPDATE_ATIME ) != 0U ) + { + pInode->pInodeBuf->ulATime = ulNow; + } + #endif + + if( ( bTimeFields & IPUT_UPDATE_MTIME ) != 0U ) + { + pInode->pInodeBuf->ulMTime = ulNow; + } + + if( ( bTimeFields & IPUT_UPDATE_CTIME ) != 0U ) + { + pInode->pInodeBuf->ulCTime = ulNow; + } + } + } + #else /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_INODE_TIMESTAMPS == 1 ) */ + ( void ) bTimeFields; + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_INODE_TIMESTAMPS == 1 ) */ + + RedBufferPut( pInode->pInodeBuf ); + pInode->pInodeBuf = NULL; + } + } +} + + +/** @brief Put all buffers in the cached inode structure except for the inode + * node buffer. + * + * @param pInode A pointer to the cached inode structure. + */ +void RedInodePutCoord( CINODE * pInode ) +{ + if( pInode == NULL ) + { + REDERROR(); + } + else + { + RedInodePutData( pInode ); + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + RedInodePutIndir( pInode ); + #endif + #if DINDIR_POINTERS > 0U + RedInodePutDindir( pInode ); + #endif + } +} + + +#if DINDIR_POINTERS > 0U + +/** @brief Put the double indirect buffer. + * + * @param pInode A pointer to the cached inode structure. + */ + void RedInodePutDindir( CINODE * pInode ) + { + if( pInode == NULL ) + { + REDERROR(); + } + else if( pInode->pDindir != NULL ) + { + RedBufferPut( pInode->pDindir ); + pInode->pDindir = NULL; + } + else + { + /* No double indirect buffer, nothing to put. + */ + } + } +#endif /* if DINDIR_POINTERS > 0U */ + + +#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + +/** @brief Put the indirect buffer. + * + * @param pInode A pointer to the cached inode structure. + */ + void RedInodePutIndir( CINODE * pInode ) + { + if( pInode == NULL ) + { + REDERROR(); + } + else if( pInode->pIndir != NULL ) + { + RedBufferPut( pInode->pIndir ); + pInode->pIndir = NULL; + } + else + { + /* No indirect buffer, nothing to put. + */ + } + } +#endif /* if REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ + + +/** @brief Put the inode data buffer. + * + * @param pInode A pointer to the cached inode structure. + */ +void RedInodePutData( CINODE * pInode ) +{ + if( pInode == NULL ) + { + REDERROR(); + } + else if( pInode->pbData != NULL ) + { + RedBufferPut( pInode->pbData ); + pInode->pbData = NULL; + } + else + { + /* No data buffer, nothing to put. + */ + } +} + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Determine if an inode is branched. + * + * @param ulInode The inode number to examine. + * @param pfIsBranched On successful return, populated with whether the inode + * is branched. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p pInode is `NULL`; or @p ulInode is not a valid inode + * number. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS InodeIsBranched( uint32_t ulInode, + bool * pfIsBranched ) + { + REDSTATUS ret; + + if( !INODE_IS_VALID( ulInode ) || ( pfIsBranched == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ALLOCSTATE state; + + ret = RedImapBlockState( InodeBlock( ulInode, 0U ), &state ); + + if( ret == 0 ) + { + if( state == ALLOCSTATE_NEW ) + { + *pfIsBranched = true; + } + else + { + ret = RedImapBlockState( InodeBlock( ulInode, 1U ), &state ); + + if( ret == 0 ) + { + if( state == ALLOCSTATE_NEW ) + { + *pfIsBranched = true; + } + else + { + *pfIsBranched = false; + } + } + } + } + } + + return ret; + } + + +/** @brief Branch an inode. + * + * A branched inode is one in which the allocation state for one copy is free + * or almost free, and the other copy is in the new state. The copy which is + * in the new state is the writeable copy, which is also buffered and dirty. + * + * @param pInode Pointer to the cached inode structure which has already been + * mounted. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL Invalid parameters. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedInodeBranch( CINODE * pInode ) + { + REDSTATUS ret; + + if( !CINODE_IS_MOUNTED( pInode ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( !pInode->fBranched ) + { + uint8_t bWhich; + + ret = InodeGetWriteableCopy( pInode->ulInode, &bWhich ); + + if( ret == 0 ) + { + RedBufferBranch( pInode->pInodeBuf, InodeBlock( pInode->ulInode, bWhich ) ); + pInode->fBranched = true; + pInode->fDirty = true; + } + + /* Toggle the inode slots: the old slot block becomes almost free + * (still used by the committed state) and the new slot block becomes + * new. + */ + if( ret == 0 ) + { + ret = InodeBitSet( pInode->ulInode, 1U - bWhich, false ); + } + + if( ret == 0 ) + { + ret = InodeBitSet( pInode->ulInode, bWhich, true ); + } + + CRITICAL_ASSERT( ret == 0 ); + } + else + { + RedBufferDirty( pInode->pInodeBuf ); + pInode->fDirty = true; + ret = 0; + } + + return ret; + } +#endif /* REDCONF_READ_ONLY == 0 */ + + +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) + +/** @brief Find a free inode number. + * + * @param pulInode On successful return, populated with a free inode number. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p pulInode is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENFILE No available inode numbers. + */ + static REDSTATUS InodeFindFree( uint32_t * pulInode ) + { + REDSTATUS ret; + + if( pulInode == NULL ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( gpRedMR->ulFreeInodes == 0U ) + { + ret = -RED_ENFILE; + } + else + { + uint32_t ulInode; + + ret = 0; + + for( ulInode = INODE_FIRST_FREE; ulInode < ( INODE_FIRST_VALID + gpRedVolConf->ulInodeCount ); ulInode++ ) + { + bool fFree; + + ret = RedInodeIsFree( ulInode, &fFree ); + + if( ( ret != 0 ) || fFree ) + { + break; + } + } + + if( ret == 0 ) + { + if( ulInode < ( INODE_FIRST_VALID + gpRedVolConf->ulInodeCount ) ) + { + *pulInode = ulInode; + } + else + { + /* If gpRedMR->ulFreeInodes > 0, we should have found an inode. + */ + CRITICAL_ERROR(); + ret = -RED_ENFILE; + } + } + } + + return ret; + } +#endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) */ + + +#if ( ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED ) ) || ( REDCONF_CHECKER == 1 ) + +/** @brief Determine whether an inode number is available. + * + * @param ulInode The node number to examine. + * @param pfFree On successful return, populated with whether the inode + * number is available (true) or in use (false). + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p pfFree is `NULL`; or @p ulInode is not a valid inode + * number. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedInodeIsFree( uint32_t ulInode, + bool * pfFree ) + { + REDSTATUS ret; + + if( pfFree == NULL ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + bool fSlot0Allocated; + + *pfFree = false; + + ret = RedInodeBitGet( gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated ); + + if( ( ret == 0 ) && !fSlot0Allocated ) + { + bool fSlot1Allocated; + + ret = RedInodeBitGet( gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated ); + + if( ( ret == 0 ) && !fSlot1Allocated ) + { + *pfFree = true; + } + } + } + + return ret; + } +#endif /* if ( ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED ) ) || ( REDCONF_CHECKER == 1 ) */ + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Determine which copy of the inode is currently writeable. + * + * @param ulInode The inode number to examine. + * @param pbWhich On successful return, populated with which copy of the inode + * (either 0 or 1) is writeable. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p pbWhich is `NULL`; or ulInode is not a valid inode + * number. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS InodeGetWriteableCopy( uint32_t ulInode, + uint8_t * pbWhich ) + { + REDSTATUS ret; + + if( pbWhich == NULL ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + bool fSlot0Allocated; + + /* The writeable inode slot is the one which is free in the committed + * state, so query the committed state metaroot. + */ + ret = RedInodeBitGet( 1U - gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated ); + + if( ret == 0 ) + { + if( !fSlot0Allocated ) + { + *pbWhich = 0U; + } + else + { + bool fSlot1Allocated; + + ret = RedInodeBitGet( 1U - gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated ); + + if( ret == 0 ) + { + if( !fSlot1Allocated ) + { + *pbWhich = 1U; + } + else + { + /* Both inode slots were allocated, which should never + * happen. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + } + } + } + } + + return ret; + } +#endif /* if REDCONF_READ_ONLY == 0 */ + + +/** @brief Determine which copy of the inode is current. + * + * @param ulInode The inode number to examine. + * @param pbWhich On successful return, populated with which copy of the inode + * (either 0 or 1) is current. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is an unallocated inode number. + * @retval -RED_EINVAL @p pbWhich is `NULL`; or ulInode is not a valid inode + * number. + * @retval -RED_EIO A disk I/O error occurred. + */ +static REDSTATUS InodeGetCurrentCopy( uint32_t ulInode, + uint8_t * pbWhich ) +{ + REDSTATUS ret; + + if( pbWhich == NULL ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + bool fSlot0Allocated; + + /* The current inode slot is the one which is allocated in the working + * state metaroot. + */ + ret = RedInodeBitGet( gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated ); + + if( ret == 0 ) + { + if( fSlot0Allocated ) + { + *pbWhich = 0U; + } + else + { + bool fSlot1Allocated; + + ret = RedInodeBitGet( gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated ); + + if( ret == 0 ) + { + if( fSlot1Allocated ) + { + *pbWhich = 1U; + } + else + { + /* Neither slot for this inode was allocated, so the + * inode is actually free. + */ + ret = -RED_EBADF; + } + } + } + } + } + + return ret; +} + + +/** @brief Get whether a copy of an inode is allocated. + * + * @param bMR The metaroot index: either 0 or 1. + * @param ulInode The inode number. + * @param bWhich Which copy of the inode to get. + * @param pfAllocated On successful return, populated with whether the given + * copy of the inode is allocated. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bMR is not 1 or 0; @p ulInode is not a valid inode + * number; or @p bWhich is not 1 or 0; or @p pfAllocated is + * `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + */ +REDSTATUS RedInodeBitGet( uint8_t bMR, + uint32_t ulInode, + uint8_t bWhich, + bool * pfAllocated ) +{ + REDSTATUS ret; + + if( !INODE_IS_VALID( ulInode ) || ( bWhich > 1U ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ret = RedImapBlockGet( bMR, InodeBlock( ulInode, bWhich ), pfAllocated ); + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Set whether a copy of an inode is allocated. + * + * @param ulInode The inode number. + * @param bWhich Which copy of the inode to set. + * @param fAllocated If true, the inode is set to allocated; if false, the + * inode is set to free. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p ulInode is not a valid inode number; or @p bWhich is + * not 1 or 0. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS InodeBitSet( uint32_t ulInode, + uint8_t bWhich, + bool fAllocated ) + { + REDSTATUS ret; + + if( !INODE_IS_VALID( ulInode ) || ( bWhich > 1U ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ret = RedImapBlockSet( InodeBlock( ulInode, bWhich ), fAllocated ); + } + + return ret; + } +#endif /* if REDCONF_READ_ONLY == 0 */ + + +/** @brief Determine the block number of an inode. + * + * @param ulInode The inode number. + * @param bWhich Which copy of the inode. + * + * @return The block number of the inode. + */ +static uint32_t InodeBlock( uint32_t ulInode, + uint8_t bWhich ) +{ + REDASSERT( INODE_IS_VALID( ulInode ) ); + REDASSERT( bWhich <= 1U ); + + return gpRedCoreVol->ulInodeTableStartBN + ( ( ulInode - INODE_FIRST_VALID ) * 2U ) + bWhich; +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c index c311925eb..941202cc0 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c @@ -1,1917 +1,1936 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements inode I/O functions. -*/ -#include -#include - - -/* This value is used to initialize the uIndirEntry and uDindirEntry members of - the CINODE structure. After seeking, a value of COORD_ENTRY_INVALID in - uIndirEntry indicates that there is no indirect node in the path through the - file metadata structure, and a value of COORD_ENTRY_INVALID in uDindirEntry - indicates that there is no double indirect node. -*/ -#define COORD_ENTRY_INVALID (UINT16_MAX) - -/* This enumeration is used by the BranchBlock() and BranchBlockCost() - functions to determine which blocks of the file metadata structure need to - be branched, and which to ignore. DINDIR requires requires branching the - double indirect only, INDIR requires branching the double indirect - (if present) and the indirect, and FILE_DATA requires branching the indirect - and double indirect (if present) and the file data block. -*/ -typedef enum -{ - BRANCHDEPTH_DINDIR = 0U, - BRANCHDEPTH_INDIR = 1U, - BRANCHDEPTH_FILE_DATA = 2U, - BRANCHDEPTH_MAX = BRANCHDEPTH_FILE_DATA -} BRANCHDEPTH; - - -#if REDCONF_READ_ONLY == 0 -#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED -static REDSTATUS Shrink(CINODE *pInode, uint64_t ullSize); -#if DINDIR_POINTERS > 0U -static REDSTATUS TruncDindir(CINODE *pInode, bool *pfFreed); -#endif -#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES -static REDSTATUS TruncIndir(CINODE *pInode, bool *pfFreed); -#endif -static REDSTATUS TruncDataBlock(const CINODE *pInode, uint32_t *pulBlock, bool fPropagate); -#endif -static REDSTATUS ExpandPrepare(CINODE *pInode); -#endif -static void SeekCoord(CINODE *pInode, uint32_t ulBlock); -static REDSTATUS ReadUnaligned(CINODE *pInode, uint64_t ullStart, uint32_t ulLen, uint8_t *pbBuffer); -static REDSTATUS ReadAligned(CINODE *pInode, uint32_t ulBlockStart, uint32_t ulBlockCount, uint8_t *pbBuffer); -#if REDCONF_READ_ONLY == 0 -static REDSTATUS WriteUnaligned(CINODE *pInode, uint64_t ullStart, uint32_t ulLen, const uint8_t *pbBuffer); -static REDSTATUS WriteAligned(CINODE *pInode, uint32_t ulBlockStart, uint32_t *pulBlockCount, const uint8_t *pbBuffer); -#endif -static REDSTATUS GetExtent(CINODE *pInode, uint32_t ulBlockStart, uint32_t *pulExtentStart, uint32_t *pulExtentLen); -#if REDCONF_READ_ONLY == 0 -static REDSTATUS BranchBlock(CINODE *pInode, BRANCHDEPTH depth, bool fBuffer); -static REDSTATUS BranchOneBlock(uint32_t *pulBlock, void **ppBuffer, uint16_t uBFlag); -static REDSTATUS BranchBlockCost(const CINODE *pInode, BRANCHDEPTH depth, uint32_t *pulCost); -static uint32_t FreeBlockCount(void); -#endif - - -/** @brief Read data from an inode. - - @param pInode A pointer to the cached inode structure of the inode from - which to read. - @param ullStart The file offset at which to read. - @param pulLen On input, the number of bytes to attempt to read. On - successful return, populated with the number of bytes - actually read. - @param pBuffer The buffer to read into. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer; or - @p pulLen is `NULL`; or @p pBuffer is `NULL`. -*/ -REDSTATUS RedInodeDataRead( - CINODE *pInode, - uint64_t ullStart, - uint32_t *pulLen, - void *pBuffer) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_MOUNTED(pInode) || (pulLen == NULL) || (pBuffer == NULL)) - { - ret = -RED_EINVAL; - } - else if(ullStart >= pInode->pInodeBuf->ullSize) - { - *pulLen = 0U; - } - else if(*pulLen == 0U) - { - /* Do nothing, just return success. - */ - } - else - { - uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer); - uint32_t ulReadIndex = 0U; - uint32_t ulLen = *pulLen; - uint32_t ulRemaining; - - /* Reading beyond the end of the file is not allowed. If the requested - read extends beyond the end of the file, truncate the read length so - that the read stops at the end of the file. - */ - if((pInode->pInodeBuf->ullSize - ullStart) < ulLen) - { - ulLen = (uint32_t)(pInode->pInodeBuf->ullSize - ullStart); - } - - ulRemaining = ulLen; - - /* Unaligned partial block at start. - */ - if((ullStart & (REDCONF_BLOCK_SIZE - 1U)) != 0U) - { - uint32_t ulBytesInFirstBlock = REDCONF_BLOCK_SIZE - (uint32_t)(ullStart & (REDCONF_BLOCK_SIZE - 1U)); - uint32_t ulThisRead = REDMIN(ulRemaining, ulBytesInFirstBlock); - - ret = ReadUnaligned(pInode, ullStart, ulThisRead, pbBuffer); - - if(ret == 0) - { - ulReadIndex += ulThisRead; - ulRemaining -= ulThisRead; - } - } - - /* Whole blocks. - */ - if((ret == 0) && (ulRemaining >= REDCONF_BLOCK_SIZE)) - { - uint32_t ulBlockOffset = (uint32_t)((ullStart + ulReadIndex) >> BLOCK_SIZE_P2); - uint32_t ulBlockCount = ulRemaining >> BLOCK_SIZE_P2; - - REDASSERT(((ullStart + ulReadIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U); - - ret = ReadAligned(pInode, ulBlockOffset, ulBlockCount, &pbBuffer[ulReadIndex]); - - if(ret == 0) - { - ulReadIndex += ulBlockCount << BLOCK_SIZE_P2; - ulRemaining -= ulBlockCount << BLOCK_SIZE_P2; - } - } - - /* Aligned partial block at end. - */ - if((ret == 0) && (ulRemaining > 0U)) - { - REDASSERT(ulRemaining < REDCONF_BLOCK_SIZE); - REDASSERT(((ullStart + ulReadIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U); - - ret = ReadUnaligned(pInode, ullStart + ulReadIndex, ulRemaining, &pbBuffer[ulReadIndex]); - } - - if(ret == 0) - { - *pulLen = ulLen; - } - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Write to an inode. - - @param pInode A pointer to the cached inode structure of the inode into - which to write. - @param ullStart The file offset at which to write. - @param pulLen On input, the number of bytes to attempt to write. On - successful return, populated with the number of bytes - actually written. - @param pBuffer The buffer to write from. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EFBIG @p ullStart is greater than the maximum file size; or - @p ullStart is equal to the maximum file size and the - write length is non-zero. - @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer; or - @p pulLen is `NULL`; or @p pBuffer is `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC No data can be written because there is insufficient - free space. -*/ -REDSTATUS RedInodeDataWrite( - CINODE *pInode, - uint64_t ullStart, - uint32_t *pulLen, - const void *pBuffer) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_DIRTY(pInode) || (pulLen == NULL) || (pBuffer == NULL)) - { - ret = -RED_EINVAL; - } - else if((ullStart > INODE_SIZE_MAX) || ((ullStart == INODE_SIZE_MAX) && (*pulLen > 0U))) - { - ret = -RED_EFBIG; - } - else if(*pulLen == 0U) - { - /* Do nothing, just return success. - */ - } - else - { - const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); - uint32_t ulWriteIndex = 0U; - uint32_t ulLen = *pulLen; - uint32_t ulRemaining; - - if((INODE_SIZE_MAX - ullStart) < ulLen) - { - ulLen = (uint32_t)(INODE_SIZE_MAX - ullStart); - } - - ulRemaining = ulLen; - - /* If the write is beyond the current end of the file, and the current - end of the file is not block-aligned, then there may be some data - that needs to be zeroed in the last block. - */ - if(ullStart > pInode->pInodeBuf->ullSize) - { - ret = ExpandPrepare(pInode); - } - - /* Partial block at start. - */ - if((ret == 0) && (((ullStart & (REDCONF_BLOCK_SIZE - 1U)) != 0U) || (ulRemaining < REDCONF_BLOCK_SIZE))) - { - uint32_t ulBytesInFirstBlock = REDCONF_BLOCK_SIZE - (uint32_t)(ullStart & (REDCONF_BLOCK_SIZE - 1U)); - uint32_t ulThisWrite = REDMIN(ulRemaining, ulBytesInFirstBlock); - - ret = WriteUnaligned(pInode, ullStart, ulThisWrite, pbBuffer); - - if(ret == 0) - { - ulWriteIndex += ulThisWrite; - ulRemaining -= ulThisWrite; - } - } - - /* Whole blocks. - */ - if((ret == 0) && (ulRemaining >= REDCONF_BLOCK_SIZE)) - { - uint32_t ulBlockOffset = (uint32_t)((ullStart + ulWriteIndex) >> BLOCK_SIZE_P2); - uint32_t ulBlockCount = ulRemaining >> BLOCK_SIZE_P2; - uint32_t ulBlocksWritten = ulBlockCount; - - REDASSERT(((ullStart + ulWriteIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U); - - ret = WriteAligned(pInode, ulBlockOffset, &ulBlocksWritten, &pbBuffer[ulWriteIndex]); - - if((ret == -RED_ENOSPC) && (ulWriteIndex > 0U)) - { - ulBlocksWritten = 0U; - ret = 0; - } - - if(ret == 0) - { - ulWriteIndex += ulBlocksWritten << BLOCK_SIZE_P2; - ulRemaining -= ulBlocksWritten << BLOCK_SIZE_P2; - - if(ulBlocksWritten < ulBlockCount) - { - ulRemaining = 0U; - } - } - } - - /* Partial block at end. - */ - if((ret == 0) && (ulRemaining > 0U)) - { - REDASSERT(ulRemaining < REDCONF_BLOCK_SIZE); - REDASSERT(((ullStart + ulWriteIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U); - REDASSERT(ulWriteIndex > 0U); - - ret = WriteUnaligned(pInode, ullStart + ulWriteIndex, ulRemaining, &pbBuffer[ulWriteIndex]); - - if(ret == -RED_ENOSPC) - { - ret = 0; - } - else if(ret == 0) - { - ulWriteIndex += ulRemaining; - - REDASSERT(ulWriteIndex == ulLen); - } - else - { - /* Unexpected error, return it. - */ - } - } - - if(ret == 0) - { - *pulLen = ulWriteIndex; - - if((ullStart + ulWriteIndex) > pInode->pInodeBuf->ullSize) - { - pInode->pInodeBuf->ullSize = ullStart + ulWriteIndex; - } - } - } - - return ret; -} - - -#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED -/** @brief Change the size of an inode. - - @param pInode A pointer to the cached inode structure. - @praam ullSize The new file size for the inode. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EFBIG @p ullSize is greater than the maximum file size. - @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC Insufficient free space to perform the truncate. -*/ -REDSTATUS RedInodeDataTruncate( - CINODE *pInode, - uint64_t ullSize) -{ - REDSTATUS ret = 0; - - /* The inode does not need to be dirtied when it is being deleted, because - the inode buffer will be discarded without ever being written to disk. - Thus, we only check to see if it's mounted here. - */ - if(!CINODE_IS_MOUNTED(pInode)) - { - ret = -RED_EINVAL; - } - else if(ullSize > INODE_SIZE_MAX) - { - ret = -RED_EFBIG; - } - else - { - if(ullSize > pInode->pInodeBuf->ullSize) - { - ret = ExpandPrepare(pInode); - } - else if(ullSize < pInode->pInodeBuf->ullSize) - { - ret = Shrink(pInode, ullSize); - } - else - { - /* Size is staying the same, nothing to do. - */ - } - - if(ret == 0) - { - pInode->pInodeBuf->ullSize = ullSize; - } - } - - return ret; -} - - -/** @brief Free all file data beyond a specified point. - - @param pInode A pointer to the cached inode structure. - @param ullSize The point beyond which to free all file data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC Insufficient free space to perform the truncate. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS Shrink( - CINODE *pInode, - uint64_t ullSize) -{ - REDSTATUS ret = 0; - - /* pInode->fDirty is checked explicitly here, instead of using the - CINODE_IS_DIRTY() macro, to avoid a duplicate mount check. - */ - if(!CINODE_IS_MOUNTED(pInode) || ((ullSize > 0U) && !pInode->fDirty)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint32_t ulTruncBlock = (uint32_t)((ullSize + REDCONF_BLOCK_SIZE - 1U) >> BLOCK_SIZE_P2); - - RedInodePutData(pInode); - - #if REDCONF_DIRECT_POINTERS > 0U - while(ulTruncBlock < REDCONF_DIRECT_POINTERS) - { - ret = TruncDataBlock(pInode, &pInode->pInodeBuf->aulEntries[ulTruncBlock], true); - - if(ret != 0) - { - break; - } - - ulTruncBlock++; - } - #endif - - #if REDCONF_INDIRECT_POINTERS > 0U - while((ret == 0) && (ulTruncBlock < (REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS))) - { - ret = RedInodeDataSeek(pInode, ulTruncBlock); - - if((ret == 0) || (ret == -RED_ENODATA)) - { - bool fFreed; - - ret = TruncIndir(pInode, &fFreed); - - if(ret == 0) - { - if(fFreed) - { - pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = BLOCK_SPARSE; - } - - /* The next seek will go to the beginning of the next - indirect. - */ - ulTruncBlock += (INDIR_ENTRIES - pInode->uIndirEntry); - } - } - } - #endif - - #if DINDIR_POINTERS > 0U - while((ret == 0) && (ulTruncBlock < INODE_DATA_BLOCKS)) - { - ret = RedInodeDataSeek(pInode, ulTruncBlock); - - if((ret == 0) || (ret == -RED_ENODATA)) - { - bool fFreed; - - /* TruncDindir() invokes seek as it goes along, which will - update the entry values (possibly all three of these); - make a copy so we can compute things correctly after. - */ - uint16_t uOrigInodeEntry = pInode->uInodeEntry; - uint16_t uOrigDindirEntry = pInode->uDindirEntry; - uint16_t uOrigIndirEntry = pInode->uIndirEntry; - - ret = TruncDindir(pInode, &fFreed); - - if(ret == 0) - { - if(fFreed) - { - pInode->pInodeBuf->aulEntries[uOrigInodeEntry] = BLOCK_SPARSE; - } - - /* The next seek will go to the beginning of the next - double indirect. - */ - ulTruncBlock += (DINDIR_DATA_BLOCKS - (uOrigDindirEntry * INDIR_ENTRIES)) - uOrigIndirEntry; - } - } - } - #endif - } - - return ret; -} - - -#if DINDIR_POINTERS > 0U -/** @brief Truncate a double indirect. - - @param pInode A pointer to the cached inode, whose coordinates indicate - the truncation boundary. - @param pfFreed On successful return, populated with whether the double - indirect node was freed. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC Insufficient free space to perform the truncate. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS TruncDindir( - CINODE *pInode, - bool *pfFreed) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_MOUNTED(pInode) || (pfFreed == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(pInode->pDindir == NULL) - { - *pfFreed = false; - } - else - { - bool fBranch = false; - uint16_t uEntry; - - /* The double indirect is definitely going to be branched (instead of - deleted) if any of its indirect pointers which are entirely prior to - the truncation boundary are non-sparse. - */ - for(uEntry = 0U; !fBranch && (uEntry < pInode->uDindirEntry); uEntry++) - { - fBranch = pInode->pDindir->aulEntries[uEntry] != BLOCK_SPARSE; - } - - /* Unless we already know for a fact that the double indirect is going - to be branched, examine the contents of the indirect pointer which - straddles the truncation boundary. If the indirect is going to be - deleted, we know this indirect pointer is going away, and that might - mean the double indirect is going to be deleted also. - */ - if(!fBranch && (pInode->pDindir->aulEntries[pInode->uDindirEntry] != BLOCK_SPARSE)) - { - for(uEntry = 0U; !fBranch && (uEntry < pInode->uIndirEntry); uEntry++) - { - fBranch = pInode->pIndir->aulEntries[uEntry] != BLOCK_SPARSE; - } - } - - if(fBranch) - { - ret = BranchBlock(pInode, BRANCHDEPTH_DINDIR, false); - } - - if(ret == 0) - { - uint32_t ulBlock = pInode->ulLogicalBlock; - uint16_t uStart = pInode->uDindirEntry; /* pInode->uDindirEntry will change. */ - - for(uEntry = uStart; uEntry < INDIR_ENTRIES; uEntry++) - { - /* Seek so that TruncIndir() has the correct indirect - buffer and indirect entry. - */ - ret = RedInodeDataSeek(pInode, ulBlock); - - if(ret == -RED_ENODATA) - { - ret = 0; - } - - if((ret == 0) && (pInode->ulIndirBlock != BLOCK_SPARSE)) - { - bool fIndirFreed; - - ret = TruncIndir(pInode, &fIndirFreed); - - if(ret == 0) - { - /* All of the indirects after the one which straddles - the truncation boundary should definitely end up - deleted. - */ - REDASSERT((uEntry == uStart) || fIndirFreed); - - /* If the double indirect is being freed, all of the - indirects should be freed too. - */ - REDASSERT(fIndirFreed || fBranch); - - if(fBranch && fIndirFreed) - { - pInode->pDindir->aulEntries[uEntry] = BLOCK_SPARSE; - } - } - } - - if(ret != 0) - { - break; - } - - ulBlock += (INDIR_ENTRIES - pInode->uIndirEntry); - } - - if(ret == 0) - { - *pfFreed = !fBranch; - - if(!fBranch) - { - RedInodePutDindir(pInode); - - ret = RedImapBlockSet(pInode->ulDindirBlock, false); - } - } - } - } - - return ret; -} -#endif /* DINDIR_POINTERS > 0U */ - - -#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES -/** @brief Truncate a indirect. - - @param pInode A pointer to the cached inode, whose coordinates indicate - the truncation boundary. - @param pfFreed On successful return, populated with whether the indirect - node was freed. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC Insufficient free space to perform the truncate. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS TruncIndir( - CINODE *pInode, - bool *pfFreed) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_MOUNTED(pInode) || (pfFreed == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(pInode->pIndir == NULL) - { - *pfFreed = false; - } - else - { - bool fBranch = false; - uint16_t uEntry; - - /* Scan the range of entries which are not being truncated. If there - is anything there, then the indirect will not be empty after the - truncate, so it is branched and modified instead of deleted. - */ - for(uEntry = 0U; !fBranch && (uEntry < pInode->uIndirEntry); uEntry++) - { - fBranch = pInode->pIndir->aulEntries[uEntry] != BLOCK_SPARSE; - } - - if(fBranch) - { - ret = BranchBlock(pInode, BRANCHDEPTH_INDIR, false); - } - - if(ret == 0) - { - for(uEntry = pInode->uIndirEntry; uEntry < INDIR_ENTRIES; uEntry++) - { - ret = TruncDataBlock(pInode, &pInode->pIndir->aulEntries[uEntry], fBranch); - - if(ret != 0) - { - break; - } - } - - if(ret == 0) - { - *pfFreed = !fBranch; - - if(!fBranch) - { - RedInodePutIndir(pInode); - - ret = RedImapBlockSet(pInode->ulIndirBlock, false); - } - } - } - } - - return ret; -} -#endif /* REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ - - -/** @brief Truncate a file data block. - - @param pInode A pointer to the cached inode structure. - @param pulBlock On entry, contains the block to be truncated. On - successful return, if @p fPropagate is true, populated - with BLOCK_SPARSE, otherwise unmodified. - @param fPropagate Whether the parent node is being branched. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS TruncDataBlock( - const CINODE *pInode, - uint32_t *pulBlock, - bool fPropagate) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_MOUNTED(pInode) || (pulBlock == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(*pulBlock != BLOCK_SPARSE) - { - ret = RedImapBlockSet(*pulBlock, false); - - #if REDCONF_INODE_BLOCKS == 1 - if(ret == 0) - { - if(pInode->pInodeBuf->ulBlocks == 0U) - { - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - else - { - pInode->pInodeBuf->ulBlocks--; - } - } - #endif - - if((ret == 0) && fPropagate) - { - *pulBlock = BLOCK_SPARSE; - } - } - else - { - /* Data block is sparse, nothing to truncate. - */ - } - - return ret; -} -#endif /* DELETE_SUPPORTED || TRUNCATE_SUPPORTED */ - - -/** @brief Prepare to increase the file size. - - When the inode size is increased, a sparse region is created. It is - possible that a prior shrink operation to an unaligned size left stale data - beyond the end of the file in the last data block. That data is not zeroed - while shrinking the inode in order to transfer the disk full burden from the - shrink operation to the expand operation. - - @param pInode A pointer to the cached inode structure. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC Insufficient free space to perform the truncate. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS ExpandPrepare( - CINODE *pInode) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_DIRTY(pInode)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint32_t ulOldSizeByteInBlock = (uint32_t)(pInode->pInodeBuf->ullSize & (REDCONF_BLOCK_SIZE - 1U)); - - if(ulOldSizeByteInBlock != 0U) - { - ret = RedInodeDataSeek(pInode, (uint32_t)(pInode->pInodeBuf->ullSize >> BLOCK_SIZE_P2)); - - if(ret == -RED_ENODATA) - { - ret = 0; - } - else if(ret == 0) - { - ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, true); - - if(ret == 0) - { - RedMemSet(&pInode->pbData[ulOldSizeByteInBlock], 0U, REDCONF_BLOCK_SIZE - ulOldSizeByteInBlock); - } - } - else - { - REDERROR(); - } - } - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ - - -/** @brief Seek to a given position within an inode, then buffer the data block. - - On successful return, pInode->pbData will be populated with a buffer - corresponding to the @p ulBlock block offset. - - @param pInode A pointer to the cached inode structure. - @param ulBlock The block offset to seek to and buffer. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_ENODATA The block offset is sparse. - @retval -RED_EINVAL @p ulBlock is too large. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedInodeDataSeekAndRead( - CINODE *pInode, - uint32_t ulBlock) -{ - REDSTATUS ret; - - ret = RedInodeDataSeek(pInode, ulBlock); - - if((ret == 0) && (pInode->pbData == NULL)) - { - REDASSERT(pInode->ulDataBlock != BLOCK_SPARSE); - - ret = RedBufferGet(pInode->ulDataBlock, 0U, CAST_VOID_PTR_PTR(&pInode->pbData)); - } - - return ret; -} - - -/** @brief Seek to a given position within an inode. - - On successful return, pInode->ulDataBlock will be populated with the - physical block number corresponding to the @p ulBlock block offset. - - Note: Callers of this function depend on its parameter checking. - - @param pInode A pointer to the cached inode structure. - @param ulBlock The block offset to seek to. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_ENODATA The block offset is sparse. - @retval -RED_EINVAL @p ulBlock is too large; or @p pInode is not a - mounted cached inode pointer. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedInodeDataSeek( - CINODE *pInode, - uint32_t ulBlock) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_MOUNTED(pInode) || (ulBlock >= INODE_DATA_BLOCKS)) - { - ret = -RED_EINVAL; - } - else - { - SeekCoord(pInode, ulBlock); - - #if DINDIR_POINTERS > 0U - if(pInode->uDindirEntry != COORD_ENTRY_INVALID) - { - if(pInode->ulDindirBlock == BLOCK_SPARSE) - { - /* If the double indirect is unallocated, so is the indirect. - */ - pInode->ulIndirBlock = BLOCK_SPARSE; - } - else - { - if(pInode->pDindir == NULL) - { - ret = RedBufferGet(pInode->ulDindirBlock, BFLAG_META_DINDIR, CAST_VOID_PTR_PTR(&pInode->pDindir)); - } - - if(ret == 0) - { - pInode->ulIndirBlock = pInode->pDindir->aulEntries[pInode->uDindirEntry]; - } - } - } - #endif - - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - if((ret == 0) && (pInode->uIndirEntry != COORD_ENTRY_INVALID)) - { - if(pInode->ulIndirBlock == BLOCK_SPARSE) - { - /* If the indirect is unallocated, so is the data block. - */ - pInode->ulDataBlock = BLOCK_SPARSE; - } - else - { - if(pInode->pIndir == NULL) - { - ret = RedBufferGet(pInode->ulIndirBlock, BFLAG_META_INDIR, CAST_VOID_PTR_PTR(&pInode->pIndir)); - } - - if(ret == 0) - { - pInode->ulDataBlock = pInode->pIndir->aulEntries[pInode->uIndirEntry]; - } - } - } - #endif - - if((ret == 0) && (pInode->ulDataBlock == BLOCK_SPARSE)) - { - ret = -RED_ENODATA; - } - } - - return ret; -} - - -/** @brief Seek to the coordinates. - - Compute the new coordinates, and put any buffers which are not needed or are - no longer appropriate. - - @param pInode A pointer to the cached inode structure. - @param ulBlock The block offset to seek to. -*/ -static void SeekCoord( - CINODE *pInode, - uint32_t ulBlock) -{ - if(!CINODE_IS_MOUNTED(pInode) || (ulBlock >= INODE_DATA_BLOCKS)) - { - REDERROR(); - } - else if((pInode->ulLogicalBlock != ulBlock) || !pInode->fCoordInited) - { - RedInodePutData(pInode); - pInode->ulLogicalBlock = ulBlock; - - #if REDCONF_DIRECT_POINTERS > 0U - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - if(ulBlock < REDCONF_DIRECT_POINTERS) - #endif - { - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - RedInodePutCoord(pInode); - #endif - - pInode->uInodeEntry = (uint16_t)ulBlock; - pInode->ulDataBlock = pInode->pInodeBuf->aulEntries[pInode->uInodeEntry]; - - #if DINDIR_POINTERS > 0U - pInode->uDindirEntry = COORD_ENTRY_INVALID; - #endif - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - pInode->uIndirEntry = COORD_ENTRY_INVALID; - #endif - } - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - else - #endif - #endif - #if REDCONF_INDIRECT_POINTERS > 0U - #if REDCONF_INDIRECT_POINTERS < INODE_ENTRIES - if(ulBlock < (INODE_INDIR_BLOCKS + REDCONF_DIRECT_POINTERS)) - #endif - { - uint32_t ulIndirRangeOffset = ulBlock - REDCONF_DIRECT_POINTERS; - uint16_t uInodeEntry = (uint16_t)((ulIndirRangeOffset / INDIR_ENTRIES) + REDCONF_DIRECT_POINTERS); - uint16_t uIndirEntry = (uint16_t)(ulIndirRangeOffset % INDIR_ENTRIES); - - #if DINDIR_POINTERS > 0U - RedInodePutDindir(pInode); - #endif - - /* If the inode entry is not changing, then the previous indirect - is still the correct one. Otherwise, the old indirect will be - released and the new one will be read later. - */ - if((pInode->uInodeEntry != uInodeEntry) || !pInode->fCoordInited) - { - RedInodePutIndir(pInode); - - pInode->uInodeEntry = uInodeEntry; - - pInode->ulIndirBlock = pInode->pInodeBuf->aulEntries[pInode->uInodeEntry]; - } - - #if DINDIR_POINTERS > 0U - pInode->uDindirEntry = COORD_ENTRY_INVALID; - #endif - pInode->uIndirEntry = uIndirEntry; - - /* At this point, the following pInode members are needed but not - yet populated: - - - pIndir - - ulDataBlock - */ - } - #if DINDIR_POINTERS > 0U - else - #endif - #endif - #if DINDIR_POINTERS > 0U - { - uint32_t ulDindirRangeOffset = (ulBlock - REDCONF_DIRECT_POINTERS) - INODE_INDIR_BLOCKS; - uint16_t uInodeEntry = (uint16_t)((ulDindirRangeOffset / DINDIR_DATA_BLOCKS) + REDCONF_DIRECT_POINTERS + REDCONF_INDIRECT_POINTERS); - uint32_t ulDindirNodeOffset = ulDindirRangeOffset % DINDIR_DATA_BLOCKS; - uint16_t uDindirEntry = (uint16_t)(ulDindirNodeOffset / INDIR_ENTRIES); - uint16_t uIndirEntry = (uint16_t)(ulDindirNodeOffset % INDIR_ENTRIES); - - /* If the inode entry is not changing, then the previous double - indirect is still the correct one. Otherwise, the old double - indirect will be released and the new one will be read later. - */ - if((pInode->uInodeEntry != uInodeEntry) || !pInode->fCoordInited) - { - RedInodePutIndir(pInode); - RedInodePutDindir(pInode); - - pInode->uInodeEntry = uInodeEntry; - - pInode->ulDindirBlock = pInode->pInodeBuf->aulEntries[pInode->uInodeEntry]; - } - /* If neither the inode entry nor double indirect entry are - changing, then the previous indirect is still the correct one. - Otherwise, it old indirect will be released and the new one will - be read later. - */ - else if(pInode->uDindirEntry != uDindirEntry) - { - RedInodePutIndir(pInode); - } - else - { - /* Data buffer has already been put, nothing to do. - */ - } - - pInode->uDindirEntry = uDindirEntry; - pInode->uIndirEntry = uIndirEntry; - - /* At this point, the following pInode members are needed but not - yet populated: - - - pDindir - - pIndir - - ulIndirBlock - - ulDataBlock - */ - } - #elif (REDCONF_DIRECT_POINTERS > 0U) && (REDCONF_INDIRECT_POINTERS > 0U) - else - { - /* There are no double indirects, so the block should have been in - the direct or indirect range. - */ - REDERROR(); - } - #endif - - pInode->fCoordInited = true; - } - else - { - /* Seeking to the current position, nothing to do. - */ - } -} - - -/** @brief Read an unaligned portion of a block. - - @param pInode A pointer to the cached inode structure. - @param ullStart The file offset at which to read. - @param ulLen The number of bytes to read. - @param pbBuffer The buffer to read into. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS ReadUnaligned( - CINODE *pInode, - uint64_t ullStart, - uint32_t ulLen, - uint8_t *pbBuffer) -{ - REDSTATUS ret; - - /* This read should not cross a block boundary. - */ - if( ((ullStart >> BLOCK_SIZE_P2) != (((ullStart + ulLen) - 1U) >> BLOCK_SIZE_P2)) - || (pbBuffer == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - ret = RedInodeDataSeekAndRead(pInode, (uint32_t)(ullStart >> BLOCK_SIZE_P2)); - - if(ret == 0) - { - RedMemCpy(pbBuffer, &pInode->pbData[ullStart & (REDCONF_BLOCK_SIZE - 1U)], ulLen); - } - else if(ret == -RED_ENODATA) - { - /* Sparse block, return zeroed data. - */ - RedMemSet(pbBuffer, 0U, ulLen); - ret = 0; - } - else - { - /* No action, just return the error. - */ - } - } - - return ret; -} - - -/** @brief Read one or more whole blocks. - - @param pInode A pointer to the cached inode structure. - @param ulBlockStart The file block offset at which to read. - @param ulBlockCount The number of blocks to read. - @param pbBuffer The buffer to read into. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS ReadAligned( - CINODE *pInode, - uint32_t ulBlockStart, - uint32_t ulBlockCount, - uint8_t *pbBuffer) -{ - REDSTATUS ret = 0; - - if(pbBuffer == NULL) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - uint32_t ulBlockIndex = 0U; - - /* Read the data from disk one contiguous extent at a time. - */ - while((ret == 0) && (ulBlockIndex < ulBlockCount)) - { - uint32_t ulExtentStart; - uint32_t ulExtentLen = ulBlockCount - ulBlockIndex; - - ret = GetExtent(pInode, ulBlockStart + ulBlockIndex, &ulExtentStart, &ulExtentLen); - - if(ret == 0) - { - #if REDCONF_READ_ONLY == 0 - /* Before reading directly from disk, flush any dirty file data - buffers in the range to avoid reading stale data. - */ - ret = RedBufferFlush(ulExtentStart, ulExtentLen); - - if(ret == 0) - #endif - { - ret = RedIoRead(gbRedVolNum, ulExtentStart, ulExtentLen, &pbBuffer[ulBlockIndex << BLOCK_SIZE_P2]); - - if(ret == 0) - { - ulBlockIndex += ulExtentLen; - } - } - } - else if(ret == -RED_ENODATA) - { - /* Sparse block, return zeroed data. - */ - RedMemSet(&pbBuffer[ulBlockIndex << BLOCK_SIZE_P2], 0U, REDCONF_BLOCK_SIZE); - ulBlockIndex++; - ret = 0; - } - else - { - /* An unexpected error occurred; the loop will terminate. - */ - } - } - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Write an unaligned portion of a block. - - @param pInode A pointer to the cached inode structure. - @param ullStart The file offset at which to write. - @param ulLen The number of bytes to write. - @param pbBuffer The buffer to write from. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC No data can be written because there is insufficient - free space. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS WriteUnaligned( - CINODE *pInode, - uint64_t ullStart, - uint32_t ulLen, - const uint8_t *pbBuffer) -{ - REDSTATUS ret; - - /* This write should not cross a block boundary. - */ - if( ((ullStart >> BLOCK_SIZE_P2) != (((ullStart + ulLen) - 1U) >> BLOCK_SIZE_P2)) - || (pbBuffer == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - ret = RedInodeDataSeek(pInode, (uint32_t)(ullStart >> BLOCK_SIZE_P2)); - - if((ret == 0) || (ret == -RED_ENODATA)) - { - ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, true); - - if(ret == 0) - { - RedMemCpy(&pInode->pbData[ullStart & (REDCONF_BLOCK_SIZE - 1U)], pbBuffer, ulLen); - } - } - } - - return ret; -} - - -/** @brief Write one or more whole blocks. - - @param pInode A pointer to the cached inode structure. - @param ulBlockStart The file block offset at which to write. - @param pulBlockCount On entry, the number of blocks to attempt to write. - On successful return, the number of blocks actually - written. - @param pbBuffer The buffer to write from. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC No data can be written because there is insufficient - free space. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS WriteAligned( - CINODE *pInode, - uint32_t ulBlockStart, - uint32_t *pulBlockCount, - const uint8_t *pbBuffer) -{ - REDSTATUS ret = 0; - - if((pulBlockCount == NULL) || (pbBuffer == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - bool fFull = false; - uint32_t ulBlockCount = *pulBlockCount; - uint32_t ulBlockIndex; - - /* Branch all of the file data blocks in advance. - */ - for(ulBlockIndex = 0U; (ulBlockIndex < ulBlockCount) && !fFull; ulBlockIndex++) - { - ret = RedInodeDataSeek(pInode, ulBlockStart + ulBlockIndex); - - if((ret == 0) || (ret == -RED_ENODATA)) - { - ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, false); - - if(ret == -RED_ENOSPC) - { - if(ulBlockIndex > 0U) - { - ret = 0; - } - - fFull = true; - } - } - - if(ret != 0) - { - break; - } - } - - ulBlockCount = ulBlockIndex; - ulBlockIndex = 0U; - - if(fFull) - { - ulBlockCount--; - } - - /* Write the data to disk one contiguous extent at a time. - */ - while((ret == 0) && (ulBlockIndex < ulBlockCount)) - { - uint32_t ulExtentStart; - uint32_t ulExtentLen = ulBlockCount - ulBlockIndex; - - ret = GetExtent(pInode, ulBlockStart + ulBlockIndex, &ulExtentStart, &ulExtentLen); - - if(ret == 0) - { - ret = RedIoWrite(gbRedVolNum, ulExtentStart, ulExtentLen, &pbBuffer[ulBlockIndex << BLOCK_SIZE_P2]); - - if(ret == 0) - { - /* If there is any buffered file data for the extent we - just wrote, those buffers are now stale. - */ - ret = RedBufferDiscardRange(ulExtentStart, ulExtentLen); - } - - if(ret == 0) - { - ulBlockIndex += ulExtentLen; - } - } - } - - if(ret == 0) - { - *pulBlockCount = ulBlockCount; - } - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ - - -/** @brief Get the physical block number and count of contiguous blocks given a - starting logical block number. - - @param pInode A pointer to the cached inode structure. - @param ulBlockStart The file block offset for the start of the extent. - @param pulExtentStart On successful return, the starting physical block - number of the contiguous extent. - @param pulExtentLen On entry, the maximum length of the extent; on - successful return, the length of the contiguous - extent. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENODATA The block offset is sparse. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS GetExtent( - CINODE *pInode, - uint32_t ulBlockStart, - uint32_t *pulExtentStart, - uint32_t *pulExtentLen) -{ - REDSTATUS ret; - - if((pulExtentStart == NULL) || (pulExtentLen == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - ret = RedInodeDataSeek(pInode, ulBlockStart); - - if(ret == 0) - { - uint32_t ulExtentLen = *pulExtentLen; - uint32_t ulFirstBlock = pInode->ulDataBlock; - uint32_t ulRunLen = 1U; - - while((ret == 0) && (ulRunLen < ulExtentLen)) - { - ret = RedInodeDataSeek(pInode, ulBlockStart + ulRunLen); - - /* The extent ends when we find a sparse data block or when the - data block is not contiguous with the preceding data block. - */ - if((ret == -RED_ENODATA) || ((ret == 0) && (pInode->ulDataBlock != (ulFirstBlock + ulRunLen)))) - { - ret = 0; - break; - } - - ulRunLen++; - } - - if(ret == 0) - { - *pulExtentStart = ulFirstBlock; - *pulExtentLen = ulRunLen; - } - } - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Allocate or branch the file metadata path and data block if necessary. - - Optionally, can stop allocating/branching at a certain depth. - - @param pInode A pointer to the cached inode structure. - @param depth A BRANCHDEPTH_ value indicating the lowest depth to branch. - @param fBuffer Whether to buffer the data block. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC No data can be written because there is insufficient - free space. -*/ -static REDSTATUS BranchBlock( - CINODE *pInode, - BRANCHDEPTH depth, - bool fBuffer) -{ - REDSTATUS ret; - uint32_t ulCost = 0U; /* Init'd to quiet warnings. */ - - ret = BranchBlockCost(pInode, depth, &ulCost); - - if((ret == 0) && (ulCost > FreeBlockCount())) - { - ret = -RED_ENOSPC; - } - - if(ret == 0) - { - #if DINDIR_POINTERS > 0U - if(pInode->uDindirEntry != COORD_ENTRY_INVALID) - { - ret = BranchOneBlock(&pInode->ulDindirBlock, CAST_VOID_PTR_PTR(&pInode->pDindir), BFLAG_META_DINDIR); - - if(ret == 0) - { - /* In case we just created the double indirect. - */ - pInode->pDindir->ulInode = pInode->ulInode; - - pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = pInode->ulDindirBlock; - } - } - - if(ret == 0) - #endif - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - { - if((pInode->uIndirEntry != COORD_ENTRY_INVALID) && (depth >= BRANCHDEPTH_INDIR)) - { - ret = BranchOneBlock(&pInode->ulIndirBlock, CAST_VOID_PTR_PTR(&pInode->pIndir), BFLAG_META_INDIR); - - if(ret == 0) - { - /* In case we just created the indirect. - */ - pInode->pIndir->ulInode = pInode->ulInode; - - #if DINDIR_POINTERS > 0U - if(pInode->uDindirEntry != COORD_ENTRY_INVALID) - { - pInode->pDindir->aulEntries[pInode->uDindirEntry] = pInode->ulIndirBlock; - } - else - #endif - { - pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = pInode->ulIndirBlock; - } - } - } - } - - if(ret == 0) - #endif - { - if(depth == BRANCHDEPTH_FILE_DATA) - { - #if REDCONF_INODE_BLOCKS == 1 - bool fAllocedNew = (pInode->ulDataBlock == BLOCK_SPARSE); - #endif - void **ppBufPtr = (fBuffer || (pInode->pbData != NULL)) ? CAST_VOID_PTR_PTR(&pInode->pbData) : NULL; - - ret = BranchOneBlock(&pInode->ulDataBlock, ppBufPtr, 0U); - - if(ret == 0) - { - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - if(pInode->uIndirEntry != COORD_ENTRY_INVALID) - { - pInode->pIndir->aulEntries[pInode->uIndirEntry] = pInode->ulDataBlock; - } - else - #endif - { - pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = pInode->ulDataBlock; - } - - #if REDCONF_INODE_BLOCKS == 1 - if(fAllocedNew) - { - if(pInode->pInodeBuf->ulBlocks < INODE_DATA_BLOCKS) - { - pInode->pInodeBuf->ulBlocks++; - } - else - { - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - } - #endif - } - } - } - - CRITICAL_ASSERT(ret == 0); - } - - return ret; -} - - -/** @brief Branch a block. - - The block can be a double indirect, indirect, or file data block. - - The caller should have already handled the disk full implications of - branching this block. - - @param pulBlock On entry, the current block number, which may be - BLOCK_SPARSE if the block is to be newly allocated. On - successful return, populated with the new block number, - which may be the same as the original block number if it - was not BLOCK_SPARSE and the block was already branched. - @param ppBuffer If NULL, indicates that the caller does not want to buffer - the branched block. If non-NULL, the caller does want the - branched block buffered, and the following is true: On - entry, the current buffer for the block, if there is one, or - NULL if there is no buffer. On successful exit, populated - with a buffer for the block, which will be dirty. If the - block number is initially BLOCK_SPARSE, there should be no - buffer for the block. - @param uBFlag The buffer type flags: BFLAG_META_DINDIR, BFLAG_META_INDIR, - or zero for file data. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS BranchOneBlock( - uint32_t *pulBlock, - void **ppBuffer, - uint16_t uBFlag) -{ - REDSTATUS ret = 0; - - if(pulBlock == NULL) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - ALLOCSTATE state = ALLOCSTATE_FREE; - uint32_t ulPrevBlock = *pulBlock; - - if(ulPrevBlock != BLOCK_SPARSE) - { - ret = RedImapBlockState(ulPrevBlock, &state); - } - - if(ret == 0) - { - if(state == ALLOCSTATE_NEW) - { - /* Block is already branched, so simply get it buffered dirty - if requested. - */ - if(ppBuffer != NULL) - { - if(*ppBuffer != NULL) - { - RedBufferDirty(*ppBuffer); - } - else - { - ret = RedBufferGet(ulPrevBlock, uBFlag | BFLAG_DIRTY, ppBuffer); - } - } - } - else - { - /* Block does not exist or is committed state, so allocate a - new block for the branch. - */ - ret = RedImapAllocBlock(pulBlock); - - if(ret == 0) - { - if(ulPrevBlock == BLOCK_SPARSE) - { - /* Block did not exist previously, so just get it - buffered if requested. - */ - if(ppBuffer != NULL) - { - if(*ppBuffer != NULL) - { - /* How could there be an existing buffer when - the block did not exist? - */ - REDERROR(); - ret = -RED_EINVAL; - } - else - { - ret = RedBufferGet(*pulBlock, (uint16_t)((uint32_t)uBFlag | BFLAG_NEW | BFLAG_DIRTY), ppBuffer); - } - } - } - else - { - /* Branch the buffer for the committed state block to - the newly allocated location. - */ - if(ppBuffer != NULL) - { - if(*ppBuffer == NULL) - { - ret = RedBufferGet(ulPrevBlock, uBFlag, ppBuffer); - } - - if(ret == 0) - { - RedBufferBranch(*ppBuffer, *pulBlock); - } - } - - /* Mark the committed state block almost free. - */ - if(ret == 0) - { - ret = RedImapBlockSet(ulPrevBlock, false); - } - } - } - } - } - } - - return ret; -} - - -/** @brief Compute the free space cost of branching a block. - - The caller must first use RedInodeDataSeek() to the block to be branched. - - @param pInode A pointer to the cached inode structure, whose coordinates - indicate the block to be branched. - @param depth A BRANCHDEPTH_ value indicating how much of the file - metadata structure needs to be branched. - @param pulCost On successful return, populated with the number of blocks - that must be allocated from free space in order to branch - the given block. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EINVAL Invalid parameters. -*/ -static REDSTATUS BranchBlockCost( - const CINODE *pInode, - BRANCHDEPTH depth, - uint32_t *pulCost) -{ - REDSTATUS ret = 0; - - if(!CINODE_IS_MOUNTED(pInode) || !pInode->fCoordInited || (depth > BRANCHDEPTH_MAX) || (pulCost == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else - { - ALLOCSTATE state; - - /* ulCost is initialized to the maximum number of blocks that could - be branched, and decremented for every block we determine does not - need to be branched. - */ - #if DINDIR_POINTERS > 0U - uint32_t ulCost = 3U; - #elif REDCONF_DIRECT_POINTERS < INODE_ENTRIES - uint32_t ulCost = 2U; - #else - uint32_t ulCost = 1U; - #endif - - #if DINDIR_POINTERS > 0U - if(pInode->uDindirEntry != COORD_ENTRY_INVALID) - { - if(pInode->ulDindirBlock != BLOCK_SPARSE) - { - ret = RedImapBlockState(pInode->ulDindirBlock, &state); - - if((ret == 0) && (state == ALLOCSTATE_NEW)) - { - /* Double indirect already branched. - */ - ulCost--; - } - } - } - else - { - /* At this inode offset there are no double indirects. - */ - ulCost--; - } - - if(ret == 0) - #endif - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - { - if((pInode->uIndirEntry != COORD_ENTRY_INVALID) && (depth >= BRANCHDEPTH_INDIR)) - { - if(pInode->ulIndirBlock != BLOCK_SPARSE) - { - ret = RedImapBlockState(pInode->ulIndirBlock, &state); - - if((ret == 0) && (state == ALLOCSTATE_NEW)) - { - /* Indirect already branched. - */ - ulCost--; - } - } - } - else - { - /* Either not branching this deep, or at this inode offset - there are no indirects. - */ - ulCost--; - } - } - - if(ret == 0) - #endif - { - if(depth == BRANCHDEPTH_FILE_DATA) - { - if(pInode->ulDataBlock != BLOCK_SPARSE) - { - ret = RedImapBlockState(pInode->ulDataBlock, &state); - - if((ret == 0) && (state == ALLOCSTATE_NEW)) - { - /* File data block already branched. - */ - ulCost--; - - /* If the file data block is branched, then its parent - nodes should be branched as well. - */ - REDASSERT(ulCost == 0U); - } - } - } - else - { - /* Not branching this deep. - */ - ulCost--; - } - } - - if(ret == 0) - { - *pulCost = ulCost; - } - } - - return ret; -} - - -/** @brief Yields the number of currently available free blocks. - - Accounts for reserved blocks, subtracting the number of reserved blocks if - they are unavailable. - - @return Number of currently available free blocks. -*/ -static uint32_t FreeBlockCount(void) -{ - uint32_t ulFreeBlocks = gpRedMR->ulFreeBlocks; - - #if RESERVED_BLOCKS > 0U - if(!gpRedCoreVol->fUseReservedBlocks) - { - if(ulFreeBlocks >= RESERVED_BLOCKS) - { - ulFreeBlocks -= RESERVED_BLOCKS; - } - else - { - ulFreeBlocks = 0U; - } - } - #endif - - return ulFreeBlocks; -} -#endif /* REDCONF_READ_ONLY == 0 */ - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements inode I/O functions. + */ +#include +#include + + +/* This value is used to initialize the uIndirEntry and uDindirEntry members of + * the CINODE structure. After seeking, a value of COORD_ENTRY_INVALID in + * uIndirEntry indicates that there is no indirect node in the path through the + * file metadata structure, and a value of COORD_ENTRY_INVALID in uDindirEntry + * indicates that there is no double indirect node. + */ +#define COORD_ENTRY_INVALID ( UINT16_MAX ) + +/* This enumeration is used by the BranchBlock() and BranchBlockCost() + * functions to determine which blocks of the file metadata structure need to + * be branched, and which to ignore. DINDIR requires requires branching the + * double indirect only, INDIR requires branching the double indirect + * (if present) and the indirect, and FILE_DATA requires branching the indirect + * and double indirect (if present) and the file data block. + */ +typedef enum +{ + BRANCHDEPTH_DINDIR = 0U, + BRANCHDEPTH_INDIR = 1U, + BRANCHDEPTH_FILE_DATA = 2U, + BRANCHDEPTH_MAX = BRANCHDEPTH_FILE_DATA +} BRANCHDEPTH; + + +#if REDCONF_READ_ONLY == 0 + #if DELETE_SUPPORTED || TRUNCATE_SUPPORTED + static REDSTATUS Shrink( CINODE * pInode, + uint64_t ullSize ); + #if DINDIR_POINTERS > 0U + static REDSTATUS TruncDindir( CINODE * pInode, + bool * pfFreed ); + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + static REDSTATUS TruncIndir( CINODE * pInode, + bool * pfFreed ); + #endif + static REDSTATUS TruncDataBlock( const CINODE * pInode, + uint32_t * pulBlock, + bool fPropagate ); + #endif /* if DELETE_SUPPORTED || TRUNCATE_SUPPORTED */ + static REDSTATUS ExpandPrepare( CINODE * pInode ); +#endif /* if REDCONF_READ_ONLY == 0 */ +static void SeekCoord( CINODE * pInode, + uint32_t ulBlock ); +static REDSTATUS ReadUnaligned( CINODE * pInode, + uint64_t ullStart, + uint32_t ulLen, + uint8_t * pbBuffer ); +static REDSTATUS ReadAligned( CINODE * pInode, + uint32_t ulBlockStart, + uint32_t ulBlockCount, + uint8_t * pbBuffer ); +#if REDCONF_READ_ONLY == 0 + static REDSTATUS WriteUnaligned( CINODE * pInode, + uint64_t ullStart, + uint32_t ulLen, + const uint8_t * pbBuffer ); + static REDSTATUS WriteAligned( CINODE * pInode, + uint32_t ulBlockStart, + uint32_t * pulBlockCount, + const uint8_t * pbBuffer ); +#endif +static REDSTATUS GetExtent( CINODE * pInode, + uint32_t ulBlockStart, + uint32_t * pulExtentStart, + uint32_t * pulExtentLen ); +#if REDCONF_READ_ONLY == 0 + static REDSTATUS BranchBlock( CINODE * pInode, + BRANCHDEPTH depth, + bool fBuffer ); + static REDSTATUS BranchOneBlock( uint32_t * pulBlock, + void ** ppBuffer, + uint16_t uBFlag ); + static REDSTATUS BranchBlockCost( const CINODE * pInode, + BRANCHDEPTH depth, + uint32_t * pulCost ); + static uint32_t FreeBlockCount( void ); +#endif /* if REDCONF_READ_ONLY == 0 */ + + +/** @brief Read data from an inode. + * + * @param pInode A pointer to the cached inode structure of the inode from + * which to read. + * @param ullStart The file offset at which to read. + * @param pulLen On input, the number of bytes to attempt to read. On + * successful return, populated with the number of bytes + * actually read. + * @param pBuffer The buffer to read into. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer; or + * @p pulLen is `NULL`; or @p pBuffer is `NULL`. + */ +REDSTATUS RedInodeDataRead( CINODE * pInode, + uint64_t ullStart, + uint32_t * pulLen, + void * pBuffer ) +{ + REDSTATUS ret = 0; + + if( !CINODE_IS_MOUNTED( pInode ) || ( pulLen == NULL ) || ( pBuffer == NULL ) ) + { + ret = -RED_EINVAL; + } + else if( ullStart >= pInode->pInodeBuf->ullSize ) + { + *pulLen = 0U; + } + else if( *pulLen == 0U ) + { + /* Do nothing, just return success. + */ + } + else + { + uint8_t * pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR( pBuffer ); + uint32_t ulReadIndex = 0U; + uint32_t ulLen = *pulLen; + uint32_t ulRemaining; + + /* Reading beyond the end of the file is not allowed. If the requested + * read extends beyond the end of the file, truncate the read length so + * that the read stops at the end of the file. + */ + if( ( pInode->pInodeBuf->ullSize - ullStart ) < ulLen ) + { + ulLen = ( uint32_t ) ( pInode->pInodeBuf->ullSize - ullStart ); + } + + ulRemaining = ulLen; + + /* Unaligned partial block at start. + */ + if( ( ullStart & ( REDCONF_BLOCK_SIZE - 1U ) ) != 0U ) + { + uint32_t ulBytesInFirstBlock = REDCONF_BLOCK_SIZE - ( uint32_t ) ( ullStart & ( REDCONF_BLOCK_SIZE - 1U ) ); + uint32_t ulThisRead = REDMIN( ulRemaining, ulBytesInFirstBlock ); + + ret = ReadUnaligned( pInode, ullStart, ulThisRead, pbBuffer ); + + if( ret == 0 ) + { + ulReadIndex += ulThisRead; + ulRemaining -= ulThisRead; + } + } + + /* Whole blocks. + */ + if( ( ret == 0 ) && ( ulRemaining >= REDCONF_BLOCK_SIZE ) ) + { + uint32_t ulBlockOffset = ( uint32_t ) ( ( ullStart + ulReadIndex ) >> BLOCK_SIZE_P2 ); + uint32_t ulBlockCount = ulRemaining >> BLOCK_SIZE_P2; + + REDASSERT( ( ( ullStart + ulReadIndex ) & ( REDCONF_BLOCK_SIZE - 1U ) ) == 0U ); + + ret = ReadAligned( pInode, ulBlockOffset, ulBlockCount, &pbBuffer[ ulReadIndex ] ); + + if( ret == 0 ) + { + ulReadIndex += ulBlockCount << BLOCK_SIZE_P2; + ulRemaining -= ulBlockCount << BLOCK_SIZE_P2; + } + } + + /* Aligned partial block at end. + */ + if( ( ret == 0 ) && ( ulRemaining > 0U ) ) + { + REDASSERT( ulRemaining < REDCONF_BLOCK_SIZE ); + REDASSERT( ( ( ullStart + ulReadIndex ) & ( REDCONF_BLOCK_SIZE - 1U ) ) == 0U ); + + ret = ReadUnaligned( pInode, ullStart + ulReadIndex, ulRemaining, &pbBuffer[ ulReadIndex ] ); + } + + if( ret == 0 ) + { + *pulLen = ulLen; + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Write to an inode. + * + * @param pInode A pointer to the cached inode structure of the inode into + * which to write. + * @param ullStart The file offset at which to write. + * @param pulLen On input, the number of bytes to attempt to write. On + * successful return, populated with the number of bytes + * actually written. + * @param pBuffer The buffer to write from. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EFBIG @p ullStart is greater than the maximum file size; or + * @p ullStart is equal to the maximum file size and the + * write length is non-zero. + * @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer; or + * @p pulLen is `NULL`; or @p pBuffer is `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC No data can be written because there is insufficient + * free space. + */ + REDSTATUS RedInodeDataWrite( CINODE * pInode, + uint64_t ullStart, + uint32_t * pulLen, + const void * pBuffer ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_DIRTY( pInode ) || ( pulLen == NULL ) || ( pBuffer == NULL ) ) + { + ret = -RED_EINVAL; + } + else if( ( ullStart > INODE_SIZE_MAX ) || ( ( ullStart == INODE_SIZE_MAX ) && ( *pulLen > 0U ) ) ) + { + ret = -RED_EFBIG; + } + else if( *pulLen == 0U ) + { + /* Do nothing, just return success. + */ + } + else + { + const uint8_t * pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pBuffer ); + uint32_t ulWriteIndex = 0U; + uint32_t ulLen = *pulLen; + uint32_t ulRemaining; + + if( ( INODE_SIZE_MAX - ullStart ) < ulLen ) + { + ulLen = ( uint32_t ) ( INODE_SIZE_MAX - ullStart ); + } + + ulRemaining = ulLen; + + /* If the write is beyond the current end of the file, and the current + * end of the file is not block-aligned, then there may be some data + * that needs to be zeroed in the last block. + */ + if( ullStart > pInode->pInodeBuf->ullSize ) + { + ret = ExpandPrepare( pInode ); + } + + /* Partial block at start. + */ + if( ( ret == 0 ) && ( ( ( ullStart & ( REDCONF_BLOCK_SIZE - 1U ) ) != 0U ) || ( ulRemaining < REDCONF_BLOCK_SIZE ) ) ) + { + uint32_t ulBytesInFirstBlock = REDCONF_BLOCK_SIZE - ( uint32_t ) ( ullStart & ( REDCONF_BLOCK_SIZE - 1U ) ); + uint32_t ulThisWrite = REDMIN( ulRemaining, ulBytesInFirstBlock ); + + ret = WriteUnaligned( pInode, ullStart, ulThisWrite, pbBuffer ); + + if( ret == 0 ) + { + ulWriteIndex += ulThisWrite; + ulRemaining -= ulThisWrite; + } + } + + /* Whole blocks. + */ + if( ( ret == 0 ) && ( ulRemaining >= REDCONF_BLOCK_SIZE ) ) + { + uint32_t ulBlockOffset = ( uint32_t ) ( ( ullStart + ulWriteIndex ) >> BLOCK_SIZE_P2 ); + uint32_t ulBlockCount = ulRemaining >> BLOCK_SIZE_P2; + uint32_t ulBlocksWritten = ulBlockCount; + + REDASSERT( ( ( ullStart + ulWriteIndex ) & ( REDCONF_BLOCK_SIZE - 1U ) ) == 0U ); + + ret = WriteAligned( pInode, ulBlockOffset, &ulBlocksWritten, &pbBuffer[ ulWriteIndex ] ); + + if( ( ret == -RED_ENOSPC ) && ( ulWriteIndex > 0U ) ) + { + ulBlocksWritten = 0U; + ret = 0; + } + + if( ret == 0 ) + { + ulWriteIndex += ulBlocksWritten << BLOCK_SIZE_P2; + ulRemaining -= ulBlocksWritten << BLOCK_SIZE_P2; + + if( ulBlocksWritten < ulBlockCount ) + { + ulRemaining = 0U; + } + } + } + + /* Partial block at end. + */ + if( ( ret == 0 ) && ( ulRemaining > 0U ) ) + { + REDASSERT( ulRemaining < REDCONF_BLOCK_SIZE ); + REDASSERT( ( ( ullStart + ulWriteIndex ) & ( REDCONF_BLOCK_SIZE - 1U ) ) == 0U ); + REDASSERT( ulWriteIndex > 0U ); + + ret = WriteUnaligned( pInode, ullStart + ulWriteIndex, ulRemaining, &pbBuffer[ ulWriteIndex ] ); + + if( ret == -RED_ENOSPC ) + { + ret = 0; + } + else if( ret == 0 ) + { + ulWriteIndex += ulRemaining; + + REDASSERT( ulWriteIndex == ulLen ); + } + else + { + /* Unexpected error, return it. + */ + } + } + + if( ret == 0 ) + { + *pulLen = ulWriteIndex; + + if( ( ullStart + ulWriteIndex ) > pInode->pInodeBuf->ullSize ) + { + pInode->pInodeBuf->ullSize = ullStart + ulWriteIndex; + } + } + } + + return ret; + } + + + #if DELETE_SUPPORTED || TRUNCATE_SUPPORTED + +/** @brief Change the size of an inode. + * + * @param pInode A pointer to the cached inode structure. + * @param ullSize The new file size for the inode. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EFBIG @p ullSize is greater than the maximum file size. + * @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC Insufficient free space to perform the truncate. + */ + REDSTATUS RedInodeDataTruncate( CINODE * pInode, + uint64_t ullSize ) + { + REDSTATUS ret = 0; + + /* The inode does not need to be dirtied when it is being deleted, because + * the inode buffer will be discarded without ever being written to disk. + * Thus, we only check to see if it's mounted here. + */ + if( !CINODE_IS_MOUNTED( pInode ) ) + { + ret = -RED_EINVAL; + } + else if( ullSize > INODE_SIZE_MAX ) + { + ret = -RED_EFBIG; + } + else + { + if( ullSize > pInode->pInodeBuf->ullSize ) + { + ret = ExpandPrepare( pInode ); + } + else if( ullSize < pInode->pInodeBuf->ullSize ) + { + ret = Shrink( pInode, ullSize ); + } + else + { + /* Size is staying the same, nothing to do. + */ + } + + if( ret == 0 ) + { + pInode->pInodeBuf->ullSize = ullSize; + } + } + + return ret; + } + + +/** @brief Free all file data beyond a specified point. + * + * @param pInode A pointer to the cached inode structure. + * @param ullSize The point beyond which to free all file data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC Insufficient free space to perform the truncate. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS Shrink( CINODE * pInode, + uint64_t ullSize ) + { + REDSTATUS ret = 0; + + /* pInode->fDirty is checked explicitly here, instead of using the + * CINODE_IS_DIRTY() macro, to avoid a duplicate mount check. + */ + if( !CINODE_IS_MOUNTED( pInode ) || ( ( ullSize > 0U ) && !pInode->fDirty ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulTruncBlock = ( uint32_t ) ( ( ullSize + REDCONF_BLOCK_SIZE - 1U ) >> BLOCK_SIZE_P2 ); + + RedInodePutData( pInode ); + + #if REDCONF_DIRECT_POINTERS > 0U + while( ulTruncBlock < REDCONF_DIRECT_POINTERS ) + { + ret = TruncDataBlock( pInode, &pInode->pInodeBuf->aulEntries[ ulTruncBlock ], true ); + + if( ret != 0 ) + { + break; + } + + ulTruncBlock++; + } + #endif /* if REDCONF_DIRECT_POINTERS > 0U */ + + #if REDCONF_INDIRECT_POINTERS > 0U + while( ( ret == 0 ) && ( ulTruncBlock < ( REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS ) ) ) + { + ret = RedInodeDataSeek( pInode, ulTruncBlock ); + + if( ( ret == 0 ) || ( ret == -RED_ENODATA ) ) + { + bool fFreed; + + ret = TruncIndir( pInode, &fFreed ); + + if( ret == 0 ) + { + if( fFreed ) + { + pInode->pInodeBuf->aulEntries[ pInode->uInodeEntry ] = BLOCK_SPARSE; + } + + /* The next seek will go to the beginning of the next + * indirect. + */ + ulTruncBlock += ( INDIR_ENTRIES - pInode->uIndirEntry ); + } + } + } + #endif /* if REDCONF_INDIRECT_POINTERS > 0U */ + + #if DINDIR_POINTERS > 0U + while( ( ret == 0 ) && ( ulTruncBlock < INODE_DATA_BLOCKS ) ) + { + ret = RedInodeDataSeek( pInode, ulTruncBlock ); + + if( ( ret == 0 ) || ( ret == -RED_ENODATA ) ) + { + bool fFreed; + + /* TruncDindir() invokes seek as it goes along, which will + * update the entry values (possibly all three of these); + * make a copy so we can compute things correctly after. + */ + uint16_t uOrigInodeEntry = pInode->uInodeEntry; + uint16_t uOrigDindirEntry = pInode->uDindirEntry; + uint16_t uOrigIndirEntry = pInode->uIndirEntry; + + ret = TruncDindir( pInode, &fFreed ); + + if( ret == 0 ) + { + if( fFreed ) + { + pInode->pInodeBuf->aulEntries[ uOrigInodeEntry ] = BLOCK_SPARSE; + } + + /* The next seek will go to the beginning of the next + * double indirect. + */ + ulTruncBlock += ( DINDIR_DATA_BLOCKS - ( uOrigDindirEntry * INDIR_ENTRIES ) ) - uOrigIndirEntry; + } + } + } + #endif /* if DINDIR_POINTERS > 0U */ + } + + return ret; + } + + + #if DINDIR_POINTERS > 0U + +/** @brief Truncate a double indirect. + * + * @param pInode A pointer to the cached inode, whose coordinates indicate + * the truncation boundary. + * @param pfFreed On successful return, populated with whether the double + * indirect node was freed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC Insufficient free space to perform the truncate. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS TruncDindir( CINODE * pInode, + bool * pfFreed ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_MOUNTED( pInode ) || ( pfFreed == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( pInode->pDindir == NULL ) + { + *pfFreed = false; + } + else + { + bool fBranch = false; + uint16_t uEntry; + + /* The double indirect is definitely going to be branched (instead of + * deleted) if any of its indirect pointers which are entirely prior to + * the truncation boundary are non-sparse. + */ + for( uEntry = 0U; !fBranch && ( uEntry < pInode->uDindirEntry ); uEntry++ ) + { + fBranch = pInode->pDindir->aulEntries[ uEntry ] != BLOCK_SPARSE; + } + + /* Unless we already know for a fact that the double indirect is going + * to be branched, examine the contents of the indirect pointer which + * straddles the truncation boundary. If the indirect is going to be + * deleted, we know this indirect pointer is going away, and that might + * mean the double indirect is going to be deleted also. + */ + if( !fBranch && ( pInode->pDindir->aulEntries[ pInode->uDindirEntry ] != BLOCK_SPARSE ) ) + { + for( uEntry = 0U; !fBranch && ( uEntry < pInode->uIndirEntry ); uEntry++ ) + { + fBranch = pInode->pIndir->aulEntries[ uEntry ] != BLOCK_SPARSE; + } + } + + if( fBranch ) + { + ret = BranchBlock( pInode, BRANCHDEPTH_DINDIR, false ); + } + + if( ret == 0 ) + { + uint32_t ulBlock = pInode->ulLogicalBlock; + uint16_t uStart = pInode->uDindirEntry; /* pInode->uDindirEntry will change. */ + + for( uEntry = uStart; uEntry < INDIR_ENTRIES; uEntry++ ) + { + /* Seek so that TruncIndir() has the correct indirect + * buffer and indirect entry. + */ + ret = RedInodeDataSeek( pInode, ulBlock ); + + if( ret == -RED_ENODATA ) + { + ret = 0; + } + + if( ( ret == 0 ) && ( pInode->ulIndirBlock != BLOCK_SPARSE ) ) + { + bool fIndirFreed; + + ret = TruncIndir( pInode, &fIndirFreed ); + + if( ret == 0 ) + { + /* All of the indirects after the one which straddles + * the truncation boundary should definitely end up + * deleted. + */ + REDASSERT( ( uEntry == uStart ) || fIndirFreed ); + + /* If the double indirect is being freed, all of the + * indirects should be freed too. + */ + REDASSERT( fIndirFreed || fBranch ); + + if( fBranch && fIndirFreed ) + { + pInode->pDindir->aulEntries[ uEntry ] = BLOCK_SPARSE; + } + } + } + + if( ret != 0 ) + { + break; + } + + ulBlock += ( INDIR_ENTRIES - pInode->uIndirEntry ); + } + + if( ret == 0 ) + { + *pfFreed = !fBranch; + + if( !fBranch ) + { + RedInodePutDindir( pInode ); + + ret = RedImapBlockSet( pInode->ulDindirBlock, false ); + } + } + } + } + + return ret; + } + #endif /* DINDIR_POINTERS > 0U */ + + + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + +/** @brief Truncate a indirect. + * + * @param pInode A pointer to the cached inode, whose coordinates indicate + * the truncation boundary. + * @param pfFreed On successful return, populated with whether the indirect + * node was freed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC Insufficient free space to perform the truncate. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS TruncIndir( CINODE * pInode, + bool * pfFreed ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_MOUNTED( pInode ) || ( pfFreed == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( pInode->pIndir == NULL ) + { + *pfFreed = false; + } + else + { + bool fBranch = false; + uint16_t uEntry; + + /* Scan the range of entries which are not being truncated. If there + * is anything there, then the indirect will not be empty after the + * truncate, so it is branched and modified instead of deleted. + */ + for( uEntry = 0U; !fBranch && ( uEntry < pInode->uIndirEntry ); uEntry++ ) + { + fBranch = pInode->pIndir->aulEntries[ uEntry ] != BLOCK_SPARSE; + } + + if( fBranch ) + { + ret = BranchBlock( pInode, BRANCHDEPTH_INDIR, false ); + } + + if( ret == 0 ) + { + for( uEntry = pInode->uIndirEntry; uEntry < INDIR_ENTRIES; uEntry++ ) + { + ret = TruncDataBlock( pInode, &pInode->pIndir->aulEntries[ uEntry ], fBranch ); + + if( ret != 0 ) + { + break; + } + } + + if( ret == 0 ) + { + *pfFreed = !fBranch; + + if( !fBranch ) + { + RedInodePutIndir( pInode ); + + ret = RedImapBlockSet( pInode->ulIndirBlock, false ); + } + } + } + } + + return ret; + } + #endif /* REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ + + +/** @brief Truncate a file data block. + * + * @param pInode A pointer to the cached inode structure. + * @param pulBlock On entry, contains the block to be truncated. On + * successful return, if @p fPropagate is true, populated + * with BLOCK_SPARSE, otherwise unmodified. + * @param fPropagate Whether the parent node is being branched. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS TruncDataBlock( const CINODE * pInode, + uint32_t * pulBlock, + bool fPropagate ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_MOUNTED( pInode ) || ( pulBlock == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( *pulBlock != BLOCK_SPARSE ) + { + ret = RedImapBlockSet( *pulBlock, false ); + + #if REDCONF_INODE_BLOCKS == 1 + if( ret == 0 ) + { + if( pInode->pInodeBuf->ulBlocks == 0U ) + { + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else + { + pInode->pInodeBuf->ulBlocks--; + } + } + #endif /* if REDCONF_INODE_BLOCKS == 1 */ + + if( ( ret == 0 ) && fPropagate ) + { + *pulBlock = BLOCK_SPARSE; + } + } + else + { + /* Data block is sparse, nothing to truncate. + */ + } + + return ret; + } + #endif /* DELETE_SUPPORTED || TRUNCATE_SUPPORTED */ + + +/** @brief Prepare to increase the file size. + * + * When the inode size is increased, a sparse region is created. It is + * possible that a prior shrink operation to an unaligned size left stale data + * beyond the end of the file in the last data block. That data is not zeroed + * while shrinking the inode in order to transfer the disk full burden from the + * shrink operation to the expand operation. + * + * @param pInode A pointer to the cached inode structure. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC Insufficient free space to perform the truncate. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS ExpandPrepare( CINODE * pInode ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_DIRTY( pInode ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulOldSizeByteInBlock = ( uint32_t ) ( pInode->pInodeBuf->ullSize & ( REDCONF_BLOCK_SIZE - 1U ) ); + + if( ulOldSizeByteInBlock != 0U ) + { + ret = RedInodeDataSeek( pInode, ( uint32_t ) ( pInode->pInodeBuf->ullSize >> BLOCK_SIZE_P2 ) ); + + if( ret == -RED_ENODATA ) + { + ret = 0; + } + else if( ret == 0 ) + { + ret = BranchBlock( pInode, BRANCHDEPTH_FILE_DATA, true ); + + if( ret == 0 ) + { + RedMemSet( &pInode->pbData[ ulOldSizeByteInBlock ], 0U, REDCONF_BLOCK_SIZE - ulOldSizeByteInBlock ); + } + } + else + { + REDERROR(); + } + } + } + + return ret; + } +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Seek to a given position within an inode, then buffer the data block. + * + * On successful return, pInode->pbData will be populated with a buffer + * corresponding to the @p ulBlock block offset. + * + * @param pInode A pointer to the cached inode structure. + * @param ulBlock The block offset to seek to and buffer. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_ENODATA The block offset is sparse. + * @retval -RED_EINVAL @p ulBlock is too large. + * @retval -RED_EIO A disk I/O error occurred. + */ +REDSTATUS RedInodeDataSeekAndRead( CINODE * pInode, + uint32_t ulBlock ) +{ + REDSTATUS ret; + + ret = RedInodeDataSeek( pInode, ulBlock ); + + if( ( ret == 0 ) && ( pInode->pbData == NULL ) ) + { + REDASSERT( pInode->ulDataBlock != BLOCK_SPARSE ); + + ret = RedBufferGet( pInode->ulDataBlock, 0U, CAST_VOID_PTR_PTR( &pInode->pbData ) ); + } + + return ret; +} + + +/** @brief Seek to a given position within an inode. + * + * On successful return, pInode->ulDataBlock will be populated with the + * physical block number corresponding to the @p ulBlock block offset. + * + * Note: Callers of this function depend on its parameter checking. + * + * @param pInode A pointer to the cached inode structure. + * @param ulBlock The block offset to seek to. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_ENODATA The block offset is sparse. + * @retval -RED_EINVAL @p ulBlock is too large; or @p pInode is not a + * mounted cached inode pointer. + * @retval -RED_EIO A disk I/O error occurred. + */ +REDSTATUS RedInodeDataSeek( CINODE * pInode, + uint32_t ulBlock ) +{ + REDSTATUS ret = 0; + + if( !CINODE_IS_MOUNTED( pInode ) || ( ulBlock >= INODE_DATA_BLOCKS ) ) + { + ret = -RED_EINVAL; + } + else + { + SeekCoord( pInode, ulBlock ); + + #if DINDIR_POINTERS > 0U + if( pInode->uDindirEntry != COORD_ENTRY_INVALID ) + { + if( pInode->ulDindirBlock == BLOCK_SPARSE ) + { + /* If the double indirect is unallocated, so is the indirect. + */ + pInode->ulIndirBlock = BLOCK_SPARSE; + } + else + { + if( pInode->pDindir == NULL ) + { + ret = RedBufferGet( pInode->ulDindirBlock, BFLAG_META_DINDIR, CAST_VOID_PTR_PTR( &pInode->pDindir ) ); + } + + if( ret == 0 ) + { + pInode->ulIndirBlock = pInode->pDindir->aulEntries[ pInode->uDindirEntry ]; + } + } + } + #endif /* if DINDIR_POINTERS > 0U */ + + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + if( ( ret == 0 ) && ( pInode->uIndirEntry != COORD_ENTRY_INVALID ) ) + { + if( pInode->ulIndirBlock == BLOCK_SPARSE ) + { + /* If the indirect is unallocated, so is the data block. + */ + pInode->ulDataBlock = BLOCK_SPARSE; + } + else + { + if( pInode->pIndir == NULL ) + { + ret = RedBufferGet( pInode->ulIndirBlock, BFLAG_META_INDIR, CAST_VOID_PTR_PTR( &pInode->pIndir ) ); + } + + if( ret == 0 ) + { + pInode->ulDataBlock = pInode->pIndir->aulEntries[ pInode->uIndirEntry ]; + } + } + } + #endif /* if REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ + + if( ( ret == 0 ) && ( pInode->ulDataBlock == BLOCK_SPARSE ) ) + { + ret = -RED_ENODATA; + } + } + + return ret; +} + + +/** @brief Seek to the coordinates. + * + * Compute the new coordinates, and put any buffers which are not needed or are + * no longer appropriate. + * + * @param pInode A pointer to the cached inode structure. + * @param ulBlock The block offset to seek to. + */ +static void SeekCoord( CINODE * pInode, + uint32_t ulBlock ) +{ + if( !CINODE_IS_MOUNTED( pInode ) || ( ulBlock >= INODE_DATA_BLOCKS ) ) + { + REDERROR(); + } + else if( ( pInode->ulLogicalBlock != ulBlock ) || !pInode->fCoordInited ) + { + RedInodePutData( pInode ); + pInode->ulLogicalBlock = ulBlock; + + #if REDCONF_DIRECT_POINTERS > 0U + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + if( ulBlock < REDCONF_DIRECT_POINTERS ) + #endif + { + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + RedInodePutCoord( pInode ); + #endif + + pInode->uInodeEntry = ( uint16_t ) ulBlock; + pInode->ulDataBlock = pInode->pInodeBuf->aulEntries[ pInode->uInodeEntry ]; + + #if DINDIR_POINTERS > 0U + pInode->uDindirEntry = COORD_ENTRY_INVALID; + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + pInode->uIndirEntry = COORD_ENTRY_INVALID; + #endif + } + + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + else + #endif + #endif /* if REDCONF_DIRECT_POINTERS > 0U */ + #if REDCONF_INDIRECT_POINTERS > 0U + #if REDCONF_INDIRECT_POINTERS < INODE_ENTRIES + if( ulBlock < ( INODE_INDIR_BLOCKS + REDCONF_DIRECT_POINTERS ) ) + #endif + { + uint32_t ulIndirRangeOffset = ulBlock - REDCONF_DIRECT_POINTERS; + uint16_t uInodeEntry = ( uint16_t ) ( ( ulIndirRangeOffset / INDIR_ENTRIES ) + REDCONF_DIRECT_POINTERS ); + uint16_t uIndirEntry = ( uint16_t ) ( ulIndirRangeOffset % INDIR_ENTRIES ); + + #if DINDIR_POINTERS > 0U + RedInodePutDindir( pInode ); + #endif + + /* If the inode entry is not changing, then the previous indirect + * is still the correct one. Otherwise, the old indirect will be + * released and the new one will be read later. + */ + if( ( pInode->uInodeEntry != uInodeEntry ) || !pInode->fCoordInited ) + { + RedInodePutIndir( pInode ); + + pInode->uInodeEntry = uInodeEntry; + + pInode->ulIndirBlock = pInode->pInodeBuf->aulEntries[ pInode->uInodeEntry ]; + } + + #if DINDIR_POINTERS > 0U + pInode->uDindirEntry = COORD_ENTRY_INVALID; + #endif + pInode->uIndirEntry = uIndirEntry; + + /* At this point, the following pInode members are needed but not + * yet populated: + * + * - pIndir + * - ulDataBlock + */ + } + + #if DINDIR_POINTERS > 0U + else + #endif + #endif /* if REDCONF_INDIRECT_POINTERS > 0U */ + #if DINDIR_POINTERS > 0U + { + uint32_t ulDindirRangeOffset = ( ulBlock - REDCONF_DIRECT_POINTERS ) - INODE_INDIR_BLOCKS; + uint16_t uInodeEntry = ( uint16_t ) ( ( ulDindirRangeOffset / DINDIR_DATA_BLOCKS ) + REDCONF_DIRECT_POINTERS + REDCONF_INDIRECT_POINTERS ); + uint32_t ulDindirNodeOffset = ulDindirRangeOffset % DINDIR_DATA_BLOCKS; + uint16_t uDindirEntry = ( uint16_t ) ( ulDindirNodeOffset / INDIR_ENTRIES ); + uint16_t uIndirEntry = ( uint16_t ) ( ulDindirNodeOffset % INDIR_ENTRIES ); + + /* If the inode entry is not changing, then the previous double + * indirect is still the correct one. Otherwise, the old double + * indirect will be released and the new one will be read later. + */ + if( ( pInode->uInodeEntry != uInodeEntry ) || !pInode->fCoordInited ) + { + RedInodePutIndir( pInode ); + RedInodePutDindir( pInode ); + + pInode->uInodeEntry = uInodeEntry; + + pInode->ulDindirBlock = pInode->pInodeBuf->aulEntries[ pInode->uInodeEntry ]; + } + + /* If neither the inode entry nor double indirect entry are + * changing, then the previous indirect is still the correct one. + * Otherwise, it old indirect will be released and the new one will + * be read later. + */ + else if( pInode->uDindirEntry != uDindirEntry ) + { + RedInodePutIndir( pInode ); + } + else + { + /* Data buffer has already been put, nothing to do. + */ + } + + pInode->uDindirEntry = uDindirEntry; + pInode->uIndirEntry = uIndirEntry; + + /* At this point, the following pInode members are needed but not + * yet populated: + * + * - pDindir + * - pIndir + * - ulIndirBlock + * - ulDataBlock + */ + } + #elif ( REDCONF_DIRECT_POINTERS > 0U ) && ( REDCONF_INDIRECT_POINTERS > 0U ) + else + { + /* There are no double indirects, so the block should have been in + * the direct or indirect range. + */ + REDERROR(); + } + #endif /* if DINDIR_POINTERS > 0U */ + + pInode->fCoordInited = true; + } + else + { + /* Seeking to the current position, nothing to do. + */ + } +} + + +/** @brief Read an unaligned portion of a block. + * + * @param pInode A pointer to the cached inode structure. + * @param ullStart The file offset at which to read. + * @param ulLen The number of bytes to read. + * @param pbBuffer The buffer to read into. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + */ +static REDSTATUS ReadUnaligned( CINODE * pInode, + uint64_t ullStart, + uint32_t ulLen, + uint8_t * pbBuffer ) +{ + REDSTATUS ret; + + /* This read should not cross a block boundary. + */ + if( ( ( ullStart >> BLOCK_SIZE_P2 ) != ( ( ( ullStart + ulLen ) - 1U ) >> BLOCK_SIZE_P2 ) ) || + ( pbBuffer == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ret = RedInodeDataSeekAndRead( pInode, ( uint32_t ) ( ullStart >> BLOCK_SIZE_P2 ) ); + + if( ret == 0 ) + { + RedMemCpy( pbBuffer, &pInode->pbData[ ullStart & ( REDCONF_BLOCK_SIZE - 1U ) ], ulLen ); + } + else if( ret == -RED_ENODATA ) + { + /* Sparse block, return zeroed data. + */ + RedMemSet( pbBuffer, 0U, ulLen ); + ret = 0; + } + else + { + /* No action, just return the error. + */ + } + } + + return ret; +} + + +/** @brief Read one or more whole blocks. + * + * @param pInode A pointer to the cached inode structure. + * @param ulBlockStart The file block offset at which to read. + * @param ulBlockCount The number of blocks to read. + * @param pbBuffer The buffer to read into. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + */ +static REDSTATUS ReadAligned( CINODE * pInode, + uint32_t ulBlockStart, + uint32_t ulBlockCount, + uint8_t * pbBuffer ) +{ + REDSTATUS ret = 0; + + if( pbBuffer == NULL ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulBlockIndex = 0U; + + /* Read the data from disk one contiguous extent at a time. + */ + while( ( ret == 0 ) && ( ulBlockIndex < ulBlockCount ) ) + { + uint32_t ulExtentStart; + uint32_t ulExtentLen = ulBlockCount - ulBlockIndex; + + ret = GetExtent( pInode, ulBlockStart + ulBlockIndex, &ulExtentStart, &ulExtentLen ); + + if( ret == 0 ) + { + #if REDCONF_READ_ONLY == 0 + + /* Before reading directly from disk, flush any dirty file data + * buffers in the range to avoid reading stale data. + */ + ret = RedBufferFlush( ulExtentStart, ulExtentLen ); + + if( ret == 0 ) + #endif + { + ret = RedIoRead( gbRedVolNum, ulExtentStart, ulExtentLen, &pbBuffer[ ulBlockIndex << BLOCK_SIZE_P2 ] ); + + if( ret == 0 ) + { + ulBlockIndex += ulExtentLen; + } + } + } + else if( ret == -RED_ENODATA ) + { + /* Sparse block, return zeroed data. + */ + RedMemSet( &pbBuffer[ ulBlockIndex << BLOCK_SIZE_P2 ], 0U, REDCONF_BLOCK_SIZE ); + ulBlockIndex++; + ret = 0; + } + else + { + /* An unexpected error occurred; the loop will terminate. + */ + } + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Write an unaligned portion of a block. + * + * @param pInode A pointer to the cached inode structure. + * @param ullStart The file offset at which to write. + * @param ulLen The number of bytes to write. + * @param pbBuffer The buffer to write from. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC No data can be written because there is insufficient + * free space. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS WriteUnaligned( CINODE * pInode, + uint64_t ullStart, + uint32_t ulLen, + const uint8_t * pbBuffer ) + { + REDSTATUS ret; + + /* This write should not cross a block boundary. + */ + if( ( ( ullStart >> BLOCK_SIZE_P2 ) != ( ( ( ullStart + ulLen ) - 1U ) >> BLOCK_SIZE_P2 ) ) || + ( pbBuffer == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ret = RedInodeDataSeek( pInode, ( uint32_t ) ( ullStart >> BLOCK_SIZE_P2 ) ); + + if( ( ret == 0 ) || ( ret == -RED_ENODATA ) ) + { + ret = BranchBlock( pInode, BRANCHDEPTH_FILE_DATA, true ); + + if( ret == 0 ) + { + RedMemCpy( &pInode->pbData[ ullStart & ( REDCONF_BLOCK_SIZE - 1U ) ], pbBuffer, ulLen ); + } + } + } + + return ret; + } + + +/** @brief Write one or more whole blocks. + * + * @param pInode A pointer to the cached inode structure. + * @param ulBlockStart The file block offset at which to write. + * @param pulBlockCount On entry, the number of blocks to attempt to write. + * On successful return, the number of blocks actually + * written. + * @param pbBuffer The buffer to write from. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC No data can be written because there is insufficient + * free space. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS WriteAligned( CINODE * pInode, + uint32_t ulBlockStart, + uint32_t * pulBlockCount, + const uint8_t * pbBuffer ) + { + REDSTATUS ret = 0; + + if( ( pulBlockCount == NULL ) || ( pbBuffer == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + bool fFull = false; + uint32_t ulBlockCount = *pulBlockCount; + uint32_t ulBlockIndex; + + /* Branch all of the file data blocks in advance. + */ + for( ulBlockIndex = 0U; ( ulBlockIndex < ulBlockCount ) && !fFull; ulBlockIndex++ ) + { + ret = RedInodeDataSeek( pInode, ulBlockStart + ulBlockIndex ); + + if( ( ret == 0 ) || ( ret == -RED_ENODATA ) ) + { + ret = BranchBlock( pInode, BRANCHDEPTH_FILE_DATA, false ); + + if( ret == -RED_ENOSPC ) + { + if( ulBlockIndex > 0U ) + { + ret = 0; + } + + fFull = true; + } + } + + if( ret != 0 ) + { + break; + } + } + + ulBlockCount = ulBlockIndex; + ulBlockIndex = 0U; + + if( fFull ) + { + ulBlockCount--; + } + + /* Write the data to disk one contiguous extent at a time. + */ + while( ( ret == 0 ) && ( ulBlockIndex < ulBlockCount ) ) + { + uint32_t ulExtentStart; + uint32_t ulExtentLen = ulBlockCount - ulBlockIndex; + + ret = GetExtent( pInode, ulBlockStart + ulBlockIndex, &ulExtentStart, &ulExtentLen ); + + if( ret == 0 ) + { + ret = RedIoWrite( gbRedVolNum, ulExtentStart, ulExtentLen, &pbBuffer[ ulBlockIndex << BLOCK_SIZE_P2 ] ); + + if( ret == 0 ) + { + /* If there is any buffered file data for the extent we + * just wrote, those buffers are now stale. + */ + ret = RedBufferDiscardRange( ulExtentStart, ulExtentLen ); + } + + if( ret == 0 ) + { + ulBlockIndex += ulExtentLen; + } + } + } + + if( ret == 0 ) + { + *pulBlockCount = ulBlockCount; + } + } + + return ret; + } +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Get the physical block number and count of contiguous blocks given a + * starting logical block number. + * + * @param pInode A pointer to the cached inode structure. + * @param ulBlockStart The file block offset for the start of the extent. + * @param pulExtentStart On successful return, the starting physical block + * number of the contiguous extent. + * @param pulExtentLen On entry, the maximum length of the extent; on + * successful return, the length of the contiguous + * extent. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENODATA The block offset is sparse. + * @retval -RED_EINVAL Invalid parameters. + */ +static REDSTATUS GetExtent( CINODE * pInode, + uint32_t ulBlockStart, + uint32_t * pulExtentStart, + uint32_t * pulExtentLen ) +{ + REDSTATUS ret; + + if( ( pulExtentStart == NULL ) || ( pulExtentLen == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ret = RedInodeDataSeek( pInode, ulBlockStart ); + + if( ret == 0 ) + { + uint32_t ulExtentLen = *pulExtentLen; + uint32_t ulFirstBlock = pInode->ulDataBlock; + uint32_t ulRunLen = 1U; + + while( ( ret == 0 ) && ( ulRunLen < ulExtentLen ) ) + { + ret = RedInodeDataSeek( pInode, ulBlockStart + ulRunLen ); + + /* The extent ends when we find a sparse data block or when the + * data block is not contiguous with the preceding data block. + */ + if( ( ret == -RED_ENODATA ) || ( ( ret == 0 ) && ( pInode->ulDataBlock != ( ulFirstBlock + ulRunLen ) ) ) ) + { + ret = 0; + break; + } + + ulRunLen++; + } + + if( ret == 0 ) + { + *pulExtentStart = ulFirstBlock; + *pulExtentLen = ulRunLen; + } + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Allocate or branch the file metadata path and data block if necessary. + * + * Optionally, can stop allocating/branching at a certain depth. + * + * @param pInode A pointer to the cached inode structure. + * @param depth A BRANCHDEPTH_ value indicating the lowest depth to branch. + * @param fBuffer Whether to buffer the data block. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC No data can be written because there is insufficient + * free space. + */ + static REDSTATUS BranchBlock( CINODE * pInode, + BRANCHDEPTH depth, + bool fBuffer ) + { + REDSTATUS ret; + uint32_t ulCost = 0U; /* Init'd to quiet warnings. */ + + ret = BranchBlockCost( pInode, depth, &ulCost ); + + if( ( ret == 0 ) && ( ulCost > FreeBlockCount() ) ) + { + ret = -RED_ENOSPC; + } + + if( ret == 0 ) + { + #if DINDIR_POINTERS > 0U + if( pInode->uDindirEntry != COORD_ENTRY_INVALID ) + { + ret = BranchOneBlock( &pInode->ulDindirBlock, CAST_VOID_PTR_PTR( &pInode->pDindir ), BFLAG_META_DINDIR ); + + if( ret == 0 ) + { + /* In case we just created the double indirect. + */ + pInode->pDindir->ulInode = pInode->ulInode; + + pInode->pInodeBuf->aulEntries[ pInode->uInodeEntry ] = pInode->ulDindirBlock; + } + } + + if( ret == 0 ) + #endif /* if DINDIR_POINTERS > 0U */ + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + { + if( ( pInode->uIndirEntry != COORD_ENTRY_INVALID ) && ( depth >= BRANCHDEPTH_INDIR ) ) + { + ret = BranchOneBlock( &pInode->ulIndirBlock, CAST_VOID_PTR_PTR( &pInode->pIndir ), BFLAG_META_INDIR ); + + if( ret == 0 ) + { + /* In case we just created the indirect. + */ + pInode->pIndir->ulInode = pInode->ulInode; + + #if DINDIR_POINTERS > 0U + if( pInode->uDindirEntry != COORD_ENTRY_INVALID ) + { + pInode->pDindir->aulEntries[ pInode->uDindirEntry ] = pInode->ulIndirBlock; + } + else + #endif + { + pInode->pInodeBuf->aulEntries[ pInode->uInodeEntry ] = pInode->ulIndirBlock; + } + } + } + } + + if( ret == 0 ) + #endif /* if REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ + { + if( depth == BRANCHDEPTH_FILE_DATA ) + { + #if REDCONF_INODE_BLOCKS == 1 + bool fAllocedNew = ( pInode->ulDataBlock == BLOCK_SPARSE ); + #endif + void ** ppBufPtr = ( fBuffer || ( pInode->pbData != NULL ) ) ? CAST_VOID_PTR_PTR( &pInode->pbData ) : NULL; + + ret = BranchOneBlock( &pInode->ulDataBlock, ppBufPtr, 0U ); + + if( ret == 0 ) + { + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + if( pInode->uIndirEntry != COORD_ENTRY_INVALID ) + { + pInode->pIndir->aulEntries[ pInode->uIndirEntry ] = pInode->ulDataBlock; + } + else + #endif + { + pInode->pInodeBuf->aulEntries[ pInode->uInodeEntry ] = pInode->ulDataBlock; + } + + #if REDCONF_INODE_BLOCKS == 1 + if( fAllocedNew ) + { + if( pInode->pInodeBuf->ulBlocks < INODE_DATA_BLOCKS ) + { + pInode->pInodeBuf->ulBlocks++; + } + else + { + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + } + #endif /* if REDCONF_INODE_BLOCKS == 1 */ + } + } + } + + CRITICAL_ASSERT( ret == 0 ); + } + + return ret; + } + + +/** @brief Branch a block. + * + * The block can be a double indirect, indirect, or file data block. + * + * The caller should have already handled the disk full implications of + * branching this block. + * + * @param pulBlock On entry, the current block number, which may be + * BLOCK_SPARSE if the block is to be newly allocated. On + * successful return, populated with the new block number, + * which may be the same as the original block number if it + * was not BLOCK_SPARSE and the block was already branched. + * @param ppBuffer If NULL, indicates that the caller does not want to buffer + * the branched block. If non-NULL, the caller does want the + * branched block buffered, and the following is true: On + * entry, the current buffer for the block, if there is one, or + * NULL if there is no buffer. On successful exit, populated + * with a buffer for the block, which will be dirty. If the + * block number is initially BLOCK_SPARSE, there should be no + * buffer for the block. + * @param uBFlag The buffer type flags: BFLAG_META_DINDIR, BFLAG_META_INDIR, + * or zero for file data. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS BranchOneBlock( uint32_t * pulBlock, + void ** ppBuffer, + uint16_t uBFlag ) + { + REDSTATUS ret = 0; + + if( pulBlock == NULL ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ALLOCSTATE state = ALLOCSTATE_FREE; + uint32_t ulPrevBlock = *pulBlock; + + if( ulPrevBlock != BLOCK_SPARSE ) + { + ret = RedImapBlockState( ulPrevBlock, &state ); + } + + if( ret == 0 ) + { + if( state == ALLOCSTATE_NEW ) + { + /* Block is already branched, so simply get it buffered dirty + * if requested. + */ + if( ppBuffer != NULL ) + { + if( *ppBuffer != NULL ) + { + RedBufferDirty( *ppBuffer ); + } + else + { + ret = RedBufferGet( ulPrevBlock, uBFlag | BFLAG_DIRTY, ppBuffer ); + } + } + } + else + { + /* Block does not exist or is committed state, so allocate a + * new block for the branch. + */ + ret = RedImapAllocBlock( pulBlock ); + + if( ret == 0 ) + { + if( ulPrevBlock == BLOCK_SPARSE ) + { + /* Block did not exist previously, so just get it + * buffered if requested. + */ + if( ppBuffer != NULL ) + { + if( *ppBuffer != NULL ) + { + /* How could there be an existing buffer when + * the block did not exist? + */ + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ret = RedBufferGet( *pulBlock, ( uint16_t ) ( ( uint32_t ) uBFlag | BFLAG_NEW | BFLAG_DIRTY ), ppBuffer ); + } + } + } + else + { + /* Branch the buffer for the committed state block to + * the newly allocated location. + */ + if( ppBuffer != NULL ) + { + if( *ppBuffer == NULL ) + { + ret = RedBufferGet( ulPrevBlock, uBFlag, ppBuffer ); + } + + if( ret == 0 ) + { + RedBufferBranch( *ppBuffer, *pulBlock ); + } + } + + /* Mark the committed state block almost free. + */ + if( ret == 0 ) + { + ret = RedImapBlockSet( ulPrevBlock, false ); + } + } + } + } + } + } + + return ret; + } + + +/** @brief Compute the free space cost of branching a block. + * + * The caller must first use RedInodeDataSeek() to the block to be branched. + * + * @param pInode A pointer to the cached inode structure, whose coordinates + * indicate the block to be branched. + * @param depth A BRANCHDEPTH_ value indicating how much of the file + * metadata structure needs to be branched. + * @param pulCost On successful return, populated with the number of blocks + * that must be allocated from free space in order to branch + * the given block. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EINVAL Invalid parameters. + */ + static REDSTATUS BranchBlockCost( const CINODE * pInode, + BRANCHDEPTH depth, + uint32_t * pulCost ) + { + REDSTATUS ret = 0; + + if( !CINODE_IS_MOUNTED( pInode ) || !pInode->fCoordInited || ( depth > BRANCHDEPTH_MAX ) || ( pulCost == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ALLOCSTATE state; + + /* ulCost is initialized to the maximum number of blocks that could + * be branched, and decremented for every block we determine does not + * need to be branched. + */ + #if DINDIR_POINTERS > 0U + uint32_t ulCost = 3U; + #elif REDCONF_DIRECT_POINTERS < INODE_ENTRIES + uint32_t ulCost = 2U; + #else + uint32_t ulCost = 1U; + #endif + + #if DINDIR_POINTERS > 0U + if( pInode->uDindirEntry != COORD_ENTRY_INVALID ) + { + if( pInode->ulDindirBlock != BLOCK_SPARSE ) + { + ret = RedImapBlockState( pInode->ulDindirBlock, &state ); + + if( ( ret == 0 ) && ( state == ALLOCSTATE_NEW ) ) + { + /* Double indirect already branched. + */ + ulCost--; + } + } + } + else + { + /* At this inode offset there are no double indirects. + */ + ulCost--; + } + + if( ret == 0 ) + #endif /* if DINDIR_POINTERS > 0U */ + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + { + if( ( pInode->uIndirEntry != COORD_ENTRY_INVALID ) && ( depth >= BRANCHDEPTH_INDIR ) ) + { + if( pInode->ulIndirBlock != BLOCK_SPARSE ) + { + ret = RedImapBlockState( pInode->ulIndirBlock, &state ); + + if( ( ret == 0 ) && ( state == ALLOCSTATE_NEW ) ) + { + /* Indirect already branched. + */ + ulCost--; + } + } + } + else + { + /* Either not branching this deep, or at this inode offset + * there are no indirects. + */ + ulCost--; + } + } + + if( ret == 0 ) + #endif /* if REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ + { + if( depth == BRANCHDEPTH_FILE_DATA ) + { + if( pInode->ulDataBlock != BLOCK_SPARSE ) + { + ret = RedImapBlockState( pInode->ulDataBlock, &state ); + + if( ( ret == 0 ) && ( state == ALLOCSTATE_NEW ) ) + { + /* File data block already branched. + */ + ulCost--; + + /* If the file data block is branched, then its parent + * nodes should be branched as well. + */ + REDASSERT( ulCost == 0U ); + } + } + } + else + { + /* Not branching this deep. + */ + ulCost--; + } + } + + if( ret == 0 ) + { + *pulCost = ulCost; + } + } + + return ret; + } + + +/** @brief Yields the number of currently available free blocks. + * + * Accounts for reserved blocks, subtracting the number of reserved blocks if + * they are unavailable. + * + * @return Number of currently available free blocks. + */ + static uint32_t FreeBlockCount( void ) + { + uint32_t ulFreeBlocks = gpRedMR->ulFreeBlocks; + + #if RESERVED_BLOCKS > 0U + if( !gpRedCoreVol->fUseReservedBlocks ) + { + if( ulFreeBlocks >= RESERVED_BLOCKS ) + { + ulFreeBlocks -= RESERVED_BLOCKS; + } + else + { + ulFreeBlocks = 0U; + } + } + #endif /* if RESERVED_BLOCKS > 0U */ + + return ulFreeBlocks; + } +#endif /* REDCONF_READ_ONLY == 0 */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/volume.c b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/volume.c index 976a2f01a..8151bd0d4 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/volume.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/driver/volume.c @@ -1,540 +1,542 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements core volume operations. -*/ -#include -#include - - -static bool MetarootIsValid(METAROOT *pMR, bool *pfSectorCRCIsValid); -#ifdef REDCONF_ENDIAN_SWAP -static void MetaRootEndianSwap(METAROOT *pMetaRoot); -#endif - - -/** @brief Mount a file system volume. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt. -*/ -REDSTATUS RedVolMount(void) -{ - REDSTATUS ret; - - #if REDCONF_READ_ONLY == 0 - ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR); - #else - ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDONLY); - #endif - - if(ret == 0) - { - ret = RedVolMountMaster(); - - if(ret == 0) - { - ret = RedVolMountMetaroot(); - } - - if(ret != 0) - { - /* If we fail to mount, invalidate the buffers to prevent any - confusion that could be caused by stale or corrupt metadata. - */ - (void)RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount); - (void)RedOsBDevClose(gbRedVolNum); - } - } - - return ret; -} - - -/** @brief Mount the master block. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO Master block missing, corrupt, or inconsistent with the - compile-time driver settings. -*/ -REDSTATUS RedVolMountMaster(void) -{ - REDSTATUS ret; - MASTERBLOCK *pMB; - - /* Read the master block, to ensure that the disk was formatted with - Reliance Edge. - */ - ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_META_MASTER, CAST_VOID_PTR_PTR(&pMB)); - - if(ret == 0) - { - /* Verify that the driver was compiled with the same settings that - the disk was formatted with. If not, the user has made a - mistake: either the driver settings are wrong, or the disk needs - to be reformatted. - */ - if( (pMB->ulVersion != RED_DISK_LAYOUT_VERSION) - || (pMB->ulInodeCount != gpRedVolConf->ulInodeCount) - || (pMB->ulBlockCount != gpRedVolume->ulBlockCount) - || (pMB->uMaxNameLen != REDCONF_NAME_MAX) - || (pMB->uDirectPointers != REDCONF_DIRECT_POINTERS) - || (pMB->uIndirectPointers != REDCONF_INDIRECT_POINTERS) - || (pMB->bBlockSizeP2 != BLOCK_SIZE_P2) - || (((pMB->bFlags & MBFLAG_API_POSIX) != 0U) != (REDCONF_API_POSIX == 1)) - || (((pMB->bFlags & MBFLAG_INODE_TIMESTAMPS) != 0U) != (REDCONF_INODE_TIMESTAMPS == 1)) - || (((pMB->bFlags & MBFLAG_INODE_BLOCKS) != 0U) != (REDCONF_INODE_BLOCKS == 1))) - { - ret = -RED_EIO; - } - #if REDCONF_API_POSIX == 1 - else if(((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U) != (REDCONF_API_POSIX_LINK == 1)) - { - ret = -RED_EIO; - } - #else - else if((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U) - { - ret = -RED_EIO; - } - #endif - else - { - /* Master block configuration is valid. - - Save the sequence number of the master block in the volume, - since we need it later (see RedVolMountMetaroot()) and we do - not want to re-buffer the master block. - */ - gpRedVolume->ullSequence = pMB->hdr.ullSequence; - } - - RedBufferPut(pMB); - } - - return ret; -} - - -/** @brief Mount the latest metaroot. - - This function also populates the volume contexts. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO Both metaroots are missing or corrupt. -*/ -REDSTATUS RedVolMountMetaroot(void) -{ - REDSTATUS ret; - - ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT, 1U, &gpRedCoreVol->aMR[0U]); - - if(ret == 0) - { - ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + 1U, 1U, &gpRedCoreVol->aMR[1U]); - } - - /* Determine which metaroot is the most recent copy that was written - completely. - */ - if(ret == 0) - { - uint8_t bMR = UINT8_MAX; - bool fSectorCRCIsValid; - - if(MetarootIsValid(&gpRedCoreVol->aMR[0U], &fSectorCRCIsValid)) - { - bMR = 0U; - - #ifdef REDCONF_ENDIAN_SWAP - MetaRootEndianSwap(&gpRedCoreVol->aMR[0U]); - #endif - } - else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid) - { - ret = -RED_EIO; - } - else - { - /* Metaroot is not valid, so it is ignored and there's nothing - to do here. - */ - } - - if(ret == 0) - { - if(MetarootIsValid(&gpRedCoreVol->aMR[1U], &fSectorCRCIsValid)) - { - #ifdef REDCONF_ENDIAN_SWAP - MetaRootEndianSwap(&gpRedCoreVol->aMR[1U]); - #endif - - if((bMR != 0U) || (gpRedCoreVol->aMR[1U].hdr.ullSequence > gpRedCoreVol->aMR[0U].hdr.ullSequence)) - { - bMR = 1U; - } - } - else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid) - { - ret = -RED_EIO; - } - else - { - /* Metaroot is not valid, so it is ignored and there's nothing - to do here. - */ - } - } - - if(ret == 0) - { - if(bMR == UINT8_MAX) - { - /* Neither metaroot was valid. - */ - ret = -RED_EIO; - } - else - { - gpRedCoreVol->bCurMR = bMR; - gpRedMR = &gpRedCoreVol->aMR[bMR]; - } - } - } - - if(ret == 0) - { - /* Normally the metaroot contains the highest sequence number, but the - master block is the last block written during format, so on a - freshly formatted volume the master block sequence number (stored in - gpRedVolume->ullSequence) will be higher than that in the metaroot. - */ - if(gpRedMR->hdr.ullSequence > gpRedVolume->ullSequence) - { - gpRedVolume->ullSequence = gpRedMR->hdr.ullSequence; - } - - /* gpRedVolume->ullSequence stores the *next* sequence number; to avoid - giving the next node written to disk the same sequence number as the - metaroot, increment it here. - */ - ret = RedVolSeqNumIncrement(); - } - - if(ret == 0) - { - gpRedVolume->fMounted = true; - #if REDCONF_READ_ONLY == 0 - gpRedVolume->fReadOnly = false; - #endif - - #if RESERVED_BLOCKS > 0U - gpRedCoreVol->fUseReservedBlocks = false; - #endif - gpRedCoreVol->ulAlmostFreeBlocks = 0U; - - gpRedCoreVol->aMR[1U - gpRedCoreVol->bCurMR] = *gpRedMR; - gpRedCoreVol->bCurMR = 1U - gpRedCoreVol->bCurMR; - gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR]; - } - - return ret; -} - - -/** @brief Determine whether the metaroot is valid. - - @param pMR The metaroot buffer. - @param pfSectorCRCIsValid Populated with whether the first sector of the - metaroot buffer is valid. - - @return Whether the metaroot is valid. - - @retval true The metaroot buffer is valid. - @retval false The metaroot buffer is invalid. -*/ -static bool MetarootIsValid( - METAROOT *pMR, - bool *pfSectorCRCIsValid) -{ - bool fRet = false; - - if(pfSectorCRCIsValid == NULL) - { - REDERROR(); - } - else if(pMR == NULL) - { - REDERROR(); - *pfSectorCRCIsValid = false; - } - #ifdef REDCONF_ENDIAN_SWAP - else if(RedRev32(pMR->hdr.ulSignature) != META_SIG_METAROOT) - #else - else if(pMR->hdr.ulSignature != META_SIG_METAROOT) - #endif - { - *pfSectorCRCIsValid = false; - } - else - { - const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMR); - uint32_t ulSectorCRC = pMR->ulSectorCRC; - uint32_t ulCRC; - - #ifdef REDCONF_ENDIAN_SWAP - ulSectorCRC = RedRev32(ulSectorCRC); - #endif - - /* The sector CRC was zero when the CRC was computed during the - transaction, so it must be zero here. - */ - pMR->ulSectorCRC = 0U; - - ulCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U); - - fRet = ulCRC == ulSectorCRC; - *pfSectorCRCIsValid = fRet; - - if(fRet) - { - if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE) - { - ulCRC = RedCrc32Update(ulCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize); - } - - #ifdef REDCONF_ENDIAN_SWAP - ulCRC = RedRev32(ulCRC); - #endif - - fRet = ulCRC == pMR->hdr.ulCRC; - } - } - - return fRet; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Commit a transaction point. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedVolTransact(void) -{ - REDSTATUS ret = 0; - - REDASSERT(!gpRedVolume->fReadOnly); /* Should be checked by caller. */ - - if(gpRedCoreVol->fBranched) - { - gpRedMR->ulFreeBlocks += gpRedCoreVol->ulAlmostFreeBlocks; - gpRedCoreVol->ulAlmostFreeBlocks = 0U; - - ret = RedBufferFlush(0U, gpRedVolume->ulBlockCount); - - if(ret == 0) - { - gpRedMR->hdr.ulSignature = META_SIG_METAROOT; - gpRedMR->hdr.ullSequence = gpRedVolume->ullSequence; - - ret = RedVolSeqNumIncrement(); - } - - if(ret == 0) - { - const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(gpRedMR); - uint32_t ulSectorCRC; - - #ifdef REDCONF_ENDIAN_SWAP - MetaRootEndianSwap(gpRedMR); - #endif - - gpRedMR->ulSectorCRC = 0U; - - ulSectorCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U); - - if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE) - { - gpRedMR->hdr.ulCRC = RedCrc32Update(ulSectorCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize); - } - else - { - gpRedMR->hdr.ulCRC = ulSectorCRC; - } - - gpRedMR->ulSectorCRC = ulSectorCRC; - - #ifdef REDCONF_ENDIAN_SWAP - gpRedMR->hdr.ulCRC = RedRev32(gpRedMR->hdr.ulCRC); - gpRedMR->ulSectorCRC = RedRev32(gpRedMR->ulSectorCRC); - #endif - - /* Flush the block device before writing the metaroot, so that all - previously written blocks are guaranteed to be on the media before - the metaroot is written. Otherwise, if the block device reorders - the writes, the metaroot could reach the media before metadata it - points at, creating a window for disk corruption if power is lost. - */ - ret = RedIoFlush(gbRedVolNum); - } - - if(ret == 0) - { - ret = RedIoWrite(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + gpRedCoreVol->bCurMR, 1U, gpRedMR); - - #ifdef REDCONF_ENDIAN_SWAP - MetaRootEndianSwap(gpRedMR); - #endif - } - - /* Flush the block device to force the metaroot write to the media. This - guarantees the transaction point is really complete before we return. - */ - if(ret == 0) - { - ret = RedIoFlush(gbRedVolNum); - } - - /* Toggle to the other metaroot buffer. The working state and committed - state metaroot buffers exchange places. - */ - if(ret == 0) - { - uint8_t bNextMR = 1U - gpRedCoreVol->bCurMR; - - gpRedCoreVol->aMR[bNextMR] = *gpRedMR; - gpRedCoreVol->bCurMR = bNextMR; - - gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR]; - - gpRedCoreVol->fBranched = false; - } - - CRITICAL_ASSERT(ret == 0); - } - - return ret; -} -#endif - - -#ifdef REDCONF_ENDIAN_SWAP -static void MetaRootEndianSwap( - METAROOT *pMetaRoot) -{ - if(pMetaRoot == NULL) - { - REDERROR(); - } - else - { - pMetaRoot->ulSectorCRC = RedRev32(pMetaRoot->ulSectorCRC); - pMetaRoot->ulFreeBlocks = RedRev32(pMetaRoot->ulFreeBlocks); - #if REDCONF_API_POSIX == 1 - pMetaRoot->ulFreeInodes = RedRev32(pMetaRoot->ulFreeInodes); - #endif - pMetaRoot->ulAllocNextBlock = RedRev32(pMetaRoot->ulAllocNextBlock); - } -} -#endif - - -/** @brief Process a critical file system error. - - @param pszFileName The file in which the error occurred. - @param ulLineNum The line number at which the error occurred. -*/ -void RedVolCriticalError( - const char *pszFileName, - uint32_t ulLineNum) -{ - #if REDCONF_OUTPUT == 1 - #if REDCONF_READ_ONLY == 0 - if(!gpRedVolume->fReadOnly) - { - RedOsOutputString("Critical file system error in Reliance Edge, setting volume to READONLY\n"); - } - else - #endif - { - RedOsOutputString("Critical file system error in Reliance Edge (volume already READONLY)\n"); - } - #endif - - #if REDCONF_READ_ONLY == 0 - gpRedVolume->fReadOnly = true; - #endif - - #if REDCONF_ASSERTS == 1 - RedOsAssertFail(pszFileName, ulLineNum); - #else - (void)pszFileName; - (void)ulLineNum; - #endif -} - - -/** @brief Increment the sequence number. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL Cannot increment sequence number: maximum value reached. - This should not ever happen. -*/ -REDSTATUS RedVolSeqNumIncrement(void) -{ - REDSTATUS ret; - - if(gpRedVolume->ullSequence == UINT64_MAX) - { - /* In practice this should never, ever happen; to get here, there would - need to be UINT64_MAX disk writes, which would take eons: longer - than the lifetime of any product or storage media. If this assert - fires and the current year is still written with four digits, - suspect memory corruption. - */ - CRITICAL_ERROR(); - ret = -RED_EFUBAR; - } - else - { - gpRedVolume->ullSequence++; - ret = 0; - } - - return ret; -} - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements core volume operations. + */ +#include +#include + + +static bool MetarootIsValid( METAROOT * pMR, + bool * pfSectorCRCIsValid ); +#ifdef REDCONF_ENDIAN_SWAP + static void MetaRootEndianSwap( METAROOT * pMetaRoot ); +#endif + + +/** @brief Mount a file system volume. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt. + */ +REDSTATUS RedVolMount( void ) +{ + REDSTATUS ret; + + #if REDCONF_READ_ONLY == 0 + ret = RedOsBDevOpen( gbRedVolNum, BDEV_O_RDWR ); + #else + ret = RedOsBDevOpen( gbRedVolNum, BDEV_O_RDONLY ); + #endif + + if( ret == 0 ) + { + ret = RedVolMountMaster(); + + if( ret == 0 ) + { + ret = RedVolMountMetaroot(); + } + + if( ret != 0 ) + { + /* If we fail to mount, invalidate the buffers to prevent any + * confusion that could be caused by stale or corrupt metadata. + */ + ( void ) RedBufferDiscardRange( 0U, gpRedVolume->ulBlockCount ); + ( void ) RedOsBDevClose( gbRedVolNum ); + } + } + + return ret; +} + + +/** @brief Mount the master block. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO Master block missing, corrupt, or inconsistent with the + * compile-time driver settings. + */ +REDSTATUS RedVolMountMaster( void ) +{ + REDSTATUS ret; + MASTERBLOCK * pMB; + + /* Read the master block, to ensure that the disk was formatted with + * Reliance Edge. + */ + ret = RedBufferGet( BLOCK_NUM_MASTER, BFLAG_META_MASTER, CAST_VOID_PTR_PTR( &pMB ) ); + + if( ret == 0 ) + { + /* Verify that the driver was compiled with the same settings that + * the disk was formatted with. If not, the user has made a + * mistake: either the driver settings are wrong, or the disk needs + * to be reformatted. + */ + if( ( pMB->ulVersion != RED_DISK_LAYOUT_VERSION ) || + ( pMB->ulInodeCount != gpRedVolConf->ulInodeCount ) || + ( pMB->ulBlockCount != gpRedVolume->ulBlockCount ) || + ( pMB->uMaxNameLen != REDCONF_NAME_MAX ) || + ( pMB->uDirectPointers != REDCONF_DIRECT_POINTERS ) || + ( pMB->uIndirectPointers != REDCONF_INDIRECT_POINTERS ) || + ( pMB->bBlockSizeP2 != BLOCK_SIZE_P2 ) || + ( ( ( pMB->bFlags & MBFLAG_API_POSIX ) != 0U ) != ( REDCONF_API_POSIX == 1 ) ) || + ( ( ( pMB->bFlags & MBFLAG_INODE_TIMESTAMPS ) != 0U ) != ( REDCONF_INODE_TIMESTAMPS == 1 ) ) || + ( ( ( pMB->bFlags & MBFLAG_INODE_BLOCKS ) != 0U ) != ( REDCONF_INODE_BLOCKS == 1 ) ) ) + { + ret = -RED_EIO; + } + + #if REDCONF_API_POSIX == 1 + else if( ( ( pMB->bFlags & MBFLAG_INODE_NLINK ) != 0U ) != ( REDCONF_API_POSIX_LINK == 1 ) ) + { + ret = -RED_EIO; + } + #else + else if( ( pMB->bFlags & MBFLAG_INODE_NLINK ) != 0U ) + { + ret = -RED_EIO; + } + #endif + else + { + /* Master block configuration is valid. + * + * Save the sequence number of the master block in the volume, + * since we need it later (see RedVolMountMetaroot()) and we do + * not want to re-buffer the master block. + */ + gpRedVolume->ullSequence = pMB->hdr.ullSequence; + } + + RedBufferPut( pMB ); + } + + return ret; +} + + +/** @brief Mount the latest metaroot. + * + * This function also populates the volume contexts. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO Both metaroots are missing or corrupt. + */ +REDSTATUS RedVolMountMetaroot( void ) +{ + REDSTATUS ret; + + ret = RedIoRead( gbRedVolNum, BLOCK_NUM_FIRST_METAROOT, 1U, &gpRedCoreVol->aMR[ 0U ] ); + + if( ret == 0 ) + { + ret = RedIoRead( gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + 1U, 1U, &gpRedCoreVol->aMR[ 1U ] ); + } + + /* Determine which metaroot is the most recent copy that was written + * completely. + */ + if( ret == 0 ) + { + uint8_t bMR = UINT8_MAX; + bool fSectorCRCIsValid; + + if( MetarootIsValid( &gpRedCoreVol->aMR[ 0U ], &fSectorCRCIsValid ) ) + { + bMR = 0U; + + #ifdef REDCONF_ENDIAN_SWAP + MetaRootEndianSwap( &gpRedCoreVol->aMR[ 0U ] ); + #endif + } + else if( gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid ) + { + ret = -RED_EIO; + } + else + { + /* Metaroot is not valid, so it is ignored and there's nothing + * to do here. + */ + } + + if( ret == 0 ) + { + if( MetarootIsValid( &gpRedCoreVol->aMR[ 1U ], &fSectorCRCIsValid ) ) + { + #ifdef REDCONF_ENDIAN_SWAP + MetaRootEndianSwap( &gpRedCoreVol->aMR[ 1U ] ); + #endif + + if( ( bMR != 0U ) || ( gpRedCoreVol->aMR[ 1U ].hdr.ullSequence > gpRedCoreVol->aMR[ 0U ].hdr.ullSequence ) ) + { + bMR = 1U; + } + } + else if( gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid ) + { + ret = -RED_EIO; + } + else + { + /* Metaroot is not valid, so it is ignored and there's nothing + * to do here. + */ + } + } + + if( ret == 0 ) + { + if( bMR == UINT8_MAX ) + { + /* Neither metaroot was valid. + */ + ret = -RED_EIO; + } + else + { + gpRedCoreVol->bCurMR = bMR; + gpRedMR = &gpRedCoreVol->aMR[ bMR ]; + } + } + } + + if( ret == 0 ) + { + /* Normally the metaroot contains the highest sequence number, but the + * master block is the last block written during format, so on a + * freshly formatted volume the master block sequence number (stored in + * gpRedVolume->ullSequence) will be higher than that in the metaroot. + */ + if( gpRedMR->hdr.ullSequence > gpRedVolume->ullSequence ) + { + gpRedVolume->ullSequence = gpRedMR->hdr.ullSequence; + } + + /* gpRedVolume->ullSequence stores the *next* sequence number; to avoid + * giving the next node written to disk the same sequence number as the + * metaroot, increment it here. + */ + ret = RedVolSeqNumIncrement(); + } + + if( ret == 0 ) + { + gpRedVolume->fMounted = true; + #if REDCONF_READ_ONLY == 0 + gpRedVolume->fReadOnly = false; + #endif + + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = false; + #endif + gpRedCoreVol->ulAlmostFreeBlocks = 0U; + + gpRedCoreVol->aMR[ 1U - gpRedCoreVol->bCurMR ] = *gpRedMR; + gpRedCoreVol->bCurMR = 1U - gpRedCoreVol->bCurMR; + gpRedMR = &gpRedCoreVol->aMR[ gpRedCoreVol->bCurMR ]; + } + + return ret; +} + + +/** @brief Determine whether the metaroot is valid. + * + * @param pMR The metaroot buffer. + * @param pfSectorCRCIsValid Populated with whether the first sector of the + * metaroot buffer is valid. + * + * @return Whether the metaroot is valid. + * + * @retval true The metaroot buffer is valid. + * @retval false The metaroot buffer is invalid. + */ +static bool MetarootIsValid( METAROOT * pMR, + bool * pfSectorCRCIsValid ) +{ + bool fRet = false; + + if( pfSectorCRCIsValid == NULL ) + { + REDERROR(); + } + else if( pMR == NULL ) + { + REDERROR(); + *pfSectorCRCIsValid = false; + } + + #ifdef REDCONF_ENDIAN_SWAP + else if( RedRev32( pMR->hdr.ulSignature ) != META_SIG_METAROOT ) + #else + else if( pMR->hdr.ulSignature != META_SIG_METAROOT ) + #endif + { + *pfSectorCRCIsValid = false; + } + else + { + const uint8_t * pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pMR ); + uint32_t ulSectorCRC = pMR->ulSectorCRC; + uint32_t ulCRC; + + #ifdef REDCONF_ENDIAN_SWAP + ulSectorCRC = RedRev32( ulSectorCRC ); + #endif + + /* The sector CRC was zero when the CRC was computed during the + * transaction, so it must be zero here. + */ + pMR->ulSectorCRC = 0U; + + ulCRC = RedCrc32Update( 0U, &pbMR[ 8U ], gpRedVolConf->ulSectorSize - 8U ); + + fRet = ulCRC == ulSectorCRC; + *pfSectorCRCIsValid = fRet; + + if( fRet ) + { + if( gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE ) + { + ulCRC = RedCrc32Update( ulCRC, &pbMR[ gpRedVolConf->ulSectorSize ], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize ); + } + + #ifdef REDCONF_ENDIAN_SWAP + ulCRC = RedRev32( ulCRC ); + #endif + + fRet = ulCRC == pMR->hdr.ulCRC; + } + } + + return fRet; +} + + +#if REDCONF_READ_ONLY == 0 + +/** @brief Commit a transaction point. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedVolTransact( void ) + { + REDSTATUS ret = 0; + + REDASSERT( !gpRedVolume->fReadOnly ); /* Should be checked by caller. */ + + if( gpRedCoreVol->fBranched ) + { + gpRedMR->ulFreeBlocks += gpRedCoreVol->ulAlmostFreeBlocks; + gpRedCoreVol->ulAlmostFreeBlocks = 0U; + + ret = RedBufferFlush( 0U, gpRedVolume->ulBlockCount ); + + if( ret == 0 ) + { + gpRedMR->hdr.ulSignature = META_SIG_METAROOT; + gpRedMR->hdr.ullSequence = gpRedVolume->ullSequence; + + ret = RedVolSeqNumIncrement(); + } + + if( ret == 0 ) + { + const uint8_t * pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR( gpRedMR ); + uint32_t ulSectorCRC; + + #ifdef REDCONF_ENDIAN_SWAP + MetaRootEndianSwap( gpRedMR ); + #endif + + gpRedMR->ulSectorCRC = 0U; + + ulSectorCRC = RedCrc32Update( 0U, &pbMR[ 8U ], gpRedVolConf->ulSectorSize - 8U ); + + if( gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE ) + { + gpRedMR->hdr.ulCRC = RedCrc32Update( ulSectorCRC, &pbMR[ gpRedVolConf->ulSectorSize ], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize ); + } + else + { + gpRedMR->hdr.ulCRC = ulSectorCRC; + } + + gpRedMR->ulSectorCRC = ulSectorCRC; + + #ifdef REDCONF_ENDIAN_SWAP + gpRedMR->hdr.ulCRC = RedRev32( gpRedMR->hdr.ulCRC ); + gpRedMR->ulSectorCRC = RedRev32( gpRedMR->ulSectorCRC ); + #endif + + /* Flush the block device before writing the metaroot, so that all + * previously written blocks are guaranteed to be on the media before + * the metaroot is written. Otherwise, if the block device reorders + * the writes, the metaroot could reach the media before metadata it + * points at, creating a window for disk corruption if power is lost. + */ + ret = RedIoFlush( gbRedVolNum ); + } + + if( ret == 0 ) + { + ret = RedIoWrite( gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + gpRedCoreVol->bCurMR, 1U, gpRedMR ); + + #ifdef REDCONF_ENDIAN_SWAP + MetaRootEndianSwap( gpRedMR ); + #endif + } + + /* Flush the block device to force the metaroot write to the media. This + * guarantees the transaction point is really complete before we return. + */ + if( ret == 0 ) + { + ret = RedIoFlush( gbRedVolNum ); + } + + /* Toggle to the other metaroot buffer. The working state and committed + * state metaroot buffers exchange places. + */ + if( ret == 0 ) + { + uint8_t bNextMR = 1U - gpRedCoreVol->bCurMR; + + gpRedCoreVol->aMR[ bNextMR ] = *gpRedMR; + gpRedCoreVol->bCurMR = bNextMR; + + gpRedMR = &gpRedCoreVol->aMR[ gpRedCoreVol->bCurMR ]; + + gpRedCoreVol->fBranched = false; + } + + CRITICAL_ASSERT( ret == 0 ); + } + + return ret; + } +#endif /* if REDCONF_READ_ONLY == 0 */ + + +#ifdef REDCONF_ENDIAN_SWAP + static void MetaRootEndianSwap( METAROOT * pMetaRoot ) + { + if( pMetaRoot == NULL ) + { + REDERROR(); + } + else + { + pMetaRoot->ulSectorCRC = RedRev32( pMetaRoot->ulSectorCRC ); + pMetaRoot->ulFreeBlocks = RedRev32( pMetaRoot->ulFreeBlocks ); + #if REDCONF_API_POSIX == 1 + pMetaRoot->ulFreeInodes = RedRev32( pMetaRoot->ulFreeInodes ); + #endif + pMetaRoot->ulAllocNextBlock = RedRev32( pMetaRoot->ulAllocNextBlock ); + } + } +#endif /* ifdef REDCONF_ENDIAN_SWAP */ + + +/** @brief Process a critical file system error. + * + * @param pszFileName The file in which the error occurred. + * @param ulLineNum The line number at which the error occurred. + */ +void RedVolCriticalError( const char * pszFileName, + uint32_t ulLineNum ) +{ + #if REDCONF_OUTPUT == 1 + #if REDCONF_READ_ONLY == 0 + if( !gpRedVolume->fReadOnly ) + { + RedOsOutputString( "Critical file system error in Reliance Edge, setting volume to READONLY\n" ); + } + else + #endif + { + RedOsOutputString( "Critical file system error in Reliance Edge (volume already READONLY)\n" ); + } + #endif /* if REDCONF_OUTPUT == 1 */ + + #if REDCONF_READ_ONLY == 0 + gpRedVolume->fReadOnly = true; + #endif + + #if REDCONF_ASSERTS == 1 + RedOsAssertFail( pszFileName, ulLineNum ); + #else + ( void ) pszFileName; + ( void ) ulLineNum; + #endif +} + + +/** @brief Increment the sequence number. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL Cannot increment sequence number: maximum value reached. + * This should not ever happen. + */ +REDSTATUS RedVolSeqNumIncrement( void ) +{ + REDSTATUS ret; + + if( gpRedVolume->ullSequence == UINT64_MAX ) + { + /* In practice this should never, ever happen; to get here, there would + * need to be UINT64_MAX disk writes, which would take eons: longer + * than the lifetime of any product or storage media. If this assert + * fires and the current year is still written with four digits, + * suspect memory corruption. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else + { + gpRedVolume->ullSequence++; + ret = 0; + } + + return ret; +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcore.h b/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcore.h index 077eb9347..8611834af 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcore.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcore.h @@ -1,257 +1,313 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDCORE_H -#define REDCORE_H - - -#include -#include -#include "rednodes.h" -#include "redcoremacs.h" -#include "redcorevol.h" - - -#define META_SIG_MASTER (0x5453414DU) /* 'MAST' */ -#define META_SIG_METAROOT (0x4154454DU) /* 'META' */ -#define META_SIG_IMAP (0x50414D49U) /* 'IMAP' */ -#define META_SIG_INODE (0x444F4E49U) /* 'INOD' */ -#define META_SIG_DINDIR (0x494C4244U) /* 'DBLI' */ -#define META_SIG_INDIR (0x49444E49U) /* 'INDI' */ - - -REDSTATUS RedIoRead(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, void *pBuffer); -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedIoWrite(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, const void *pBuffer); -REDSTATUS RedIoFlush(uint8_t bVolNum); -#endif - - -/** Indicates a block buffer is dirty (its contents are different than the - contents of the corresponding block on disk); or, when passed into - RedBufferGet(), indicates that the buffer should be marked dirty. -*/ -#define BFLAG_DIRTY ((uint16_t) 0x0001U) - -/** Tells RedBufferGet() that the buffer is for a newly allocated block, and its - contents should be zeroed instead of being read from disk. Always used in - combination with BFLAG_DIRTY. -*/ -#define BFLAG_NEW ((uint16_t) 0x0002U) - -/** Indicates that a block buffer is a master block (MASTERBLOCK) metadata node. -*/ -#define BFLAG_META_MASTER ((uint16_t)(0x0004U | BFLAG_META)) - -/** Indicates that a block buffer is an imap (IMAPNODE) metadata node. -*/ -#define BFLAG_META_IMAP ((uint16_t)(0x0008U | BFLAG_META)) - -/** Indicates that a block buffer is an inode (INODE) metadata node. -*/ -#define BFLAG_META_INODE ((uint16_t)(0x0010U | BFLAG_META)) - -/** Indicates that a block buffer is an indirect (INDIR) metadata node. -*/ -#define BFLAG_META_INDIR ((uint16_t)(0x0020U | BFLAG_META)) - -/** Indicates that a block buffer is a double indirect (DINDIR) metadata node. -*/ -#define BFLAG_META_DINDIR ((uint16_t)(0x0040U | BFLAG_META)) - -/** Indicates that a block buffer is a metadata node. Callers of RedBufferGet() - should not use this flag; instead, use one of the BFLAG_META_* flags. -*/ -#define BFLAG_META ((uint16_t) 0x8000U) - - -void RedBufferInit(void); -REDSTATUS RedBufferGet(uint32_t ulBlock, uint16_t uFlags, void **ppBuffer); -void RedBufferPut(const void *pBuffer); -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedBufferFlush(uint32_t ulBlockStart, uint32_t ulBlockCount); -void RedBufferDirty(const void *pBuffer); -void RedBufferBranch(const void *pBuffer, uint32_t ulBlockNew); -#if (REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED -void RedBufferDiscard(const void *pBuffer); -#endif -#endif -REDSTATUS RedBufferDiscardRange(uint32_t ulBlockStart, uint32_t ulBlockCount); - - -/** @brief Allocation state of a block. -*/ -typedef enum -{ - ALLOCSTATE_FREE, /**< Free and may be allocated; writeable. */ - ALLOCSTATE_USED, /**< In-use and transacted; not writeable. */ - ALLOCSTATE_NEW, /**< In-use but not transacted; writeable. */ - ALLOCSTATE_AFREE /**< Will become free after a transaction; not writeable. */ -} ALLOCSTATE; - -REDSTATUS RedImapBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated); -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedImapBlockSet(uint32_t ulBlock, bool fAllocated); -REDSTATUS RedImapAllocBlock(uint32_t *pulBlock); -#endif -REDSTATUS RedImapBlockState(uint32_t ulBlock, ALLOCSTATE *pState); - -#if REDCONF_IMAP_INLINE == 1 -REDSTATUS RedImapIBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated); -REDSTATUS RedImapIBlockSet(uint32_t ulBlock, bool fAllocated); -#endif - -#if REDCONF_IMAP_EXTERNAL == 1 -REDSTATUS RedImapEBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated); -REDSTATUS RedImapEBlockSet(uint32_t ulBlock, bool fAllocated); -uint32_t RedImapNodeBlock(uint8_t bMR, uint32_t ulImapNode); -#endif - - -/** @brief Cached inode structure. -*/ -typedef struct -{ - uint32_t ulInode; /**< The inode number of the cached inode. */ - #if REDCONF_API_POSIX == 1 - bool fDirectory; /**< True if the inode is a directory. */ - #endif - #if REDCONF_READ_ONLY == 0 - bool fBranched; /**< True if the inode is branched (writeable). */ - bool fDirty; /**< True if the inode buffer is dirty. */ - #endif - bool fCoordInited; /**< True after the first seek. */ - - INODE *pInodeBuf; /**< Pointer to the inode buffer. */ - #if DINDIR_POINTERS > 0U - DINDIR *pDindir; /**< Pointer to the double indirect node buffer. */ - #endif - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - INDIR *pIndir; /**< Pointer to the indirect node buffer. */ - #endif - uint8_t *pbData; /**< Pointer to the data block buffer. */ - - /* All the members below this point are part of the seek coordinates; see - RedInodeDataSeek(). - */ - uint32_t ulLogicalBlock; /**< Logical block offset into the inode. */ - #if DINDIR_POINTERS > 0U - uint32_t ulDindirBlock; /**< Physical block number of the double indirect node. */ - #endif - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - uint32_t ulIndirBlock; /**< Physical block number of the indirect node. */ - #endif - uint32_t ulDataBlock; /**< Physical block number of the file data block. */ - - uint16_t uInodeEntry; /**< Which inode entry to traverse to reach ulLogicalBlock. */ - #if DINDIR_POINTERS > 0U - uint16_t uDindirEntry; /**< Which double indirect entry to traverse to reach ulLogicalBlock. */ - #endif - #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES - uint16_t uIndirEntry; /**< Which indirect entry to traverse to reach ulLogicalBlock. */ - #endif -} CINODE; - -#define CINODE_IS_MOUNTED(pInode) (((pInode) != NULL) && INODE_IS_VALID((pInode)->ulInode) && ((pInode)->pInodeBuf != NULL)) -#define CINODE_IS_DIRTY(pInode) (CINODE_IS_MOUNTED(pInode) && (pInode)->fDirty) - - -#define IPUT_UPDATE_ATIME (0x01U) -#define IPUT_UPDATE_MTIME (0x02U) -#define IPUT_UPDATE_CTIME (0x04U) -#define IPUT_UPDATE_MASK (IPUT_UPDATE_ATIME|IPUT_UPDATE_MTIME|IPUT_UPDATE_CTIME) - - -REDSTATUS RedInodeMount(CINODE *pInode, FTYPE type, bool fBranch); -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedInodeBranch(CINODE *pInode); -#endif -#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED) -REDSTATUS RedInodeCreate(CINODE *pInode, uint32_t ulPInode, uint16_t uMode); -#endif -#if DELETE_SUPPORTED -REDSTATUS RedInodeDelete(CINODE *pInode); -REDSTATUS RedInodeLinkDec(CINODE *pInode); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) -REDSTATUS RedInodeFree(CINODE *pInode); -#endif -void RedInodePut(CINODE *pInode, uint8_t bTimeFields); -void RedInodePutCoord(CINODE *pInode); -#if DINDIR_POINTERS > 0U -void RedInodePutDindir(CINODE *pInode); -#endif -#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES -void RedInodePutIndir(CINODE *pInode); -#endif -void RedInodePutData(CINODE *pInode); -#if ((REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)) || (REDCONF_CHECKER == 1) -REDSTATUS RedInodeIsFree(uint32_t ulInode, bool *pfFree); -#endif -REDSTATUS RedInodeBitGet(uint8_t bMR, uint32_t ulInode, uint8_t bWhich, bool *pfAllocated); - -REDSTATUS RedInodeDataRead(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer); -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedInodeDataWrite(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer); -#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED -REDSTATUS RedInodeDataTruncate(CINODE *pInode, uint64_t ullSize); -#endif -#endif -REDSTATUS RedInodeDataSeekAndRead(CINODE *pInode, uint32_t ulBlock); -REDSTATUS RedInodeDataSeek(CINODE *pInode, uint32_t ulBlock); - -#if REDCONF_API_POSIX == 1 -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedDirEntryCreate(CINODE *pPInode, const char *pszName, uint32_t ulInode); -#endif -#if DELETE_SUPPORTED -REDSTATUS RedDirEntryDelete(CINODE *pPInode, uint32_t ulDeleteIdx); -#endif -REDSTATUS RedDirEntryLookup(CINODE *pPInode, const char *pszName, uint32_t *pulEntryIdx, uint32_t *pulInode); -#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1) -REDSTATUS RedDirEntryRead(CINODE *pPInode, uint32_t *pulIdx, char *pszName, uint32_t *pulInode); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) -REDSTATUS RedDirEntryRename(CINODE *pSrcPInode, const char *pszSrcName, CINODE *pSrcInode, CINODE *pDstPInode, const char *pszDstName, CINODE *pDstInode); -#endif -#endif - -REDSTATUS RedVolMount(void); -REDSTATUS RedVolMountMaster(void); -REDSTATUS RedVolMountMetaroot(void); -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedVolTransact(void); -#endif -void RedVolCriticalError(const char *pszFileName, uint32_t ulLineNum); -REDSTATUS RedVolSeqNumIncrement(void); - -#if FORMAT_SUPPORTED -REDSTATUS RedVolFormat(void); -#endif - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDCORE_H +#define REDCORE_H + + +#include +#include +#include "rednodes.h" +#include "redcoremacs.h" +#include "redcorevol.h" + + +#define META_SIG_MASTER ( 0x5453414DU ) /* 'MAST' */ +#define META_SIG_METAROOT ( 0x4154454DU ) /* 'META' */ +#define META_SIG_IMAP ( 0x50414D49U ) /* 'IMAP' */ +#define META_SIG_INODE ( 0x444F4E49U ) /* 'INOD' */ +#define META_SIG_DINDIR ( 0x494C4244U ) /* 'DBLI' */ +#define META_SIG_INDIR ( 0x49444E49U ) /* 'INDI' */ + + +REDSTATUS RedIoRead( uint8_t bVolNum, + uint32_t ulBlockStart, + uint32_t ulBlockCount, + void * pBuffer ); +#if REDCONF_READ_ONLY == 0 + REDSTATUS RedIoWrite( uint8_t bVolNum, + uint32_t ulBlockStart, + uint32_t ulBlockCount, + const void * pBuffer ); + REDSTATUS RedIoFlush( uint8_t bVolNum ); +#endif + + +/** Indicates a block buffer is dirty (its contents are different than the + * contents of the corresponding block on disk); or, when passed into + * RedBufferGet(), indicates that the buffer should be marked dirty. + */ +#define BFLAG_DIRTY ( ( uint16_t ) 0x0001U ) + +/** Tells RedBufferGet() that the buffer is for a newly allocated block, and its + * contents should be zeroed instead of being read from disk. Always used in + * combination with BFLAG_DIRTY. + */ +#define BFLAG_NEW ( ( uint16_t ) 0x0002U ) + +/** Indicates that a block buffer is a master block (MASTERBLOCK) metadata node. + */ +#define BFLAG_META_MASTER ( ( uint16_t ) ( 0x0004U | BFLAG_META ) ) + +/** Indicates that a block buffer is an imap (IMAPNODE) metadata node. + */ +#define BFLAG_META_IMAP ( ( uint16_t ) ( 0x0008U | BFLAG_META ) ) + +/** Indicates that a block buffer is an inode (INODE) metadata node. + */ +#define BFLAG_META_INODE ( ( uint16_t ) ( 0x0010U | BFLAG_META ) ) + +/** Indicates that a block buffer is an indirect (INDIR) metadata node. + */ +#define BFLAG_META_INDIR ( ( uint16_t ) ( 0x0020U | BFLAG_META ) ) + +/** Indicates that a block buffer is a double indirect (DINDIR) metadata node. + */ +#define BFLAG_META_DINDIR ( ( uint16_t ) ( 0x0040U | BFLAG_META ) ) + +/** Indicates that a block buffer is a metadata node. Callers of RedBufferGet() + * should not use this flag; instead, use one of the BFLAG_META_* flags. + */ +#define BFLAG_META ( ( uint16_t ) 0x8000U ) + + +void RedBufferInit( void ); +REDSTATUS RedBufferGet( uint32_t ulBlock, + uint16_t uFlags, + void ** ppBuffer ); +void RedBufferPut( const void * pBuffer ); +#if REDCONF_READ_ONLY == 0 + REDSTATUS RedBufferFlush( uint32_t ulBlockStart, + uint32_t ulBlockCount ); + void RedBufferDirty( const void * pBuffer ); + void RedBufferBranch( const void * pBuffer, + uint32_t ulBlockNew ); + #if ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED + void RedBufferDiscard( const void * pBuffer ); + #endif +#endif +REDSTATUS RedBufferDiscardRange( uint32_t ulBlockStart, + uint32_t ulBlockCount ); + + +/** @brief Allocation state of a block. + */ +typedef enum +{ + ALLOCSTATE_FREE, /**< Free and may be allocated; writeable. */ + ALLOCSTATE_USED, /**< In-use and transacted; not writeable. */ + ALLOCSTATE_NEW, /**< In-use but not transacted; writeable. */ + ALLOCSTATE_AFREE /**< Will become free after a transaction; not writeable. */ +} ALLOCSTATE; + +REDSTATUS RedImapBlockGet( uint8_t bMR, + uint32_t ulBlock, + bool * pfAllocated ); +#if REDCONF_READ_ONLY == 0 + REDSTATUS RedImapBlockSet( uint32_t ulBlock, + bool fAllocated ); + REDSTATUS RedImapAllocBlock( uint32_t * pulBlock ); +#endif +REDSTATUS RedImapBlockState( uint32_t ulBlock, + ALLOCSTATE * pState ); + +#if REDCONF_IMAP_INLINE == 1 + REDSTATUS RedImapIBlockGet( uint8_t bMR, + uint32_t ulBlock, + bool * pfAllocated ); + REDSTATUS RedImapIBlockSet( uint32_t ulBlock, + bool fAllocated ); +#endif + +#if REDCONF_IMAP_EXTERNAL == 1 + REDSTATUS RedImapEBlockGet( uint8_t bMR, + uint32_t ulBlock, + bool * pfAllocated ); + REDSTATUS RedImapEBlockSet( uint32_t ulBlock, + bool fAllocated ); + uint32_t RedImapNodeBlock( uint8_t bMR, + uint32_t ulImapNode ); +#endif + + +/** @brief Cached inode structure. + */ +typedef struct +{ + uint32_t ulInode; /**< The inode number of the cached inode. */ + #if REDCONF_API_POSIX == 1 + bool fDirectory; /**< True if the inode is a directory. */ + #endif + #if REDCONF_READ_ONLY == 0 + bool fBranched; /**< True if the inode is branched (writeable). */ + bool fDirty; /**< True if the inode buffer is dirty. */ + #endif + bool fCoordInited; /**< True after the first seek. */ + + INODE * pInodeBuf; /**< Pointer to the inode buffer. */ + #if DINDIR_POINTERS > 0U + DINDIR * pDindir; /**< Pointer to the double indirect node buffer. */ + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + INDIR * pIndir; /**< Pointer to the indirect node buffer. */ + #endif + uint8_t * pbData; /**< Pointer to the data block buffer. */ + + /* All the members below this point are part of the seek coordinates; see + * RedInodeDataSeek(). + */ + uint32_t ulLogicalBlock; /**< Logical block offset into the inode. */ + #if DINDIR_POINTERS > 0U + uint32_t ulDindirBlock; /**< Physical block number of the double indirect node. */ + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + uint32_t ulIndirBlock; /**< Physical block number of the indirect node. */ + #endif + uint32_t ulDataBlock; /**< Physical block number of the file data block. */ + + uint16_t uInodeEntry; /**< Which inode entry to traverse to reach ulLogicalBlock. */ + #if DINDIR_POINTERS > 0U + uint16_t uDindirEntry; /**< Which double indirect entry to traverse to reach ulLogicalBlock. */ + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + uint16_t uIndirEntry; /**< Which indirect entry to traverse to reach ulLogicalBlock. */ + #endif +} CINODE; + +#define CINODE_IS_MOUNTED( pInode ) ( ( ( pInode ) != NULL ) && INODE_IS_VALID( ( pInode )->ulInode ) && ( ( pInode )->pInodeBuf != NULL ) ) +#define CINODE_IS_DIRTY( pInode ) ( CINODE_IS_MOUNTED( pInode ) && ( pInode )->fDirty ) + + +#define IPUT_UPDATE_ATIME ( 0x01U ) +#define IPUT_UPDATE_MTIME ( 0x02U ) +#define IPUT_UPDATE_CTIME ( 0x04U ) +#define IPUT_UPDATE_MASK ( IPUT_UPDATE_ATIME | IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME ) + + +REDSTATUS RedInodeMount( CINODE * pInode, + FTYPE type, + bool fBranch ); +#if REDCONF_READ_ONLY == 0 + REDSTATUS RedInodeBranch( CINODE * pInode ); +#endif +#if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED ) + REDSTATUS RedInodeCreate( CINODE * pInode, + uint32_t ulPInode, + uint16_t uMode ); +#endif +#if DELETE_SUPPORTED + REDSTATUS RedInodeDelete( CINODE * pInode ); + REDSTATUS RedInodeLinkDec( CINODE * pInode ); +#endif +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) + REDSTATUS RedInodeFree( CINODE * pInode ); +#endif +void RedInodePut( CINODE * pInode, + uint8_t bTimeFields ); +void RedInodePutCoord( CINODE * pInode ); +#if DINDIR_POINTERS > 0U + void RedInodePutDindir( CINODE * pInode ); +#endif +#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + void RedInodePutIndir( CINODE * pInode ); +#endif +void RedInodePutData( CINODE * pInode ); +#if ( ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED ) ) || ( REDCONF_CHECKER == 1 ) + REDSTATUS RedInodeIsFree( uint32_t ulInode, + bool * pfFree ); +#endif +REDSTATUS RedInodeBitGet( uint8_t bMR, + uint32_t ulInode, + uint8_t bWhich, + bool * pfAllocated ); + +REDSTATUS RedInodeDataRead( CINODE * pInode, + uint64_t ullStart, + uint32_t * pulLen, + void * pBuffer ); +#if REDCONF_READ_ONLY == 0 + REDSTATUS RedInodeDataWrite( CINODE * pInode, + uint64_t ullStart, + uint32_t * pulLen, + const void * pBuffer ); + #if DELETE_SUPPORTED || TRUNCATE_SUPPORTED + REDSTATUS RedInodeDataTruncate( CINODE * pInode, + uint64_t ullSize ); + #endif +#endif +REDSTATUS RedInodeDataSeekAndRead( CINODE * pInode, + uint32_t ulBlock ); +REDSTATUS RedInodeDataSeek( CINODE * pInode, + uint32_t ulBlock ); + +#if REDCONF_API_POSIX == 1 + #if REDCONF_READ_ONLY == 0 + REDSTATUS RedDirEntryCreate( CINODE * pPInode, + const char * pszName, + uint32_t ulInode ); + #endif + #if DELETE_SUPPORTED + REDSTATUS RedDirEntryDelete( CINODE * pPInode, + uint32_t ulDeleteIdx ); + #endif + REDSTATUS RedDirEntryLookup( CINODE * pPInode, + const char * pszName, + uint32_t * pulEntryIdx, + uint32_t * pulInode ); + #if ( REDCONF_API_POSIX_READDIR == 1 ) || ( REDCONF_CHECKER == 1 ) + REDSTATUS RedDirEntryRead( CINODE * pPInode, + uint32_t * pulIdx, + char * pszName, + uint32_t * pulInode ); + #endif + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RENAME == 1 ) + REDSTATUS RedDirEntryRename( CINODE * pSrcPInode, + const char * pszSrcName, + CINODE * pSrcInode, + CINODE * pDstPInode, + const char * pszDstName, + CINODE * pDstInode ); + #endif +#endif /* if REDCONF_API_POSIX == 1 */ + +REDSTATUS RedVolMount( void ); +REDSTATUS RedVolMountMaster( void ); +REDSTATUS RedVolMountMetaroot( void ); +#if REDCONF_READ_ONLY == 0 + REDSTATUS RedVolTransact( void ); +#endif +void RedVolCriticalError( const char * pszFileName, + uint32_t ulLineNum ); +REDSTATUS RedVolSeqNumIncrement( void ); + +#if FORMAT_SUPPORTED + REDSTATUS RedVolFormat( void ); +#endif + + +#endif /* ifndef REDCORE_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcoremacs.h b/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcoremacs.h index 221ac9197..dfda69822 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcoremacs.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcoremacs.h @@ -1,92 +1,93 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDCOREMACS_H -#define REDCOREMACS_H - - -#define BLOCK_NUM_MASTER (0UL) /* Block number of the master block. */ -#define BLOCK_NUM_FIRST_METAROOT (1UL) /* Block number of the first metaroot. */ - -#define BLOCK_SPARSE (0U) - -#define DINDIR_POINTERS ((INODE_ENTRIES - REDCONF_DIRECT_POINTERS) - REDCONF_INDIRECT_POINTERS) -#define DINDIR_DATA_BLOCKS (INDIR_ENTRIES * INDIR_ENTRIES) - -#define INODE_INDIR_BLOCKS (REDCONF_INDIRECT_POINTERS * INDIR_ENTRIES) -#define INODE_DINDIR_BLOCKS (DINDIR_POINTERS * DINDIR_DATA_BLOCKS) -#define INODE_DATA_BLOCKS (REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS + INODE_DINDIR_BLOCKS) -#define INODE_SIZE_MAX (UINT64_SUFFIX(1) * REDCONF_BLOCK_SIZE * INODE_DATA_BLOCKS) - - -/* First inode number that can be allocated. -*/ -#if REDCONF_API_POSIX == 1 -#define INODE_FIRST_FREE (INODE_FIRST_VALID + 1U) -#else -#define INODE_FIRST_FREE (INODE_FIRST_VALID) -#endif - -/** @brief Determine if an inode number is valid. -*/ -#define INODE_IS_VALID(INODENUM) (((INODENUM) >= INODE_FIRST_VALID) && ((INODENUM) < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount))) - - -/* The number of blocks reserved to allow a truncate or delete operation to - complete when the disk is otherwise full. - - The more expensive of the two operations is delete, which has to actually - write to a file data block to remove the directory entry. -*/ -#if REDCONF_READ_ONLY == 1 - #define RESERVED_BLOCKS 0U -#elif (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) - #if DINDIR_POINTERS > 0U - #define RESERVED_BLOCKS 3U - #elif REDCONF_INDIRECT_POINTERS > 0U - #define RESERVED_BLOCKS 2U - #else - #define RESERVED_BLOCKS 1U - #endif -#elif ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1)) - #if DINDIR_POINTERS > 0U - #define RESERVED_BLOCKS 2U - #elif REDCONF_INDIRECT_POINTERS > 0U - #define RESERVED_BLOCKS 1U - #else - #define RESERVED_BLOCKS 0U - #endif -#else - #define RESERVED_BLOCKS 0U -#endif - - -#define CRITICAL_ASSERT(EXP) ((EXP) ? (void)0 : CRITICAL_ERROR()) -#define CRITICAL_ERROR() RedVolCriticalError(__FILE__, __LINE__) - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDCOREMACS_H +#define REDCOREMACS_H + + +#define BLOCK_NUM_MASTER ( 0UL ) /* Block number of the master block. */ +#define BLOCK_NUM_FIRST_METAROOT ( 1UL ) /* Block number of the first metaroot. */ + +#define BLOCK_SPARSE ( 0U ) + +#define DINDIR_POINTERS ( ( INODE_ENTRIES - REDCONF_DIRECT_POINTERS ) - REDCONF_INDIRECT_POINTERS ) +#define DINDIR_DATA_BLOCKS ( INDIR_ENTRIES * INDIR_ENTRIES ) + +#define INODE_INDIR_BLOCKS ( REDCONF_INDIRECT_POINTERS * INDIR_ENTRIES ) +#define INODE_DINDIR_BLOCKS ( DINDIR_POINTERS * DINDIR_DATA_BLOCKS ) +#define INODE_DATA_BLOCKS ( REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS + INODE_DINDIR_BLOCKS ) +#define INODE_SIZE_MAX ( UINT64_SUFFIX( 1 ) * REDCONF_BLOCK_SIZE * INODE_DATA_BLOCKS ) + + +/* First inode number that can be allocated. + */ +#if REDCONF_API_POSIX == 1 + #define INODE_FIRST_FREE ( INODE_FIRST_VALID + 1U ) +#else + #define INODE_FIRST_FREE ( INODE_FIRST_VALID ) +#endif + +/** @brief Determine if an inode number is valid. + */ +#define INODE_IS_VALID( INODENUM ) ( ( ( INODENUM ) >= INODE_FIRST_VALID ) && ( ( INODENUM ) < ( INODE_FIRST_VALID + gpRedVolConf->ulInodeCount ) ) ) + + +/* The number of blocks reserved to allow a truncate or delete operation to + * complete when the disk is otherwise full. + * + * The more expensive of the two operations is delete, which has to actually + * write to a file data block to remove the directory entry. + */ +#if REDCONF_READ_ONLY == 1 + #define RESERVED_BLOCKS 0U +#elif ( REDCONF_API_POSIX == 1 ) && ( ( REDCONF_API_POSIX_UNLINK == 1 ) || ( REDCONF_API_POSIX_RMDIR == 1 ) ) + #if DINDIR_POINTERS > 0U + #define RESERVED_BLOCKS 3U + #elif REDCONF_INDIRECT_POINTERS > 0U + #define RESERVED_BLOCKS 2U + #else + #define RESERVED_BLOCKS 1U + #endif +#elif ( ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_FTRUNCATE == 1 ) ) || ( ( REDCONF_API_FSE == 1 ) && ( REDCONF_API_FSE_TRUNCATE == 1 ) ) + #if DINDIR_POINTERS > 0U + #define RESERVED_BLOCKS 2U + #elif REDCONF_INDIRECT_POINTERS > 0U + #define RESERVED_BLOCKS 1U + #else + #define RESERVED_BLOCKS 0U + #endif +#else /* if REDCONF_READ_ONLY == 1 */ + #define RESERVED_BLOCKS 0U +#endif /* if REDCONF_READ_ONLY == 1 */ + + +#define CRITICAL_ASSERT( EXP ) ( ( EXP ) ? ( void ) 0 : CRITICAL_ERROR() ) +#define CRITICAL_ERROR() RedVolCriticalError( __FILE__, __LINE__ ) + + +#endif /* ifndef REDCOREMACS_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcorevol.h b/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcorevol.h index 881cbb376..9fa3322a2 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcorevol.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcorevol.h @@ -1,95 +1,98 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDCOREVOL_H -#define REDCOREVOL_H - - -/** @brief Per-volume run-time data specific to the core. -*/ -typedef struct -{ - /** Whether this volume uses the inline imap (true) or external imap - (false). Computed at initialization time based on the block count. - */ - bool fImapInline; - -#if REDCONF_IMAP_EXTERNAL == 1 - /** First block number of the on-disk imap. Valid only when fImapInline - is false. - */ - uint32_t ulImapStartBN; - - /** The number of double-allocated imap nodes that make up the imap. - */ - uint32_t ulImapNodeCount; -#endif - - /** Block number where the inode table starts. - */ - uint32_t ulInodeTableStartBN; - - /** First block number that can be allocated. - */ - uint32_t ulFirstAllocableBN; - - /** The two metaroot structures, committed and working state. - */ - METAROOT aMR[2U]; - - /** The index of the current metaroot; must be 0 or 1. - */ - uint8_t bCurMR; - - /** Whether the volume has been branched or not. - */ - bool fBranched; - - /** The number of blocks which will become free after the next transaction. - */ - uint32_t ulAlmostFreeBlocks; - - #if RESERVED_BLOCKS > 0U - /** Whether to use the blocks reserved for operations that create free - space. - */ - bool fUseReservedBlocks; - #endif -} COREVOLUME; - -/* Pointer to the core volume currently being accessed; populated during - RedCoreVolSetCurrent(). -*/ -extern COREVOLUME * CONST_IF_ONE_VOLUME gpRedCoreVol; - -/* Pointer to the metaroot currently being accessed; populated during - RedCoreVolSetCurrent() and RedCoreVolTransact(). -*/ -extern METAROOT *gpRedMR; - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDCOREVOL_H +#define REDCOREVOL_H + + +/** @brief Per-volume run-time data specific to the core. + */ +typedef struct +{ + /** Whether this volume uses the inline imap (true) or external imap + * (false). Computed at initialization time based on the block count. + */ + bool fImapInline; + + #if REDCONF_IMAP_EXTERNAL == 1 + + /** First block number of the on-disk imap. Valid only when fImapInline + * is false. + */ + uint32_t ulImapStartBN; + + /** The number of double-allocated imap nodes that make up the imap. + */ + uint32_t ulImapNodeCount; + #endif + + /** Block number where the inode table starts. + */ + uint32_t ulInodeTableStartBN; + + /** First block number that can be allocated. + */ + uint32_t ulFirstAllocableBN; + + /** The two metaroot structures, committed and working state. + */ + METAROOT aMR[ 2U ]; + + /** The index of the current metaroot; must be 0 or 1. + */ + uint8_t bCurMR; + + /** Whether the volume has been branched or not. + */ + bool fBranched; + + /** The number of blocks which will become free after the next transaction. + */ + uint32_t ulAlmostFreeBlocks; + + #if RESERVED_BLOCKS > 0U + + /** Whether to use the blocks reserved for operations that create free + * space. + */ + bool fUseReservedBlocks; + #endif +} COREVOLUME; + +/* Pointer to the core volume currently being accessed; populated during + * RedCoreVolSetCurrent(). + */ +extern COREVOLUME * CONST_IF_ONE_VOLUME gpRedCoreVol; + +/* Pointer to the metaroot currently being accessed; populated during + * RedCoreVolSetCurrent() and RedCoreVolTransact(). + */ +extern METAROOT * gpRedMR; + + +#endif /* ifndef REDCOREVOL_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/core/include/rednodes.h b/FreeRTOS-Plus/Source/Reliance-Edge/core/include/rednodes.h index b33387854..cc93dd468 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/core/include/rednodes.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/core/include/rednodes.h @@ -1,195 +1,197 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDNODES_H -#define REDNODES_H - - -#define NODEHEADER_SIZE (16U) -#define NODEHEADER_OFFSET_SIG (0U) -#define NODEHEADER_OFFSET_CRC (4U) -#define NODEHEADER_OFFSET_SEQ (8U) - -/** @brief Common header for all metadata nodes. -*/ -typedef struct -{ - uint32_t ulSignature; /**< Value which uniquely identifies the metadata node type. */ - uint32_t ulCRC; /**< CRC-32 checksum of the node contents, starting after the CRC. */ - uint64_t ullSequence; /**< Current sequence number at the time the node was written to disk. */ -} NODEHEADER; - - -/** Flag set in the master block when REDCONF_API_POSIX == 1. */ -#define MBFLAG_API_POSIX (0x01U) - -/** Flag set in the master block when REDCONF_INODE_TIMESTAMPS == 1. */ -#define MBFLAG_INODE_TIMESTAMPS (0x02U) - -/** Flag set in the master block when REDCONF_INODE_BLOCKS == 1. */ -#define MBFLAG_INODE_BLOCKS (0x04U) - -/** Flag set in the master block when (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1). */ -#define MBFLAG_INODE_NLINK (0x08U) - - -/** @brief Node which identifies the volume and stores static volume information. -*/ -typedef struct -{ - NODEHEADER hdr; /**< Common node header. */ - - uint32_t ulVersion; /**< On-disk layout version number. */ - char acBuildNum[8U]; /**< Build number of the product (not null terminated). */ - uint32_t ulFormatTime; /**< Date and time the volume was formatted. */ - uint32_t ulInodeCount; /**< Compile-time configured number of inodes. */ - uint32_t ulBlockCount; /**< Compile-time configured number of logical blocks. */ - uint16_t uMaxNameLen; /**< Compile-time configured maximum file name length. */ - uint16_t uDirectPointers; /**< Compile-time configured number of direct pointers per inode. */ - uint16_t uIndirectPointers; /**< Compile-time configured number of indirect pointers per inode. */ - uint8_t bBlockSizeP2; /**< Compile-time configured block size, expressed as a power of two. */ - uint8_t bFlags; /**< Compile-time booleans which affect on-disk structures. */ -} MASTERBLOCK; - - -#if REDCONF_API_POSIX == 1 -#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 16U) /* Size in bytes of the metaroot header fields. */ -#else -#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 12U) /* Size in bytes of the metaroot header fields. */ -#endif -#define METAROOT_ENTRY_BYTES (REDCONF_BLOCK_SIZE - METAROOT_HEADER_SIZE) /* Number of bytes remaining in the metaroot block for entries. */ -#define METAROOT_ENTRIES (METAROOT_ENTRY_BYTES * 8U) - -/** @brief Metadata root node; each volume has two. -*/ -typedef struct -{ - NODEHEADER hdr; /**< Common node header. */ - - uint32_t ulSectorCRC; /**< CRC-32 checksum of the first sector. */ - uint32_t ulFreeBlocks; /**< Number of allocable blocks that are free. */ - #if REDCONF_API_POSIX == 1 - uint32_t ulFreeInodes; /**< Number of inode slots that are free. */ - #endif - uint32_t ulAllocNextBlock; /**< Forward allocation pointer. */ - - /** Imap bitmap. With inline imaps, this is the imap bitmap that indicates - which inode blocks are used and which allocable blocks are used. - Otherwise, this bitmap toggles nodes in the external imap between one - of two possible block locations. - */ - uint8_t abEntries[METAROOT_ENTRY_BYTES]; -} METAROOT; - - -#if REDCONF_IMAP_EXTERNAL == 1 -#define IMAPNODE_HEADER_SIZE (NODEHEADER_SIZE) /* Size in bytes of the imap node header fields. */ -#define IMAPNODE_ENTRY_BYTES (REDCONF_BLOCK_SIZE - IMAPNODE_HEADER_SIZE) /* Number of bytes remaining in the imap node for entries. */ -#define IMAPNODE_ENTRIES (IMAPNODE_ENTRY_BYTES * 8U) - -/** @brief One node of the external imap. -*/ -typedef struct -{ - NODEHEADER hdr; /**< Common node header. */ - - /** Bitmap which indicates which inode blocks are used and which allocable - blocks are used. - */ - uint8_t abEntries[IMAPNODE_ENTRY_BYTES]; -} IMAPNODE; -#endif - - -#define INODE_HEADER_SIZE (NODEHEADER_SIZE + 8U + ((REDCONF_INODE_BLOCKS == 1) ? 4U : 0U) + \ - ((REDCONF_INODE_TIMESTAMPS == 1) ? 12U : 0U) + 4U + ((REDCONF_API_POSIX == 1) ? 4U : 0U)) -#define INODE_ENTRIES ((REDCONF_BLOCK_SIZE - INODE_HEADER_SIZE) / 4U) - -#if (REDCONF_DIRECT_POINTERS < 0) || (REDCONF_DIRECT_POINTERS > (INODE_ENTRIES - REDCONF_INDIRECT_POINTERS)) - #error "Configuration error: invalid value of REDCONF_DIRECT_POINTERS" -#endif -#if (REDCONF_INDIRECT_POINTERS < 0) || (REDCONF_INDIRECT_POINTERS > (INODE_ENTRIES - REDCONF_DIRECT_POINTERS)) - #error "Configuration error: invalid value of REDCONF_INDIRECT_POINTERS" -#endif - -/** @brief Stores metadata for a file or directory. -*/ -typedef struct -{ - NODEHEADER hdr; /**< Common node header. */ - - uint64_t ullSize; /**< Size of the inode, in bytes. */ -#if REDCONF_INODE_BLOCKS == 1 - uint32_t ulBlocks; /**< Total number file data blocks allocated to the inode. */ -#endif -#if REDCONF_INODE_TIMESTAMPS == 1 - uint32_t ulATime; /**< Time of last access (seconds since January 1, 1970). */ - uint32_t ulMTime; /**< Time of last modification (seconds since January 1, 1970). */ - uint32_t ulCTime; /**< Time of last status change (seconds since January 1, 1970). */ -#endif - uint16_t uMode; /**< Inode type (file or directory) and permissions (reserved). */ -#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) - uint16_t uNLink; /**< Link count, number of names pointing to the inode. */ -#else - uint8_t abPadding[2]; /**< Padding to 32-bit align the next member. */ -#endif -#if REDCONF_API_POSIX == 1 - uint32_t ulPInode; /**< Parent inode number. Only guaranteed to be accurate for directories. */ -#endif - - /** Block numbers for lower levels of the file metadata structure. Some - fraction of these entries are for direct pointers (file data block - numbers), some for indirect pointers, some for double-indirect - pointers; the number allocated to each is static but user-configurable. - For all types, an array slot is zero if the range is sparse or beyond - the end of file. - */ - uint32_t aulEntries[INODE_ENTRIES]; -} INODE; - - -#define INDIR_HEADER_SIZE (NODEHEADER_SIZE + 4U) -#define INDIR_ENTRIES ((REDCONF_BLOCK_SIZE - INDIR_HEADER_SIZE) / 4U) - -/** @brief Node for storing block pointers. -*/ -typedef struct -{ - NODEHEADER hdr; /**< Common node header. */ - - uint32_t ulInode; /**< Inode which owns this indirect or double indirect. */ - - /** For indirect nodes, stores block numbers of file data. For double - indirect nodes, stores block numbers of indirect nodes. An array - slot is zero if the corresponding block or indirect range is beyond - the end of file or entirely sparse. - */ - uint32_t aulEntries[INDIR_ENTRIES]; -} INDIR, DINDIR; - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDNODES_H +#define REDNODES_H + + +#define NODEHEADER_SIZE ( 16U ) +#define NODEHEADER_OFFSET_SIG ( 0U ) +#define NODEHEADER_OFFSET_CRC ( 4U ) +#define NODEHEADER_OFFSET_SEQ ( 8U ) + +/** @brief Common header for all metadata nodes. + */ +typedef struct +{ + uint32_t ulSignature; /**< Value which uniquely identifies the metadata node type. */ + uint32_t ulCRC; /**< CRC-32 checksum of the node contents, starting after the CRC. */ + uint64_t ullSequence; /**< Current sequence number at the time the node was written to disk. */ +} NODEHEADER; + + +/** Flag set in the master block when REDCONF_API_POSIX == 1. */ +#define MBFLAG_API_POSIX ( 0x01U ) + +/** Flag set in the master block when REDCONF_INODE_TIMESTAMPS == 1. */ +#define MBFLAG_INODE_TIMESTAMPS ( 0x02U ) + +/** Flag set in the master block when REDCONF_INODE_BLOCKS == 1. */ +#define MBFLAG_INODE_BLOCKS ( 0x04U ) + +/** Flag set in the master block when (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1). */ +#define MBFLAG_INODE_NLINK ( 0x08U ) + + +/** @brief Node which identifies the volume and stores static volume information. + */ +typedef struct +{ + NODEHEADER hdr; /**< Common node header. */ + + uint32_t ulVersion; /**< On-disk layout version number. */ + char acBuildNum[ 8U ]; /**< Build number of the product (not null terminated). */ + uint32_t ulFormatTime; /**< Date and time the volume was formatted. */ + uint32_t ulInodeCount; /**< Compile-time configured number of inodes. */ + uint32_t ulBlockCount; /**< Compile-time configured number of logical blocks. */ + uint16_t uMaxNameLen; /**< Compile-time configured maximum file name length. */ + uint16_t uDirectPointers; /**< Compile-time configured number of direct pointers per inode. */ + uint16_t uIndirectPointers; /**< Compile-time configured number of indirect pointers per inode. */ + uint8_t bBlockSizeP2; /**< Compile-time configured block size, expressed as a power of two. */ + uint8_t bFlags; /**< Compile-time booleans which affect on-disk structures. */ +} MASTERBLOCK; + + +#if REDCONF_API_POSIX == 1 + #define METAROOT_HEADER_SIZE ( NODEHEADER_SIZE + 16U ) /* Size in bytes of the metaroot header fields. */ +#else + #define METAROOT_HEADER_SIZE ( NODEHEADER_SIZE + 12U ) /* Size in bytes of the metaroot header fields. */ +#endif +#define METAROOT_ENTRY_BYTES ( REDCONF_BLOCK_SIZE - METAROOT_HEADER_SIZE ) /* Number of bytes remaining in the metaroot block for entries. */ +#define METAROOT_ENTRIES ( METAROOT_ENTRY_BYTES * 8U ) + +/** @brief Metadata root node; each volume has two. + */ +typedef struct +{ + NODEHEADER hdr; /**< Common node header. */ + + uint32_t ulSectorCRC; /**< CRC-32 checksum of the first sector. */ + uint32_t ulFreeBlocks; /**< Number of allocable blocks that are free. */ + #if REDCONF_API_POSIX == 1 + uint32_t ulFreeInodes; /**< Number of inode slots that are free. */ + #endif + uint32_t ulAllocNextBlock; /**< Forward allocation pointer. */ + + /** Imap bitmap. With inline imaps, this is the imap bitmap that indicates + * which inode blocks are used and which allocable blocks are used. + * Otherwise, this bitmap toggles nodes in the external imap between one + * of two possible block locations. + */ + uint8_t abEntries[ METAROOT_ENTRY_BYTES ]; +} METAROOT; + + +#if REDCONF_IMAP_EXTERNAL == 1 + #define IMAPNODE_HEADER_SIZE ( NODEHEADER_SIZE ) /* Size in bytes of the imap node header fields. */ + #define IMAPNODE_ENTRY_BYTES ( REDCONF_BLOCK_SIZE - IMAPNODE_HEADER_SIZE ) /* Number of bytes remaining in the imap node for entries. */ + #define IMAPNODE_ENTRIES ( IMAPNODE_ENTRY_BYTES * 8U ) + +/** @brief One node of the external imap. + */ + typedef struct + { + NODEHEADER hdr; /**< Common node header. */ + + /** Bitmap which indicates which inode blocks are used and which allocable + * blocks are used. + */ + uint8_t abEntries[ IMAPNODE_ENTRY_BYTES ]; + } IMAPNODE; +#endif /* if REDCONF_IMAP_EXTERNAL == 1 */ + + +#define INODE_HEADER_SIZE \ + ( NODEHEADER_SIZE + 8U + ( ( REDCONF_INODE_BLOCKS == 1 ) ? 4U : 0U ) + \ + ( ( REDCONF_INODE_TIMESTAMPS == 1 ) ? 12U : 0U ) + 4U + ( ( REDCONF_API_POSIX == 1 ) ? 4U : 0U ) ) +#define INODE_ENTRIES ( ( REDCONF_BLOCK_SIZE - INODE_HEADER_SIZE ) / 4U ) + +#if ( REDCONF_DIRECT_POINTERS < 0 ) || ( REDCONF_DIRECT_POINTERS > ( INODE_ENTRIES - REDCONF_INDIRECT_POINTERS ) ) + #error "Configuration error: invalid value of REDCONF_DIRECT_POINTERS" +#endif +#if ( REDCONF_INDIRECT_POINTERS < 0 ) || ( REDCONF_INDIRECT_POINTERS > ( INODE_ENTRIES - REDCONF_DIRECT_POINTERS ) ) + #error "Configuration error: invalid value of REDCONF_INDIRECT_POINTERS" +#endif + +/** @brief Stores metadata for a file or directory. + */ +typedef struct +{ + NODEHEADER hdr; /**< Common node header. */ + + uint64_t ullSize; /**< Size of the inode, in bytes. */ + #if REDCONF_INODE_BLOCKS == 1 + uint32_t ulBlocks; /**< Total number file data blocks allocated to the inode. */ + #endif + #if REDCONF_INODE_TIMESTAMPS == 1 + uint32_t ulATime; /**< Time of last access (seconds since January 1, 1970). */ + uint32_t ulMTime; /**< Time of last modification (seconds since January 1, 1970). */ + uint32_t ulCTime; /**< Time of last status change (seconds since January 1, 1970). */ + #endif + uint16_t uMode; /**< Inode type (file or directory) and permissions (reserved). */ + #if ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_LINK == 1 ) + uint16_t uNLink; /**< Link count, number of names pointing to the inode. */ + #else + uint8_t abPadding[ 2 ]; /**< Padding to 32-bit align the next member. */ + #endif + #if REDCONF_API_POSIX == 1 + uint32_t ulPInode; /**< Parent inode number. Only guaranteed to be accurate for directories. */ + #endif + + /** Block numbers for lower levels of the file metadata structure. Some + * fraction of these entries are for direct pointers (file data block + * numbers), some for indirect pointers, some for double-indirect + * pointers; the number allocated to each is static but user-configurable. + * For all types, an array slot is zero if the range is sparse or beyond + * the end of file. + */ + uint32_t aulEntries[ INODE_ENTRIES ]; +} INODE; + + +#define INDIR_HEADER_SIZE ( NODEHEADER_SIZE + 4U ) +#define INDIR_ENTRIES ( ( REDCONF_BLOCK_SIZE - INDIR_HEADER_SIZE ) / 4U ) + +/** @brief Node for storing block pointers. + */ +typedef struct +{ + NODEHEADER hdr; /**< Common node header. */ + + uint32_t ulInode; /**< Inode which owns this indirect or double indirect. */ + + /** For indirect nodes, stores block numbers of file data. For double + * indirect nodes, stores block numbers of indirect nodes. An array + * slot is zero if the corresponding block or indirect range is beyond + * the end of file or entirely sparse. + */ + uint32_t aulEntries[ INDIR_ENTRIES ]; +} INDIR, DINDIR; + + +#endif /* ifndef REDNODES_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/doc/coding_style.txt b/FreeRTOS-Plus/Source/Reliance-Edge/doc/coding_style.txt index 1a816ddb1..c6d1c2ab3 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/doc/coding_style.txt +++ b/FreeRTOS-Plus/Source/Reliance-Edge/doc/coding_style.txt @@ -1,389 +1,389 @@ -Datalight Coding Style -====================== - -This is a description of the Datalight Coding Style intended for third parties -who want to contribute code to Reliance Edge. This document is derived from the -DDSS Coding Guidelines, but only contains a subset of the content which is most -likely to be relevant to third party contributors. - -Reliance Edge complies with the MISRA-C:2012 coding guidelines, which includes -many rules that affect coding style. Unfortunately the MISRA-C:2012 document is -not freely available, and is much too long to be effectively summarized, but if -you are familiar with the rules, adhere to them. A few important rules of -thumb: avoid the goto and continue keywords; avoid using more than one break -in a loop; and avoid having more than one return from a function (single point -of exit); default cases in every switch statement; avoid recursion; and make -generous use of parentheses. Outside of the file system driver, in tests and -host tools, the MISRA-C rules are relaxed. - -Beyond MISRA-C, Datalight has a standard coding style. Most aspects of this -style are matters of preference, but when contributing code to Datalight an -effort should be made to use this style for the sake of consistency. - -Below is an example function, which illustrates several key points of Datalight -Coding Style: - -/** @brief One-sentence description of what this function does. - - Additional description. - - @param ulFirstParameter Description of the parameter. - @param pszPointer Description of the parameter. - - @return Describe the return value. - - @retval true Optional description of specific return value. - @retval false Optional description of specific return value. -*/ -bool ExampleFunction( - uint32_t ulFirstParameter, - char *pszPointer) -{ - bool fStatus = true; - - /* This is a single-line comment. - */ - if(ulFirstParameter > 0U) - { - /* This is a multi-line comment. Filler text: Lorem ipsum dolor sit - amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt - ut labore et dolore magna aliqua. - */ - FunctionCall(); - - while(fStatus) - { - fStatus = AnotherFunction(ulFirstParameter, pszPointer); - } - } - - return fStatus; -} - -Tab Stop Conventions --------------------- - -In all C code (.c/.h), use a tab width of four spaces, and use soft tabs (in -other words, tabs are expanded to spaces). In Makefiles, use hard tabs and a -tab width of 8. - -Naming ------- - -Datalight uses CamelCase for functions and variables. Type names are generally -UPPERCASE, except for standard types like uint32_t. Preprocessor macros are -UPPERCASE, with words separated by underscores (for example, INODE_INVALID). - -Doxygen Documentation ---------------------- - -Doxygen is used to document functions (including static functions), along with -types, structures, files, etc. For Doxygen tags, use '@' instead of a backslash -(thus "@param" not "\param"). - -Function Declarations ---------------------- - -Multi-line function declarations are preferred, as they tend to be more -readable. Use the following form: - -static bool ExampleFunctionDeclaration( - uint32_t ulFirstParameter, - char *pszPointer, - uint8_t **ppbBuffer) -{ - uint16_t uLocalVar; /* descriptive comment */ - uint8_t *pbBuffer = NULL; /* descriptive comment */ - - Function body... -} - -The following guidelines should be used: - -- Align both the data-type and the variable names, for parameters and locals, at - the same level if practical. -- For pointer types, the '*' belongs to the variable name---it's not part of the - data-type, so keep it with the variable name. -- If useful, single line comments may be used to describe local variables (not - a requirement). -- For functions with no parameters, the "void" declaration does not need to be - on a separate line. -- Generally each variable should be declared on a separate line. This promotes - readability, and facilitates having a comment for each variable. - -Function declarations should be spaced apart by two blank lines between the -closing brace which ends a function and the Doxygen comment which starts the -next. - -Curly Braces ------------- - -Datalight lines up all curly braces vertically. As per MISRA-C, curly braces -are never omitted, even if the braces contain only a single statement. - -For consistency, even structure declarations and initializations should use the -same style, with the curly braces lined up vertically. One exception is for -structure initializations where both the opening and closing curly braces can -fit on the same line. If so, do it. - -Code Comments -------------- - -Datalight uses the standard C style /* comments */. C++ style comments (//) are -never used. The Datalight standard comment style is shown below. This style -applies to all general comments within the code. - -/* This is a single-line comment. -*/ -if(ulFirstParameter > 0U) -{ - /* This is a multi-line comment. Filler text: Lorem ipsum dolor sit amet, - consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore - et dolore magna aliqua. - */ - while(fStatus) - { - } -} - -Note the characteristics: - -- The /* and */ align with the natural 4 character indentation. -- The comment text is exactly indented another 4 characters. -- The comment text starts on the same line as the opening /*. -- The terminating */ is on its own line. -- There is usually a single blank line preceding the comment, however if the - preceding line is an opening curly brace, then an extra blank line is not - necessary. -- There is usually no blank line after the comment, but rather the closing */ - "attaches" the comment to the code about which the comment refers. -- These comments should always fit with the standard 80 character margin. - -Comments where the /* and */ are on the same line may be used in a few places: - -- For variable or parameter descriptions, where the comment fits on the same - line as the declaration. -- For structure member declarations, where the comment fits on the same line as - the declaration. -- For macros or preprocessor logic, where the comment fits on the same line. - -It is OK for such comments to exceed the 80 character margin by a small amount, -if necessary, as this sometimes promotes code readability. - -Indentation Style ------------------ - -The general paradigm used in Datalight code is that curly braces line up -vertically, and everything in between them is indented. This should include all -comments, labels, and preprocessor symbols. The only things which are aligned -at the left-most columns are: - -- Symbols, variables, declarations, and preprocessor logic which are at the - module-scope (outside of a function) -- Comments which are outside of a function -- Function declarations -- Function open and closing curly braces - -Typically comments are always lined up directly with the code to which they -apply. - -Labels (when used; gotos are disallowed in driver code) are lined up two -characters to the left of the code they reside in, to make them stand out, while -as the same time, still remaining subservient to the level of curly braces in -which they reside. For example: - -bool ExampleLabelUsage(void) -{ - MutexLock(); - - Lots of complicated code... - - Unlock: - - MutexUnlock(); - - return fSuccess; -} - -Preprocessor logic, such as controlling features which are conditionally -compiled in or out, should not disrupt the flow of the code, but rather should -be indented in similar fashion to the code it controls, but positioned two -characters to the left. For example, consider the following code snippet. The -preprocessor conditions are both indented relative to the outer curly braces, -but do not disrupt the normal code flow. - -int32_t red_statvfs( - const char *pszVolume, - REDSTATFS *pStatvfs) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - uint8_t bVolNum; - - ret = RedPathSplit(pszVolume, &bVolNum, NULL); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreVolStat(pStatvfs); - } - - PosixLeave(); - } - - return PosixReturn(ret); -} - -Note that, like anything else between curly brackets, the contents of a switch -statement are indented: - -switch(ulSignature) -{ - case META_SIG_MASTER: - fValid = (uFlags == BFLAG_META_MASTER); - break; - case META_SIG_IMAP: - fValid = (uFlags == BFLAG_META_IMAP); - break; - case META_SIG_INODE: - fValid = (uFlags == BFLAG_META_INODE); - break; - case META_SIG_DINDIR: - fValid = (uFlags == BFLAG_META_DINDIR); - break; - case META_SIG_INDIR: - fValid = (uFlags == BFLAG_META_INDIR); - break; - default: - fValid = false; - break; -} - -Maximum Line Length -------------------- - -The maximum line length for code need not be rigidly limited to the traditional -80 characters. Nevertheless the line lengths should be kept reasonable. -Anything longer than 100 to 120 characters should probably be broken up. The -most important consideration is readability---fitting on the screen is important -for readability, but equally important is facilitating an easy understanding of -the logical code flow. - -There are a few exceptions on both sides of the issue. Generally comments -should be limited to 80 characters always. Some lines of code may exceed the -120 character length by a large margin, if it makes the code more understandable -and maintainable. This is especially true when dealing with code that generates -output which needs to be lined up. - -Regardless of everything else, no lines should exceed 250 characters because -some editors cannot handle anything larger. - -Maximum Display Output Line Length ----------------------------------- - -Any code which displays TTY style output, whether on a screen or a terminal, -should be constructed so the output is readable and wraps properly on an 80 -character wide display. This primarily applies to the "standard" output from -various tests and tools as well as syntax output for those tests and tools; -debug output can violate this rule. - -Preprocessor Notation ---------------------- - -Don't use preprocessor notation where the # is separated from the keyword by one -or more white spaces. For example, don't do: - -#ifndef SYMBOL1 -# define SYMBOL1 -#endif - -Instead, do: - -#ifndef SYMBOL1 - #define SYMBOL1 -#endif - -Hexadecimal Notation --------------------- - -Use uppercase for any alphabetic hexadecimal digits, and lower case for the -notational element. For example: - -#define HEXNUM 0x123abd /* Bad */ -#define HEXNUM 0X123ABD /* Bad */ -#define HEXNUM 0x123ABD /* Good */ - -Hungarian Notation ------------------- - -Datalight uses Hungarian notation. The following type prefixes are used: - -Type Prefix | Meaning ------------ | ------- -c | char -uc | unsigned char -i | int -n | unsigned int or size_t -b | uint8_t -u | uint16_t -ul | uint32_t -ull | uint64_t -sz | array of char that will be null-terminated -f | bool -h | A handle -fn | A function (always used with the "p" modifier) - -There is no official Hungarian for int8_t, int16_t, int32_t, or int64_t, -although some code uses unofficial variants (like "ll" for int64_t). - -The following modifiers may be used in combination with the type prefixes -defined above, or in combination with other types: - -Modifier | Meaning --------- | ------- -a | An array -p | A pointer -g | A global variable - -Notes: - -- There is no standard Hungarian for structure declarations, however the use of - the "a" and "p" modifiers is completely appropriate (and expected). -- For those data types which do not have any standard defined Hungarian prefix, - using none is preferable to misusing another prefix which would lead to - confusion. -- The "p" pointer modifier must be used such that a variable which is a pointer - to a pointer uses multiple "p" prefixes. A general rule-of-thumb is that the - variable name should have the same number of "p" prefixes as the declaration - has asterisks. This allows pointer expressions to be easily decoded using - cancellation. - -Variable Scope --------------- - -Declare a variable in the narrowest scope in which it is meaningful. -Unnecessarily declaring all variables at the beginning of a function, where they -may be physically far from where they are actually used, makes the code harder -to maintain. - -When multiple blocks of code share a variable, but not its value, declare the -variable separately for each code block. - -For example, if two separate blocks contain loops indexed by a variable ulIndex -declare it separately in each block rather than declaring it once in a wider -scope and using it in both places. - -Using distinct declarations in the two blocks allows the compiler to check for -failure to initialize the variable in the second block. If there is a single -declaration, the (now meaningless) value left over from the first block can be -used erroneously in the second block. - +Datalight Coding Style +====================== + +This is a description of the Datalight Coding Style intended for third parties +who want to contribute code to Reliance Edge. This document is derived from the +DDSS Coding Guidelines, but only contains a subset of the content which is most +likely to be relevant to third party contributors. + +Reliance Edge complies with the MISRA-C:2012 coding guidelines, which includes +many rules that affect coding style. Unfortunately the MISRA-C:2012 document is +not freely available, and is much too long to be effectively summarized, but if +you are familiar with the rules, adhere to them. A few important rules of +thumb: avoid the goto and continue keywords; avoid using more than one break +in a loop; and avoid having more than one return from a function (single point +of exit); default cases in every switch statement; avoid recursion; and make +generous use of parentheses. Outside of the file system driver, in tests and +host tools, the MISRA-C rules are relaxed. + +Beyond MISRA-C, Datalight has a standard coding style. Most aspects of this +style are matters of preference, but when contributing code to Datalight an +effort should be made to use this style for the sake of consistency. + +Below is an example function, which illustrates several key points of Datalight +Coding Style: + +/** @brief One-sentence description of what this function does. + + Additional description. + + @param ulFirstParameter Description of the parameter. + @param pszPointer Description of the parameter. + + @return Describe the return value. + + @retval true Optional description of specific return value. + @retval false Optional description of specific return value. +*/ +bool ExampleFunction( + uint32_t ulFirstParameter, + char *pszPointer) +{ + bool fStatus = true; + + /* This is a single-line comment. + */ + if(ulFirstParameter > 0U) + { + /* This is a multi-line comment. It is a comment that spans multiple + lines. It is explaining the important following function call. + This is the last line of this multi-line comment. + */ + FunctionCall(); + + while(fStatus) + { + fStatus = AnotherFunction(ulFirstParameter, pszPointer); + } + } + + return fStatus; +} + +Tab Stop Conventions +-------------------- + +In all C code (.c/.h), use a tab width of four spaces, and use soft tabs (in +other words, tabs are expanded to spaces). In Makefiles, use hard tabs and a +tab width of 8. + +Naming +------ + +Datalight uses CamelCase for functions and variables. Type names are generally +UPPERCASE, except for standard types like uint32_t. Preprocessor macros are +UPPERCASE, with words separated by underscores (for example, INODE_INVALID). + +Doxygen Documentation +--------------------- + +Doxygen is used to document functions (including static functions), along with +types, structures, files, etc. For Doxygen tags, use '@' instead of a backslash +(thus "@param" not "\param"). + +Function Declarations +--------------------- + +Multi-line function declarations are preferred, as they tend to be more +readable. Use the following form: + +static bool ExampleFunctionDeclaration( + uint32_t ulFirstParameter, + char *pszPointer, + uint8_t **ppbBuffer) +{ + uint16_t uLocalVar; /* descriptive comment */ + uint8_t *pbBuffer = NULL; /* descriptive comment */ + + Function body... +} + +The following guidelines should be used: + +- Align both the data-type and the variable names, for parameters and locals, at + the same level if practical. +- For pointer types, the '*' belongs to the variable name---it's not part of the + data-type, so keep it with the variable name. +- If useful, single line comments may be used to describe local variables (not + a requirement). +- For functions with no parameters, the "void" declaration does not need to be + on a separate line. +- Generally each variable should be declared on a separate line. This promotes + readability, and facilitates having a comment for each variable. + +Function declarations should be spaced apart by two blank lines between the +closing brace which ends a function and the Doxygen comment which starts the +next. + +Curly Braces +------------ + +Datalight lines up all curly braces vertically. As per MISRA-C, curly braces +are never omitted, even if the braces contain only a single statement. + +For consistency, even structure declarations and initializations should use the +same style, with the curly braces lined up vertically. One exception is for +structure initializations where both the opening and closing curly braces can +fit on the same line. If so, do it. + +Code Comments +------------- + +Datalight uses the standard C style /* comments */. C++ style comments (//) are +never used. The Datalight standard comment style is shown below. This style +applies to all general comments within the code. + +/* This is a single-line comment. +*/ +if(ulFirstParameter > 0U) +{ + /* This is a multi-line comment. It is a comment that spans multiple + lines. It is explaining the important following function call. + This is the last line of this multi-line comment. + */ + while(fStatus) + { + } +} + +Note the characteristics: + +- The /* and */ align with the natural 4 character indentation. +- The comment text is exactly indented another 4 characters. +- The comment text starts on the same line as the opening /*. +- The terminating */ is on its own line. +- There is usually a single blank line preceding the comment, however if the + preceding line is an opening curly brace, then an extra blank line is not + necessary. +- There is usually no blank line after the comment, but rather the closing */ + "attaches" the comment to the code about which the comment refers. +- These comments should always fit with the standard 80 character margin. + +Comments where the /* and */ are on the same line may be used in a few places: + +- For variable or parameter descriptions, where the comment fits on the same + line as the declaration. +- For structure member declarations, where the comment fits on the same line as + the declaration. +- For macros or preprocessor logic, where the comment fits on the same line. + +It is OK for such comments to exceed the 80 character margin by a small amount, +if necessary, as this sometimes promotes code readability. + +Indentation Style +----------------- + +The general paradigm used in Datalight code is that curly braces line up +vertically, and everything in between them is indented. This should include all +comments, labels, and preprocessor symbols. The only things which are aligned +at the left-most columns are: + +- Symbols, variables, declarations, and preprocessor logic which are at the + module-scope (outside of a function) +- Comments which are outside of a function +- Function declarations +- Function open and closing curly braces + +Typically comments are always lined up directly with the code to which they +apply. + +Labels (when used; gotos are disallowed in driver code) are lined up two +characters to the left of the code they reside in, to make them stand out, while +as the same time, still remaining subservient to the level of curly braces in +which they reside. For example: + +bool ExampleLabelUsage(void) +{ + MutexLock(); + + Lots of complicated code... + + Unlock: + + MutexUnlock(); + + return fSuccess; +} + +Preprocessor logic, such as controlling features which are conditionally +compiled in or out, should not disrupt the flow of the code, but rather should +be indented in similar fashion to the code it controls, but positioned two +characters to the left. For example, consider the following code snippet. The +preprocessor conditions are both indented relative to the outer curly braces, +but do not disrupt the normal code flow. + +int32_t red_statvfs( + const char *pszVolume, + REDSTATFS *pStatvfs) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + uint8_t bVolNum; + + ret = RedPathSplit(pszVolume, &bVolNum, NULL); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreVolStat(pStatvfs); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} + +Note that, like anything else between curly brackets, the contents of a switch +statement are indented: + +switch(ulSignature) +{ + case META_SIG_MASTER: + fValid = (uFlags == BFLAG_META_MASTER); + break; + case META_SIG_IMAP: + fValid = (uFlags == BFLAG_META_IMAP); + break; + case META_SIG_INODE: + fValid = (uFlags == BFLAG_META_INODE); + break; + case META_SIG_DINDIR: + fValid = (uFlags == BFLAG_META_DINDIR); + break; + case META_SIG_INDIR: + fValid = (uFlags == BFLAG_META_INDIR); + break; + default: + fValid = false; + break; +} + +Maximum Line Length +------------------- + +The maximum line length for code need not be rigidly limited to the traditional +80 characters. Nevertheless the line lengths should be kept reasonable. +Anything longer than 100 to 120 characters should probably be broken up. The +most important consideration is readability---fitting on the screen is important +for readability, but equally important is facilitating an easy understanding of +the logical code flow. + +There are a few exceptions on both sides of the issue. Generally comments +should be limited to 80 characters always. Some lines of code may exceed the +120 character length by a large margin, if it makes the code more understandable +and maintainable. This is especially true when dealing with code that generates +output which needs to be lined up. + +Regardless of everything else, no lines should exceed 250 characters because +some editors cannot handle anything larger. + +Maximum Display Output Line Length +---------------------------------- + +Any code which displays TTY style output, whether on a screen or a terminal, +should be constructed so the output is readable and wraps properly on an 80 +character wide display. This primarily applies to the "standard" output from +various tests and tools as well as syntax output for those tests and tools; +debug output can violate this rule. + +Preprocessor Notation +--------------------- + +Don't use preprocessor notation where the # is separated from the keyword by one +or more white spaces. For example, don't do: + +#ifndef SYMBOL1 +# define SYMBOL1 +#endif + +Instead, do: + +#ifndef SYMBOL1 + #define SYMBOL1 +#endif + +Hexadecimal Notation +-------------------- + +Use uppercase for any alphabetic hexadecimal digits, and lower case for the +notational element. For example: + +#define HEXNUM 0x123abd /* Bad */ +#define HEXNUM 0X123ABD /* Bad */ +#define HEXNUM 0x123ABD /* Good */ + +Hungarian Notation +------------------ + +Datalight uses Hungarian notation. The following type prefixes are used: + +Type Prefix | Meaning +----------- | ------- +c | char +uc | unsigned char +i | int +n | unsigned int or size_t +b | uint8_t +u | uint16_t +ul | uint32_t +ull | uint64_t +sz | array of char that will be null-terminated +f | bool +h | A handle +fn | A function (always used with the "p" modifier) + +There is no official Hungarian for int8_t, int16_t, int32_t, or int64_t, +although some code uses unofficial variants (like "ll" for int64_t). + +The following modifiers may be used in combination with the type prefixes +defined above, or in combination with other types: + +Modifier | Meaning +-------- | ------- +a | An array +p | A pointer +g | A global variable + +Notes: + +- There is no standard Hungarian for structure declarations, however the use of + the "a" and "p" modifiers is completely appropriate (and expected). +- For those data types which do not have any standard defined Hungarian prefix, + using none is preferable to misusing another prefix which would lead to + confusion. +- The "p" pointer modifier must be used such that a variable which is a pointer + to a pointer uses multiple "p" prefixes. A general rule-of-thumb is that the + variable name should have the same number of "p" prefixes as the declaration + has asterisks. This allows pointer expressions to be easily decoded using + cancellation. + +Variable Scope +-------------- + +Declare a variable in the narrowest scope in which it is meaningful. +Unnecessarily declaring all variables at the beginning of a function, where they +may be physically far from where they are actually used, makes the code harder +to maintain. + +When multiple blocks of code share a variable, but not its value, declare the +variable separately for each code block. + +For example, if two separate blocks contain loops indexed by a variable ulIndex +declare it separately in each block rather than declaring it once in a wider +scope and using it in both places. + +Using distinct declarations in the two blocks allows the compiler to check for +failure to initialize the variable in the second block. If there is a single +declaration, the (now meaningless) value left over from the first block can be +used erroneously in the second block. + diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/doc/release_notes.md b/FreeRTOS-Plus/Source/Reliance-Edge/doc/release_notes.md index 2a3d9370a..bbddd7433 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/doc/release_notes.md +++ b/FreeRTOS-Plus/Source/Reliance-Edge/doc/release_notes.md @@ -48,7 +48,7 @@ recent releases and a list of known issues. - Added support for static memory allocation configuration in FreeRTOS version 9. No common code changes. - + ### Reliance Edge v1.0.2, February 2016 #### Common Code Changes @@ -72,7 +72,7 @@ recent releases and a list of known issues. Essentials API was selected in the configuration. - Fixed a bug which would have returned an uninitialized value from `RedOsBDevFlush()` for block devices that support flushing. - + ### Reliance Edge v1.0.1, October 2015 - Added MQX RTOS support in the commercial kit, with example projects for diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/fse/fse.c b/FreeRTOS-Plus/Source/Reliance-Edge/fse/fse.c index 4ad08ef2c..d5578fe1f 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/fse/fse.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/fse/fse.c @@ -1,690 +1,686 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implementation of the Reliance Edge FSE API. -*/ -#include - -#if REDCONF_API_FSE == 1 - -/** @defgroup red_group_fse The File System Essentials Interface - @{ -*/ - -#include -#include -#include - - -static REDSTATUS FseEnter(uint8_t bVolNum); -static void FseLeave(void); - - -static bool gfFseInited; /* Whether driver is initialized. */ - - -/** @brief Initialize the Reliance Edge file system driver. - - Prepares the Reliance Edge file system driver to be used. Must be the first - Reliance Edge function to be invoked: no volumes can be mounted until the - driver has been initialized. - - If this function is called when the Reliance Edge driver is already - initialized, it does nothing and returns success. - - This function is not thread safe: attempting to initialize from multiple - threads could leave things in a bad state. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -REDSTATUS RedFseInit(void) -{ - REDSTATUS ret; - - if(gfFseInited) - { - ret = 0; - } - else - { - ret = RedCoreInit(); - - if(ret == 0) - { - gfFseInited = true; - } - } - - return ret; -} - - -/** @brief Uninitialize the Reliance Edge file system driver. - - Tears down the Reliance Edge file system driver. Cannot be used until all - Reliance Edge volumes are unmounted. A subsequent call to RedFseInit() - will initialize the driver again. - - If this function is called when the Reliance Edge driver is already - uninitialized, it does nothing and returns success. - - This function is not thread safe: attempting to uninitialize from multiple - threads could leave things in a bad state. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBUSY At least one volume is still mounted. -*/ -REDSTATUS RedFseUninit(void) -{ - REDSTATUS ret = 0; - - if(!gfFseInited) - { - ret = 0; - } - else - { - uint8_t bVolNum; - - #if REDCONF_TASK_COUNT > 1U - RedOsMutexAcquire(); - #endif - - for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++) - { - if(gaRedVolume[bVolNum].fMounted) - { - ret = -RED_EBUSY; - break; - } - } - - if(ret == 0) - { - gfFseInited = false; - } - - #if REDCONF_TASK_COUNT > 1U - RedOsMutexRelease(); - #endif - - if(ret == 0) - { - ret = RedCoreUninit(); - } - } - - return ret; -} - - -/** @brief Mount a file system volume. - - Prepares the file system volume to be accessed. Mount will fail if the - volume has never been formatted, or if the on-disk format is inconsistent - with the compile-time configuration. - - If the volume is already mounted, this function does nothing and returns - success. - - @param bVolNum The volume number of the volume to be mounted. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is - uninitialized. - @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt. -*/ -REDSTATUS RedFseMount( - uint8_t bVolNum) -{ - REDSTATUS ret; - - ret = FseEnter(bVolNum); - - if(ret == 0) - { - if(!gpRedVolume->fMounted) - { - ret = RedCoreVolMount(); - } - - FseLeave(); - } - - return ret; -} - - -/** @brief Unmount a file system volume. - - This function discards the in-memory state for the file system and marks it - as unmounted. Subsequent attempts to access the volume will fail until the - volume is mounted again. - - If unmount automatic transaction points are enabled, this function will - commit a transaction point prior to unmounting. If unmount automatic - transaction points are disabled, this function will unmount without - transacting, effectively discarding the working state. - - Before unmounting, this function will wait for any active file system - thread to complete by acquiring the FS mutex. The volume will be marked as - unmounted before the FS mutex is released, so subsequent FS threads will - possibly block and then see an error when attempting to access a volume - which is unmounting or unmounted. - - If the volume is already unmounted, this function does nothing and returns - success. - - @param bVolNum The volume number of the volume to be unmounted. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is - uninitialized. - @retval -RED_EIO I/O error during unmount automatic transaction point. -*/ -REDSTATUS RedFseUnmount( - uint8_t bVolNum) -{ - REDSTATUS ret; - - ret = FseEnter(bVolNum); - - if(ret == 0) - { - if(gpRedVolume->fMounted) - { - ret = RedCoreVolUnmount(); - } - - FseLeave(); - } - - return ret; -} - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_FORMAT == 1) -/** @brief Format a file system volume. - - Uses the statically defined volume configuration. After calling this - function, the volume needs to be mounted -- see RedFseMount(). - - An error is returned if the volume is mounted. - - @param bVolNum The volume number of the volume to be formatted. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBUSY The volume is mounted. - @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is - uninitialized. - @retval -RED_EIO I/O error formatting the volume. -*/ -REDSTATUS RedFseFormat( - uint8_t bVolNum) -{ - REDSTATUS ret; - - ret = FseEnter(bVolNum); - - if(ret == 0) - { - ret = RedCoreVolFormat(); - - FseLeave(); - } - - return ret; -} -#endif - - -/** @brief Read from a file. - - Data which has not yet been written, but which is before the end-of-file - (sparse data), shall read as zeroes. A short read -- where the number of - bytes read is less than requested -- indicates that the requested read was - partially or, if zero bytes were read, entirely beyond the end-of-file. - - If @p ullFileOffset is at or beyond the maximum file size, it is treated - like any other read entirely beyond the end-of-file: no data is read and - zero is returned. - - @param bVolNum The volume number of the file to read. - @param ulFileNum The file number of the file to read. - @param ullFileOffset The file offset to read from. - @param ulLength The number of bytes to read. - @param pBuffer The buffer to populate with the data read. Must be - at least ulLength bytes in size. - - @return The number of bytes read (nonnegative) or a negated ::REDSTATUS - code indicating the operation result (negative). - - @retval >=0 The number of bytes read from the file. - @retval -RED_EBADF @p ulFileNum is not a valid file number. - @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; - or @p pBuffer is `NULL`; or @p ulLength exceeds - INT32_MAX and cannot be returned properly. - @retval -RED_EIO A disk I/O error occurred. -*/ -int32_t RedFseRead( - uint8_t bVolNum, - uint32_t ulFileNum, - uint64_t ullFileOffset, - uint32_t ulLength, - void *pBuffer) -{ - int32_t ret; - - if(ulLength > (uint32_t)INT32_MAX) - { - ret = -RED_EINVAL; - } - else - { - ret = FseEnter(bVolNum); - } - - if(ret == 0) - { - uint32_t ulReadLen = ulLength; - - ret = RedCoreFileRead(ulFileNum, ullFileOffset, &ulReadLen, pBuffer); - - FseLeave(); - - if(ret == 0) - { - ret = (int32_t)ulReadLen; - } - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Write to a file. - - If the write extends beyond the end-of-file, the file size will be - increased. - - A short write -- where the number of bytes written is less than requested - -- indicates either that the file system ran out of space but was still - able to write some of the request; or that the request would have caused - the file to exceed the maximum file size, but some of the data could be - written prior to the file size limit. - - If an error is returned (negative return), either none of the data was - written or a critical error occurred (like an I/O error) and the file - system volume will be read-only. - - @param bVolNum The volume number of the file to write. - @param ulFileNum The file number of the file to write. - @param ullFileOffset The file offset to write at. - @param ulLength The number of bytes to write. - @param pBuffer The buffer containing the data to be written. Must - be at least ulLength bytes in size. - - @return The number of bytes written (nonnegative) or a negated ::REDSTATUS - code indicating the operation result (negative). - - @retval >0 The number of bytes written to the file. - @retval -RED_EBADF @p ulFileNum is not a valid file number. - @retval -RED_EFBIG No data can be written to the given file offset since - the resulting file size would exceed the maximum file - size. - @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; - or @p pBuffer is `NULL`; or @p ulLength exceeds - INT32_MAX and cannot be returned properly. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC No data can be written because there is insufficient - free space. - @retval -RED_EROFS The file system volume is read-only. -*/ -int32_t RedFseWrite( - uint8_t bVolNum, - uint32_t ulFileNum, - uint64_t ullFileOffset, - uint32_t ulLength, - const void *pBuffer) -{ - int32_t ret; - - if(ulLength > (uint32_t)INT32_MAX) - { - ret = -RED_EINVAL; - } - else - { - ret = FseEnter(bVolNum); - } - - if(ret == 0) - { - uint32_t ulWriteLen = ulLength; - - ret = RedCoreFileWrite(ulFileNum, ullFileOffset, &ulWriteLen, pBuffer); - - FseLeave(); - - if(ret == 0) - { - ret = (int32_t)ulWriteLen; - } - } - - return ret; -} -#endif - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1) -/** @brief Truncate a file (set the file size). - - Allows the file size to be increased, decreased, or to remain the same. If - the file size is increased, the new area is sparse (will read as zeroes). - If the file size is decreased, the data beyond the new end-of-file will - return to free space once it is no longer part of the committed state - (either immediately or after the next transaction point). - - This function can fail when the disk is full if @p ullNewFileSize is - non-zero. If decreasing the file size, this can be fixed by transacting and - trying again: Reliance Edge guarantees that it is possible to perform a - truncate of at least one file that decreases the file size after a - transaction point. If disk full transactions are enabled, this will happen - automatically. - - @param bVolNum The volume number of the file to truncate. - @param ulFileNum The file number of the file to truncate. - @param ullNewFileSize The new file size, in bytes. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulFileNum is not a valid file number. - @retval -RED_EFBIG @p ullNewFileSize exceeds the maximum file size. - @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOSPC Insufficient free space to perform the truncate. - @retval -RED_EROFS The file system volume is read-only. -*/ -REDSTATUS RedFseTruncate( - uint8_t bVolNum, - uint32_t ulFileNum, - uint64_t ullNewFileSize) -{ - REDSTATUS ret; - - ret = FseEnter(bVolNum); - - if(ret == 0) - { - ret = RedCoreFileTruncate(ulFileNum, ullNewFileSize); - - FseLeave(); - } - - return ret; -} -#endif - - -/** @brief Retrieve the size of a file. - - @param bVolNum The volume number of the file whose size is being read. - @param ulFileNum The file number of the file whose size is being read. - - @return The size of the file (nonnegative) or a negated ::REDSTATUS code - indicating the operation result (negative). - - @retval >=0 The size of the file. - @retval -RED_EBADF @p ulFileNum is not a valid file number. - @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted. - @retval -RED_EIO A disk I/O error occurred. -*/ -int64_t RedFseSizeGet( - uint8_t bVolNum, - uint32_t ulFileNum) -{ - int64_t ret; - - ret = FseEnter(bVolNum); - - if(ret == 0) - { - uint64_t ullSize; - - ret = RedCoreFileSizeGet(ulFileNum, &ullSize); - - FseLeave(); - - if(ret == 0) - { - /* Unless there is an on-disk format change, the maximum file size - is guaranteed to be less than INT64_MAX, and so it can be safely - returned in an int64_t. - */ - REDASSERT(ullSize < (uint64_t)INT64_MAX); - - ret = (int64_t)ullSize; - } - } - - return ret; -} - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1) -/** @brief Update the transaction mask. - - The following events are available: - - - #RED_TRANSACT_UMOUNT - - #RED_TRANSACT_WRITE - - #RED_TRANSACT_TRUNCATE - - #RED_TRANSACT_VOLFULL - - The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all - automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of - all transaction flags, excluding those representing excluded functionality. - - Attempting to enable events for excluded functionality will result in an - error. - - @param bVolNum The volume number of the volume whose transaction mask - is being changed. - @param ulEventMask A bitwise-OR'd mask of automatic transaction events to - be set as the current transaction mode. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; - or @p ulEventMask contains invalid bits. - @retval -RED_EROFS The file system volume is read-only. -*/ -REDSTATUS RedFseTransMaskSet( - uint8_t bVolNum, - uint32_t ulEventMask) -{ - REDSTATUS ret; - - ret = FseEnter(bVolNum); - - if(ret == 0) - { - ret = RedCoreTransMaskSet(ulEventMask); - - FseLeave(); - } - - return ret; -} -#endif - - -#if REDCONF_API_FSE_TRANSMASKGET == 1 -/** @brief Read the transaction mask. - - If the volume is read-only, the returned event mask is always zero. - - @param bVolNum The volume number of the volume whose transaction mask - is being retrieved. - @param pulEventMask Populated with a bitwise-OR'd mask of automatic - transaction events which represent the current - transaction mode for the volume. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; - or @p pulEventMask is `NULL`. -*/ -REDSTATUS RedFseTransMaskGet( - uint8_t bVolNum, - uint32_t *pulEventMask) -{ - REDSTATUS ret; - - ret = FseEnter(bVolNum); - - if(ret == 0) - { - ret = RedCoreTransMaskGet(pulEventMask); - - FseLeave(); - } - - return ret; -} -#endif - - -#if REDCONF_READ_ONLY == 0 -/** @brief Commit a transaction point. - - Reliance Edge is a transactional file system. All modifications, of both - metadata and filedata, are initially working state. A transaction point - is a process whereby the working state atomically becomes the committed - state, replacing the previous committed state. Whenever Reliance Edge is - mounted, including after power loss, the state of the file system after - mount is the most recent committed state. Nothing from the committed - state is ever missing, and nothing from the working state is ever included. - - @param bVolNum The volume number of the volume to transact. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EROFS The file system volume is read-only. -*/ -REDSTATUS RedFseTransact( - uint8_t bVolNum) -{ - REDSTATUS ret; - - ret = FseEnter(bVolNum); - - if(ret == 0) - { - ret = RedCoreVolTransact(); - - FseLeave(); - } - - return ret; -} -#endif - -/** @} */ - -/** @brief Enter the file system driver. - - @param bVolNum The volume to be accessed. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL The file system driver is uninitialized; or @p bVolNum - is not a valid volume number. -*/ -static REDSTATUS FseEnter( - uint8_t bVolNum) -{ - REDSTATUS ret; - - if(gfFseInited) - { - #if REDCONF_TASK_COUNT > 1U - RedOsMutexAcquire(); - #endif - - /* This also serves to range-check the volume number (even in single - volume configurations). - */ - ret = RedCoreVolSetCurrent(bVolNum); - - #if REDCONF_TASK_COUNT > 1U - if(ret != 0) - { - RedOsMutexRelease(); - } - #endif - } - else - { - ret = -RED_EINVAL; - } - - return ret; -} - - -/** @brief Leave the file system driver. -*/ -static void FseLeave(void) -{ - REDASSERT(gfFseInited); - - #if REDCONF_TASK_COUNT > 1U - RedOsMutexRelease(); - #endif -} - - -#endif /* REDCONF_API_FSE == 1 */ - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implementation of the Reliance Edge FSE API. + */ +#include + +#if REDCONF_API_FSE == 1 + +/** @defgroup red_group_fse The File System Essentials Interface + * @{ + */ + + #include + #include + #include + + + static REDSTATUS FseEnter( uint8_t bVolNum ); + static void FseLeave( void ); + + + static bool gfFseInited; /* Whether driver is initialized. */ + + +/** @brief Initialize the Reliance Edge file system driver. + * + * Prepares the Reliance Edge file system driver to be used. Must be the first + * Reliance Edge function to be invoked: no volumes can be mounted until the + * driver has been initialized. + * + * If this function is called when the Reliance Edge driver is already + * initialized, it does nothing and returns success. + * + * This function is not thread safe: attempting to initialize from multiple + * threads could leave things in a bad state. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + REDSTATUS RedFseInit( void ) + { + REDSTATUS ret; + + if( gfFseInited ) + { + ret = 0; + } + else + { + ret = RedCoreInit(); + + if( ret == 0 ) + { + gfFseInited = true; + } + } + + return ret; + } + + +/** @brief Uninitialize the Reliance Edge file system driver. + * + * Tears down the Reliance Edge file system driver. Cannot be used until all + * Reliance Edge volumes are unmounted. A subsequent call to RedFseInit() + * will initialize the driver again. + * + * If this function is called when the Reliance Edge driver is already + * uninitialized, it does nothing and returns success. + * + * This function is not thread safe: attempting to uninitialize from multiple + * threads could leave things in a bad state. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBUSY At least one volume is still mounted. + */ + REDSTATUS RedFseUninit( void ) + { + REDSTATUS ret = 0; + + if( !gfFseInited ) + { + ret = 0; + } + else + { + uint8_t bVolNum; + + #if REDCONF_TASK_COUNT > 1U + RedOsMutexAcquire(); + #endif + + for( bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++ ) + { + if( gaRedVolume[ bVolNum ].fMounted ) + { + ret = -RED_EBUSY; + break; + } + } + + if( ret == 0 ) + { + gfFseInited = false; + } + + #if REDCONF_TASK_COUNT > 1U + RedOsMutexRelease(); + #endif + + if( ret == 0 ) + { + ret = RedCoreUninit(); + } + } + + return ret; + } + + +/** @brief Mount a file system volume. + * + * Prepares the file system volume to be accessed. Mount will fail if the + * volume has never been formatted, or if the on-disk format is inconsistent + * with the compile-time configuration. + * + * If the volume is already mounted, this function does nothing and returns + * success. + * + * @param bVolNum The volume number of the volume to be mounted. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is + * uninitialized. + * @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt. + */ + REDSTATUS RedFseMount( uint8_t bVolNum ) + { + REDSTATUS ret; + + ret = FseEnter( bVolNum ); + + if( ret == 0 ) + { + if( !gpRedVolume->fMounted ) + { + ret = RedCoreVolMount(); + } + + FseLeave(); + } + + return ret; + } + + +/** @brief Unmount a file system volume. + * + * This function discards the in-memory state for the file system and marks it + * as unmounted. Subsequent attempts to access the volume will fail until the + * volume is mounted again. + * + * If unmount automatic transaction points are enabled, this function will + * commit a transaction point prior to unmounting. If unmount automatic + * transaction points are disabled, this function will unmount without + * transacting, effectively discarding the working state. + * + * Before unmounting, this function will wait for any active file system + * thread to complete by acquiring the FS mutex. The volume will be marked as + * unmounted before the FS mutex is released, so subsequent FS threads will + * possibly block and then see an error when attempting to access a volume + * which is unmounting or unmounted. + * + * If the volume is already unmounted, this function does nothing and returns + * success. + * + * @param bVolNum The volume number of the volume to be unmounted. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is + * uninitialized. + * @retval -RED_EIO I/O error during unmount automatic transaction point. + */ + REDSTATUS RedFseUnmount( uint8_t bVolNum ) + { + REDSTATUS ret; + + ret = FseEnter( bVolNum ); + + if( ret == 0 ) + { + if( gpRedVolume->fMounted ) + { + ret = RedCoreVolUnmount(); + } + + FseLeave(); + } + + return ret; + } + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE_FORMAT == 1 ) + +/** @brief Format a file system volume. + * + * Uses the statically defined volume configuration. After calling this + * function, the volume needs to be mounted -- see RedFseMount(). + * + * An error is returned if the volume is mounted. + * + * @param bVolNum The volume number of the volume to be formatted. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBUSY The volume is mounted. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is + * uninitialized. + * @retval -RED_EIO I/O error formatting the volume. + */ + REDSTATUS RedFseFormat( uint8_t bVolNum ) + { + REDSTATUS ret; + + ret = FseEnter( bVolNum ); + + if( ret == 0 ) + { + ret = RedCoreVolFormat(); + + FseLeave(); + } + + return ret; + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE_FORMAT == 1 ) */ + + +/** @brief Read from a file. + * + * Data which has not yet been written, but which is before the end-of-file + * (sparse data), shall read as zeroes. A short read -- where the number of + * bytes read is less than requested -- indicates that the requested read was + * partially or, if zero bytes were read, entirely beyond the end-of-file. + * + * If @p ullFileOffset is at or beyond the maximum file size, it is treated + * like any other read entirely beyond the end-of-file: no data is read and + * zero is returned. + * + * @param bVolNum The volume number of the file to read. + * @param ulFileNum The file number of the file to read. + * @param ullFileOffset The file offset to read from. + * @param ulLength The number of bytes to read. + * @param pBuffer The buffer to populate with the data read. Must be + * at least ulLength bytes in size. + * + * @return The number of bytes read (nonnegative) or a negated ::REDSTATUS + * code indicating the operation result (negative). + * + * @retval >=0 The number of bytes read from the file. + * @retval -RED_EBADF @p ulFileNum is not a valid file number. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; + * or @p pBuffer is `NULL`; or @p ulLength exceeds + * INT32_MAX and cannot be returned properly. + * @retval -RED_EIO A disk I/O error occurred. + */ + int32_t RedFseRead( uint8_t bVolNum, + uint32_t ulFileNum, + uint64_t ullFileOffset, + uint32_t ulLength, + void * pBuffer ) + { + int32_t ret; + + if( ulLength > ( uint32_t ) INT32_MAX ) + { + ret = -RED_EINVAL; + } + else + { + ret = FseEnter( bVolNum ); + } + + if( ret == 0 ) + { + uint32_t ulReadLen = ulLength; + + ret = RedCoreFileRead( ulFileNum, ullFileOffset, &ulReadLen, pBuffer ); + + FseLeave(); + + if( ret == 0 ) + { + ret = ( int32_t ) ulReadLen; + } + } + + return ret; + } + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Write to a file. + * + * If the write extends beyond the end-of-file, the file size will be + * increased. + * + * A short write -- where the number of bytes written is less than requested + * -- indicates either that the file system ran out of space but was still + * able to write some of the request; or that the request would have caused + * the file to exceed the maximum file size, but some of the data could be + * written prior to the file size limit. + * + * If an error is returned (negative return), either none of the data was + * written or a critical error occurred (like an I/O error) and the file + * system volume will be read-only. + * + * @param bVolNum The volume number of the file to write. + * @param ulFileNum The file number of the file to write. + * @param ullFileOffset The file offset to write at. + * @param ulLength The number of bytes to write. + * @param pBuffer The buffer containing the data to be written. Must + * be at least ulLength bytes in size. + * + * @return The number of bytes written (nonnegative) or a negated ::REDSTATUS + * code indicating the operation result (negative). + * + * @retval >0 The number of bytes written to the file. + * @retval -RED_EBADF @p ulFileNum is not a valid file number. + * @retval -RED_EFBIG No data can be written to the given file offset since + * the resulting file size would exceed the maximum file + * size. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; + * or @p pBuffer is `NULL`; or @p ulLength exceeds + * INT32_MAX and cannot be returned properly. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC No data can be written because there is insufficient + * free space. + * @retval -RED_EROFS The file system volume is read-only. + */ + int32_t RedFseWrite( uint8_t bVolNum, + uint32_t ulFileNum, + uint64_t ullFileOffset, + uint32_t ulLength, + const void * pBuffer ) + { + int32_t ret; + + if( ulLength > ( uint32_t ) INT32_MAX ) + { + ret = -RED_EINVAL; + } + else + { + ret = FseEnter( bVolNum ); + } + + if( ret == 0 ) + { + uint32_t ulWriteLen = ulLength; + + ret = RedCoreFileWrite( ulFileNum, ullFileOffset, &ulWriteLen, pBuffer ); + + FseLeave(); + + if( ret == 0 ) + { + ret = ( int32_t ) ulWriteLen; + } + } + + return ret; + } + #endif /* if REDCONF_READ_ONLY == 0 */ + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE_TRUNCATE == 1 ) + +/** @brief Truncate a file (set the file size). + * + * Allows the file size to be increased, decreased, or to remain the same. If + * the file size is increased, the new area is sparse (will read as zeroes). + * If the file size is decreased, the data beyond the new end-of-file will + * return to free space once it is no longer part of the committed state + * (either immediately or after the next transaction point). + * + * This function can fail when the disk is full if @p ullNewFileSize is + * non-zero. If decreasing the file size, this can be fixed by transacting and + * trying again: Reliance Edge guarantees that it is possible to perform a + * truncate of at least one file that decreases the file size after a + * transaction point. If disk full transactions are enabled, this will happen + * automatically. + * + * @param bVolNum The volume number of the file to truncate. + * @param ulFileNum The file number of the file to truncate. + * @param ullNewFileSize The new file size, in bytes. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulFileNum is not a valid file number. + * @retval -RED_EFBIG @p ullNewFileSize exceeds the maximum file size. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOSPC Insufficient free space to perform the truncate. + * @retval -RED_EROFS The file system volume is read-only. + */ + REDSTATUS RedFseTruncate( uint8_t bVolNum, + uint32_t ulFileNum, + uint64_t ullNewFileSize ) + { + REDSTATUS ret; + + ret = FseEnter( bVolNum ); + + if( ret == 0 ) + { + ret = RedCoreFileTruncate( ulFileNum, ullNewFileSize ); + + FseLeave(); + } + + return ret; + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE_TRUNCATE == 1 ) */ + + +/** @brief Retrieve the size of a file. + * + * @param bVolNum The volume number of the file whose size is being read. + * @param ulFileNum The file number of the file whose size is being read. + * + * @return The size of the file (nonnegative) or a negated ::REDSTATUS code + * indicating the operation result (negative). + * + * @retval >=0 The size of the file. + * @retval -RED_EBADF @p ulFileNum is not a valid file number. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted. + * @retval -RED_EIO A disk I/O error occurred. + */ + int64_t RedFseSizeGet( uint8_t bVolNum, + uint32_t ulFileNum ) + { + int64_t ret; + + ret = FseEnter( bVolNum ); + + if( ret == 0 ) + { + uint64_t ullSize; + + ret = RedCoreFileSizeGet( ulFileNum, &ullSize ); + + FseLeave(); + + if( ret == 0 ) + { + /* Unless there is an on-disk format change, the maximum file size + * is guaranteed to be less than INT64_MAX, and so it can be safely + * returned in an int64_t. + */ + REDASSERT( ullSize < ( uint64_t ) INT64_MAX ); + + ret = ( int64_t ) ullSize; + } + } + + return ret; + } + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE_TRANSMASKSET == 1 ) + +/** @brief Update the transaction mask. + * + * The following events are available: + * + * - #RED_TRANSACT_UMOUNT + * - #RED_TRANSACT_WRITE + * - #RED_TRANSACT_TRUNCATE + * - #RED_TRANSACT_VOLFULL + * + * The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all + * automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of + * all transaction flags, excluding those representing excluded functionality. + * + * Attempting to enable events for excluded functionality will result in an + * error. + * + * @param bVolNum The volume number of the volume whose transaction mask + * is being changed. + * @param ulEventMask A bitwise-OR'd mask of automatic transaction events to + * be set as the current transaction mode. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; + * or @p ulEventMask contains invalid bits. + * @retval -RED_EROFS The file system volume is read-only. + */ + REDSTATUS RedFseTransMaskSet( uint8_t bVolNum, + uint32_t ulEventMask ) + { + REDSTATUS ret; + + ret = FseEnter( bVolNum ); + + if( ret == 0 ) + { + ret = RedCoreTransMaskSet( ulEventMask ); + + FseLeave(); + } + + return ret; + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE_TRANSMASKSET == 1 ) */ + + + #if REDCONF_API_FSE_TRANSMASKGET == 1 + +/** @brief Read the transaction mask. + * + * If the volume is read-only, the returned event mask is always zero. + * + * @param bVolNum The volume number of the volume whose transaction mask + * is being retrieved. + * @param pulEventMask Populated with a bitwise-OR'd mask of automatic + * transaction events which represent the current + * transaction mode for the volume. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; + * or @p pulEventMask is `NULL`. + */ + REDSTATUS RedFseTransMaskGet( uint8_t bVolNum, + uint32_t * pulEventMask ) + { + REDSTATUS ret; + + ret = FseEnter( bVolNum ); + + if( ret == 0 ) + { + ret = RedCoreTransMaskGet( pulEventMask ); + + FseLeave(); + } + + return ret; + } + #endif /* if REDCONF_API_FSE_TRANSMASKGET == 1 */ + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Commit a transaction point. + * + * Reliance Edge is a transactional file system. All modifications, of both + * metadata and filedata, are initially working state. A transaction point + * is a process whereby the working state atomically becomes the committed + * state, replacing the previous committed state. Whenever Reliance Edge is + * mounted, including after power loss, the state of the file system after + * mount is the most recent committed state. Nothing from the committed + * state is ever missing, and nothing from the working state is ever included. + * + * @param bVolNum The volume number of the volume to transact. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EROFS The file system volume is read-only. + */ + REDSTATUS RedFseTransact( uint8_t bVolNum ) + { + REDSTATUS ret; + + ret = FseEnter( bVolNum ); + + if( ret == 0 ) + { + ret = RedCoreVolTransact(); + + FseLeave(); + } + + return ret; + } + #endif /* if REDCONF_READ_ONLY == 0 */ + +/** @} */ + +/** @brief Enter the file system driver. + * + * @param bVolNum The volume to be accessed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL The file system driver is uninitialized; or @p bVolNum + * is not a valid volume number. + */ + static REDSTATUS FseEnter( uint8_t bVolNum ) + { + REDSTATUS ret; + + if( gfFseInited ) + { + #if REDCONF_TASK_COUNT > 1U + RedOsMutexAcquire(); + #endif + + /* This also serves to range-check the volume number (even in single + * volume configurations). + */ + ret = RedCoreVolSetCurrent( bVolNum ); + + #if REDCONF_TASK_COUNT > 1U + if( ret != 0 ) + { + RedOsMutexRelease(); + } + #endif + } + else + { + ret = -RED_EINVAL; + } + + return ret; + } + + +/** @brief Leave the file system driver. + */ + static void FseLeave( void ) + { + REDASSERT( gfFseInited ); + + #if REDCONF_TASK_COUNT > 1U + RedOsMutexRelease(); + #endif + } + + +#endif /* REDCONF_API_FSE == 1 */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redapimacs.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redapimacs.h index 13de409fe..38952f5d6 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redapimacs.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redapimacs.h @@ -1,112 +1,113 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Defines macros used to interact with the Reliance Edge API. -*/ -#ifndef REDAPIMACS_H -#define REDAPIMACS_H - - -/** Clear all events: manual transactions only. */ -#define RED_TRANSACT_MANUAL 0x00000000U - -/** Transact prior to unmounting in red_umount() or RedFseUnmount(). */ -#define RED_TRANSACT_UMOUNT 0x00000001U - -/** Transact after a successful red_open() which created a file. */ -#define RED_TRANSACT_CREAT 0x00000002U - -/** Transact after a successful red_unlink() or red_rmdir(). */ -#define RED_TRANSACT_UNLINK 0x00000004U - -/** Transact after a successful red_mkdir(). */ -#define RED_TRANSACT_MKDIR 0x00000008U - -/** Transact after a successful red_rename(). */ -#define RED_TRANSACT_RENAME 0x00000010U - -/** Transact after a successful red_link(). */ -#define RED_TRANSACT_LINK 0x00000020U - -/** Transact after a successful red_close(). */ -#define RED_TRANSACT_CLOSE 0x00000040U - -/** Transact after a successful red_write() or RedFseWrite(). */ -#define RED_TRANSACT_WRITE 0x00000080U - -/** Transact after a successful red_fsync(). */ -#define RED_TRANSACT_FSYNC 0x00000100U - -/** Transact after a successful red_ftruncate(), RedFseTruncate(), or red_open() with RED_O_TRUNC that actually truncates. */ -#define RED_TRANSACT_TRUNCATE 0x00000200U - -/** Transact to free space in disk full situations. */ -#define RED_TRANSACT_VOLFULL 0x00000400U - -#if REDCONF_READ_ONLY == 1 - -/** Mask of all supported automatic transaction events. */ -#define RED_TRANSACT_MASK 0U - -#elif REDCONF_API_POSIX == 1 - -/** @brief Mask of all supported automatic transaction events. -*/ -#define RED_TRANSACT_MASK \ -( \ - RED_TRANSACT_UMOUNT | \ - RED_TRANSACT_CREAT | \ - ((REDCONF_API_POSIX_UNLINK == 1) ? RED_TRANSACT_UNLINK : 0U) | \ - ((REDCONF_API_POSIX_MKDIR == 1) ? RED_TRANSACT_MKDIR : 0U) | \ - ((REDCONF_API_POSIX_RENAME == 1) ? RED_TRANSACT_RENAME : 0U) | \ - ((REDCONF_API_POSIX_LINK == 1) ? RED_TRANSACT_LINK : 0U) | \ - RED_TRANSACT_CLOSE | \ - RED_TRANSACT_WRITE | \ - RED_TRANSACT_FSYNC | \ - ((REDCONF_API_POSIX_FTRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \ - RED_TRANSACT_VOLFULL \ -) - -#else /* REDCONF_API_FSE == 1 */ - -/** @brief Mask of all supported automatic transaction events. -*/ -#define RED_TRANSACT_MASK \ -( \ - RED_TRANSACT_UMOUNT | \ - RED_TRANSACT_WRITE | \ - ((REDCONF_API_FSE_TRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \ - RED_TRANSACT_VOLFULL \ -) - -#endif /* REDCONF_READ_ONLY */ - -#if (REDCONF_TRANSACT_DEFAULT & RED_TRANSACT_MASK) != REDCONF_TRANSACT_DEFAULT -#error "Configuration error: invalid value of REDCONF_TRANSACT_DEFAULT" -#endif - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Defines macros used to interact with the Reliance Edge API. + */ +#ifndef REDAPIMACS_H +#define REDAPIMACS_H + + +/** Clear all events: manual transactions only. */ +#define RED_TRANSACT_MANUAL 0x00000000U + +/** Transact prior to unmounting in red_umount() or RedFseUnmount(). */ +#define RED_TRANSACT_UMOUNT 0x00000001U + +/** Transact after a successful red_open() which created a file. */ +#define RED_TRANSACT_CREAT 0x00000002U + +/** Transact after a successful red_unlink() or red_rmdir(). */ +#define RED_TRANSACT_UNLINK 0x00000004U + +/** Transact after a successful red_mkdir(). */ +#define RED_TRANSACT_MKDIR 0x00000008U + +/** Transact after a successful red_rename(). */ +#define RED_TRANSACT_RENAME 0x00000010U + +/** Transact after a successful red_link(). */ +#define RED_TRANSACT_LINK 0x00000020U + +/** Transact after a successful red_close(). */ +#define RED_TRANSACT_CLOSE 0x00000040U + +/** Transact after a successful red_write() or RedFseWrite(). */ +#define RED_TRANSACT_WRITE 0x00000080U + +/** Transact after a successful red_fsync(). */ +#define RED_TRANSACT_FSYNC 0x00000100U + +/** Transact after a successful red_ftruncate(), RedFseTruncate(), or red_open() with RED_O_TRUNC that actually truncates. */ +#define RED_TRANSACT_TRUNCATE 0x00000200U + +/** Transact to free space in disk full situations. */ +#define RED_TRANSACT_VOLFULL 0x00000400U + +#if REDCONF_READ_ONLY == 1 + +/** Mask of all supported automatic transaction events. */ + #define RED_TRANSACT_MASK 0U + +#elif REDCONF_API_POSIX == 1 + +/** @brief Mask of all supported automatic transaction events. + */ + #define RED_TRANSACT_MASK \ + ( \ + RED_TRANSACT_UMOUNT | \ + RED_TRANSACT_CREAT | \ + ( ( REDCONF_API_POSIX_UNLINK == 1 ) ? RED_TRANSACT_UNLINK : 0U ) | \ + ( ( REDCONF_API_POSIX_MKDIR == 1 ) ? RED_TRANSACT_MKDIR : 0U ) | \ + ( ( REDCONF_API_POSIX_RENAME == 1 ) ? RED_TRANSACT_RENAME : 0U ) | \ + ( ( REDCONF_API_POSIX_LINK == 1 ) ? RED_TRANSACT_LINK : 0U ) | \ + RED_TRANSACT_CLOSE | \ + RED_TRANSACT_WRITE | \ + RED_TRANSACT_FSYNC | \ + ( ( REDCONF_API_POSIX_FTRUNCATE == 1 ) ? RED_TRANSACT_TRUNCATE : 0U ) | \ + RED_TRANSACT_VOLFULL \ + ) + +#else /* REDCONF_API_FSE == 1 */ + +/** @brief Mask of all supported automatic transaction events. + */ + #define RED_TRANSACT_MASK \ + ( \ + RED_TRANSACT_UMOUNT | \ + RED_TRANSACT_WRITE | \ + ( ( REDCONF_API_FSE_TRUNCATE == 1 ) ? RED_TRANSACT_TRUNCATE : 0U ) | \ + RED_TRANSACT_VOLFULL \ + ) + +#endif /* REDCONF_READ_ONLY */ + +#if ( REDCONF_TRANSACT_DEFAULT & RED_TRANSACT_MASK ) != REDCONF_TRANSACT_DEFAULT + #error "Configuration error: invalid value of REDCONF_TRANSACT_DEFAULT" +#endif + + +#endif /* ifndef REDAPIMACS_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redconfigchk.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redconfigchk.h index 8576a420d..f68b7154f 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redconfigchk.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redconfigchk.h @@ -1,349 +1,351 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Compile-time validity checks for the REDCONF macros. -*/ + * @brief Compile-time validity checks for the REDCONF macros. + */ #ifndef REDCONFIGCHK_H #define REDCONFIGCHK_H #ifdef RED_CONFIG_MINCOMPAT_VER - #if (RED_VERSION_VAL & 0xFFFFFF00U) < (RED_CONFIG_MINCOMPAT_VER & 0xFFFFFF00U) - /* This indicates that your configuration files were generated by a - version of the Reliance Edge Configuration Utility that is designed - for a more recent version of Reliance Edge and is no longer compatible - with this version. You can update to the most recent version of - Reliance Edge or contact RelianceEdgeSupport@datalight.com to obtain - the correct legacy version of the Configuration Utility. - */ - #error "Your configuration is not compatible with this version of Reliance Edge. Please download the latest version of Reliance Edge or recreate your configuration with an older version of the Configuration Utility." - #endif + #if ( RED_VERSION_VAL & 0xFFFFFF00U ) < ( RED_CONFIG_MINCOMPAT_VER & 0xFFFFFF00U ) + +/* This indicates that your configuration files were generated by a + * version of the Reliance Edge Configuration Utility that is designed + * for a more recent version of Reliance Edge and is no longer compatible + * with this version. You can update to the most recent version of + * Reliance Edge or contact RelianceEdgeSupport@datalight.com to obtain + * the correct legacy version of the Configuration Utility. + */ + #error "Your configuration is not compatible with this version of Reliance Edge. Please download the latest version of Reliance Edge or recreate your configuration with an older version of the Configuration Utility." + #endif #endif #ifndef REDCONF_READ_ONLY - #error "Configuration error: REDCONF_READ_ONLY must be defined." + #error "Configuration error: REDCONF_READ_ONLY must be defined." #endif #ifndef REDCONF_API_POSIX - #error "Configuration error: REDCONF_API_POSIX must be defined." + #error "Configuration error: REDCONF_API_POSIX must be defined." #endif #ifndef REDCONF_API_FSE - #error "Configuration error: REDCONF_API_FSE must be defined." + #error "Configuration error: REDCONF_API_FSE must be defined." #endif #if REDCONF_API_POSIX == 1 - #ifndef REDCONF_API_POSIX_FORMAT - #error "Configuration error: REDCONF_API_POSIX_FORMAT must be defined." - #endif - #ifndef REDCONF_API_POSIX_UNLINK - #error "Configuration error: REDCONF_API_POSIX_UNLINK must be defined." - #endif - #ifndef REDCONF_API_POSIX_MKDIR - #error "Configuration error: REDCONF_API_POSIX_MKDIR must be defined." - #endif - #ifndef REDCONF_API_POSIX_RMDIR - #error "Configuration error: REDCONF_API_POSIX_RMDIR must be defined." - #endif - #ifndef REDCONF_API_POSIX_RENAME - #error "Configuration error: REDCONF_API_POSIX_RENAME must be defined." - #endif - #ifndef REDCONF_API_POSIX_LINK - #error "Configuration error: REDCONF_API_POSIX_LINK must be defined." - #endif - #ifndef REDCONF_API_POSIX_FTRUNCATE - #error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be defined." - #endif - #ifndef REDCONF_API_POSIX_READDIR - #error "Configuration error: REDCONF_API_POSIX_READDIR must be defined." - #endif - #ifndef REDCONF_NAME_MAX - #error "Configuration error: REDCONF_NAME_MAX must be defined." - #endif - #ifndef REDCONF_PATH_SEPARATOR - #error "Configuration error: REDCONF_PATH_SEPARATOR must be defined." - #endif - #ifndef REDCONF_RENAME_ATOMIC - #error "Configuration error: REDCONF_RENAME_ATOMIC must be defined." - #endif - #ifndef REDCONF_HANDLE_COUNT - #error "Configuration error: REDCONF_HANDLE_COUNT must be defined." - #endif -#endif + #ifndef REDCONF_API_POSIX_FORMAT + #error "Configuration error: REDCONF_API_POSIX_FORMAT must be defined." + #endif + #ifndef REDCONF_API_POSIX_UNLINK + #error "Configuration error: REDCONF_API_POSIX_UNLINK must be defined." + #endif + #ifndef REDCONF_API_POSIX_MKDIR + #error "Configuration error: REDCONF_API_POSIX_MKDIR must be defined." + #endif + #ifndef REDCONF_API_POSIX_RMDIR + #error "Configuration error: REDCONF_API_POSIX_RMDIR must be defined." + #endif + #ifndef REDCONF_API_POSIX_RENAME + #error "Configuration error: REDCONF_API_POSIX_RENAME must be defined." + #endif + #ifndef REDCONF_API_POSIX_LINK + #error "Configuration error: REDCONF_API_POSIX_LINK must be defined." + #endif + #ifndef REDCONF_API_POSIX_FTRUNCATE + #error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be defined." + #endif + #ifndef REDCONF_API_POSIX_READDIR + #error "Configuration error: REDCONF_API_POSIX_READDIR must be defined." + #endif + #ifndef REDCONF_NAME_MAX + #error "Configuration error: REDCONF_NAME_MAX must be defined." + #endif + #ifndef REDCONF_PATH_SEPARATOR + #error "Configuration error: REDCONF_PATH_SEPARATOR must be defined." + #endif + #ifndef REDCONF_RENAME_ATOMIC + #error "Configuration error: REDCONF_RENAME_ATOMIC must be defined." + #endif + #ifndef REDCONF_HANDLE_COUNT + #error "Configuration error: REDCONF_HANDLE_COUNT must be defined." + #endif +#endif /* if REDCONF_API_POSIX == 1 */ #if REDCONF_API_FSE == 1 - #ifndef REDCONF_API_FSE_FORMAT - #error "Configuration error: REDCONF_API_FSE_FORMAT must be defined." - #endif - #ifndef REDCONF_API_FSE_TRUNCATE - #error "Configuration error: REDCONF_API_FSE_TRUNCATE must be defined." - #endif - #ifndef REDCONF_API_FSE_TRANSMASKSET - #error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be defined." - #endif - #ifndef REDCONF_API_FSE_TRANSMASKGET - #error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be defined." - #endif -#endif + #ifndef REDCONF_API_FSE_FORMAT + #error "Configuration error: REDCONF_API_FSE_FORMAT must be defined." + #endif + #ifndef REDCONF_API_FSE_TRUNCATE + #error "Configuration error: REDCONF_API_FSE_TRUNCATE must be defined." + #endif + #ifndef REDCONF_API_FSE_TRANSMASKSET + #error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be defined." + #endif + #ifndef REDCONF_API_FSE_TRANSMASKGET + #error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be defined." + #endif +#endif /* if REDCONF_API_FSE == 1 */ #ifndef REDCONF_TASK_COUNT - #error "Configuration error: REDCONF_TASK_COUNT must be defined." + #error "Configuration error: REDCONF_TASK_COUNT must be defined." #endif #ifndef REDCONF_ENDIAN_BIG - #error "Configuration error: REDCONF_ENDIAN_BIG must be defined." + #error "Configuration error: REDCONF_ENDIAN_BIG must be defined." #endif #ifndef REDCONF_ALIGNMENT_SIZE - #error "Configuration error: REDCONF_ALIGNMENT_SIZE must be defined." + #error "Configuration error: REDCONF_ALIGNMENT_SIZE must be defined." #endif #ifndef REDCONF_CRC_ALGORITHM - #error "Configuration error: REDCONF_CRC_ALGORITHM must be defined." + #error "Configuration error: REDCONF_CRC_ALGORITHM must be defined." #endif #ifndef REDCONF_INODE_TIMESTAMPS - #error "Configuration error: REDCONF_INODE_TIMESTAMPS must be defined." + #error "Configuration error: REDCONF_INODE_TIMESTAMPS must be defined." #endif #ifndef REDCONF_ATIME - #error "Configuration error: REDCONF_ATIME must be defined." + #error "Configuration error: REDCONF_ATIME must be defined." #endif #ifndef REDCONF_DIRECT_POINTERS - #error "Configuration error: REDCONF_DIRECT_POINTERS must be defined." + #error "Configuration error: REDCONF_DIRECT_POINTERS must be defined." #endif #ifndef REDCONF_INDIRECT_POINTERS - #error "Configuration error: REDCONF_INDIRECT_POINTERS must be defined." + #error "Configuration error: REDCONF_INDIRECT_POINTERS must be defined." #endif #ifndef REDCONF_INODE_BLOCKS - #error "Configuration error: REDCONF_INODE_BLOCKS must be defined." + #error "Configuration error: REDCONF_INODE_BLOCKS must be defined." #endif #ifndef REDCONF_IMAP_EXTERNAL - #error "Configuration error: REDCONF_IMAP_EXTERNAL must be defined." + #error "Configuration error: REDCONF_IMAP_EXTERNAL must be defined." #endif #ifndef REDCONF_IMAP_INLINE - #error "Configuration error: REDCONF_IMAP_INLINE must be defined." + #error "Configuration error: REDCONF_IMAP_INLINE must be defined." #endif #ifndef REDCONF_OUTPUT - #error "Configuration error: REDCONF_OUTPUT must be defined." + #error "Configuration error: REDCONF_OUTPUT must be defined." #endif #ifndef REDCONF_ASSERTS - #error "Configuration error: REDCONF_ASSERTS must be defined." + #error "Configuration error: REDCONF_ASSERTS must be defined." #endif #ifndef REDCONF_TRANSACT_DEFAULT - #error "Configuration error: REDCONF_TRANSACT_DEFAULT must be defined." + #error "Configuration error: REDCONF_TRANSACT_DEFAULT must be defined." #endif #ifndef REDCONF_BUFFER_COUNT - #error "Configuration error: REDCONF_BUFFER_COUNT must be defined." + #error "Configuration error: REDCONF_BUFFER_COUNT must be defined." #endif #ifndef REDCONF_BLOCK_SIZE - #error "Configuration error: REDCONF_BLOCK_SIZE must be defined." + #error "Configuration error: REDCONF_BLOCK_SIZE must be defined." #endif #ifndef REDCONF_VOLUME_COUNT - #error "Configuration error: REDCONF_VOLUME_COUNT must be defined." + #error "Configuration error: REDCONF_VOLUME_COUNT must be defined." #endif #ifndef REDCONF_DISCARDS - /* Reliance Edge 1.0.5 and below did not have REDCONF_DISCARDS. You can - fix this error by downloading the latest version of the Configuration - Utility (assuming you are using the latest version of Reliance Edge) - from http://www.datalight.com/reliance-edge, loading your redconf.c - and redconf.h files, and saving them again, replacing the original - files. - */ - #error "Configuration error: your redconf.h is not compatible. Update your redconf files with a compatible version of the configuration utility." + +/* Reliance Edge 1.0.5 and below did not have REDCONF_DISCARDS. You can + * fix this error by downloading the latest version of the Configuration + * Utility (assuming you are using the latest version of Reliance Edge) + * from http://www.datalight.com/reliance-edge, loading your redconf.c + * and redconf.h files, and saving them again, replacing the original + * files. + */ + #error "Configuration error: your redconf.h is not compatible. Update your redconf files with a compatible version of the configuration utility." #endif #ifndef REDCONF_IMAGE_BUILDER - #error "Configuration error: REDCONF_IMAGE_BUILDER must be defined." + #error "Configuration error: REDCONF_IMAGE_BUILDER must be defined." #endif #ifndef REDCONF_CHECKER - #error "Configuration error: REDCONF_CHECKER must be defined." + #error "Configuration error: REDCONF_CHECKER must be defined." #endif -#if (REDCONF_READ_ONLY != 0) && (REDCONF_READ_ONLY != 1) - #error "Configuration error: REDCONF_READ_ONLY must be either 0 or 1" +#if ( REDCONF_READ_ONLY != 0 ) && ( REDCONF_READ_ONLY != 1 ) + #error "Configuration error: REDCONF_READ_ONLY must be either 0 or 1" #endif -#if (REDCONF_API_POSIX != 0) && (REDCONF_API_POSIX != 1) - #error "Configuration error: REDCONF_API_POSIX must be either 0 or 1." +#if ( REDCONF_API_POSIX != 0 ) && ( REDCONF_API_POSIX != 1 ) + #error "Configuration error: REDCONF_API_POSIX must be either 0 or 1." #endif -#if (REDCONF_API_FSE != 0) && (REDCONF_API_FSE != 1) - #error "Configuration error: REDCONF_API_FSE must be either 0 or 1." +#if ( REDCONF_API_FSE != 0 ) && ( REDCONF_API_FSE != 1 ) + #error "Configuration error: REDCONF_API_FSE must be either 0 or 1." #endif -#if (REDCONF_API_FSE == 0) && (REDCONF_API_POSIX == 0) - #error "Configuration error: either REDCONF_API_FSE or REDCONF_API_POSIX must be set to 1." +#if ( REDCONF_API_FSE == 0 ) && ( REDCONF_API_POSIX == 0 ) + #error "Configuration error: either REDCONF_API_FSE or REDCONF_API_POSIX must be set to 1." #endif #if REDCONF_API_POSIX == 1 - #if REDCONF_API_FSE != 0 - #error "Configuration error: REDCONF_API_FSE must be 0 if REDCONF_API_POSIX is 1" - #endif + #if REDCONF_API_FSE != 0 + #error "Configuration error: REDCONF_API_FSE must be 0 if REDCONF_API_POSIX is 1" + #endif - #if (REDCONF_API_POSIX_FORMAT != 0) && (REDCONF_API_POSIX_FORMAT != 1) - #error "Configuration error: REDCONF_API_POSIX_FORMAT must be either 0 or 1." - #endif + #if ( REDCONF_API_POSIX_FORMAT != 0 ) && ( REDCONF_API_POSIX_FORMAT != 1 ) + #error "Configuration error: REDCONF_API_POSIX_FORMAT must be either 0 or 1." + #endif - #if (REDCONF_API_POSIX_UNLINK != 0) && (REDCONF_API_POSIX_UNLINK != 1) - #error "Configuration error: REDCONF_API_POSIX_UNLINK must be either 0 or 1." - #endif + #if ( REDCONF_API_POSIX_UNLINK != 0 ) && ( REDCONF_API_POSIX_UNLINK != 1 ) + #error "Configuration error: REDCONF_API_POSIX_UNLINK must be either 0 or 1." + #endif - #if (REDCONF_API_POSIX_MKDIR != 0) && (REDCONF_API_POSIX_MKDIR != 1) - #error "Configuration error: REDCONF_API_POSIX_MKDIR must be either 0 or 1." - #endif + #if ( REDCONF_API_POSIX_MKDIR != 0 ) && ( REDCONF_API_POSIX_MKDIR != 1 ) + #error "Configuration error: REDCONF_API_POSIX_MKDIR must be either 0 or 1." + #endif - #if (REDCONF_API_POSIX_RMDIR != 0) && (REDCONF_API_POSIX_RMDIR != 1) - #error "Configuration error: REDCONF_API_POSIX_RMDIR must be either 0 or 1." - #endif + #if ( REDCONF_API_POSIX_RMDIR != 0 ) && ( REDCONF_API_POSIX_RMDIR != 1 ) + #error "Configuration error: REDCONF_API_POSIX_RMDIR must be either 0 or 1." + #endif - #if (REDCONF_API_POSIX_RENAME != 0) && (REDCONF_API_POSIX_RENAME != 1) - #error "Configuration error: REDCONF_API_POSIX_RENAME must be either 0 or 1." - #endif + #if ( REDCONF_API_POSIX_RENAME != 0 ) && ( REDCONF_API_POSIX_RENAME != 1 ) + #error "Configuration error: REDCONF_API_POSIX_RENAME must be either 0 or 1." + #endif - #if (REDCONF_API_POSIX_LINK != 0) && (REDCONF_API_POSIX_LINK != 1) - #error "Configuration error: REDCONF_API_POSIX_LINK must be either 0 or 1." - #endif + #if ( REDCONF_API_POSIX_LINK != 0 ) && ( REDCONF_API_POSIX_LINK != 1 ) + #error "Configuration error: REDCONF_API_POSIX_LINK must be either 0 or 1." + #endif - #if (REDCONF_API_POSIX_FTRUNCATE != 0) && (REDCONF_API_POSIX_FTRUNCATE != 1) - #error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be either 0 or 1." - #endif + #if ( REDCONF_API_POSIX_FTRUNCATE != 0 ) && ( REDCONF_API_POSIX_FTRUNCATE != 1 ) + #error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be either 0 or 1." + #endif - #if (REDCONF_API_POSIX_READDIR != 0) && (REDCONF_API_POSIX_READDIR != 1) - #error "Configuration error: REDCONF_API_POSIX_READDIR must be either 0 or 1." - #endif + #if ( REDCONF_API_POSIX_READDIR != 0 ) && ( REDCONF_API_POSIX_READDIR != 1 ) + #error "Configuration error: REDCONF_API_POSIX_READDIR must be either 0 or 1." + #endif - #if (REDCONF_NAME_MAX < 1U) || (REDCONF_NAME_MAX > (REDCONF_BLOCK_SIZE - 4U)) - #error "Configuration error: invalid value of REDCONF_NAME_MAX" - #endif + #if ( REDCONF_NAME_MAX < 1U ) || ( REDCONF_NAME_MAX > ( REDCONF_BLOCK_SIZE - 4U ) ) + #error "Configuration error: invalid value of REDCONF_NAME_MAX" + #endif - #if (REDCONF_PATH_SEPARATOR < 1) || (REDCONF_PATH_SEPARATOR > 127) - #error "Configuration error: invalid value of REDCONF_PATH_SEPARATOR" - #endif + #if ( REDCONF_PATH_SEPARATOR < 1 ) || ( REDCONF_PATH_SEPARATOR > 127 ) + #error "Configuration error: invalid value of REDCONF_PATH_SEPARATOR" + #endif - #if (REDCONF_RENAME_ATOMIC != 0) && (REDCONF_RENAME_ATOMIC != 1) - #error "Configuration error: REDCONF_RENAME_ATOMIC must be either 0 or 1." - #endif + #if ( REDCONF_RENAME_ATOMIC != 0 ) && ( REDCONF_RENAME_ATOMIC != 1 ) + #error "Configuration error: REDCONF_RENAME_ATOMIC must be either 0 or 1." + #endif - #if (REDCONF_HANDLE_COUNT < 1U) || (REDCONF_HANDLE_COUNT > 4096U) - #error "Configuration error: invalid value of REDCONF_HANDLE_COUNT" - #endif -#endif + #if ( REDCONF_HANDLE_COUNT < 1U ) || ( REDCONF_HANDLE_COUNT > 4096U ) + #error "Configuration error: invalid value of REDCONF_HANDLE_COUNT" + #endif +#endif /* if REDCONF_API_POSIX == 1 */ #if REDCONF_API_FSE == 1 - #if (REDCONF_API_FSE_FORMAT != 0) && (REDCONF_API_FSE_FORMAT != 1) - #error "Configuration error: REDCONF_API_FSE_FORMAT must be either 0 or 1." - #endif + #if ( REDCONF_API_FSE_FORMAT != 0 ) && ( REDCONF_API_FSE_FORMAT != 1 ) + #error "Configuration error: REDCONF_API_FSE_FORMAT must be either 0 or 1." + #endif - #if (REDCONF_API_FSE_TRUNCATE != 0) && (REDCONF_API_FSE_TRUNCATE != 1) - #error "Configuration error: REDCONF_API_FSE_TRUNCATE must be either 0 or 1." - #endif + #if ( REDCONF_API_FSE_TRUNCATE != 0 ) && ( REDCONF_API_FSE_TRUNCATE != 1 ) + #error "Configuration error: REDCONF_API_FSE_TRUNCATE must be either 0 or 1." + #endif - #if (REDCONF_API_FSE_TRANSMASKSET != 0) && (REDCONF_API_FSE_TRANSMASKSET != 1) - #error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be either 0 or 1." - #endif + #if ( REDCONF_API_FSE_TRANSMASKSET != 0 ) && ( REDCONF_API_FSE_TRANSMASKSET != 1 ) + #error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be either 0 or 1." + #endif - #if (REDCONF_API_FSE_TRANSMASKGET != 0) && (REDCONF_API_FSE_TRANSMASKGET != 1) - #error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be either 0 or 1." - #endif -#endif + #if ( REDCONF_API_FSE_TRANSMASKGET != 0 ) && ( REDCONF_API_FSE_TRANSMASKGET != 1 ) + #error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be either 0 or 1." + #endif +#endif /* if REDCONF_API_FSE == 1 */ #if REDCONF_TASK_COUNT < 1U - #error "Configuration error: invalid value of REDCONF_TASK_COUNT" + #error "Configuration error: invalid value of REDCONF_TASK_COUNT" #endif -#if (REDCONF_ENDIAN_BIG != 0) && (REDCONF_ENDIAN_BIG != 1) - #error "Configuration error: REDCONF_ENDIAN_BIG must be either 0 or 1." +#if ( REDCONF_ENDIAN_BIG != 0 ) && ( REDCONF_ENDIAN_BIG != 1 ) + #error "Configuration error: REDCONF_ENDIAN_BIG must be either 0 or 1." #endif -#if (REDCONF_ALIGNMENT_SIZE != 1U) && (REDCONF_ALIGNMENT_SIZE != 2U) && (REDCONF_ALIGNMENT_SIZE != 4U) && (REDCONF_ALIGNMENT_SIZE != 8U) - #error "Configuration error: invalid value REDCONF_ALIGNMENT_SIZE" +#if ( REDCONF_ALIGNMENT_SIZE != 1U ) && ( REDCONF_ALIGNMENT_SIZE != 2U ) && ( REDCONF_ALIGNMENT_SIZE != 4U ) && ( REDCONF_ALIGNMENT_SIZE != 8U ) + #error "Configuration error: invalid value REDCONF_ALIGNMENT_SIZE" #endif /* REDCONF_CRC_ALGORITHM checked in crc.c -*/ + */ -#if (REDCONF_INODE_TIMESTAMPS != 0) && (REDCONF_INODE_TIMESTAMPS != 1) - #error "Configuration error: REDCONF_INODE_TIMESTAMPS must be either 0 or 1." +#if ( REDCONF_INODE_TIMESTAMPS != 0 ) && ( REDCONF_INODE_TIMESTAMPS != 1 ) + #error "Configuration error: REDCONF_INODE_TIMESTAMPS must be either 0 or 1." #endif -#if (REDCONF_ATIME != 0) && (REDCONF_ATIME != 1) - #error "Configuration error: REDCONF_ATIME must be either 0 or 1." +#if ( REDCONF_ATIME != 0 ) && ( REDCONF_ATIME != 1 ) + #error "Configuration error: REDCONF_ATIME must be either 0 or 1." #endif -#if (REDCONF_INODE_TIMESTAMPS == 0) && (REDCONF_ATIME == 1) - #error "Configuration error: REDCONF_ATIME must be 0 when REDCONF_INODE_TIMESTAMPS is 0." +#if ( REDCONF_INODE_TIMESTAMPS == 0 ) && ( REDCONF_ATIME == 1 ) + #error "Configuration error: REDCONF_ATIME must be 0 when REDCONF_INODE_TIMESTAMPS is 0." #endif /* REDCONF_DIRECT_POINTERS and REDCONF_INDIRECT_POINTERS checked in rednodes.h -*/ + */ -#if (REDCONF_INODE_BLOCKS != 0) && (REDCONF_INODE_BLOCKS != 1) - #error "Configuration error: REDCONF_INODE_BLOCKS must be either 0 or 1." +#if ( REDCONF_INODE_BLOCKS != 0 ) && ( REDCONF_INODE_BLOCKS != 1 ) + #error "Configuration error: REDCONF_INODE_BLOCKS must be either 0 or 1." #endif /* Further validity checking of imap specs done in RelCoreInit() -*/ -#if (REDCONF_IMAP_EXTERNAL != 0) && (REDCONF_IMAP_EXTERNAL != 1) - #error "Configuration error: REDCONF_IMAP_EXTERNAL must be either 0 or 1." + */ +#if ( REDCONF_IMAP_EXTERNAL != 0 ) && ( REDCONF_IMAP_EXTERNAL != 1 ) + #error "Configuration error: REDCONF_IMAP_EXTERNAL must be either 0 or 1." #endif -#if (REDCONF_IMAP_INLINE != 0) && (REDCONF_IMAP_INLINE != 1) - #error "Configuration error: REDCONF_IMAP_INLINE must be either 0 or 1." +#if ( REDCONF_IMAP_INLINE != 0 ) && ( REDCONF_IMAP_INLINE != 1 ) + #error "Configuration error: REDCONF_IMAP_INLINE must be either 0 or 1." #endif -#if (REDCONF_IMAP_INLINE == 0) && (REDCONF_IMAP_EXTERNAL == 0) - #error "Configuration error: At least one of REDCONF_IMAP_INLINE and REDCONF_IMAP_EXTERNAL must be set" +#if ( REDCONF_IMAP_INLINE == 0 ) && ( REDCONF_IMAP_EXTERNAL == 0 ) + #error "Configuration error: At least one of REDCONF_IMAP_INLINE and REDCONF_IMAP_EXTERNAL must be set" #endif -#if (REDCONF_OUTPUT != 0) && (REDCONF_OUTPUT != 1) - #error "Configuration error: REDCONF_OUTPUT must be either 0 or 1." +#if ( REDCONF_OUTPUT != 0 ) && ( REDCONF_OUTPUT != 1 ) + #error "Configuration error: REDCONF_OUTPUT must be either 0 or 1." #endif -#if (REDCONF_ASSERTS != 0) && (REDCONF_ASSERTS != 1) - #error "Configuration error: REDCONF_ASSERTS must be either 0 or 1." +#if ( REDCONF_ASSERTS != 0 ) && ( REDCONF_ASSERTS != 1 ) + #error "Configuration error: REDCONF_ASSERTS must be either 0 or 1." #endif /* REDCONF_BLOCK_SIZE checked in redmacs.h -*/ + */ -#if (REDCONF_VOLUME_COUNT < 1U) || (REDCONF_VOLUME_COUNT > 255U) - #error "REDCONF_VOLUME_COUNT must be an integer between 1 and 255" +#if ( REDCONF_VOLUME_COUNT < 1U ) || ( REDCONF_VOLUME_COUNT > 255U ) + #error "REDCONF_VOLUME_COUNT must be an integer between 1 and 255" #endif -#if (REDCONF_DISCARDS != 0) && (REDCONF_DISCARDS != 1) - #error "Configuration error: REDCONF_DISCARDS must be either 0 or 1." +#if ( REDCONF_DISCARDS != 0 ) && ( REDCONF_DISCARDS != 1 ) + #error "Configuration error: REDCONF_DISCARDS must be either 0 or 1." #endif /* REDCONF_BUFFER_COUNT lower limit checked in buffer.c -*/ + */ #if REDCONF_BUFFER_COUNT > 255U - #error "REDCONF_BUFFER_COUNT cannot be greater than 255" + #error "REDCONF_BUFFER_COUNT cannot be greater than 255" #endif -#if (REDCONF_IMAGE_BUILDER != 0) && (REDCONF_IMAGE_BUILDER != 1) - #error "Configuration error: REDCONF_IMAGE_BUILDER must be either 0 or 1." +#if ( REDCONF_IMAGE_BUILDER != 0 ) && ( REDCONF_IMAGE_BUILDER != 1 ) + #error "Configuration error: REDCONF_IMAGE_BUILDER must be either 0 or 1." #endif -#if (REDCONF_CHECKER != 0) && (REDCONF_CHECKER != 1) - #error "Configuration error: REDCONF_CHECKER must be either 0 or 1." -#endif - - -#if (REDCONF_DISCARDS == 1) && (RED_KIT == RED_KIT_GPL) - #error "REDCONF_DISCARDS not supported in Reliance Edge under GPL. Contact sales@datalight.com to upgrade." +#if ( REDCONF_CHECKER != 0 ) && ( REDCONF_CHECKER != 1 ) + #error "Configuration error: REDCONF_CHECKER must be either 0 or 1." #endif +#if ( REDCONF_DISCARDS == 1 ) && ( RED_KIT == RED_KIT_GPL ) + #error "REDCONF_DISCARDS not supported in Reliance Edge under GPL. Contact sales@datalight.com to upgrade." #endif +#endif /* ifndef REDCONFIGCHK_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redcoreapi.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redcoreapi.h index 20c6691a3..455fb6772 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redcoreapi.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redcoreapi.h @@ -1,97 +1,121 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDCOREAPI_H -#define REDCOREAPI_H - - -#include - - -REDSTATUS RedCoreInit(void); -REDSTATUS RedCoreUninit(void); - -REDSTATUS RedCoreVolSetCurrent(uint8_t bVolNum); - -#if FORMAT_SUPPORTED -REDSTATUS RedCoreVolFormat(void); -#endif -#if REDCONF_CHECKER == 1 -REDSTATUS RedCoreVolCheck(void); -#endif -REDSTATUS RedCoreVolMount(void); -REDSTATUS RedCoreVolUnmount(void); -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedCoreVolTransact(void); -#endif -#if REDCONF_API_POSIX == 1 -REDSTATUS RedCoreVolStat(REDSTATFS *pStatFS); -#endif - -#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKSET == 1)) -REDSTATUS RedCoreTransMaskSet(uint32_t ulEventMask); -#endif -#if (REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKGET == 1) -REDSTATUS RedCoreTransMaskGet(uint32_t *pulEventMask); -#endif - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) -REDSTATUS RedCoreCreate(uint32_t ulPInode, const char *pszName, bool fDir, uint32_t *pulInode); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) -REDSTATUS RedCoreLink(uint32_t ulPInode, const char *pszName, uint32_t ulInode); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) -REDSTATUS RedCoreUnlink(uint32_t ulPInode, const char *pszName); -#endif -#if REDCONF_API_POSIX == 1 -REDSTATUS RedCoreLookup(uint32_t ulPInode, const char *pszName, uint32_t *pulInode); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) -REDSTATUS RedCoreRename(uint32_t ulSrcPInode, const char *pszSrcName, uint32_t ulDstPInode, const char *pszDstName); -#endif -#if REDCONF_API_POSIX == 1 -REDSTATUS RedCoreStat(uint32_t ulInode, REDSTAT *pStat); -#endif -#if REDCONF_API_FSE == 1 -REDSTATUS RedCoreFileSizeGet(uint32_t ulInode, uint64_t *pullSize); -#endif - -REDSTATUS RedCoreFileRead(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer); -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedCoreFileWrite(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer); -#endif -#if TRUNCATE_SUPPORTED -REDSTATUS RedCoreFileTruncate(uint32_t ulInode, uint64_t ullSize); -#endif - -#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1) -REDSTATUS RedCoreDirRead(uint32_t ulInode, uint32_t *pulPos, char *pszName, uint32_t *pulInode); -#endif - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDCOREAPI_H +#define REDCOREAPI_H + + +#include + + +REDSTATUS RedCoreInit( void ); +REDSTATUS RedCoreUninit( void ); + +REDSTATUS RedCoreVolSetCurrent( uint8_t bVolNum ); + +#if FORMAT_SUPPORTED + REDSTATUS RedCoreVolFormat( void ); +#endif +#if REDCONF_CHECKER == 1 + REDSTATUS RedCoreVolCheck( void ); +#endif +REDSTATUS RedCoreVolMount( void ); +REDSTATUS RedCoreVolUnmount( void ); +#if REDCONF_READ_ONLY == 0 + REDSTATUS RedCoreVolTransact( void ); +#endif +#if REDCONF_API_POSIX == 1 + REDSTATUS RedCoreVolStat( REDSTATFS * pStatFS ); +#endif + +#if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || ( REDCONF_API_FSE_TRANSMASKSET == 1 ) ) + REDSTATUS RedCoreTransMaskSet( uint32_t ulEventMask ); +#endif +#if ( REDCONF_API_POSIX == 1 ) || ( REDCONF_API_FSE_TRANSMASKGET == 1 ) + REDSTATUS RedCoreTransMaskGet( uint32_t * pulEventMask ); +#endif + +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) + REDSTATUS RedCoreCreate( uint32_t ulPInode, + const char * pszName, + bool fDir, + uint32_t * pulInode ); +#endif +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_LINK == 1 ) + REDSTATUS RedCoreLink( uint32_t ulPInode, + const char * pszName, + uint32_t ulInode ); +#endif +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) && ( ( REDCONF_API_POSIX_UNLINK == 1 ) || ( REDCONF_API_POSIX_RMDIR == 1 ) ) + REDSTATUS RedCoreUnlink( uint32_t ulPInode, + const char * pszName ); +#endif +#if REDCONF_API_POSIX == 1 + REDSTATUS RedCoreLookup( uint32_t ulPInode, + const char * pszName, + uint32_t * pulInode ); +#endif +#if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_RENAME == 1 ) + REDSTATUS RedCoreRename( uint32_t ulSrcPInode, + const char * pszSrcName, + uint32_t ulDstPInode, + const char * pszDstName ); +#endif +#if REDCONF_API_POSIX == 1 + REDSTATUS RedCoreStat( uint32_t ulInode, + REDSTAT * pStat ); +#endif +#if REDCONF_API_FSE == 1 + REDSTATUS RedCoreFileSizeGet( uint32_t ulInode, + uint64_t * pullSize ); +#endif + +REDSTATUS RedCoreFileRead( uint32_t ulInode, + uint64_t ullStart, + uint32_t * pulLen, + void * pBuffer ); +#if REDCONF_READ_ONLY == 0 + REDSTATUS RedCoreFileWrite( uint32_t ulInode, + uint64_t ullStart, + uint32_t * pulLen, + const void * pBuffer ); +#endif +#if TRUNCATE_SUPPORTED + REDSTATUS RedCoreFileTruncate( uint32_t ulInode, + uint64_t ullSize ); +#endif + +#if ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_READDIR == 1 ) + REDSTATUS RedCoreDirRead( uint32_t ulInode, + uint32_t * pulPos, + char * pszName, + uint32_t * pulInode ); +#endif + + +#endif /* ifndef REDCOREAPI_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/reddeviations.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/reddeviations.h index 302f33320..d3dd98981 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/reddeviations.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/reddeviations.h @@ -1,224 +1,226 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief This header contains macros which deviate from MISRA C:2012 -*/ -#ifndef REDDEVIATIONS_H -#define REDDEVIATIONS_H - - -/** @brief Append a suffix to a constant so that it is an unsigned 64-bit value. - - Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). The - rule prohibits the use of language extensions. The ULL suffix became part - of the C standard with C99. Since this code base adheres to C89, use of - this suffix is a language extension. Reliance Edge needs to deal with - 64-bit quantities, which by convention are explicitly suffixed. In at - least one case, with the INODE_SIZE_MAX macro, the code needs a way to force - a constant to be 64-bits even though its value is not so large that it would - be automatically promoted to 64-bits. Thus the need for this macro and the - deviation. In practice, the ULL suffix has proven to be a nearly universal - extension among C89 compilers. - - As rule 19.2 is advisory, a deviation record is not required. This notice - is the only record of the deviation. PC-Lint does not issue an error for - this deviation so there is no error inhibition option. - - Usages of this macro also deviate from MISRA C:2012 Rule 20.10 (advisory). - The rule prohibits use of the ## preprocessor operator. The code is not - obscure, and the operator is used only once, so this is deemed to be safe. - - As rule 20.10 is advisory, a deviation record is not required. This notice - is the only record of the deviation. - - Consistent use of this macro, even in non MISRA C code, is encouraged to - make it easier to search for 64-bit values. - -*/ -#define UINT64_SUFFIX(number) (number##ULL) - - -/** @brief Append a suffix to a constant so that it is a signed 64-bit value. - - Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). See the - description of UINT64_SUFFIX() for details. - - Usages of this macro deviate from MISRA C:2012 Rule 20.10 (advisory). See - the description of UINT64_SUFFIX() for details. -*/ -#define INT64_SUFFIX(number) (number##LL) - - -/** @brief Cast a pointer to a const uint8_t pointer. - - All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). - Because there are no alignment requirements for a uint8_t pointer, this is - safe. However, it is technically a deviation from the rule. - - As Rule 11.5 is advisory, a deviation record is not required. This notice - and the PC-Lint error inhibition option are the only records of the - deviation. -*/ -#define CAST_VOID_PTR_TO_CONST_UINT8_PTR(PTR) ((const uint8_t *)(PTR)) - - -/** @brief Cast a pointer to a uint8_t pointer. - - All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). - Because there are no alignment requirements for a uint8_t pointer, this is - safe. However, it is technically a deviation from the rule. - - As Rule 11.5 is advisory, a deviation record is not required. This notice - and the PC-Lint error inhibition option are the only records of the - deviation. -*/ -#define CAST_VOID_PTR_TO_UINT8_PTR(PTR) ((uint8_t *)(PTR)) - - -/** @brief Cast a pointer to a const uint32_t pointer. - - Usages of this macro may deviate from MISRA C:2012 Rule 11.5 (advisory). - It is only used in cases where the pointer is known to be aligned, and thus - it is safe to do so. - - As Rule 11.5 is advisory, a deviation record is not required. This notice - and the PC-Lint error inhibition option are the only records of the - deviation. - - Usages of this macro may deviate from MISRA C:2012 Rule 11.3 (required). - As Rule 11.3 is required, a separate deviation record is required. - - Regarding the cast to (const void *): this is there to placate some - compilers which emit warnings when a type with lower alignment requirements - (such as const uint8_t *) is cast to a type with higher alignment - requirements. In the places where this macro is used, the pointer is - checked to be of sufficient alignment. -*/ -#define CAST_CONST_UINT32_PTR(PTR) ((const uint32_t *)(const void *)(PTR)) - - -/** @brief Cast a pointer to a pointer to (void **). - - Usages of this macro deviate from MISRA C:2012 Rule 11.3 (required). - It is only used for populating a node structure pointer with a buffer - pointer. Buffer pointers are 8-byte aligned, thus it is safe to do so. - - As Rule 11.3 is required, a separate deviation record is required. -*/ -#define CAST_VOID_PTR_PTR(PTRPTR) ((void **)(PTRPTR)) - - -/** @brief Create a two-dimensional byte array which is safely aligned. - - Usages of this macro deviate from MISRA C:2012 Rule 19.2 (advisory). - A union is required to force alignment of the block buffers, which are used - to access metadata nodes, which must be safely aligned for 64-bit types. - - As rule 19.2 is advisory, a deviation record is not required. This notice - and the PC-Lint error inhibition option are the only records of the - deviation. -*/ -#define ALIGNED_2D_BYTE_ARRAY(un, nam, size1, size2) \ - union \ - { \ - uint8_t nam[size1][size2]; \ - uint64_t DummyAlign; \ - } un - - -/** @brief Determine whether RedMemMove() must copy memory in the forward - direction, instead of in the reverse. - - In order to copy between overlapping memory regions, RedMemMove() must copy - forward if the destination memory is lower, and backward if the destination - memory is higher. Failure to do so would yield incorrect results. - - The only way to make this determination without gross inefficiency is to - use pointer comparison. Pointer comparisons are undefined unless both - pointers point within the same object or array (or one element past the end - of the array); see section 6.3.8 of ANSI C89. While RedMemMove() is - normally only used when memory regions overlap, which would not result in - undefined behavior, it (like memmove()) is supposed to work even for non- - overlapping regions, which would make this function invoke undefined - behavior. Experience has shown the pointer comparisons of this sort behave - intuitively on common platforms, even though the behavior is undefined. For - those platforms where this is not the case, this implementation of memmove() - should be replaced with an alternate one. - - Usages of this macro deviate from MISRA-C:2012 Rule 18.3 (required). As - Rule 18.3 is required, a separate deviation record is required. -*/ -#define MEMMOVE_MUST_COPY_FORWARD(dest, src) ((dest) < (src)) - - -/** @brief Cast a pointer to a (const DIRENT *). - - Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required). - It is used for populating a directory entry structure pointer with a - buffer pointer. Buffer pointers are 8-byte aligned, and DIRENT only - requires 4-byte alignment, thus the typecast is safe. - - As Rule 11.3 is required, a separate deviation record is required. -*/ -#define CAST_CONST_DIRENT_PTR(PTR) ((const DIRENT *)(PTR)) - - -/** @brief Determine whether a pointer is aligned. - - A pointer is aligned if its address is an even multiple of - ::REDCONF_ALIGNMENT_SIZE. - - This is used in the slice-by-8 RedCrc32Update() function, which needs to - know whether a pointer is aligned, since the slice-by-8 algorithm needs to - access the memory in an aligned fashion, and if the pointer is not aligned, - this can result in faults or suboptimal performance (depending on platform). - - There is no way to perform this check without deviating from MISRA C rules - against casting pointers to integer types. Usage of this macro deviates - from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites - against converting pointers to integers is that the chosen integer type may - not be able to represent the pointer; this is a non-issue here since we use - uintptr_t. The text says the rule still applies when using uintptr_t due to - concern about unaligned pointers, but that is not an issue here since the - integer value of the pointer is not saved and not converted back into a - pointer and dereferenced. The result of casting a pointer to a sufficiently - large integer is implementation-defined, but macros similar to this one have - been used by Datalight for a long time in a wide variety of environments and - they have always worked as expected. - - As Rule 11.4 is advisory, a deviation record is not required. This notice - and the PC-Lint error inhibition option are the only records of the - deviation. - - @note PC-Lint also thinks this macro as it is used below violates Rule 11.6 - (required). This is a false positive, since Rule 11.6 only applies to - void pointers. Below, we use it on a pointer-to-object (uint8_t *), - which is covered by Rule 11.4. -*/ -#define IS_ALIGNED_PTR(ptr) (((uintptr_t)(ptr) & (REDCONF_ALIGNMENT_SIZE - 1U)) == 0U) - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief This header contains macros which deviate from MISRA C:2012 + */ +#ifndef REDDEVIATIONS_H +#define REDDEVIATIONS_H + + +/** @brief Append a suffix to a constant so that it is an unsigned 64-bit value. + * + * Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). The + * rule prohibits the use of language extensions. The ULL suffix became part + * of the C standard with C99. Since this code base adheres to C89, use of + * this suffix is a language extension. Reliance Edge needs to deal with + * 64-bit quantities, which by convention are explicitly suffixed. In at + * least one case, with the INODE_SIZE_MAX macro, the code needs a way to force + * a constant to be 64-bits even though its value is not so large that it would + * be automatically promoted to 64-bits. Thus the need for this macro and the + * deviation. In practice, the ULL suffix has proven to be a nearly universal + * extension among C89 compilers. + * + * As rule 19.2 is advisory, a deviation record is not required. This notice + * is the only record of the deviation. PC-Lint does not issue an error for + * this deviation so there is no error inhibition option. + * + * Usages of this macro also deviate from MISRA C:2012 Rule 20.10 (advisory). + * The rule prohibits use of the ## preprocessor operator. The code is not + * obscure, and the operator is used only once, so this is deemed to be safe. + * + * As rule 20.10 is advisory, a deviation record is not required. This notice + * is the only record of the deviation. + * + * Consistent use of this macro, even in non MISRA C code, is encouraged to + * make it easier to search for 64-bit values. + * + */ +#define UINT64_SUFFIX( number ) ( number ## ULL ) + + +/** @brief Append a suffix to a constant so that it is a signed 64-bit value. + * + * Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). See the + * description of UINT64_SUFFIX() for details. + * + * Usages of this macro deviate from MISRA C:2012 Rule 20.10 (advisory). See + * the description of UINT64_SUFFIX() for details. + */ +#define INT64_SUFFIX( number ) ( number ## LL ) + + +/** @brief Cast a pointer to a const uint8_t pointer. + * + * All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). + * Because there are no alignment requirements for a uint8_t pointer, this is + * safe. However, it is technically a deviation from the rule. + * + * As Rule 11.5 is advisory, a deviation record is not required. This notice + * and the PC-Lint error inhibition option are the only records of the + * deviation. + */ +#define CAST_VOID_PTR_TO_CONST_UINT8_PTR( PTR ) ( ( const uint8_t * ) ( PTR ) ) + + +/** @brief Cast a pointer to a uint8_t pointer. + * + * All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). + * Because there are no alignment requirements for a uint8_t pointer, this is + * safe. However, it is technically a deviation from the rule. + * + * As Rule 11.5 is advisory, a deviation record is not required. This notice + * and the PC-Lint error inhibition option are the only records of the + * deviation. + */ +#define CAST_VOID_PTR_TO_UINT8_PTR( PTR ) ( ( uint8_t * ) ( PTR ) ) + + +/** @brief Cast a pointer to a const uint32_t pointer. + * + * Usages of this macro may deviate from MISRA C:2012 Rule 11.5 (advisory). + * It is only used in cases where the pointer is known to be aligned, and thus + * it is safe to do so. + * + * As Rule 11.5 is advisory, a deviation record is not required. This notice + * and the PC-Lint error inhibition option are the only records of the + * deviation. + * + * Usages of this macro may deviate from MISRA C:2012 Rule 11.3 (required). + * As Rule 11.3 is required, a separate deviation record is required. + * + * Regarding the cast to (const void *): this is there to placate some + * compilers which emit warnings when a type with lower alignment requirements + * (such as const uint8_t *) is cast to a type with higher alignment + * requirements. In the places where this macro is used, the pointer is + * checked to be of sufficient alignment. + */ +#define CAST_CONST_UINT32_PTR( PTR ) ( ( const uint32_t * ) ( const void * ) ( PTR ) ) + + +/** @brief Cast a pointer to a pointer to (void **). + * + * Usages of this macro deviate from MISRA C:2012 Rule 11.3 (required). + * It is only used for populating a node structure pointer with a buffer + * pointer. Buffer pointers are 8-byte aligned, thus it is safe to do so. + * + * As Rule 11.3 is required, a separate deviation record is required. + */ +#define CAST_VOID_PTR_PTR( PTRPTR ) ( ( void ** ) ( PTRPTR ) ) + + +/** @brief Create a two-dimensional byte array which is safely aligned. + * + * Usages of this macro deviate from MISRA C:2012 Rule 19.2 (advisory). + * A union is required to force alignment of the block buffers, which are used + * to access metadata nodes, which must be safely aligned for 64-bit types. + * + * As rule 19.2 is advisory, a deviation record is not required. This notice + * and the PC-Lint error inhibition option are the only records of the + * deviation. + */ +#define ALIGNED_2D_BYTE_ARRAY( un, nam, size1, size2 ) \ + union \ + { \ + uint8_t nam[ size1 ][ size2 ]; \ + uint64_t DummyAlign; \ + } \ + un + + +/** @brief Determine whether RedMemMove() must copy memory in the forward + * direction, instead of in the reverse. + * + * In order to copy between overlapping memory regions, RedMemMove() must copy + * forward if the destination memory is lower, and backward if the destination + * memory is higher. Failure to do so would yield incorrect results. + * + * The only way to make this determination without gross inefficiency is to + * use pointer comparison. Pointer comparisons are undefined unless both + * pointers point within the same object or array (or one element past the end + * of the array); see section 6.3.8 of ANSI C89. While RedMemMove() is + * normally only used when memory regions overlap, which would not result in + * undefined behavior, it (like memmove()) is supposed to work even for non- + * overlapping regions, which would make this function invoke undefined + * behavior. Experience has shown the pointer comparisons of this sort behave + * intuitively on common platforms, even though the behavior is undefined. For + * those platforms where this is not the case, this implementation of memmove() + * should be replaced with an alternate one. + * + * Usages of this macro deviate from MISRA-C:2012 Rule 18.3 (required). As + * Rule 18.3 is required, a separate deviation record is required. + */ +#define MEMMOVE_MUST_COPY_FORWARD( dest, src ) ( ( dest ) < ( src ) ) + + +/** @brief Cast a pointer to a (const DIRENT *). + * + * Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required). + * It is used for populating a directory entry structure pointer with a + * buffer pointer. Buffer pointers are 8-byte aligned, and DIRENT only + * requires 4-byte alignment, thus the typecast is safe. + * + * As Rule 11.3 is required, a separate deviation record is required. + */ +#define CAST_CONST_DIRENT_PTR( PTR ) ( ( const DIRENT * ) ( PTR ) ) + + +/** @brief Determine whether a pointer is aligned. + * + * A pointer is aligned if its address is an even multiple of + * ::REDCONF_ALIGNMENT_SIZE. + * + * This is used in the slice-by-8 RedCrc32Update() function, which needs to + * know whether a pointer is aligned, since the slice-by-8 algorithm needs to + * access the memory in an aligned fashion, and if the pointer is not aligned, + * this can result in faults or suboptimal performance (depending on platform). + * + * There is no way to perform this check without deviating from MISRA C rules + * against casting pointers to integer types. Usage of this macro deviates + * from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites + * against converting pointers to integers is that the chosen integer type may + * not be able to represent the pointer; this is a non-issue here since we use + * uintptr_t. The text says the rule still applies when using uintptr_t due to + * concern about unaligned pointers, but that is not an issue here since the + * integer value of the pointer is not saved and not converted back into a + * pointer and dereferenced. The result of casting a pointer to a sufficiently + * large integer is implementation-defined, but macros similar to this one have + * been used by Datalight for a long time in a wide variety of environments and + * they have always worked as expected. + * + * As Rule 11.4 is advisory, a deviation record is not required. This notice + * and the PC-Lint error inhibition option are the only records of the + * deviation. + * + * @note PC-Lint also thinks this macro as it is used below violates Rule 11.6 + * (required). This is a false positive, since Rule 11.6 only applies to + * void pointers. Below, we use it on a pointer-to-object (uint8_t *), + * which is covered by Rule 11.4. + */ +#define IS_ALIGNED_PTR( ptr ) ( ( ( uintptr_t ) ( ptr ) & ( REDCONF_ALIGNMENT_SIZE - 1U ) ) == 0U ) + + +#endif /* ifndef REDDEVIATIONS_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/rederrno.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/rederrno.h index 9b71060ab..3cafa59a0 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/rederrno.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/rederrno.h @@ -1,114 +1,115 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Error values for Reliance Edge APIs -*/ -#ifndef REDERRNO_H -#define REDERRNO_H - - -/** @brief Return type for Reliance Edge error values. -*/ -typedef int32_t REDSTATUS; - - -/* The errno numbers are the same as Linux. -*/ - -/** Operation not permitted. */ -#define RED_EPERM 1 - -/** No such file or directory. */ -#define RED_ENOENT 2 - -/** I/O error. */ -#define RED_EIO 5 - -/** Bad file number. */ -#define RED_EBADF 9 - -/** Out of memory */ -#define RED_ENOMEM 12 - -/** Device or resource busy. */ -#define RED_EBUSY 16 - -/** File exists. */ -#define RED_EEXIST 17 - -/** Cross-device link. */ -#define RED_EXDEV 18 - -/** Not a directory. */ -#define RED_ENOTDIR 20 - -/** Is a directory. */ -#define RED_EISDIR 21 - -/** Invalid argument. */ -#define RED_EINVAL 22 - -/** File table overflow. */ -#define RED_ENFILE 23 - -/** Too many open files. */ -#define RED_EMFILE 24 - -/** File too large. */ -#define RED_EFBIG 27 - -/** No space left on device. */ -#define RED_ENOSPC 28 - -/** Read-only file system. */ -#define RED_EROFS 30 - -/** Too many links. */ -#define RED_EMLINK 31 - -/** Math result not representable. */ -#define RED_ERANGE 34 - -/** File name too long. */ -#define RED_ENAMETOOLONG 36 - -/** Function not implemented. */ -#define RED_ENOSYS 38 - -/** Directory not empty. */ -#define RED_ENOTEMPTY 39 - -/** No data available. */ -#define RED_ENODATA 61 - -/** Too many users. */ -#define RED_EUSERS 87 - -/** Nothing will be okay ever again. */ -#define RED_EFUBAR RED_EINVAL - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Error values for Reliance Edge APIs + */ +#ifndef REDERRNO_H +#define REDERRNO_H + + +/** @brief Return type for Reliance Edge error values. + */ +typedef int32_t REDSTATUS; + + +/* The errno numbers are the same as Linux. + */ + +/** Operation not permitted. */ +#define RED_EPERM 1 + +/** No such file or directory. */ +#define RED_ENOENT 2 + +/** I/O error. */ +#define RED_EIO 5 + +/** Bad file number. */ +#define RED_EBADF 9 + +/** Out of memory */ +#define RED_ENOMEM 12 + +/** Device or resource busy. */ +#define RED_EBUSY 16 + +/** File exists. */ +#define RED_EEXIST 17 + +/** Cross-device link. */ +#define RED_EXDEV 18 + +/** Not a directory. */ +#define RED_ENOTDIR 20 + +/** Is a directory. */ +#define RED_EISDIR 21 + +/** Invalid argument. */ +#define RED_EINVAL 22 + +/** File table overflow. */ +#define RED_ENFILE 23 + +/** Too many open files. */ +#define RED_EMFILE 24 + +/** File too large. */ +#define RED_EFBIG 27 + +/** No space left on device. */ +#define RED_ENOSPC 28 + +/** Read-only file system. */ +#define RED_EROFS 30 + +/** Too many links. */ +#define RED_EMLINK 31 + +/** Math result not representable. */ +#define RED_ERANGE 34 + +/** File name too long. */ +#define RED_ENAMETOOLONG 36 + +/** Function not implemented. */ +#define RED_ENOSYS 38 + +/** Directory not empty. */ +#define RED_ENOTEMPTY 39 + +/** No data available. */ +#define RED_ENODATA 61 + +/** Too many users. */ +#define RED_EUSERS 87 + +/** Nothing will be okay ever again. */ +#define RED_EFUBAR RED_EINVAL + + +#endif /* ifndef REDERRNO_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redexclude.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redexclude.h index 01a003c87..a4f69f36b 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redexclude.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redexclude.h @@ -1,53 +1,54 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDEXCLUDE_H -#define REDEXCLUDE_H - - -#define DELETE_SUPPORTED \ - ( \ - (REDCONF_READ_ONLY == 0) \ - && ( (REDCONF_API_POSIX == 1) \ - && ( (REDCONF_API_POSIX_RMDIR == 1) \ - || (REDCONF_API_POSIX_UNLINK == 1) \ - || ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1))))) - -#define TRUNCATE_SUPPORTED \ - ( \ - (REDCONF_READ_ONLY == 0) \ - && ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) \ - || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1)))) - -#define FORMAT_SUPPORTED \ - ( \ - (REDCONF_READ_ONLY == 0) \ - && ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) \ - || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_FORMAT == 1)) \ - || (REDCONF_IMAGE_BUILDER == 1))) - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDEXCLUDE_H +#define REDEXCLUDE_H + + +#define DELETE_SUPPORTED \ + ( \ + ( REDCONF_READ_ONLY == 0 ) \ + && ( ( REDCONF_API_POSIX == 1 ) \ + && ( ( REDCONF_API_POSIX_RMDIR == 1 ) \ + || ( REDCONF_API_POSIX_UNLINK == 1 ) \ + || ( ( REDCONF_API_POSIX_RENAME == 1 ) && ( REDCONF_RENAME_ATOMIC == 1 ) ) ) ) ) + +#define TRUNCATE_SUPPORTED \ + ( \ + ( REDCONF_READ_ONLY == 0 ) \ + && ( ( ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_FTRUNCATE == 1 ) ) \ + || ( ( REDCONF_API_FSE == 1 ) && ( REDCONF_API_FSE_TRUNCATE == 1 ) ) ) ) + +#define FORMAT_SUPPORTED \ + ( \ + ( REDCONF_READ_ONLY == 0 ) \ + && ( ( ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_FORMAT == 1 ) ) \ + || ( ( REDCONF_API_FSE == 1 ) && ( REDCONF_API_FSE_FORMAT == 1 ) ) \ + || ( REDCONF_IMAGE_BUILDER == 1 ) ) ) + +#endif /* ifndef REDEXCLUDE_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redfs.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redfs.h index 512d703fb..430c5ebe4 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redfs.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redfs.h @@ -1,46 +1,47 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDFS_H -#define REDFS_H - - -#include -#include "redver.h" -#include "redconfigchk.h" -#include -#include "rederrno.h" -#include "reddeviations.h" -#include "redmacs.h" -#include "redapimacs.h" -#include "redutils.h" -#include "redosserv.h" -#include "redmisc.h" -#include "redexclude.h" - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDFS_H +#define REDFS_H + + +#include +#include "redver.h" +#include "redconfigchk.h" +#include +#include "rederrno.h" +#include "reddeviations.h" +#include "redmacs.h" +#include "redapimacs.h" +#include "redutils.h" +#include "redosserv.h" +#include "redmisc.h" +#include "redexclude.h" + + +#endif /* ifndef REDFS_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redfse.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redfse.h index 3b0ef8833..19ca992d2 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redfse.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redfse.h @@ -1,105 +1,119 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Interface for the Reliance Edge FSE API. - - The FSE (File Systems Essentials) API is a minimalist file system API - intended for simple use cases with a fixed number of statically-defined - files. It does not support creating or deleting files dynamically. Files - are referenced by a fixed file number, rather than by name; there are no - file names and no directories. There are also no file handles: files are - not opened or closed, and file offsets are given explicitly. - - If the FSE API is too limited to meet the needs of your application, - consider using the more feature-rich POSIX-like file system API instead. -*/ -#ifndef REDFSE_H -#define REDFSE_H - -/* This header is intended for application use; some applications are written - in C++. -*/ -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#if REDCONF_API_FSE == 1 - -#include -#include "redapimacs.h" -#include "rederrno.h" - - -/** @brief First valid file number. - - This macro can be used to statically define file numbers for given files, - as in the below example: - - ~~~{.c} - #define LOG_FILE (RED_FILENUM_FIRST_VALID) - #define DATABASE_FILE (RED_FILENUM_FIRST_VALID + 1U) - #define ICON1_FILE (RED_FILENUM_FIRST_VALID + 2U) - #define ICON2_FILE (RED_FILENUM_FIRST_VALID + 3U) - ~~~ -*/ -#define RED_FILENUM_FIRST_VALID (2U) - - -REDSTATUS RedFseInit(void); -REDSTATUS RedFseUninit(void); -REDSTATUS RedFseMount(uint8_t bVolNum); -REDSTATUS RedFseUnmount(uint8_t bVolNum); -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_FORMAT == 1) -REDSTATUS RedFseFormat(uint8_t bVolNum); -#endif -int32_t RedFseRead(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, void *pBuffer); -#if REDCONF_READ_ONLY == 0 -int32_t RedFseWrite(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, const void *pBuffer); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1) -REDSTATUS RedFseTruncate(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullNewFileSize); -#endif -int64_t RedFseSizeGet(uint8_t bVolNum, uint32_t ulFileNum); -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1) -REDSTATUS RedFseTransMaskSet(uint8_t bVolNum, uint32_t ulEventMask); -#endif -#if REDCONF_API_FSE_TRANSMASKGET == 1 -REDSTATUS RedFseTransMaskGet(uint8_t bVolNum, uint32_t *pulEventMask); -#endif -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedFseTransact(uint8_t bVolNum); -#endif - -#endif /* REDCONF_API_FSE == 1 */ - - -#ifdef __cplusplus -} -#endif - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Interface for the Reliance Edge FSE API. + * + * The FSE (File Systems Essentials) API is a minimalist file system API + * intended for simple use cases with a fixed number of statically-defined + * files. It does not support creating or deleting files dynamically. Files + * are referenced by a fixed file number, rather than by name; there are no + * file names and no directories. There are also no file handles: files are + * not opened or closed, and file offsets are given explicitly. + * + * If the FSE API is too limited to meet the needs of your application, + * consider using the more feature-rich POSIX-like file system API instead. + */ +#ifndef REDFSE_H + #define REDFSE_H + +/* This header is intended for application use; some applications are written + * in C++. + */ + #ifdef __cplusplus + extern "C" { + #endif + + #include + + #if REDCONF_API_FSE == 1 + + #include + #include "redapimacs.h" + #include "rederrno.h" + + +/** @brief First valid file number. + * + * This macro can be used to statically define file numbers for given files, + * as in the below example: + * + * ~~~{.c} + #define LOG_FILE (RED_FILENUM_FIRST_VALID) + #define DATABASE_FILE (RED_FILENUM_FIRST_VALID + 1U) + #define ICON1_FILE (RED_FILENUM_FIRST_VALID + 2U) + #define ICON2_FILE (RED_FILENUM_FIRST_VALID + 3U) + * ~~~ + */ + #define RED_FILENUM_FIRST_VALID ( 2U ) + + + REDSTATUS RedFseInit( void ); + REDSTATUS RedFseUninit( void ); + REDSTATUS RedFseMount( uint8_t bVolNum ); + REDSTATUS RedFseUnmount( uint8_t bVolNum ); + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE_FORMAT == 1 ) + REDSTATUS RedFseFormat( uint8_t bVolNum ); + #endif + int32_t RedFseRead( uint8_t bVolNum, + uint32_t ulFileNum, + uint64_t ullFileOffset, + uint32_t ulLength, + void * pBuffer ); + #if REDCONF_READ_ONLY == 0 + int32_t RedFseWrite( uint8_t bVolNum, + uint32_t ulFileNum, + uint64_t ullFileOffset, + uint32_t ulLength, + const void * pBuffer ); + #endif + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE_TRUNCATE == 1 ) + REDSTATUS RedFseTruncate( uint8_t bVolNum, + uint32_t ulFileNum, + uint64_t ullNewFileSize ); + #endif + int64_t RedFseSizeGet( uint8_t bVolNum, + uint32_t ulFileNum ); + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE_TRANSMASKSET == 1 ) + REDSTATUS RedFseTransMaskSet( uint8_t bVolNum, + uint32_t ulEventMask ); + #endif + #if REDCONF_API_FSE_TRANSMASKGET == 1 + REDSTATUS RedFseTransMaskGet( uint8_t bVolNum, + uint32_t * pulEventMask ); + #endif + #if REDCONF_READ_ONLY == 0 + REDSTATUS RedFseTransact( uint8_t bVolNum ); + #endif + + #endif /* REDCONF_API_FSE == 1 */ + + + #ifdef __cplusplus +} + #endif + +#endif /* ifndef REDFSE_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redgetopt.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redgetopt.h index 11c12064b..bcba7e0d9 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redgetopt.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redgetopt.h @@ -1,77 +1,84 @@ -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dieter Baron and Thomas Klausner. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/** @file - @brief Interfaces for getopt() and getopt_long() work-alike functions. - - This code was taken from FreeBSD and slightly modified, mostly to rename - symbols with external linkage to avoid naming conflicts in systems where - there are real getopt()/getopt_long() implementations. Changed to use - fixed-width types to allow code using these interfaces to be consistent - with the rest of the product. -*/ -#ifndef REDGETOPT_H -#define REDGETOPT_H - - -#define red_no_argument 0 -#define red_required_argument 1 -#define red_optional_argument 2 - - -/** @brief Specifies a long option. -*/ -typedef struct -{ - /* name of long option */ - const char *name; - /* - * one of red_no_argument, red_required_argument, and red_optional_argument: - * whether option takes an argument - */ - int32_t has_arg; - /* if not NULL, set *flag to val when option found */ - int32_t *flag; - /* if flag not NULL, value to set *flag to; else return value */ - int32_t val; -} REDOPTION; - - -int32_t RedGetopt(int32_t nargc, char * const *nargv, const char *options); -int32_t RedGetoptLong(int32_t nargc, char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx); - - -extern const char *red_optarg; -extern int32_t red_optind; -extern int32_t red_opterr; -extern int32_t red_optopt; -extern int32_t red_optreset; - - -#endif - +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** @file + * @brief Interfaces for getopt() and getopt_long() work-alike functions. + * + * This code was taken from FreeBSD and slightly modified, mostly to rename + * symbols with external linkage to avoid naming conflicts in systems where + * there are real getopt()/getopt_long() implementations. Changed to use + * fixed-width types to allow code using these interfaces to be consistent + * with the rest of the product. + */ +#ifndef REDGETOPT_H +#define REDGETOPT_H + + +#define red_no_argument 0 +#define red_required_argument 1 +#define red_optional_argument 2 + + +/** @brief Specifies a long option. + */ +typedef struct +{ + /* name of long option */ + const char * name; + + /* + * one of red_no_argument, red_required_argument, and red_optional_argument: + * whether option takes an argument + */ + int32_t has_arg; + /* if not NULL, set *flag to val when option found */ + int32_t * flag; + /* if flag not NULL, value to set *flag to; else return value */ + int32_t val; +} REDOPTION; + + +int32_t RedGetopt( int32_t nargc, + char * const * nargv, + const char * options ); +int32_t RedGetoptLong( int32_t nargc, + char * const * nargv, + const char * options, + const REDOPTION * long_options, + int32_t * idx ); + + +extern const char * red_optarg; +extern int32_t red_optind; +extern int32_t red_opterr; +extern int32_t red_optopt; +extern int32_t red_optreset; + + +#endif /* ifndef REDGETOPT_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redmacs.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redmacs.h index 0fe8a572d..7a0a38300 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redmacs.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redmacs.h @@ -1,103 +1,104 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDMACS_H -#define REDMACS_H - - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef UINT8_MAX -#define UINT8_MAX (0xFFU) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (0xFFFFU) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (0xFFFFFFFFU) -#endif -#ifndef UINT64_MAX -#define UINT64_MAX UINT64_SUFFIX(0xFFFFFFFFFFFFFFFF) -#endif -#ifndef INT32_MAX -#define INT32_MAX (0x7FFFFFFF) -#endif -#ifndef INT64_MAX -#define INT64_MAX INT64_SUFFIX(0x7FFFFFFFFFFFFFFF) -#endif - -#ifndef true -#define true (1) -#endif -#ifndef false -#define false (0) -#endif - -#define SECTOR_SIZE_MIN (256U) - -#if REDCONF_BLOCK_SIZE == 256U -#define BLOCK_SIZE_P2 8U -#elif REDCONF_BLOCK_SIZE == 512U -#define BLOCK_SIZE_P2 9U -#elif REDCONF_BLOCK_SIZE == 1024U -#define BLOCK_SIZE_P2 10U -#elif REDCONF_BLOCK_SIZE == 2048U -#define BLOCK_SIZE_P2 11U -#elif REDCONF_BLOCK_SIZE == 4096U -#define BLOCK_SIZE_P2 12U -#elif REDCONF_BLOCK_SIZE == 8192U -#define BLOCK_SIZE_P2 13U -#elif REDCONF_BLOCK_SIZE == 16384U -#define BLOCK_SIZE_P2 14U -#elif REDCONF_BLOCK_SIZE == 32768U -#define BLOCK_SIZE_P2 15U -#elif REDCONF_BLOCK_SIZE == 65536U -#define BLOCK_SIZE_P2 16U -#else -#error "REDCONF_BLOCK_SIZE must be a power of two value between 256 and 65536" -#endif - -#define REDMIN(a, b) (((a) < (b)) ? (a) : (b)) - -#define INODE_INVALID (0U) /* General-purpose invalid inode number (must be zero). */ -#define INODE_FIRST_VALID (2U) /* First valid inode number. */ -#define INODE_ROOTDIR (INODE_FIRST_VALID) /* Inode number of the root directory. */ - -/* Expands to a "const" qualifier when the volume count is one, otherwise - expands to nothing. This is useful for variables that never change in - single-volume configurations but do change in multi-volume configurations. -*/ -#if REDCONF_VOLUME_COUNT == 1U - #define CONST_IF_ONE_VOLUME const -#else - #define CONST_IF_ONE_VOLUME -#endif - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDMACS_H +#define REDMACS_H + + +#ifndef NULL + #define NULL ( ( void * ) 0 ) +#endif + +#ifndef UINT8_MAX + #define UINT8_MAX ( 0xFFU ) +#endif +#ifndef UINT16_MAX + #define UINT16_MAX ( 0xFFFFU ) +#endif +#ifndef UINT32_MAX + #define UINT32_MAX ( 0xFFFFFFFFU ) +#endif +#ifndef UINT64_MAX + #define UINT64_MAX UINT64_SUFFIX( 0xFFFFFFFFFFFFFFFF ) +#endif +#ifndef INT32_MAX + #define INT32_MAX ( 0x7FFFFFFF ) +#endif +#ifndef INT64_MAX + #define INT64_MAX INT64_SUFFIX( 0x7FFFFFFFFFFFFFFF ) +#endif + +#ifndef true + #define true ( 1 ) +#endif +#ifndef false + #define false ( 0 ) +#endif + +#define SECTOR_SIZE_MIN ( 256U ) + +#if REDCONF_BLOCK_SIZE == 256U + #define BLOCK_SIZE_P2 8U +#elif REDCONF_BLOCK_SIZE == 512U + #define BLOCK_SIZE_P2 9U +#elif REDCONF_BLOCK_SIZE == 1024U + #define BLOCK_SIZE_P2 10U +#elif REDCONF_BLOCK_SIZE == 2048U + #define BLOCK_SIZE_P2 11U +#elif REDCONF_BLOCK_SIZE == 4096U + #define BLOCK_SIZE_P2 12U +#elif REDCONF_BLOCK_SIZE == 8192U + #define BLOCK_SIZE_P2 13U +#elif REDCONF_BLOCK_SIZE == 16384U + #define BLOCK_SIZE_P2 14U +#elif REDCONF_BLOCK_SIZE == 32768U + #define BLOCK_SIZE_P2 15U +#elif REDCONF_BLOCK_SIZE == 65536U + #define BLOCK_SIZE_P2 16U +#else /* if REDCONF_BLOCK_SIZE == 256U */ + #error "REDCONF_BLOCK_SIZE must be a power of two value between 256 and 65536" +#endif /* if REDCONF_BLOCK_SIZE == 256U */ + +#define REDMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) + +#define INODE_INVALID ( 0U ) /* General-purpose invalid inode number (must be zero). */ +#define INODE_FIRST_VALID ( 2U ) /* First valid inode number. */ +#define INODE_ROOTDIR ( INODE_FIRST_VALID ) /* Inode number of the root directory. */ + +/* Expands to a "const" qualifier when the volume count is one, otherwise + * expands to nothing. This is useful for variables that never change in + * single-volume configurations but do change in multi-volume configurations. + */ +#if REDCONF_VOLUME_COUNT == 1U + #define CONST_IF_ONE_VOLUME const +#else + #define CONST_IF_ONE_VOLUME +#endif + + +#endif /* ifndef REDMACS_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redmisc.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redmisc.h index 8ad810540..41890fc9d 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redmisc.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redmisc.h @@ -1,48 +1,49 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDMISC_H -#define REDMISC_H - - -/** @brief Type of an inode or handle. - - Used to indicate the actual or expected type of an inode or handle. -*/ -typedef enum -{ - FTYPE_FILE, /**< Type is file. */ - FTYPE_DIR, /**< Type is directory. */ - - /** Type is either file or directory: used only to indicate an expected - type, never as an actual type. - */ - FTYPE_EITHER -} FTYPE; - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDMISC_H +#define REDMISC_H + + +/** @brief Type of an inode or handle. + * + * Used to indicate the actual or expected type of an inode or handle. + */ +typedef enum +{ + FTYPE_FILE, /**< Type is file. */ + FTYPE_DIR, /**< Type is directory. */ + + /** Type is either file or directory: used only to indicate an expected + * type, never as an actual type. + */ + FTYPE_EITHER +} FTYPE; + + +#endif /* ifndef REDMISC_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redosserv.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redosserv.h index 66c11c600..0508e31d5 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redosserv.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redosserv.h @@ -1,86 +1,96 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDOSSERV_H -#define REDOSSERV_H - - -#include - - -/** @brief Type of access requested when opening a block device. -*/ -typedef enum -{ - BDEV_O_RDONLY, /**< Open block device for read access. */ - BDEV_O_WRONLY, /**< Open block device for write access. */ - BDEV_O_RDWR /**< Open block device for read and write access. */ -} BDEVOPENMODE; - -REDSTATUS RedOsBDevOpen(uint8_t bVolNum, BDEVOPENMODE mode); -REDSTATUS RedOsBDevClose(uint8_t bVolNum); -REDSTATUS RedOsBDevRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer); - -#if REDCONF_READ_ONLY == 0 -REDSTATUS RedOsBDevWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer); -REDSTATUS RedOsBDevFlush(uint8_t bVolNum); -#endif - -/* Non-standard API: for host machines only. -*/ -REDSTATUS RedOsBDevConfig(uint8_t bVolNum, const char *pszBDevSpec); - - -#if REDCONF_TASK_COUNT > 1U -REDSTATUS RedOsMutexInit(void); -REDSTATUS RedOsMutexUninit(void); -void RedOsMutexAcquire(void); -void RedOsMutexRelease(void); -#endif -#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1) -uint32_t RedOsTaskId(void); -#endif - -REDSTATUS RedOsClockInit(void); -REDSTATUS RedOsClockUninit(void); -uint32_t RedOsClockGetTime(void); - -REDSTATUS RedOsTimestampInit(void); -REDSTATUS RedOsTimestampUninit(void); -REDTIMESTAMP RedOsTimestamp(void); -uint64_t RedOsTimePassed(REDTIMESTAMP tsSince); - -#if REDCONF_OUTPUT == 1 -void RedOsOutputString(const char *pszString); -#endif - -#if REDCONF_ASSERTS == 1 -void RedOsAssertFail(const char *pszFileName, uint32_t ulLineNum); -#endif - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDOSSERV_H +#define REDOSSERV_H + + +#include + + +/** @brief Type of access requested when opening a block device. + */ +typedef enum +{ + BDEV_O_RDONLY, /**< Open block device for read access. */ + BDEV_O_WRONLY, /**< Open block device for write access. */ + BDEV_O_RDWR /**< Open block device for read and write access. */ +} BDEVOPENMODE; + +REDSTATUS RedOsBDevOpen( uint8_t bVolNum, + BDEVOPENMODE mode ); +REDSTATUS RedOsBDevClose( uint8_t bVolNum ); +REDSTATUS RedOsBDevRead( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void * pBuffer ); + +#if REDCONF_READ_ONLY == 0 + REDSTATUS RedOsBDevWrite( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void * pBuffer ); + REDSTATUS RedOsBDevFlush( uint8_t bVolNum ); +#endif + +/* Non-standard API: for host machines only. + */ +REDSTATUS RedOsBDevConfig( uint8_t bVolNum, + const char * pszBDevSpec ); + + +#if REDCONF_TASK_COUNT > 1U + REDSTATUS RedOsMutexInit( void ); + REDSTATUS RedOsMutexUninit( void ); + void RedOsMutexAcquire( void ); + void RedOsMutexRelease( void ); +#endif +#if ( REDCONF_TASK_COUNT > 1U ) && ( REDCONF_API_POSIX == 1 ) + uint32_t RedOsTaskId( void ); +#endif + +REDSTATUS RedOsClockInit( void ); +REDSTATUS RedOsClockUninit( void ); +uint32_t RedOsClockGetTime( void ); + +REDSTATUS RedOsTimestampInit( void ); +REDSTATUS RedOsTimestampUninit( void ); +REDTIMESTAMP RedOsTimestamp( void ); +uint64_t RedOsTimePassed( REDTIMESTAMP tsSince ); + +#if REDCONF_OUTPUT == 1 + void RedOsOutputString( const char * pszString ); +#endif + +#if REDCONF_ASSERTS == 1 + void RedOsAssertFail( const char * pszFileName, + uint32_t ulLineNum ); +#endif + + +#endif /* ifndef REDOSSERV_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redpath.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redpath.h index 06f7c3637..1d3e9c7d1 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redpath.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redpath.h @@ -1,38 +1,44 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Interfaces of path utilities for the POSIX-like API layer. -*/ + * @brief Interfaces of path utilities for the POSIX-like API layer. + */ #ifndef REDPATH_H #define REDPATH_H -REDSTATUS RedPathSplit(const char *pszPath, uint8_t *pbVolNum, const char **ppszLocalPath); -REDSTATUS RedPathLookup(const char *pszLocalPath, uint32_t *pulInode); -REDSTATUS RedPathToName(const char *pszLocalPath, uint32_t *pulPInode, const char **ppszName); +REDSTATUS RedPathSplit( const char * pszPath, + uint8_t * pbVolNum, + const char ** ppszLocalPath ); +REDSTATUS RedPathLookup( const char * pszLocalPath, + uint32_t * pulInode ); +REDSTATUS RedPathToName( const char * pszLocalPath, + uint32_t * pulPInode, + const char ** ppszName ); -#endif - +#endif /* ifndef REDPATH_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redposix.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redposix.h index bedb00896..b75a305fc 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redposix.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redposix.h @@ -1,196 +1,212 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Interface for the Reliance Edge POSIX-like API. - - The POSIX-like file system API is the primary file system API for - Reliance Edge, which supports the full functionality of the file system. - This API aims to be compatible with POSIX where reasonable, but it is - simplified considerably to meet the needs of resource-constrained embedded - systems. The API has also been extended to provide access to the unique - features of Reliance Edge, and to cover areas (like mountins and formatting) - which do not have APIs in the POSIX specification. -*/ -#ifndef REDPOSIX_H -#define REDPOSIX_H - -/* This header is intended for application use; some applications are written - in C++. -*/ -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#if REDCONF_API_POSIX == 1 - -#include -#include "redapimacs.h" -#include "rederrno.h" -#include "redstat.h" - -/** Open for reading only. */ -#define RED_O_RDONLY 0x00000001U - -/** Open for writing only. */ -#define RED_O_WRONLY 0x00000002U - -/** Open for reading and writing. */ -#define RED_O_RDWR 0x00000004U - -/** File offset for all writes is end-of-file. */ -#define RED_O_APPEND 0x00000008U - -/** Create the file. */ -#define RED_O_CREAT 0x00000010U - -/** Error if path already exists. */ -#define RED_O_EXCL 0x00000020U - -/** Truncate file to size zero. */ -#define RED_O_TRUNC 0x00000040U - - -/** @brief Last file system error (errno). - - Under normal circumstances, each task using the file system has an - independent `red_errno` value. Applications do not need to worry about - one task obliterating an error value that another task needed to read. The - value is initially zero. When one of the POSIX-like APIs return an - indication of error, `red_errno` is set to an error value. - - In some circumstances, `red_errno` will be a global errno location which - is shared by multiple tasks. If the calling task is not registered as a - file system user and all of the task slots are full, there can be no - task-specific errno, so the global errno is used. Likewise, if the file - system driver is uninitialized, there are no registered file system users - and `red_errno` always refers to the global errno. Under these - circumstances, multiple tasks manipulating `red_errno` could be - problematic. When the task count is set to one, `red_errno` always refers - to the global errno. - - Note that `red_errno` is usable as an lvalue; i.e., in addition to reading - the error value, the error value can be set: - - ~~~{.c} - red_errno = 0; - ~~~ -*/ -#define red_errno (*red_errnoptr()) - - -/** @brief Positions from which to seek within a file. -*/ -typedef enum -{ - /* 0/1/2 are the traditional values for SET/CUR/END, respectively. Prior - to the release of Unix System V in 1983, the SEEK_* symbols did not - exist and C programs hard-coded the 0/1/2 values with those meanings. - */ - RED_SEEK_SET = 0, /**< Set file offset to given offset. */ - RED_SEEK_CUR = 1, /**< Set file offset to current offset plus signed offset. */ - RED_SEEK_END = 2 /**< Set file offset to EOF plus signed offset. */ -} REDWHENCE; - - -#if REDCONF_API_POSIX_READDIR == 1 -/** @brief Opaque directory handle. -*/ -typedef struct sREDHANDLE REDDIR; - - -/** @brief Directory entry information. -*/ -typedef struct -{ - uint32_t d_ino; /**< File serial number (inode number). */ - char d_name[REDCONF_NAME_MAX+1U]; /**< Name of entry. */ - REDSTAT d_stat; /**< File information (POSIX extension). */ -} REDDIRENT; -#endif - - -int32_t red_init(void); -int32_t red_uninit(void); -int32_t red_mount(const char *pszVolume); -int32_t red_umount(const char *pszVolume); -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1) -int32_t red_format(const char *pszVolume); -#endif -#if REDCONF_READ_ONLY == 0 -int32_t red_transact(const char *pszVolume); -#endif -#if REDCONF_READ_ONLY == 0 -int32_t red_settransmask(const char *pszVolume, uint32_t ulEventMask); -#endif -int32_t red_gettransmask(const char *pszVolume, uint32_t *pulEventMask); -int32_t red_statvfs(const char *pszVolume, REDSTATFS *pStatvfs); -int32_t red_open(const char *pszPath, uint32_t ulOpenMode); -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1) -int32_t red_unlink(const char *pszPath); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_MKDIR == 1) -int32_t red_mkdir(const char *pszPath); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RMDIR == 1) -int32_t red_rmdir(const char *pszPath); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) -int32_t red_rename(const char *pszOldPath, const char *pszNewPath); -#endif -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_LINK == 1) -int32_t red_link(const char *pszPath, const char *pszHardLink); -#endif -int32_t red_close(int32_t iFildes); -int32_t red_read(int32_t iFildes, void *pBuffer, uint32_t ulLength); -#if REDCONF_READ_ONLY == 0 -int32_t red_write(int32_t iFildes, const void *pBuffer, uint32_t ulLength); -#endif -#if REDCONF_READ_ONLY == 0 -int32_t red_fsync(int32_t iFildes); -#endif -int64_t red_lseek(int32_t iFildes, int64_t llOffset, REDWHENCE whence); -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1) -int32_t red_ftruncate(int32_t iFildes, uint64_t ullSize); -#endif -int32_t red_fstat(int32_t iFildes, REDSTAT *pStat); -#if REDCONF_API_POSIX_READDIR == 1 -REDDIR *red_opendir(const char *pszPath); -REDDIRENT *red_readdir(REDDIR *pDirStream); -void red_rewinddir(REDDIR *pDirStream); -int32_t red_closedir(REDDIR *pDirStream); -#endif -REDSTATUS *red_errnoptr(void); - -#endif /* REDCONF_API_POSIX */ - - -#ifdef __cplusplus -} -#endif - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Interface for the Reliance Edge POSIX-like API. + * + * The POSIX-like file system API is the primary file system API for + * Reliance Edge, which supports the full functionality of the file system. + * This API aims to be compatible with POSIX where reasonable, but it is + * simplified considerably to meet the needs of resource-constrained embedded + * systems. The API has also been extended to provide access to the unique + * features of Reliance Edge, and to cover areas (like mountins and formatting) + * which do not have APIs in the POSIX specification. + */ +#ifndef REDPOSIX_H + #define REDPOSIX_H + +/* This header is intended for application use; some applications are written + * in C++. + */ + #ifdef __cplusplus + extern "C" { + #endif + + #include + + #if REDCONF_API_POSIX == 1 + + #include + #include "redapimacs.h" + #include "rederrno.h" + #include "redstat.h" + +/** Open for reading only. */ + #define RED_O_RDONLY 0x00000001U + +/** Open for writing only. */ + #define RED_O_WRONLY 0x00000002U + +/** Open for reading and writing. */ + #define RED_O_RDWR 0x00000004U + +/** File offset for all writes is end-of-file. */ + #define RED_O_APPEND 0x00000008U + +/** Create the file. */ + #define RED_O_CREAT 0x00000010U + +/** Error if path already exists. */ + #define RED_O_EXCL 0x00000020U + +/** Truncate file to size zero. */ + #define RED_O_TRUNC 0x00000040U + + +/** @brief Last file system error (errno). + * + * Under normal circumstances, each task using the file system has an + * independent `red_errno` value. Applications do not need to worry about + * one task obliterating an error value that another task needed to read. The + * value is initially zero. When one of the POSIX-like APIs return an + * indication of error, `red_errno` is set to an error value. + * + * In some circumstances, `red_errno` will be a global errno location which + * is shared by multiple tasks. If the calling task is not registered as a + * file system user and all of the task slots are full, there can be no + * task-specific errno, so the global errno is used. Likewise, if the file + * system driver is uninitialized, there are no registered file system users + * and `red_errno` always refers to the global errno. Under these + * circumstances, multiple tasks manipulating `red_errno` could be + * problematic. When the task count is set to one, `red_errno` always refers + * to the global errno. + * + * Note that `red_errno` is usable as an lvalue; i.e., in addition to reading + * the error value, the error value can be set: + * + * ~~~{.c} + * red_errno = 0; + * ~~~ + */ + #define red_errno ( *red_errnoptr() ) + + +/** @brief Positions from which to seek within a file. + */ + typedef enum + { + /* 0/1/2 are the traditional values for SET/CUR/END, respectively. Prior + * to the release of Unix System V in 1983, the SEEK_* symbols did not + * exist and C programs hard-coded the 0/1/2 values with those meanings. + */ + RED_SEEK_SET = 0, /**< Set file offset to given offset. */ + RED_SEEK_CUR = 1, /**< Set file offset to current offset plus signed offset. */ + RED_SEEK_END = 2 /**< Set file offset to EOF plus signed offset. */ + } REDWHENCE; + + + #if REDCONF_API_POSIX_READDIR == 1 + +/** @brief Opaque directory handle. + */ + typedef struct sREDHANDLE REDDIR; + + +/** @brief Directory entry information. + */ + typedef struct + { + uint32_t d_ino; /**< File serial number (inode number). */ + char d_name[ REDCONF_NAME_MAX + 1U ]; /**< Name of entry. */ + REDSTAT d_stat; /**< File information (POSIX extension). */ + } REDDIRENT; + #endif /* if REDCONF_API_POSIX_READDIR == 1 */ + + + int32_t red_init( void ); + int32_t red_uninit( void ); + int32_t red_mount( const char * pszVolume ); + int32_t red_umount( const char * pszVolume ); + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_FORMAT == 1 ) + int32_t red_format( const char * pszVolume ); + #endif + #if REDCONF_READ_ONLY == 0 + int32_t red_transact( const char * pszVolume ); + #endif + #if REDCONF_READ_ONLY == 0 + int32_t red_settransmask( const char * pszVolume, + uint32_t ulEventMask ); + #endif + int32_t red_gettransmask( const char * pszVolume, + uint32_t * pulEventMask ); + int32_t red_statvfs( const char * pszVolume, + REDSTATFS * pStatvfs ); + int32_t red_open( const char * pszPath, + uint32_t ulOpenMode ); + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_UNLINK == 1 ) + int32_t red_unlink( const char * pszPath ); + #endif + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_MKDIR == 1 ) + int32_t red_mkdir( const char * pszPath ); + #endif + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RMDIR == 1 ) + int32_t red_rmdir( const char * pszPath ); + #endif + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RENAME == 1 ) + int32_t red_rename( const char * pszOldPath, + const char * pszNewPath ); + #endif + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_LINK == 1 ) + int32_t red_link( const char * pszPath, + const char * pszHardLink ); + #endif + int32_t red_close( int32_t iFildes ); + int32_t red_read( int32_t iFildes, + void * pBuffer, + uint32_t ulLength ); + #if REDCONF_READ_ONLY == 0 + int32_t red_write( int32_t iFildes, + const void * pBuffer, + uint32_t ulLength ); + #endif + #if REDCONF_READ_ONLY == 0 + int32_t red_fsync( int32_t iFildes ); + #endif + int64_t red_lseek( int32_t iFildes, + int64_t llOffset, + REDWHENCE whence ); + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_FTRUNCATE == 1 ) + int32_t red_ftruncate( int32_t iFildes, + uint64_t ullSize ); + #endif + int32_t red_fstat( int32_t iFildes, + REDSTAT * pStat ); + #if REDCONF_API_POSIX_READDIR == 1 + REDDIR * red_opendir( const char * pszPath ); + REDDIRENT * red_readdir( REDDIR * pDirStream ); + void red_rewinddir( REDDIR * pDirStream ); + int32_t red_closedir( REDDIR * pDirStream ); + #endif + REDSTATUS * red_errnoptr( void ); + + #endif /* REDCONF_API_POSIX */ + + + #ifdef __cplusplus +} + #endif + +#endif /* ifndef REDPOSIX_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redstat.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redstat.h index bf3801141..d7ccbfa7e 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redstat.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redstat.h @@ -1,94 +1,95 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDSTAT_H -#define REDSTAT_H - - -/** Mode bit for a directory. */ -#define RED_S_IFDIR 0x4000U - -/** Mode bit for a regular file. */ -#define RED_S_IFREG 0x8000U - -/** @brief Test for a directory. -*/ -#define RED_S_ISDIR(m) (((m) & RED_S_IFDIR) != 0U) - -/** @brief Test for a regular file. -*/ -#define RED_S_ISREG(m) (((m) & RED_S_IFREG) != 0U) - - -/** File system is read-only. */ -#define RED_ST_RDONLY 0x00000001U - -/** File system ignores suid and sgid bits. */ -#define RED_ST_NOSUID 0x00000002U - - -/** @brief Status information on an inode. -*/ -typedef struct -{ - uint8_t st_dev; /**< Volume number of volume containing file. */ - uint32_t st_ino; /**< File serial number (inode number). */ - uint16_t st_mode; /**< Mode of file. */ - uint16_t st_nlink; /**< Number of hard links to the file. */ - uint64_t st_size; /**< File size in bytes. */ - #if REDCONF_INODE_TIMESTAMPS == 1 - uint32_t st_atime; /**< Time of last access (seconds since 01-01-1970). */ - uint32_t st_mtime; /**< Time of last data modification (seconds since 01-01-1970). */ - uint32_t st_ctime; /**< Time of last status change (seconds since 01-01-1970). */ - #endif - #if REDCONF_INODE_BLOCKS == 1 - uint32_t st_blocks; /**< Number of blocks allocated for this object. */ - #endif -} REDSTAT; - - -/** @brief Status information on a file system volume. -*/ -typedef struct -{ - uint32_t f_bsize; /**< File system block size. */ - uint32_t f_frsize; /**< Fundamental file system block size. */ - uint32_t f_blocks; /**< Total number of blocks on file system in units of f_frsize. */ - uint32_t f_bfree; /**< Total number of free blocks. */ - uint32_t f_bavail; /**< Number of free blocks available to non-privileged process. */ - uint32_t f_files; /**< Total number of file serial numbers. */ - uint32_t f_ffree; /**< Total number of free file serial numbers. */ - uint32_t f_favail; /**< Number of file serial numbers available to non-privileged process. */ - uint32_t f_fsid; /**< File system ID (useless, populated with zero). */ - uint32_t f_flag; /**< Bit mask of f_flag values. Includes read-only file system flag. */ - uint32_t f_namemax; /**< Maximum filename length. */ - uint64_t f_maxfsize; /**< Maximum file size (POSIX extension). */ - uint32_t f_dev; /**< Volume number (POSIX extension). */ -} REDSTATFS; - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDSTAT_H +#define REDSTAT_H + + +/** Mode bit for a directory. */ +#define RED_S_IFDIR 0x4000U + +/** Mode bit for a regular file. */ +#define RED_S_IFREG 0x8000U + +/** @brief Test for a directory. + */ +#define RED_S_ISDIR( m ) ( ( ( m ) & RED_S_IFDIR ) != 0U ) + +/** @brief Test for a regular file. + */ +#define RED_S_ISREG( m ) ( ( ( m ) & RED_S_IFREG ) != 0U ) + + +/** File system is read-only. */ +#define RED_ST_RDONLY 0x00000001U + +/** File system ignores suid and sgid bits. */ +#define RED_ST_NOSUID 0x00000002U + + +/** @brief Status information on an inode. + */ +typedef struct +{ + uint8_t st_dev; /**< Volume number of volume containing file. */ + uint32_t st_ino; /**< File serial number (inode number). */ + uint16_t st_mode; /**< Mode of file. */ + uint16_t st_nlink; /**< Number of hard links to the file. */ + uint64_t st_size; /**< File size in bytes. */ + #if REDCONF_INODE_TIMESTAMPS == 1 + uint32_t st_atime; /**< Time of last access (seconds since 01-01-1970). */ + uint32_t st_mtime; /**< Time of last data modification (seconds since 01-01-1970). */ + uint32_t st_ctime; /**< Time of last status change (seconds since 01-01-1970). */ + #endif + #if REDCONF_INODE_BLOCKS == 1 + uint32_t st_blocks; /**< Number of blocks allocated for this object. */ + #endif +} REDSTAT; + + +/** @brief Status information on a file system volume. + */ +typedef struct +{ + uint32_t f_bsize; /**< File system block size. */ + uint32_t f_frsize; /**< Fundamental file system block size. */ + uint32_t f_blocks; /**< Total number of blocks on file system in units of f_frsize. */ + uint32_t f_bfree; /**< Total number of free blocks. */ + uint32_t f_bavail; /**< Number of free blocks available to non-privileged process. */ + uint32_t f_files; /**< Total number of file serial numbers. */ + uint32_t f_ffree; /**< Total number of free file serial numbers. */ + uint32_t f_favail; /**< Number of file serial numbers available to non-privileged process. */ + uint32_t f_fsid; /**< File system ID (useless, populated with zero). */ + uint32_t f_flag; /**< Bit mask of f_flag values. Includes read-only file system flag. */ + uint32_t f_namemax; /**< Maximum filename length. */ + uint64_t f_maxfsize; /**< Maximum file size (POSIX extension). */ + uint32_t f_dev; /**< Volume number (POSIX extension). */ +} REDSTATFS; + + +#endif /* ifndef REDSTAT_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redtests.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redtests.h index 6cd776953..f98ab2d73 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redtests.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redtests.h @@ -1,30 +1,32 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Prototypes for Reliance Edge test entry points. -*/ + * @brief Prototypes for Reliance Edge test entry points. + */ #ifndef REDTESTS_H #define REDTESTS_H @@ -33,233 +35,267 @@ #include "redver.h" /* This macro is only defined by the error injection project. -*/ + */ #ifdef REDCONF_ERROR_INJECTION -#include + #include #endif -#define FSSTRESS_SUPPORTED \ - ( ((RED_KIT == RED_KIT_GPL) || (RED_KIT == RED_KIT_SANDBOX)) \ - && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_PATH_SEPARATOR == '/') \ - && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_UNLINK == 1) && (REDCONF_API_POSIX_MKDIR == 1) \ - && (REDCONF_API_POSIX_RMDIR == 1) && (REDCONF_API_POSIX_RENAME == 1) && (REDCONF_API_POSIX_LINK == 1) \ - && (REDCONF_API_POSIX_FTRUNCATE == 1) && (REDCONF_API_POSIX_READDIR == 1)) +#define FSSTRESS_SUPPORTED \ + ( ( ( RED_KIT == RED_KIT_GPL ) || ( RED_KIT == RED_KIT_SANDBOX ) ) \ + && ( REDCONF_OUTPUT == 1 ) && ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_PATH_SEPARATOR == '/' ) \ + && ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_UNLINK == 1 ) && ( REDCONF_API_POSIX_MKDIR == 1 ) \ + && ( REDCONF_API_POSIX_RMDIR == 1 ) && ( REDCONF_API_POSIX_RENAME == 1 ) && ( REDCONF_API_POSIX_LINK == 1 ) \ + && ( REDCONF_API_POSIX_FTRUNCATE == 1 ) && ( REDCONF_API_POSIX_READDIR == 1 ) ) -#define FSE_STRESS_TEST_SUPPORTED \ - ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ - && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE == 1) \ - && (REDCONF_API_FSE_FORMAT == 1) && (REDCONF_API_FSE_TRANSMASKSET == 1) && (REDCONF_API_FSE_TRANSMASKGET == 1) \ - && (REDCONF_API_FSE_TRUNCATE == 1)) +#define FSE_STRESS_TEST_SUPPORTED \ + ( ( ( RED_KIT == RED_KIT_COMMERCIAL ) || ( RED_KIT == RED_KIT_SANDBOX ) ) \ + && ( REDCONF_OUTPUT == 1 ) && ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE == 1 ) \ + && ( REDCONF_API_FSE_FORMAT == 1 ) && ( REDCONF_API_FSE_TRANSMASKSET == 1 ) && ( REDCONF_API_FSE_TRANSMASKGET == 1 ) \ + && ( REDCONF_API_FSE_TRUNCATE == 1 ) ) -#define POSIX_API_TEST_SUPPORTED \ - ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ - && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \ - && (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_UNLINK == 1)) +#define POSIX_API_TEST_SUPPORTED \ + ( ( ( RED_KIT == RED_KIT_COMMERCIAL ) || ( RED_KIT == RED_KIT_SANDBOX ) ) \ + && ( REDCONF_OUTPUT == 1 ) && ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) \ + && ( REDCONF_API_POSIX_FORMAT == 1 ) && ( REDCONF_API_POSIX_UNLINK == 1 ) ) -#define FSE_API_TEST_SUPPORTED \ - ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ - && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE == 1) \ - && (REDCONF_API_FSE_FORMAT == 1)) +#define FSE_API_TEST_SUPPORTED \ + ( ( ( RED_KIT == RED_KIT_COMMERCIAL ) || ( RED_KIT == RED_KIT_SANDBOX ) ) \ + && ( REDCONF_OUTPUT == 1 ) && ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_FSE == 1 ) \ + && ( REDCONF_API_FSE_FORMAT == 1 ) ) -#define STOCH_POSIX_TEST_SUPPORTED \ - ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ - && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \ - && (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_READDIR == 1) \ - && (REDCONF_API_POSIX_MKDIR == 1) && (REDCONF_API_POSIX_RMDIR == 1) && (REDCONF_API_POSIX_UNLINK == 1) \ - && (REDCONF_API_POSIX_RENAME == 1)) +#define STOCH_POSIX_TEST_SUPPORTED \ + ( ( ( RED_KIT == RED_KIT_COMMERCIAL ) || ( RED_KIT == RED_KIT_SANDBOX ) ) \ + && ( REDCONF_OUTPUT == 1 ) && ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) \ + && ( REDCONF_API_POSIX_FORMAT == 1 ) && ( REDCONF_API_POSIX_READDIR == 1 ) \ + && ( REDCONF_API_POSIX_MKDIR == 1 ) && ( REDCONF_API_POSIX_RMDIR == 1 ) && ( REDCONF_API_POSIX_UNLINK == 1 ) \ + && ( REDCONF_API_POSIX_RENAME == 1 ) ) -#define FSIOTEST_SUPPORTED \ - ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ - && (REDCONF_OUTPUT == 1) && (REDCONF_API_POSIX == 1)) +#define FSIOTEST_SUPPORTED \ + ( ( ( RED_KIT == RED_KIT_COMMERCIAL ) || ( RED_KIT == RED_KIT_SANDBOX ) ) \ + && ( REDCONF_OUTPUT == 1 ) && ( REDCONF_API_POSIX == 1 ) ) -#define BDEVTEST_SUPPORTED \ - ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ - && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0)) +#define BDEVTEST_SUPPORTED \ + ( ( ( RED_KIT == RED_KIT_COMMERCIAL ) || ( RED_KIT == RED_KIT_SANDBOX ) ) \ + && ( REDCONF_OUTPUT == 1 ) && ( REDCONF_READ_ONLY == 0 ) ) -#define DISKFULL_TEST_SUPPORTED \ - ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ - && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \ - && (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) +#define DISKFULL_TEST_SUPPORTED \ + ( ( ( RED_KIT == RED_KIT_COMMERCIAL ) || ( RED_KIT == RED_KIT_SANDBOX ) ) \ + && ( REDCONF_OUTPUT == 1 ) && ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) \ + && ( REDCONF_API_POSIX_FORMAT == 1 ) && ( REDCONF_API_POSIX_FTRUNCATE == 1 ) ) typedef enum { - PARAMSTATUS_OK, /* Parameters were good; continue. */ - PARAMSTATUS_BAD, /* Parameters were bad; stop. */ - PARAMSTATUS_HELP /* Help request; not an error, but stop. */ + PARAMSTATUS_OK, /* Parameters were good; continue. */ + PARAMSTATUS_BAD, /* Parameters were bad; stop. */ + PARAMSTATUS_HELP /* Help request; not an error, but stop. */ } PARAMSTATUS; #if FSSTRESS_SUPPORTED -typedef struct -{ - bool fNoCleanup; /**< --no-cleanup */ - uint32_t ulLoops; /**< --loops */ - uint32_t ulNops; /**< --nops */ - bool fNamePad; /**< --namepad */ - uint32_t ulSeed; /**< --seed */ - bool fVerbose; /**< --verbose */ -} FSSTRESSPARAM; + typedef struct + { + bool fNoCleanup; /**< --no-cleanup */ + uint32_t ulLoops; /**< --loops */ + uint32_t ulNops; /**< --nops */ + bool fNamePad; /**< --namepad */ + uint32_t ulSeed; /**< --seed */ + bool fVerbose; /**< --verbose */ + } FSSTRESSPARAM; -PARAMSTATUS FsstressParseParams(int argc, char *argv[], FSSTRESSPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice); -void FsstressDefaultParams(FSSTRESSPARAM *pParam); -int FsstressStart(const FSSTRESSPARAM *pParam); -#endif + PARAMSTATUS FsstressParseParams( int argc, + char * argv[], + FSSTRESSPARAM * pParam, + uint8_t * pbVolNum, + const char ** ppszDevice ); + void FsstressDefaultParams( FSSTRESSPARAM * pParam ); + int FsstressStart( const FSSTRESSPARAM * pParam ); +#endif /* if FSSTRESS_SUPPORTED */ #if STOCH_POSIX_TEST_SUPPORTED -typedef struct -{ - const char *pszVolume; /**< Volume path prefix. */ - uint32_t ulIterations; /**< --iterations */ - uint32_t ulFileListMax; /**< --files */ - uint32_t ulDirListMax; /**< --dirs */ - uint32_t ulOpenFileListMax; /**< --open-files */ - uint32_t ulOpenDirListMax; /**< --open-dirs */ - uint32_t ulRandomSeed; /**< --seed */ -} STOCHPOSIXPARAM; + typedef struct + { + const char * pszVolume; /**< Volume path prefix. */ + uint32_t ulIterations; /**< --iterations */ + uint32_t ulFileListMax; /**< --files */ + uint32_t ulDirListMax; /**< --dirs */ + uint32_t ulOpenFileListMax; /**< --open-files */ + uint32_t ulOpenDirListMax; /**< --open-dirs */ + uint32_t ulRandomSeed; /**< --seed */ + } STOCHPOSIXPARAM; -PARAMSTATUS RedStochPosixParseParams(int argc, char *argv[], STOCHPOSIXPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice); -void RedStochPosixDefaultParams(STOCHPOSIXPARAM *pParam); -int RedStochPosixStart(const STOCHPOSIXPARAM *pParam); -#endif + PARAMSTATUS RedStochPosixParseParams( int argc, + char * argv[], + STOCHPOSIXPARAM * pParam, + uint8_t * pbVolNum, + const char ** ppszDevice ); + void RedStochPosixDefaultParams( STOCHPOSIXPARAM * pParam ); + int RedStochPosixStart( const STOCHPOSIXPARAM * pParam ); +#endif /* if STOCH_POSIX_TEST_SUPPORTED */ #if FSE_STRESS_TEST_SUPPORTED -typedef struct -{ - uint8_t bVolNum; /**< Volume number. */ - uint32_t ulFileCount; /**< --files */ - uint32_t ulMaxFileSize; /**< --max */ - uint32_t ulMaxOpSize; /**< --buffer-size */ - uint32_t ulNops; /**< --nops */ - uint32_t ulLoops; /**< --loops */ - uint32_t ulSampleRate; /**< --sample-rate */ - uint64_t ullSeed; /**< --seed */ -} FSESTRESSPARAM; + typedef struct + { + uint8_t bVolNum; /**< Volume number. */ + uint32_t ulFileCount; /**< --files */ + uint32_t ulMaxFileSize; /**< --max */ + uint32_t ulMaxOpSize; /**< --buffer-size */ + uint32_t ulNops; /**< --nops */ + uint32_t ulLoops; /**< --loops */ + uint32_t ulSampleRate; /**< --sample-rate */ + uint64_t ullSeed; /**< --seed */ + } FSESTRESSPARAM; -PARAMSTATUS FseStressParseParams(int argc, char *argv[], FSESTRESSPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice); -void FseStressDefaultParams(FSESTRESSPARAM *pParam); -int FseStressStart(const FSESTRESSPARAM *pParam); -#endif + PARAMSTATUS FseStressParseParams( int argc, + char * argv[], + FSESTRESSPARAM * pParam, + uint8_t * pbVolNum, + const char ** ppszDevice ); + void FseStressDefaultParams( FSESTRESSPARAM * pParam ); + int FseStressStart( const FSESTRESSPARAM * pParam ); +#endif /* if FSE_STRESS_TEST_SUPPORTED */ #if POSIX_API_TEST_SUPPORTED -typedef struct -{ - const char *pszVolume; /**< Volume path prefix. */ - bool fQuick; /**< --quick */ - bool fQuitOnFailure; /**< --quit-on-failure */ - bool fDebugErrors; /**< --debug */ -} POSIXTESTPARAM; + typedef struct + { + const char * pszVolume; /**< Volume path prefix. */ + bool fQuick; /**< --quick */ + bool fQuitOnFailure; /**< --quit-on-failure */ + bool fDebugErrors; /**< --debug */ + } POSIXTESTPARAM; -PARAMSTATUS RedPosixTestParseParams(int argc, char *argv[], POSIXTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice); -void RedPosixTestDefaultParams(POSIXTESTPARAM *pParam); -int RedPosixTestStart(const POSIXTESTPARAM *pParam); -#endif + PARAMSTATUS RedPosixTestParseParams( int argc, + char * argv[], + POSIXTESTPARAM * pParam, + uint8_t * pbVolNum, + const char ** ppszDevice ); + void RedPosixTestDefaultParams( POSIXTESTPARAM * pParam ); + int RedPosixTestStart( const POSIXTESTPARAM * pParam ); +#endif /* if POSIX_API_TEST_SUPPORTED */ #if POSIX_API_TEST_SUPPORTED -typedef struct -{ - const char *pszVolume; /**< Volume path prefix. */ - bool fQuick; /**< --quick */ - bool fVerbose; /**< --verbose */ - bool fQuitOnFailure; /**< --quit-on-failure */ - bool fDebugErrors; /**< --debug */ -} OSAPITESTPARAM; + typedef struct + { + const char * pszVolume; /**< Volume path prefix. */ + bool fQuick; /**< --quick */ + bool fVerbose; /**< --verbose */ + bool fQuitOnFailure; /**< --quit-on-failure */ + bool fDebugErrors; /**< --debug */ + } OSAPITESTPARAM; -PARAMSTATUS RedOsApiTestParseParams(int argc, char *argv[], OSAPITESTPARAM *pParam, const char **ppszDevice); -void RedOsApiTestDefaultParams(OSAPITESTPARAM *pParam); -int RedOsApiTestStart(const OSAPITESTPARAM *pParam); -#endif + PARAMSTATUS RedOsApiTestParseParams( int argc, + char * argv[], + OSAPITESTPARAM * pParam, + const char ** ppszDevice ); + void RedOsApiTestDefaultParams( OSAPITESTPARAM * pParam ); + int RedOsApiTestStart( const OSAPITESTPARAM * pParam ); +#endif /* if POSIX_API_TEST_SUPPORTED */ #if FSE_API_TEST_SUPPORTED -typedef struct -{ - uint8_t bVolNum; /**< Volume number. */ - bool fQuitOnFailure; /**< --quit-on-failure */ - bool fDebugErrors; /**< --debug */ -} FSETESTPARAM; + typedef struct + { + uint8_t bVolNum; /**< Volume number. */ + bool fQuitOnFailure; /**< --quit-on-failure */ + bool fDebugErrors; /**< --debug */ + } FSETESTPARAM; -PARAMSTATUS RedFseTestParseParams(int argc, char *argv[], FSETESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice); -void RedFseTestDefaultParams(FSETESTPARAM *pParam); -int RedFseTestStart(const FSETESTPARAM *pParam); -#endif + PARAMSTATUS RedFseTestParseParams( int argc, + char * argv[], + FSETESTPARAM * pParam, + uint8_t * pbVolNum, + const char ** ppszDevice ); + void RedFseTestDefaultParams( FSETESTPARAM * pParam ); + int RedFseTestStart( const FSETESTPARAM * pParam ); +#endif /* if FSE_API_TEST_SUPPORTED */ #if FSIOTEST_SUPPORTED -typedef enum -{ - TESTFS_RELEDGE, /* Datalight Reliance Edge */ - TESTFS_FATFS, /* ChaN's FatFs */ - TESTFS_FATSL /* FreeRTOS+FAT SL */ -} TESTFS; + typedef enum + { + TESTFS_RELEDGE, /* Datalight Reliance Edge */ + TESTFS_FATFS, /* ChaN's FatFs */ + TESTFS_FATSL /* FreeRTOS+FAT SL */ + } TESTFS; -typedef struct -{ - TESTFS testfs; /**< --fs */ - const char *pszVolume; /**< Volume path prefix. */ - bool fSeqRead; /**< --seq=r */ - bool fSeqWrite; /**< --seq=w */ - bool fSeqRewrite; /**< --seq=e */ - bool fRandomRead; /**< --rand=r */ - bool fRandomWrite; /**< --rand=w */ - bool fMixedWrite; /**< --mixed */ - bool fScanTest; /**< --scan */ - uint32_t ulFSBlockSize; /**< --block-size */ - uint32_t ulMaxFileSize; /**< --max */ - uint32_t ulRandomReadPasses; /**< --rand-pass=r:w (r part) */ - uint32_t ulRandomWritePasses; /**< --rand-pass=r:w (w part) */ - uint32_t ulMixedWritePasses; /**< --mixed-pass */ - int32_t iFlushOnWriteRatio; /**< --rand-fow */ - uint32_t ulBufferMin; /**< --start */ - uint32_t ulBufferSize; /**< --buffer-size */ - bool fWriteVerify; /**< --verify */ - uint32_t ulSampleRate; /**< --sample-rate */ - uint32_t ulScanCount; /**< --scan-files */ - uint64_t ullSeed; /**< --seed */ -} FSIOTESTPARAM; + typedef struct + { + TESTFS testfs; /**< --fs */ + const char * pszVolume; /**< Volume path prefix. */ + bool fSeqRead; /**< --seq=r */ + bool fSeqWrite; /**< --seq=w */ + bool fSeqRewrite; /**< --seq=e */ + bool fRandomRead; /**< --rand=r */ + bool fRandomWrite; /**< --rand=w */ + bool fMixedWrite; /**< --mixed */ + bool fScanTest; /**< --scan */ + uint32_t ulFSBlockSize; /**< --block-size */ + uint32_t ulMaxFileSize; /**< --max */ + uint32_t ulRandomReadPasses; /**< --rand-pass=r:w (r part) */ + uint32_t ulRandomWritePasses; /**< --rand-pass=r:w (w part) */ + uint32_t ulMixedWritePasses; /**< --mixed-pass */ + int32_t iFlushOnWriteRatio; /**< --rand-fow */ + uint32_t ulBufferMin; /**< --start */ + uint32_t ulBufferSize; /**< --buffer-size */ + bool fWriteVerify; /**< --verify */ + uint32_t ulSampleRate; /**< --sample-rate */ + uint32_t ulScanCount; /**< --scan-files */ + uint64_t ullSeed; /**< --seed */ + } FSIOTESTPARAM; -PARAMSTATUS FSIOTestParseParams(int argc, char *argv[], FSIOTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice); -void FSIOTestDefaultParams(FSIOTESTPARAM *pParam); -int FSIOTestStart(const FSIOTESTPARAM *pParam); -#endif + PARAMSTATUS FSIOTestParseParams( int argc, + char * argv[], + FSIOTESTPARAM * pParam, + uint8_t * pbVolNum, + const char ** ppszDevice ); + void FSIOTestDefaultParams( FSIOTESTPARAM * pParam ); + int FSIOTestStart( const FSIOTESTPARAM * pParam ); +#endif /* if FSIOTEST_SUPPORTED */ #if BDEVTEST_SUPPORTED -typedef struct -{ - uint8_t bDrvNum; /**< Volume number (for sector size/count). */ - bool fSeqWrite; /**< --seq:w */ - bool fSeqRead; /**< --seq:r */ - bool fRandWrite; /**< --rand:w */ - bool fRandRead; /**< --rand:r */ - uint32_t ulSampleSecs; /**< --sample-rate */ - uint32_t ulPasses; /**< --passes */ - uint32_t ulMinIOSectors; /**< --count=min[:max] (min part) */ - uint32_t ulMaxIOSectors; /**< --count=min[:max] (max part) */ - uint32_t ulMaxSizeKB; /**< --max */ - uint32_t ulTestSeconds; /**< --time */ - bool fVerify; /**< --verify */ - bool fAsyncWrites; /**< --async */ - uint64_t ullSeed; /**< --seed */ -} BDEVTESTPARAM; + typedef struct + { + uint8_t bDrvNum; /**< Volume number (for sector size/count). */ + bool fSeqWrite; /**< --seq:w */ + bool fSeqRead; /**< --seq:r */ + bool fRandWrite; /**< --rand:w */ + bool fRandRead; /**< --rand:r */ + uint32_t ulSampleSecs; /**< --sample-rate */ + uint32_t ulPasses; /**< --passes */ + uint32_t ulMinIOSectors; /**< --count=min[:max] (min part) */ + uint32_t ulMaxIOSectors; /**< --count=min[:max] (max part) */ + uint32_t ulMaxSizeKB; /**< --max */ + uint32_t ulTestSeconds; /**< --time */ + bool fVerify; /**< --verify */ + bool fAsyncWrites; /**< --async */ + uint64_t ullSeed; /**< --seed */ + } BDEVTESTPARAM; -PARAMSTATUS BDevTestParseParams(int argc, char *argv[], BDEVTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice); -void BDevTestDefaultParams(BDEVTESTPARAM *pParam); -int BDevTestStart(const BDEVTESTPARAM *pParam); -#endif + PARAMSTATUS BDevTestParseParams( int argc, + char * argv[], + BDEVTESTPARAM * pParam, + uint8_t * pbVolNum, + const char ** ppszDevice ); + void BDevTestDefaultParams( BDEVTESTPARAM * pParam ); + int BDevTestStart( const BDEVTESTPARAM * pParam ); +#endif /* if BDEVTEST_SUPPORTED */ #if DISKFULL_TEST_SUPPORTED -typedef struct -{ - const char *pszVolume; /**< Volume path prefix. */ - bool fQuitOnFailure; /**< --quit-on-failure */ - bool fDebugErrors; /**< --debug */ -} DISKFULLTESTPARAM; + typedef struct + { + const char * pszVolume; /**< Volume path prefix. */ + bool fQuitOnFailure; /**< --quit-on-failure */ + bool fDebugErrors; /**< --debug */ + } DISKFULLTESTPARAM; -PARAMSTATUS DiskFullTestParseParams(int argc, char *argv[], DISKFULLTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice); -void DiskFullTestDefaultParams(DISKFULLTESTPARAM *pParam); -int DiskFullTestStart(const DISKFULLTESTPARAM *pParam); -#endif + PARAMSTATUS DiskFullTestParseParams( int argc, + char * argv[], + DISKFULLTESTPARAM * pParam, + uint8_t * pbVolNum, + const char ** ppszDevice ); + void DiskFullTestDefaultParams( DISKFULLTESTPARAM * pParam ); + int DiskFullTestStart( const DISKFULLTESTPARAM * pParam ); +#endif /* if DISKFULL_TEST_SUPPORTED */ -#endif - +#endif /* ifndef REDTESTS_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redtestutils.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redtestutils.h index 294da5ba7..fd316041e 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redtestutils.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redtestutils.h @@ -1,71 +1,105 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Reliance Edge utilities only needed for tests. -*/ -#ifndef REDTESTUTILS_H -#define REDTESTUTILS_H - - -#define ISDIGIT(c) (((c) >= '0') && ((c) <= '9')) - - -void RedRandSeed(uint64_t ullSeed); -uint64_t RedRand64(uint64_t *pullSeed); -uint32_t RedRand32(uint32_t *pulSeed); - -char *RedRatio(char *pBuffer, uint32_t ulBufferLen, uint64_t ullDividend, uint64_t ullDivisor, uint32_t ulDecPlaces); -uint64_t RedMulDiv64(uint64_t ullBase, uint32_t ulMultiplier, uint64_t ullDivisor); -uint64_t RedUint64DivMod32(uint64_t ullDividend, uint32_t ulDivisor, uint32_t *pulRemainder); -uint64_t RedUint64DivMod64(uint64_t ullDividend, uint64_t ullDivisor, uint64_t *pullRemainder); - -char *RedScaleBytes(uint32_t ulByteValue, char *pszBuffer, uint32_t ulBufferSize); -char *RedScaleKB(uint32_t ulKBValue, char *pszBuffer, uint32_t ulBufferSize); -uint32_t RedGetKBPerSecond(uint64_t ullKB, uint32_t ulMS); -uint32_t RedGetKBPerSecondSectors(uint32_t ulBytesPerSector, uint64_t ullSectors, uint64_t ullUS); - -int32_t RedAtoI(const char *pszNum); -const char *RedHtoUL(const char *pszNum, uint32_t *pulNum); -const char *RedHtoULL(const char *pszNum, uint64_t *pullNum); -const char *RedNtoUL(const char *pszNum, uint32_t *pulNum); -const char *RedNtoULL(const char *pszNum, uint64_t *pullNum); -const char *RedSizeToUL(const char *pszNum, uint32_t *pulResult); - -int32_t RedStrICmp(const char *pszStr1, const char *pszStr2); -int32_t RedStrNICmp(const char *pszStr1, const char *pszStr2, uint32_t ulLen); -char RedToLower(char c); - -#include - -#if REDCONF_OUTPUT == 1 -void RedPrintf(const char *pszFormat, ...); -void RedVPrintf(const char *pszFormat, va_list arglist); -#endif -int32_t RedSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, ...); -int32_t RedVSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, va_list arglist); - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Reliance Edge utilities only needed for tests. + */ +#ifndef REDTESTUTILS_H +#define REDTESTUTILS_H + + +#define ISDIGIT( c ) ( ( ( c ) >= '0' ) && ( ( c ) <= '9' ) ) + + +void RedRandSeed( uint64_t ullSeed ); +uint64_t RedRand64( uint64_t * pullSeed ); +uint32_t RedRand32( uint32_t * pulSeed ); + +char * RedRatio( char * pBuffer, + uint32_t ulBufferLen, + uint64_t ullDividend, + uint64_t ullDivisor, + uint32_t ulDecPlaces ); +uint64_t RedMulDiv64( uint64_t ullBase, + uint32_t ulMultiplier, + uint64_t ullDivisor ); +uint64_t RedUint64DivMod32( uint64_t ullDividend, + uint32_t ulDivisor, + uint32_t * pulRemainder ); +uint64_t RedUint64DivMod64( uint64_t ullDividend, + uint64_t ullDivisor, + uint64_t * pullRemainder ); + +char * RedScaleBytes( uint32_t ulByteValue, + char * pszBuffer, + uint32_t ulBufferSize ); +char * RedScaleKB( uint32_t ulKBValue, + char * pszBuffer, + uint32_t ulBufferSize ); +uint32_t RedGetKBPerSecond( uint64_t ullKB, + uint32_t ulMS ); +uint32_t RedGetKBPerSecondSectors( uint32_t ulBytesPerSector, + uint64_t ullSectors, + uint64_t ullUS ); + +int32_t RedAtoI( const char * pszNum ); +const char * RedHtoUL( const char * pszNum, + uint32_t * pulNum ); +const char * RedHtoULL( const char * pszNum, + uint64_t * pullNum ); +const char * RedNtoUL( const char * pszNum, + uint32_t * pulNum ); +const char * RedNtoULL( const char * pszNum, + uint64_t * pullNum ); +const char * RedSizeToUL( const char * pszNum, + uint32_t * pulResult ); + +int32_t RedStrICmp( const char * pszStr1, + const char * pszStr2 ); +int32_t RedStrNICmp( const char * pszStr1, + const char * pszStr2, + uint32_t ulLen ); +char RedToLower( char c ); + +#include + +#if REDCONF_OUTPUT == 1 + void RedPrintf( const char * pszFormat, + ... ); + void RedVPrintf( const char * pszFormat, + va_list arglist ); +#endif +int32_t RedSNPrintf( char * pcBuffer, + uint32_t ulBufferLen, + const char * pszFormat, + ... ); +int32_t RedVSNPrintf( char * pcBuffer, + uint32_t ulBufferLen, + const char * pszFormat, + va_list arglist ); + + +#endif /* ifndef REDTESTUTILS_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redtoolcmn.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redtoolcmn.h index 7772552c5..b2fb7f6bf 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redtoolcmn.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redtoolcmn.h @@ -1,37 +1,38 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Interfaces for common-code utilities for tools and tests. -*/ -#ifndef REDTOOLCMN_H -#define REDTOOLCMN_H - - -uint8_t RedFindVolumeNumber(const char *pszVolume); -bool RedConfirmOperation(const char *pszMessage); - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Interfaces for common-code utilities for tools and tests. + */ +#ifndef REDTOOLCMN_H +#define REDTOOLCMN_H + + +uint8_t RedFindVolumeNumber( const char * pszVolume ); +bool RedConfirmOperation( const char * pszMessage ); + + +#endif diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redtools.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redtools.h index f80ffb1f8..d96051d43 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redtools.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redtools.h @@ -1,183 +1,206 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ #ifndef REDTOOLS_H #define REDTOOLS_H #ifdef _WIN32 - #include - #define HOST_PATH_MAX MAX_PATH + #include + #define HOST_PATH_MAX MAX_PATH #else - #include - #define HOST_PATH_MAX PATH_MAX + #include + #define HOST_PATH_MAX PATH_MAX #endif #if REDCONF_IMAGE_BUILDER == 1 -#define MACRO_NAME_MAX_LEN 32 + #define MACRO_NAME_MAX_LEN 32 -typedef struct -{ - uint8_t bVolNumber; - const char *pszInputDir; - const char *pszOutputFile; - #if REDCONF_API_POSIX == 1 - const char *pszVolName; - #else - const char *pszMapFile; - const char *pszDefineFile; - bool fNowarn; - #endif -} IMGBLDPARAM; + typedef struct + { + uint8_t bVolNumber; + const char * pszInputDir; + const char * pszOutputFile; + #if REDCONF_API_POSIX == 1 + const char * pszVolName; + #else + const char * pszMapFile; + const char * pszDefineFile; + bool fNowarn; + #endif + } IMGBLDPARAM; -void ImgbldParseParams(int argc, char *argv [], IMGBLDPARAM *pParam); -int ImgbldStart(IMGBLDPARAM *pParam); + void ImgbldParseParams( int argc, + char * argv[], + IMGBLDPARAM * pParam ); + int ImgbldStart( IMGBLDPARAM * pParam ); -typedef struct -{ - #if REDCONF_API_POSIX == 1 - char asOutFilePath[HOST_PATH_MAX]; - #else - uint32_t ulOutFileIndex; - #endif - char asInFilePath[HOST_PATH_MAX]; -} FILEMAPPING; + typedef struct + { + #if REDCONF_API_POSIX == 1 + char asOutFilePath[ HOST_PATH_MAX ]; + #else + uint32_t ulOutFileIndex; + #endif + char asInFilePath[ HOST_PATH_MAX ]; + } FILEMAPPING; -extern void *gpCopyBuffer; -extern uint32_t gulCopyBufferSize; + extern void * gpCopyBuffer; + extern uint32_t gulCopyBufferSize; /* Implemented in ibposix.c -*/ -#if REDCONF_API_POSIX == 1 -REDSTATUS IbPosixCopyDir(const char *pszVolName, const char *pszInDir); -int IbPosixCreateDir(const char *pszVolName, const char *pszFullPath, const char *pszBasePath); -int IbConvertPath(const char *pszVolName, const char *pszFullPath, const char *pszBasePath, char *szOutPath); -#endif + */ + #if REDCONF_API_POSIX == 1 + REDSTATUS IbPosixCopyDir( const char * pszVolName, + const char * pszInDir ); + int IbPosixCreateDir( const char * pszVolName, + const char * pszFullPath, + const char * pszBasePath ); + int IbConvertPath( const char * pszVolName, + const char * pszFullPath, + const char * pszBasePath, + char * szOutPath ); + #endif /* Implemented in ibfse.c -*/ -#if REDCONF_API_FSE == 1 -typedef struct sFILELISTENTRY FILELISTENTRY; -struct sFILELISTENTRY -{ - FILEMAPPING fileMapping; - FILELISTENTRY *pNext; -}; + */ + #if REDCONF_API_FSE == 1 + typedef struct sFILELISTENTRY FILELISTENTRY; + struct sFILELISTENTRY + { + FILEMAPPING fileMapping; + FILELISTENTRY * pNext; + }; -void FreeFileList(FILELISTENTRY **ppsFileList); + void FreeFileList( FILELISTENTRY ** ppsFileList ); -int IbFseGetFileList(const char *pszPath, const char *pszIndirPath, FILELISTENTRY **ppFileListHead); -int IbFseOutputDefines(FILELISTENTRY *pFileList, const IMGBLDPARAM *pOptions); -int IbFseCopyFiles(int volNum, const FILELISTENTRY *pFileList); -#endif + int IbFseGetFileList( const char * pszPath, + const char * pszIndirPath, + FILELISTENTRY ** ppFileListHead ); + int IbFseOutputDefines( FILELISTENTRY * pFileList, + const IMGBLDPARAM * pOptions ); + int IbFseCopyFiles( int volNum, + const FILELISTENTRY * pFileList ); + #endif /* if REDCONF_API_FSE == 1 */ /* Implemented in os-specific space (ibwin.c and iblinux.c) -*/ -#if REDCONF_API_POSIX == 1 -int IbPosixCopyDirRecursive(const char *pszVolName, const char *pszInDir); -#endif -#if REDCONF_API_FSE == 1 -int IbFseBuildFileList(const char *pszDirPath, FILELISTENTRY **ppFileListHead); -#endif -#if REDCONF_API_FSE == 1 -int IbSetRelativePath(char *pszPath, const char *pszParentPath); -#endif -bool IsRegularFile(const char *pszPath); + */ + #if REDCONF_API_POSIX == 1 + int IbPosixCopyDirRecursive( const char * pszVolName, + const char * pszInDir ); + #endif + #if REDCONF_API_FSE == 1 + int IbFseBuildFileList( const char * pszDirPath, + FILELISTENTRY ** ppFileListHead ); + #endif + #if REDCONF_API_FSE == 1 + int IbSetRelativePath( char * pszPath, + const char * pszParentPath ); + #endif + bool IsRegularFile( const char * pszPath ); /* Implemented in ibcommon.c -*/ -int IbCopyFile(int volNum, const FILEMAPPING *pFileMapping); -int IbCheckFileExists(const char *pszPath, bool *pfExists); + */ + int IbCopyFile( int volNum, + const FILEMAPPING * pFileMapping ); + int IbCheckFileExists( const char * pszPath, + bool * pfExists ); /* Implemented separately in ibfse.c and ibposix.c -*/ -int IbApiInit(void); -int IbApiUninit(void); -int IbWriteFile(int volNum, const FILEMAPPING *pFileMapping, uint64_t ullOffset, void *pData, uint32_t ulDataLen); + */ + int IbApiInit( void ); + int IbApiUninit( void ); + int IbWriteFile( int volNum, + const FILEMAPPING * pFileMapping, + uint64_t ullOffset, + void * pData, + uint32_t ulDataLen ); #endif /* IMAGE_BUILDER */ /* For image copier tool -*/ + */ #ifdef _WIN32 - #define HOST_PSEP '\\' - #if !__STDC__ - #define snprintf _snprintf - #define stat _stat - #define S_IFDIR _S_IFDIR - #define rmdir _rmdir - #endif + #define HOST_PSEP '\\' + #if !__STDC__ + #define snprintf _snprintf + #define stat _stat + #define S_IFDIR _S_IFDIR + #define rmdir _rmdir + #endif #else - #define HOST_PSEP '/' + #define HOST_PSEP '/' #endif typedef struct { - uint8_t bVolNumber; - const char *pszOutputDir; - const char *pszBDevSpec; - #if REDCONF_API_POSIX == 1 - const char *pszVolName; - #endif - bool fNoWarn; + uint8_t bVolNumber; + const char * pszOutputDir; + const char * pszBDevSpec; + #if REDCONF_API_POSIX == 1 + const char * pszVolName; + #endif + bool fNoWarn; } IMGCOPYPARAM; typedef struct { - #if REDCONF_API_POSIX == 1 - const char *pszVolume; /* Volume path prefix. */ - uint32_t ulVolPrefixLen; /* strlen(COPIER::pszVolume) */ - #else - uint8_t bVolNum; /* Volume number. */ - #endif - const char *pszOutputDir; /* Output directory path. */ - bool fNoWarn; /* If true, no warning to overwrite. */ - uint8_t *pbCopyBuffer; /* Buffer for copying file data. */ + #if REDCONF_API_POSIX == 1 + const char * pszVolume; /* Volume path prefix. */ + uint32_t ulVolPrefixLen; /* strlen(COPIER::pszVolume) */ + #else + uint8_t bVolNum; /* Volume number. */ + #endif + const char * pszOutputDir; /* Output directory path. */ + bool fNoWarn; /* If true, no warning to overwrite. */ + uint8_t * pbCopyBuffer; /* Buffer for copying file data. */ } COPIER; -void ImgcopyParseParams(int argc, char *argv [], IMGCOPYPARAM *pParam); -int ImgcopyStart(IMGCOPYPARAM *pParam); +void ImgcopyParseParams( int argc, + char * argv[], + IMGCOPYPARAM * pParam ); +int ImgcopyStart( IMGCOPYPARAM * pParam ); /* Implemented separately in imgcopywin.c and imgcopylinux.c. These functions - print an error message and abort on failure. -*/ -void ImgcopyMkdir(const char *pszDir); -void ImgcopyRecursiveRmdir(const char *pszDir); + * print an error message and abort on failure. + */ +void ImgcopyMkdir( const char * pszDir ); +void ImgcopyRecursiveRmdir( const char * pszDir ); #endif /* REDTOOLS_H */ - diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redutils.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redutils.h index f2dd663a5..83f6d20b7 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redutils.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redutils.h @@ -1,71 +1,90 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file -*/ -#ifndef REDUTILS_H -#define REDUTILS_H - - -#if REDCONF_ASSERTS == 1 -#define REDERROR() RedOsAssertFail(__FILE__, __LINE__) -#define REDASSERT(EXP) ((EXP) ? (void)0 : REDERROR()) -#else -#define REDERROR() ((void)0) -#define REDASSERT(EXP) ((void)0) -#endif - - -void RedMemCpy(void *pDest, const void *pSrc, uint32_t ulLen); -void RedMemMove(void *pDest, const void *pSrc, uint32_t ulLen); -void RedMemSet(void *pDest, uint8_t bVal, uint32_t ulLen); -int32_t RedMemCmp(const void *pMem1, const void *pMem2, uint32_t ulLen); - -uint32_t RedStrLen(const char *pszStr); -int32_t RedStrCmp(const char *pszStr1, const char *pszStr2); -int32_t RedStrNCmp(const char *pszStr1, const char *pszStr2, uint32_t ulLen); -void RedStrNCpy(char *pszDst, const char *pszSrc, uint32_t ulLen); - -uint32_t RedCrc32Update(uint32_t ulInitCrc32, const void *pBuffer, uint32_t ulLength); -uint32_t RedCrcNode(const void *pBuffer); - -#if REDCONF_API_POSIX == 1 -uint32_t RedNameLen(const char *pszName); -#endif - -bool RedBitGet(const uint8_t *pbBitmap, uint32_t ulBit); -void RedBitSet(uint8_t *pbBitmap, uint32_t ulBit); -void RedBitClear(uint8_t *pbBitmap, uint32_t ulBit); - -#ifdef REDCONF_ENDIAN_SWAP -uint64_t RedRev64(uint64_t ullToRev); -uint32_t RedRev32(uint32_t ulToRev); -uint16_t RedRev16(uint16_t uToRev); -#endif - -void RedSignOn(void); - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + */ +#ifndef REDUTILS_H +#define REDUTILS_H + + +#if REDCONF_ASSERTS == 1 + #define REDERROR() RedOsAssertFail( __FILE__, __LINE__ ) + #define REDASSERT( EXP ) ( ( EXP ) ? ( void ) 0 : REDERROR() ) +#else + #define REDERROR() ( ( void ) 0 ) + #define REDASSERT( EXP ) ( ( void ) 0 ) +#endif + + +void RedMemCpy( void * pDest, + const void * pSrc, + uint32_t ulLen ); +void RedMemMove( void * pDest, + const void * pSrc, + uint32_t ulLen ); +void RedMemSet( void * pDest, + uint8_t bVal, + uint32_t ulLen ); +int32_t RedMemCmp( const void * pMem1, + const void * pMem2, + uint32_t ulLen ); + +uint32_t RedStrLen( const char * pszStr ); +int32_t RedStrCmp( const char * pszStr1, + const char * pszStr2 ); +int32_t RedStrNCmp( const char * pszStr1, + const char * pszStr2, + uint32_t ulLen ); +void RedStrNCpy( char * pszDst, + const char * pszSrc, + uint32_t ulLen ); + +uint32_t RedCrc32Update( uint32_t ulInitCrc32, + const void * pBuffer, + uint32_t ulLength ); +uint32_t RedCrcNode( const void * pBuffer ); + +#if REDCONF_API_POSIX == 1 + uint32_t RedNameLen( const char * pszName ); +#endif + +bool RedBitGet( const uint8_t * pbBitmap, + uint32_t ulBit ); +void RedBitSet( uint8_t * pbBitmap, + uint32_t ulBit ); +void RedBitClear( uint8_t * pbBitmap, + uint32_t ulBit ); + +#ifdef REDCONF_ENDIAN_SWAP + uint64_t RedRev64( uint64_t ullToRev ); + uint32_t RedRev32( uint32_t ulToRev ); + uint16_t RedRev16( uint16_t uToRev ); +#endif + +void RedSignOn( void ); + + +#endif /* ifndef REDUTILS_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redver.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redver.h index 28793a6e4..700b039ed 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redver.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redver.h @@ -1,111 +1,112 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Macros for version numbers, build number, and product information. -*/ + * @brief Macros for version numbers, build number, and product information. + */ #ifndef REDVER_H #define REDVER_H /** @brief Consecutive number assigned to each automated build. + * + * + */ +#define RED_BUILD_NUMBER "700" - -*/ -#define RED_BUILD_NUMBER "700" - -#define RED_KIT_GPL 0U /* Open source GPL kit. */ -#define RED_KIT_COMMERCIAL 1U /* Commercially-licensed kit. */ -#define RED_KIT_SANDBOX 2U /* Not a kit: developer sandbox. */ +#define RED_KIT_GPL 0U /* Open source GPL kit. */ +#define RED_KIT_COMMERCIAL 1U /* Commercially-licensed kit. */ +#define RED_KIT_SANDBOX 2U /* Not a kit: developer sandbox. */ /** @brief Indicates the Reliance Edge kit. - - -*/ -#define RED_KIT RED_KIT_GPL + * + * + */ +#define RED_KIT RED_KIT_GPL /** @brief Version number to display in output. -*/ -#define RED_VERSION "v2.0" + */ +#define RED_VERSION "v2.0" /** @brief Version number in hex. - - The most significant byte is the major version number, etc. -*/ -#define RED_VERSION_VAL 0x02000000U + * + * The most significant byte is the major version number, etc. + */ +#define RED_VERSION_VAL 0x02000000U /** @brief On-disk version number. - - This is incremented only when the on-disk layout is updated in such a way - which is incompatible with previously released versions of the file system. -*/ -#define RED_DISK_LAYOUT_VERSION 1U + * + * This is incremented only when the on-disk layout is updated in such a way + * which is incompatible with previously released versions of the file system. + */ +#define RED_DISK_LAYOUT_VERSION 1U /** @brief Base name of the file system product. -*/ -#define RED_PRODUCT_BASE_NAME "Reliance Edge" + */ +#define RED_PRODUCT_BASE_NAME "Reliance Edge" /* Specifies whether the product is in alpha stage, beta stage, or neither. -*/ + */ #if 0 - #if 0 - #define ALPHABETA " (Alpha)" - #else - #define ALPHABETA " (Beta)" - #endif + #if 0 + #define ALPHABETA " (Alpha)" + #else + #define ALPHABETA " (Beta)" + #endif #else - #define ALPHABETA "" + #define ALPHABETA "" #endif /** @brief Full product name and version. -*/ -#define RED_PRODUCT_NAME "Datalight " RED_PRODUCT_BASE_NAME " " RED_VERSION " Build " RED_BUILD_NUMBER ALPHABETA + */ +#define RED_PRODUCT_NAME "Datalight " RED_PRODUCT_BASE_NAME " " RED_VERSION " Build " RED_BUILD_NUMBER ALPHABETA /** @brief Product copyright. -*/ -#define RED_PRODUCT_LEGAL "Copyright (c) 2014-2017 Datalight, Inc. All Rights Reserved Worldwide." + */ +#define RED_PRODUCT_LEGAL "Copyright (c) 2014-2017 Datalight, Inc. All Rights Reserved Worldwide." /** @brief Product patents. -*/ -#define RED_PRODUCT_PATENT "Patents: US#7284101." + */ +#define RED_PRODUCT_PATENT "Patents: US#7284101." /** @brief Product edition. -*/ + */ #if RED_KIT == RED_KIT_GPL -#define RED_PRODUCT_EDITION "Open-Source GPLv2 Edition -- Compiled " __DATE__ " at " __TIME__ + #define RED_PRODUCT_EDITION "Open-Source GPLv2 Edition -- Compiled " __DATE__ " at " __TIME__ #elif RED_KIT == RED_KIT_COMMERCIAL -#define RED_PRODUCT_EDITION "Commercial Edition -- Compiled " __DATE__ " at " __TIME__ + #define RED_PRODUCT_EDITION "Commercial Edition -- Compiled " __DATE__ " at " __TIME__ #else -#define RED_PRODUCT_EDITION "Developer Sandbox -- Compiled " __DATE__ " at " __TIME__ + #define RED_PRODUCT_EDITION "Developer Sandbox -- Compiled " __DATE__ " at " __TIME__ #endif -#endif - +#endif /* ifndef REDVER_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/include/redvolume.h b/FreeRTOS-Plus/Source/Reliance-Edge/include/redvolume.h index 266cf5e15..2435cc2d3 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/include/redvolume.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/include/redvolume.h @@ -1,141 +1,144 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file -*/ + */ #ifndef REDVOLUME_H #define REDVOLUME_H /** @brief Per-volume configuration structure. - - Contains the configuration values that may differ between volumes. Must be - declared in an array in redconf.c in the Reliance Edge project directory and - statically initialized with values representing the volume configuration of - the target system. -*/ + * + * Contains the configuration values that may differ between volumes. Must be + * declared in an array in redconf.c in the Reliance Edge project directory and + * statically initialized with values representing the volume configuration of + * the target system. + */ typedef struct { /** The sector size for the block device underlying the volume: the basic - unit for reading and writing to the storage media. Commonly ranges - between 512 and 4096, but any power-of-two value not greater than the - block size will work. - */ - uint32_t ulSectorSize; + * unit for reading and writing to the storage media. Commonly ranges + * between 512 and 4096, but any power-of-two value not greater than the + * block size will work. + */ + uint32_t ulSectorSize; /** The number of sectors in this file system volume. - */ - uint64_t ullSectorCount; + */ + uint64_t ullSectorCount; /** Whether a sector write on the block device underlying the volume is - atomic. It is atomic if when the sector write is interrupted, the - contents of the sector are guaranteed to be either all of the new data, - or all of the old data. If unsure, leave as false. - */ - bool fAtomicSectorWrite; + * atomic. It is atomic if when the sector write is interrupted, the + * contents of the sector are guaranteed to be either all of the new data, + * or all of the old data. If unsure, leave as false. + */ + bool fAtomicSectorWrite; /** This is the maximum number of inodes (files and directories). This - number includes the root directory inode (inode 2; created during - format), but does not include inodes 0 or 1, which do not exist on - disk. The number of inodes cannot be less than 1. - */ - uint32_t ulInodeCount; + * number includes the root directory inode (inode 2; created during + * format), but does not include inodes 0 or 1, which do not exist on + * disk. The number of inodes cannot be less than 1. + */ + uint32_t ulInodeCount; /** This is the maximum number of times a block device I/O operation will - be retried. If a block device read, write, or flush fails, Reliance - Edge will try again up to this number of times until the operation is - successful. Set this to 0 to disable retries. - */ - uint8_t bBlockIoRetries; + * be retried. If a block device read, write, or flush fails, Reliance + * Edge will try again up to this number of times until the operation is + * successful. Set this to 0 to disable retries. + */ + uint8_t bBlockIoRetries; - #if REDCONF_API_POSIX == 1 - /** The path prefix for the volume; for example, "VOL1:", "FlashDisk", etc. - */ - const char *pszPathPrefix; - #endif + #if REDCONF_API_POSIX == 1 + + /** The path prefix for the volume; for example, "VOL1:", "FlashDisk", etc. + */ + const char * pszPathPrefix; + #endif } VOLCONF; -extern const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT]; +extern const VOLCONF gaRedVolConf[ REDCONF_VOLUME_COUNT ]; extern const VOLCONF * CONST_IF_ONE_VOLUME gpRedVolConf; /** @brief Per-volume run-time data. -*/ + */ typedef struct { /** Whether the volume is currently mounted. - */ - bool fMounted; + */ + bool fMounted; - #if REDCONF_READ_ONLY == 0 - /** Whether the volume is read-only. - */ - bool fReadOnly; + #if REDCONF_READ_ONLY == 0 - /** The active automatic transaction mask. - */ - uint32_t ulTransMask; - #endif + /** Whether the volume is read-only. + */ + bool fReadOnly; + + /** The active automatic transaction mask. + */ + uint32_t ulTransMask; + #endif /** The power of 2 difference between sector size and block size. - */ - uint8_t bBlockSectorShift; + */ + uint8_t bBlockSectorShift; /** The number of logical blocks in this file system volume. The unit here - is the global block size. - */ - uint32_t ulBlockCount; + * is the global block size. + */ + uint32_t ulBlockCount; /** The total number of allocable blocks; Also the maximum count of free - blocks. - */ - uint32_t ulBlocksAllocable; + * blocks. + */ + uint32_t ulBlocksAllocable; /** The maximum number of bytes that an inode is capable of addressing. - */ - uint64_t ullMaxInodeSize; + */ + uint64_t ullMaxInodeSize; /** The current metadata sequence number. This value is included in all - metadata nodes and incremented every time a metadata node is written. - It is assumed to never wrap around. - */ - uint64_t ullSequence; + * metadata nodes and incremented every time a metadata node is written. + * It is assumed to never wrap around. + */ + uint64_t ullSequence; } VOLUME; /* Array of VOLUME structures, populated at during RedCoreInit(). -*/ -extern VOLUME gaRedVolume[REDCONF_VOLUME_COUNT]; + */ +extern VOLUME gaRedVolume[ REDCONF_VOLUME_COUNT ]; /* Volume number currently being accessed; populated during - RedCoreVolSetCurrent(). -*/ + * RedCoreVolSetCurrent(). + */ extern CONST_IF_ONE_VOLUME uint8_t gbRedVolNum; /* Pointer to the volume currently being accessed; populated during - RedCoreVolSetCurrent(). -*/ + * RedCoreVolSetCurrent(). + */ extern VOLUME * CONST_IF_ONE_VOLUME gpRedVolume; -#endif - +#endif /* ifndef REDVOLUME_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/include/redosdeviations.h b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/include/redosdeviations.h index cfde3a708..aeb68ff8c 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/include/redosdeviations.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/include/redosdeviations.h @@ -1,244 +1,249 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Macros to encapsulate MISRA C:2012 deviations in OS-specific code. -*/ + * @brief Macros to encapsulate MISRA C:2012 deviations in OS-specific code. + */ #ifndef REDOSDEVIATIONS_H #define REDOSDEVIATIONS_H #if REDCONF_OUTPUT == 1 + /* Needed for PRINT_ASSERT() and OUTPUT_CHARACTER(). -*/ -#include + */ + #include #endif -#if (REDCONF_ASSERTS == 1) && (REDCONF_OUTPUT == 1) +#if ( REDCONF_ASSERTS == 1 ) && ( REDCONF_OUTPUT == 1 ) + /** Print a formatted message for an assertion. - - Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). Using - printf() is the most convenient way to output this information; and the risk - of "unspecified, undefined and implementation-defined" behavior causing - problems (as cited in the rationale for the rule) is small. The driver does - not depend on this string being outputted correctly. Furthermore, use of - printf() disappears when either asserts or output are disabled. - - As Rule 21.6 is required, a separate deviation record is required. -*/ -#define PRINT_ASSERT(file, line) \ - printf("Assertion failed in \"%s\" at line %u\n\r", ((file) == NULL) ? "" : (file), (unsigned)(line)) + * + * Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). Using + * printf() is the most convenient way to output this information; and the risk + * of "unspecified, undefined and implementation-defined" behavior causing + * problems (as cited in the rationale for the rule) is small. The driver does + * not depend on this string being outputted correctly. Furthermore, use of + * printf() disappears when either asserts or output are disabled. + * + * As Rule 21.6 is required, a separate deviation record is required. + */ + #define PRINT_ASSERT( file, line ) \ + printf( "Assertion failed in \"%s\" at line %u\n\r", ( ( file ) == NULL ) ? "" : ( file ), ( unsigned ) ( line ) ) #endif /** Cast a value to unsigned long. - - Usages of this macro deviate from MISRA C:2012 Directive 4.6. This macro is - used in two places to cast a uint64_t value (used by the block device - abstraction for sector numbers) to unsigned long, since third-party code - which is not under the control of this project uses unsigned long for sector - numbers. The cast is guaranteed to not lose any information, since when the - disk is opened the sector count is verified to be less than or equal to an - unsigned long value. The text of the directive mentions that "it might be - desirable not to apply this guideline when interfacing with ... code outside - the project's control", which describes the situation for this deviation. - - As Directive 4.6 is advisory, a deviation record is not required. This - notice is the only record of the deviation. -*/ -#define CAST_ULONG(ull) ((unsigned long)(ull)) + * + * Usages of this macro deviate from MISRA C:2012 Directive 4.6. This macro is + * used in two places to cast a uint64_t value (used by the block device + * abstraction for sector numbers) to unsigned long, since third-party code + * which is not under the control of this project uses unsigned long for sector + * numbers. The cast is guaranteed to not lose any information, since when the + * disk is opened the sector count is verified to be less than or equal to an + * unsigned long value. The text of the directive mentions that "it might be + * desirable not to apply this guideline when interfacing with ... code outside + * the project's control", which describes the situation for this deviation. + * + * As Directive 4.6 is advisory, a deviation record is not required. This + * notice is the only record of the deviation. + */ +#define CAST_ULONG( ull ) ( ( unsigned long ) ( ull ) ) /** Cast a const-qualified pointer to a pointer which is *not* const-qualified. - - Usages of this macro deviate from MISRA C:2012 Rule 11.8. This macro is - used in exactly one place in order to cope with a poorly designed - third-party interface. Reliance Edge, at every level of the stack, uses - const-qualified pointers for buffers used in write operations, since the - data is read from the buffer, and the buffer does not need to be modified - (consistent with Rule 8.13). One of the third-party block device interfaces - that Reliance Edge interfaces with does not follow this convention: it uses - an unqualified pointer for the buffer parameter of its sector write - function. This forces the need for the cast to avoid warnings. The - implementation of the sector write function is provided by the user, so it - is to be hoped that the buffer is not actually modified. - - As Rule 11.8 is required, a separate deviation record is required. -*/ -#define CAST_AWAY_CONST(type, ptr) ((type *)(ptr)) + * + * Usages of this macro deviate from MISRA C:2012 Rule 11.8. This macro is + * used in exactly one place in order to cope with a poorly designed + * third-party interface. Reliance Edge, at every level of the stack, uses + * const-qualified pointers for buffers used in write operations, since the + * data is read from the buffer, and the buffer does not need to be modified + * (consistent with Rule 8.13). One of the third-party block device interfaces + * that Reliance Edge interfaces with does not follow this convention: it uses + * an unqualified pointer for the buffer parameter of its sector write + * function. This forces the need for the cast to avoid warnings. The + * implementation of the sector write function is provided by the user, so it + * is to be hoped that the buffer is not actually modified. + * + * As Rule 11.8 is required, a separate deviation record is required. + */ +#define CAST_AWAY_CONST( type, ptr ) ( ( type * ) ( ptr ) ) /** Allocate zero-initialized (cleared) memory. - - All usages of this macro deviate from MISRA C:2012 Directive 4.12 (required) - and Rule 21.3 (required). In the context of the single place it is actually - used, this macro also deviates from Rule 22.1 (required). - - This macro is used in the FreeRTOS block device code in order to allocate a - RAM disk, when that implementation of the block device is selected. The - primary rationale for all these deviations is that a) the RAM disk cannot be - allocated statically (since the volume information is stored in a - structure), and b) the RAM disk is primarily intended as a temporary testing - tool for users who want to try out Reliance Edge before the real storage - media is available. In most real systems, Reliance Edge is used with - non-volatile storage like SD/MMC or eMMC, not with RAM disks. - - Rule 22.1 states that all resources which are allocated must also be - explicitly freed. The RAM disk is allocated and never freed, deviating from - that rule. This is done because the data in the RAM disk is emulating a - non-volatile storage medium, and thus needs to persist even after the block - device is closed, to allow the file system to be ormatted and then mounted, - or unmounted and remounted in the course of a test. Thus the memory will - remain allocated until the target device is rebooted. This is assumed to be - acceptable for the primary purpose of the RAM disk, which is preliminary - testing. - - As Directive 4.12, Rule 21.3, and Rule 22.1 are all required, separate - deviation records are required. -*/ -#define ALLOCATE_CLEARED_MEMORY(nelem, elsize) calloc(nelem, elsize) + * + * All usages of this macro deviate from MISRA C:2012 Directive 4.12 (required) + * and Rule 21.3 (required). In the context of the single place it is actually + * used, this macro also deviates from Rule 22.1 (required). + * + * This macro is used in the FreeRTOS block device code in order to allocate a + * RAM disk, when that implementation of the block device is selected. The + * primary rationale for all these deviations is that a) the RAM disk cannot be + * allocated statically (since the volume information is stored in a + * structure), and b) the RAM disk is primarily intended as a temporary testing + * tool for users who want to try out Reliance Edge before the real storage + * media is available. In most real systems, Reliance Edge is used with + * non-volatile storage like SD/MMC or eMMC, not with RAM disks. + * + * Rule 22.1 states that all resources which are allocated must also be + * explicitly freed. The RAM disk is allocated and never freed, deviating from + * that rule. This is done because the data in the RAM disk is emulating a + * non-volatile storage medium, and thus needs to persist even after the block + * device is closed, to allow the file system to be formatted and then mounted, + * or unmounted and remounted in the course of a test. Thus the memory will + * remain allocated until the target device is rebooted. This is assumed to be + * acceptable for the primary purpose of the RAM disk, which is preliminary + * testing. + * + * As Directive 4.12, Rule 21.3, and Rule 22.1 are all required, separate + * deviation records are required. + */ +#define ALLOCATE_CLEARED_MEMORY( nelem, elsize ) calloc( nelem, elsize ) #if REDCONF_OUTPUT == 1 + /** Output a character to a serial port or other display device. - - Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). - FreeRTOS does not include a standard method of printing characters, so - putchar() is the most convenient and portable way to accomplish the task. - The risk of "unspecified, undefined and implementation-defined" behavior - causing problems (as cited in the rationale for the rule) is small. The - driver does not depend on the character being outputted correctly. - Furthermore, use of putchar() disappears when output is disabled. - - As Rule 21.6 is required, a separate deviation record is required. -*/ -#define OUTPUT_CHARACTER(ch) (void)putchar(ch) + * + * Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). + * FreeRTOS does not include a standard method of printing characters, so + * putchar() is the most convenient and portable way to accomplish the task. + * The risk of "unspecified, undefined and implementation-defined" behavior + * causing problems (as cited in the rationale for the rule) is small. The + * driver does not depend on the character being outputted correctly. + * Furthermore, use of putchar() disappears when output is disabled. + * + * As Rule 21.6 is required, a separate deviation record is required. + */ + #define OUTPUT_CHARACTER( ch ) ( void ) putchar( ch ) #endif -#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1) +#if ( REDCONF_TASK_COUNT > 1U ) && ( REDCONF_API_POSIX == 1 ) + /** Cast a TaskHandle_t (a pointer type) to uintptr_t. - - Usage of this macro deivate from MISRA-C:2012 Rule 11.4 (advisory). This - macro is used for the FreeRTOS version of RedOsTaskId(). Some RTOSes - natively use an integer for task IDs; others use pointers. RedOsTaskId() - uses integers, FreeRTOS uses pointers; to reconcile this difference, the - pointer must be cast to integer. This is fairly safe, since the resulting - integer is never cast back to a pointer; and although the integer - representation of a pointer is implementation-defined, the representation is - irrelevant provided that unique pointers are converted to unique integers. - - As Rule 11.4 is advisory, a deviation record is not required. This notice - is the only record of the deviation. -*/ -#define CAST_TASK_PTR_TO_UINTPTR(taskptr) ((uintptr_t)(taskptr)) + * + * Usage of this macro deviate from MISRA-C:2012 Rule 11.4 (advisory). This + * macro is used for the FreeRTOS version of RedOsTaskId(). Some RTOSes + * natively use an integer for task IDs; others use pointers. RedOsTaskId() + * uses integers, FreeRTOS uses pointers; to reconcile this difference, the + * pointer must be cast to integer. This is fairly safe, since the resulting + * integer is never cast back to a pointer; and although the integer + * representation of a pointer is implementation-defined, the representation is + * irrelevant provided that unique pointers are converted to unique integers. + * + * As Rule 11.4 is advisory, a deviation record is not required. This notice + * is the only record of the deviation. + */ + #define CAST_TASK_PTR_TO_UINTPTR( taskptr ) ( ( uintptr_t ) ( taskptr ) ) #endif /** Ignore the return value of a function (cast to void) - - Usages of this macro deviate from MISRA C:2012 Directive 4.7, which states - that error information must be checked immediately after a function returns - potential error information. - - If asserts and output are enabled, then this macro is used to document that - the return value of printf() is ignored. A failure of printf() does not - impact the filesystem core, nor is there anything the filesystem can do to - respond to such an error (especially since it occurs within an assert). - Thus, the most reasonable action is to ignore the error. - - In the STM32 SDIO block device implementation, errors are also ignored in an - IRQ interrupt handler. This is the most reasonable action to take for two - reasons: (a) it would be dangerous to spend processor time responding to the - error inside the IRQ handler; (b) it has been verified that the same error - is propegated to the DiskRead/Write method, which does return the error to - the core. - - In the Atmel SD/MMC block device implementation, error information from - sd_mmc_read_capacity() is ignored. This is a reasonable action because all - of the possible error conditions were eliminated by a previous check. - sd_mmc_read_capacity() fails under the same conditions as - sd_mmc_test_unit_ready(), which was checked ealier in the same function. - - In the mutex module, error information returned from the mutex release - function is ignored when asserts are disabled. This is a reasonable action - because the mutex release function (xSemaphoreGive) is documented only to - fail if the mutex was not obtained correctly, which can be demonstrably - avoided. - - As Directive 4.7 is required, a separate deviation record is required. -*/ -#define IGNORE_ERRORS(fn) ((void) (fn)) + * + * Usages of this macro deviate from MISRA C:2012 Directive 4.7, which states + * that error information must be checked immediately after a function returns + * potential error information. + * + * If asserts and output are enabled, then this macro is used to document that + * the return value of printf() is ignored. A failure of printf() does not + * impact the filesystem core, nor is there anything the filesystem can do to + * respond to such an error (especially since it occurs within an assert). + * Thus, the most reasonable action is to ignore the error. + * + * In the STM32 SDIO block device implementation, errors are also ignored in an + * IRQ interrupt handler. This is the most reasonable action to take for two + * reasons: (a) it would be dangerous to spend processor time responding to the + * error inside the IRQ handler; (b) it has been verified that the same error + * is propagated to the DiskRead/Write method, which does return the error to + * the core. + * + * In the Atmel SD/MMC block device implementation, error information from + * sd_mmc_read_capacity() is ignored. This is a reasonable action because all + * of the possible error conditions were eliminated by a previous check. + * sd_mmc_read_capacity() fails under the same conditions as + * sd_mmc_test_unit_ready(), which was checked earlier in the same function. + * + * In the mutex module, error information returned from the mutex release + * function is ignored when asserts are disabled. This is a reasonable action + * because the mutex release function (xSemaphoreGive) is documented only to + * fail if the mutex was not obtained correctly, which can be demonstrably + * avoided. + * + * As Directive 4.7 is required, a separate deviation record is required. + */ +#define IGNORE_ERRORS( fn ) ( ( void ) ( fn ) ) /** @brief Determine whether a pointer is aligned on a 32-bit boundary. - - This is used to determine whether a data buffer meets the requirements of - the underlying block device implementation. When transferring data via - DMA (Direct Memory Access) on an STM32 device, the data buffer must be cast - as a uint32 pointer, and unexpected behavior may occur if the buffer is not - aligned correctly. - - There is no way to perform this check without deviating from MISRA C rules - against casting pointers to integer types. Usage of this macro deviates - from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites - against converting pointers to integers is that the chosen integer type may - not be able to represent the pointer; this is a non-issue here since we use - uintptr_t. The text says the rule still applies when using uintptr_t due to - concern about unaligned pointers, but that is not an issue here since the - integer value of the pointer is not saved and not converted back into a - pointer and dereferenced. The result of casting a pointer to a sufficiently - large integer is implementation-defined, but macros similar to this one have - been used by Datalight for a long time in a wide variety of environments and - they have always worked as expected. - - This deviation only occurs when using the STM32 SDIO block device - implementation. - - As Rule 11.4 is advisory, a deviation record is not required. This notice - is the only record of deviation. -*/ -#define IS_UINT32_ALIGNED_PTR(ptr) (((uintptr_t)(ptr) & (sizeof(uint32_t) - 1U)) == 0U) + * + * This is used to determine whether a data buffer meets the requirements of + * the underlying block device implementation. When transferring data via + * DMA (Direct Memory Access) on an STM32 device, the data buffer must be cast + * as a uint32 pointer, and unexpected behavior may occur if the buffer is not + * aligned correctly. + * + * There is no way to perform this check without deviating from MISRA C rules + * against casting pointers to integer types. Usage of this macro deviates + * from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites + * against converting pointers to integers is that the chosen integer type may + * not be able to represent the pointer; this is a non-issue here since we use + * uintptr_t. The text says the rule still applies when using uintptr_t due to + * concern about unaligned pointers, but that is not an issue here since the + * integer value of the pointer is not saved and not converted back into a + * pointer and dereferenced. The result of casting a pointer to a sufficiently + * large integer is implementation-defined, but macros similar to this one have + * been used by Datalight for a long time in a wide variety of environments and + * they have always worked as expected. + * + * This deviation only occurs when using the STM32 SDIO block device + * implementation. + * + * As Rule 11.4 is advisory, a deviation record is not required. This notice + * is the only record of deviation. + */ +#define IS_UINT32_ALIGNED_PTR( ptr ) ( ( ( uintptr_t ) ( ptr ) & ( sizeof( uint32_t ) - 1U ) ) == 0U ) /** @brief Cast a 32-bit aligned void pointer to a uint32 pointer. - - Usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). A - cast from a void pointer to an object pointer is discouraged because of - potential alignment issues. However, this macro is only used to cast - pointers that have already been tested to be 32-bit aligned, so the - operation will be safe. - - This deviation only occurs when using the STM32 SDIO block device - implementation. - - As rule 11.5 is advisory, a deviation record is not required. This notice - is the only record of the deviation. -*/ -#define CAST_UINT32_PTR(ptr) ((uint32_t *) (ptr)) + * + * Usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). A + * cast from a void pointer to an object pointer is discouraged because of + * potential alignment issues. However, this macro is only used to cast + * pointers that have already been tested to be 32-bit aligned, so the + * operation will be safe. + * + * This deviation only occurs when using the STM32 SDIO block device + * implementation. + * + * As rule 11.5 is advisory, a deviation record is not required. This notice + * is the only record of the deviation. + */ +#define CAST_UINT32_PTR( ptr ) ( ( uint32_t * ) ( ptr ) ) -#endif - +#endif /* ifndef REDOSDEVIATIONS_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/include/redostypes.h b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/include/redostypes.h index cf0494adf..27e8d8381 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/include/redostypes.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/include/redostypes.h @@ -1,42 +1,43 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Defines OS-specific types for use in common code. -*/ -#ifndef REDOSTYPES_H -#define REDOSTYPES_H - - -/** @brief Implementation-defined timestamp type. - - This can be an integer, a structure, or a pointer: anything that is - convenient for the implementation. Since the underlying type is not fixed, - common code should treat this as an opaque type. -*/ -typedef uint32_t REDTIMESTAMP; - - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Defines OS-specific types for use in common code. + */ +#ifndef REDOSTYPES_H +#define REDOSTYPES_H + + +/** @brief Implementation-defined timestamp type. + * + * This can be an integer, a structure, or a pointer: anything that is + * convenient for the implementation. Since the underlying type is not fixed, + * common code should treat this as an opaque type. + */ +typedef uint32_t REDTIMESTAMP; + + +#endif diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osassert.c b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osassert.c index 9822caf5c..0a86575f7 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osassert.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osassert.c @@ -1,56 +1,56 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Implements assertion handling. -*/ + * @brief Implements assertion handling. + */ #include #if REDCONF_ASSERTS == 1 -#include + #include /** @brief Invoke the native assertion handler. - - @param pszFileName Null-terminated string containing the name of the file - where the assertion fired. - @param ulLineNum Line number in @p pszFileName where the assertion - fired. -*/ -void RedOsAssertFail( - const char *pszFileName, - uint32_t ulLineNum) -{ - #if REDCONF_OUTPUT == 1 - IGNORE_ERRORS(PRINT_ASSERT(pszFileName, ulLineNum)); - #endif - - while(true) + * + * @param pszFileName Null-terminated string containing the name of the file + * where the assertion fired. + * @param ulLineNum Line number in @p pszFileName where the assertion + * fired. + */ + void RedOsAssertFail( const char * pszFileName, + uint32_t ulLineNum ) { + #if REDCONF_OUTPUT == 1 + IGNORE_ERRORS( PRINT_ASSERT( pszFileName, ulLineNum ) ); + #endif + + while( true ) + { + } } -} - -#endif +#endif /* if REDCONF_ASSERTS == 1 */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osbdev.c b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osbdev.c index bb4208763..6cc5017a3 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osbdev.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osbdev.c @@ -1,30 +1,32 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Implements block device I/O. -*/ + * @brief Implements block device I/O. + */ #include #include @@ -33,130 +35,136 @@ /*------------------------------------------------------------------------------ - Porting Note: - - Several example implementations of this module for FreeRTOS are available. - If you are lucky, you can use one of these implementations; otherwise, these - can serve as examples of how to implement this service. -------------------------------------------------------------------------------*/ + * Porting Note: + * + * Several example implementations of this module for FreeRTOS are available. + * If you are lucky, you can use one of these implementations; otherwise, these + * can serve as examples of how to implement this service. + * ------------------------------------------------------------------------------*/ /** @brief The F_DRIVER example implementation. - - This implementation is designed to reuse an existing block device driver - that was written for FreeRTOS+FAT SL. If you have such a driver, with - little work it can be "dropped in" and used for Reliance Edge. The only - customization required is that gpfnRedOsBDevInit needs to be defined and - pointed at the F_DRIVERINIT function. This can be done in this module or in - another C file. - - The disadantage of using the FreeRTOS F_DRIVER functions is that they only - support single-sector reads and writes. Reliance Edge will issue - multi-sector requests, and servicing these one sector at a time will - significantly slow down the file system. -*/ -#define BDEV_F_DRIVER (0U) + * + * This implementation is designed to reuse an existing block device driver + * that was written for FreeRTOS+FAT SL. If you have such a driver, with + * little work it can be "dropped in" and used for Reliance Edge. The only + * customization required is that gpfnRedOsBDevInit needs to be defined and + * pointed at the F_DRIVERINIT function. This can be done in this module or in + * another C file. + * + * The disadvantage of using the FreeRTOS F_DRIVER functions is that they only + * support single-sector reads and writes. Reliance Edge will issue + * multi-sector requests, and servicing these one sector at a time will + * significantly slow down the file system. + */ +#define BDEV_F_DRIVER ( 0U ) /** @brief The FatFs example implementation. - - This implementation is designed to reuse an existing block device driver - that was written for FatFs. If you have such a driver, it can be linked - in and used immediately. The FatFs `diskio.h` header must be in the include - directory path. -*/ -#define BDEV_FATFS (1U) + * + * This implementation is designed to reuse an existing block device driver + * that was written for FatFs. If you have such a driver, it can be linked + * in and used immediately. The FatFs `diskio.h` header must be in the include + * directory path. + */ +#define BDEV_FATFS ( 1U ) /** @brief The Atmel Studio Framework SD/MMC driver example implementation. - - This implementation uses a modified version of the open source SD/MMC driver - included in the Atmel Studio Framework (ASF) and will work as-is for many - varieties of Atmel hardware. This example assumes relatively minor - modifications to the ASF SD/MMC driver to make it support multi-sector read - and write requests, which greatly improves performance. The modified driver - is distributed with Reliance Edge and is included in FreeRTOS Atmel projects - (such as in projects/freertos/atmel/sam4e-ek/src/ASF). - - This example can easily be modified to work with an unmodified version of - the ASF SD/MMC driver. Simply replace sd_mmc_mem_2_ram_multi() and - sd_mmc_ram_2_mem_multi() with sd_mmc_mem_2_ram() and sd_mmc_ram_2_mem() - respectively, and add a for loop to loop over each sector in the request. - However, as described in the manual, there are considerable performance - advantages to issuing real multi-sector requests, so using the modified - driver is recommended. -*/ -#define BDEV_ATMEL_SDMMC (2U) + * + * This implementation uses a modified version of the open source SD/MMC driver + * included in the Atmel Studio Framework (ASF) and will work as-is for many + * varieties of Atmel hardware. This example assumes relatively minor + * modifications to the ASF SD/MMC driver to make it support multi-sector read + * and write requests, which greatly improves performance. The modified driver + * is distributed with Reliance Edge and is included in FreeRTOS Atmel projects + * (such as in projects/freertos/atmel/sam4e-ek/src/ASF). + * + * This example can easily be modified to work with an unmodified version of + * the ASF SD/MMC driver. Simply replace sd_mmc_mem_2_ram_multi() and + * sd_mmc_ram_2_mem_multi() with sd_mmc_mem_2_ram() and sd_mmc_ram_2_mem() + * respectively, and add a for loop to loop over each sector in the request. + * However, as described in the manual, there are considerable performance + * advantages to issuing real multi-sector requests, so using the modified + * driver is recommended. + */ +#define BDEV_ATMEL_SDMMC ( 2U ) /** @brief The ST Microelectronics STM32 SDIO driver example implementation. - - This implementation accesses the microSD card through the BSP utilities - provided as part of the STM32Cube package, used with the STM32 HAL drivers. - The STM3240G-EVAL and STM32F746NG-Discovery boards are currently supported. -*/ -#define BDEV_STM32_SDIO (3U) + * + * This implementation accesses the microSD card through the BSP utilities + * provided as part of the STM32Cube package, used with the STM32 HAL drivers. + * The STM3240G-EVAL and STM32F746NG-Discovery boards are currently supported. + */ +#define BDEV_STM32_SDIO ( 3U ) /** @brief The RAM disk example implementation. - - This implementation uses a RAM disk. It will allow you to compile and test - Reliance Edge even if your storage driver is not yet ready. On typical - target hardware, the amount of spare RAM will be limited so generally only - very small disks will be available. -*/ -#define BDEV_RAM_DISK (4U) + * + * This implementation uses a RAM disk. It will allow you to compile and test + * Reliance Edge even if your storage driver is not yet ready. On typical + * target hardware, the amount of spare RAM will be limited so generally only + * very small disks will be available. + */ +#define BDEV_RAM_DISK ( 4U ) /** @brief Pick which example implementation is compiled. - - Must be one of: - - #BDEV_F_DRIVER - - #BDEV_FATFS - - #BDEV_ATMEL_SDMMC - - #BDEV_STM32_SDIO - - #BDEV_RAM_DISK -*/ -#define BDEV_EXAMPLE_IMPLEMENTATION BDEV_RAM_DISK + * + * Must be one of: + * - #BDEV_F_DRIVER + * - #BDEV_FATFS + * - #BDEV_ATMEL_SDMMC + * - #BDEV_STM32_SDIO + * - #BDEV_RAM_DISK + */ +#define BDEV_EXAMPLE_IMPLEMENTATION BDEV_RAM_DISK -static REDSTATUS DiskOpen(uint8_t bVolNum, BDEVOPENMODE mode); -static REDSTATUS DiskClose(uint8_t bVolNum); -static REDSTATUS DiskRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer); +static REDSTATUS DiskOpen( uint8_t bVolNum, + BDEVOPENMODE mode ); +static REDSTATUS DiskClose( uint8_t bVolNum ); +static REDSTATUS DiskRead( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void * pBuffer ); #if REDCONF_READ_ONLY == 0 -static REDSTATUS DiskWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer); -static REDSTATUS DiskFlush(uint8_t bVolNum); + static REDSTATUS DiskWrite( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void * pBuffer ); + static REDSTATUS DiskFlush( uint8_t bVolNum ); #endif /** @brief Initialize a block device. - - This function is called when the file system needs access to a block - device. - - Upon successful return, the block device should be fully initialized and - ready to service read/write/flush/close requests. - - The behavior of calling this function on a block device which is already - open is undefined. - - @param bVolNum The volume number of the volume whose block device is being - initialized. - @param mode The open mode, indicating the type of access required. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedOsBDevOpen( - uint8_t bVolNum, - BDEVOPENMODE mode) + * + * This function is called when the file system needs access to a block + * device. + * + * Upon successful return, the block device should be fully initialized and + * ready to service read/write/flush/close requests. + * + * The behavior of calling this function on a block device which is already + * open is undefined. + * + * @param bVolNum The volume number of the volume whose block device is being + * initialized. + * @param mode The open mode, indicating the type of access required. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number. + * @retval -RED_EIO A disk I/O error occurred. + */ +REDSTATUS RedOsBDevOpen( uint8_t bVolNum, + BDEVOPENMODE mode ) { - REDSTATUS ret; + REDSTATUS ret; - if(bVolNum >= REDCONF_VOLUME_COUNT) + if( bVolNum >= REDCONF_VOLUME_COUNT ) { ret = -RED_EINVAL; } else { - ret = DiskOpen(bVolNum, mode); + ret = DiskOpen( bVolNum, mode ); } return ret; @@ -164,37 +172,36 @@ REDSTATUS RedOsBDevOpen( /** @brief Uninitialize a block device. - - This function is called when the file system no longer needs access to a - block device. If any resource were allocated by RedOsBDevOpen() to service - block device requests, they should be freed at this time. - - Upon successful return, the block device must be in such a state that it - can be opened again. - - The behavior of calling this function on a block device which is already - closed is undefined. - - @param bVolNum The volume number of the volume whose block device is being - uninitialized. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number. -*/ -REDSTATUS RedOsBDevClose( - uint8_t bVolNum) + * + * This function is called when the file system no longer needs access to a + * block device. If any resource were allocated by RedOsBDevOpen() to service + * block device requests, they should be freed at this time. + * + * Upon successful return, the block device must be in such a state that it + * can be opened again. + * + * The behavior of calling this function on a block device which is already + * closed is undefined. + * + * @param bVolNum The volume number of the volume whose block device is being + * uninitialized. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number. + */ +REDSTATUS RedOsBDevClose( uint8_t bVolNum ) { - REDSTATUS ret; + REDSTATUS ret; - if(bVolNum >= REDCONF_VOLUME_COUNT) + if( bVolNum >= REDCONF_VOLUME_COUNT ) { ret = -RED_EINVAL; } else { - ret = DiskClose(bVolNum); + ret = DiskClose( bVolNum ); } return ret; @@ -202,42 +209,41 @@ REDSTATUS RedOsBDevClose( /** @brief Read sectors from a physical block device. - - The behavior of calling this function is undefined if the block device is - closed or if it was opened with ::BDEV_O_WRONLY. - - @param bVolNum The volume number of the volume whose block device - is being read from. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to read. - @param pBuffer The buffer into which to read the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is - `NULL`, or @p ullStartSector and/or @p ulSectorCount - refer to an invalid range of sectors. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedOsBDevRead( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - void *pBuffer) + * + * The behavior of calling this function is undefined if the block device is + * closed or if it was opened with ::BDEV_O_WRONLY. + * + * @param bVolNum The volume number of the volume whose block device + * is being read from. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to read. + * @param pBuffer The buffer into which to read the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is + * `NULL`, or @p ullStartSector and/or @p ulSectorCount + * refer to an invalid range of sectors. + * @retval -RED_EIO A disk I/O error occurred. + */ +REDSTATUS RedOsBDevRead( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void * pBuffer ) { - REDSTATUS ret = 0; + REDSTATUS ret = 0; - if( (bVolNum >= REDCONF_VOLUME_COUNT) - || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) - || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) - || (pBuffer == NULL)) + if( ( bVolNum >= REDCONF_VOLUME_COUNT ) || + ( ullSectorStart >= gaRedVolConf[ bVolNum ].ullSectorCount ) || + ( ( gaRedVolConf[ bVolNum ].ullSectorCount - ullSectorStart ) < ulSectorCount ) || + ( pBuffer == NULL ) ) { ret = -RED_EINVAL; } else { - ret = DiskRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + ret = DiskRead( bVolNum, ullSectorStart, ulSectorCount, pBuffer ); } return ret; @@ -245,412 +251,418 @@ REDSTATUS RedOsBDevRead( #if REDCONF_READ_ONLY == 0 + /** @brief Write sectors to a physical block device. - - The behavior of calling this function is undefined if the block device is - closed or if it was opened with ::BDEV_O_RDONLY. - - @param bVolNum The volume number of the volume whose block device - is being written to. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to write. - @param pBuffer The buffer from which to write the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is - `NULL`, or @p ullStartSector and/or @p ulSectorCount - refer to an invalid range of sectors. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedOsBDevWrite( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - const void *pBuffer) -{ - REDSTATUS ret = 0; - - if( (bVolNum >= REDCONF_VOLUME_COUNT) - || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) - || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) - || (pBuffer == NULL)) + * + * The behavior of calling this function is undefined if the block device is + * closed or if it was opened with ::BDEV_O_RDONLY. + * + * @param bVolNum The volume number of the volume whose block device + * is being written to. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to write. + * @param pBuffer The buffer from which to write the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is + * `NULL`, or @p ullStartSector and/or @p ulSectorCount + * refer to an invalid range of sectors. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedOsBDevWrite( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void * pBuffer ) { - ret = -RED_EINVAL; - } - else - { - ret = DiskWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer); - } + REDSTATUS ret = 0; - return ret; -} + if( ( bVolNum >= REDCONF_VOLUME_COUNT ) || + ( ullSectorStart >= gaRedVolConf[ bVolNum ].ullSectorCount ) || + ( ( gaRedVolConf[ bVolNum ].ullSectorCount - ullSectorStart ) < ulSectorCount ) || + ( pBuffer == NULL ) ) + { + ret = -RED_EINVAL; + } + else + { + ret = DiskWrite( bVolNum, ullSectorStart, ulSectorCount, pBuffer ); + } + + return ret; + } /** @brief Flush any caches beneath the file system. - - This function must synchronously flush all software and hardware caches - beneath the file system, ensuring that all sectors written previously are - committed to permanent storage. - - If the environment has no caching beneath the file system, the - implementation of this function can do nothing and return success. - - The behavior of calling this function is undefined if the block device is - closed or if it was opened with ::BDEV_O_RDONLY. - - @param bVolNum The volume number of the volume whose block device is being - flushed. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p bVolNum is an invalid volume number. - @retval -RED_EIO A disk I/O error occurred. -*/ -REDSTATUS RedOsBDevFlush( - uint8_t bVolNum) -{ - REDSTATUS ret; - - if(bVolNum >= REDCONF_VOLUME_COUNT) + * + * This function must synchronously flush all software and hardware caches + * beneath the file system, ensuring that all sectors written previously are + * committed to permanent storage. + * + * If the environment has no caching beneath the file system, the + * implementation of this function can do nothing and return success. + * + * The behavior of calling this function is undefined if the block device is + * closed or if it was opened with ::BDEV_O_RDONLY. + * + * @param bVolNum The volume number of the volume whose block device is being + * flushed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p bVolNum is an invalid volume number. + * @retval -RED_EIO A disk I/O error occurred. + */ + REDSTATUS RedOsBDevFlush( uint8_t bVolNum ) { - ret = -RED_EINVAL; - } - else - { - ret = DiskFlush(bVolNum); - } + REDSTATUS ret; - return ret; -} + if( bVolNum >= REDCONF_VOLUME_COUNT ) + { + ret = -RED_EINVAL; + } + else + { + ret = DiskFlush( bVolNum ); + } + + return ret; + } #endif /* REDCONF_READ_ONLY == 0 */ #if BDEV_EXAMPLE_IMPLEMENTATION == BDEV_F_DRIVER -#include + #include /* This must be declared and initialized elsewere (e.g., in project code) to - point at the initialization function for the F_DRIVER block device. -*/ -extern const F_DRIVERINIT gpfnRedOsBDevInit; + * point at the initialization function for the F_DRIVER block device. + */ + extern const F_DRIVERINIT gpfnRedOsBDevInit; -static F_DRIVER *gapFDriver[REDCONF_VOLUME_COUNT]; + static F_DRIVER * gapFDriver[ REDCONF_VOLUME_COUNT ]; /** @brief Initialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - initialized. - @param mode The open mode, indicating the type of access required. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS DiskOpen( - uint8_t bVolNum, - BDEVOPENMODE mode) -{ - REDSTATUS ret; - - (void)mode; - - if((gpfnRedOsBDevInit == NULL) || (gapFDriver[bVolNum] != NULL)) + * + * @param bVolNum The volume number of the volume whose block device is being + * initialized. + * @param mode The open mode, indicating the type of access required. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS DiskOpen( uint8_t bVolNum, + BDEVOPENMODE mode ) { - ret = -RED_EINVAL; - } - else - { - F_DRIVER *pDriver; + REDSTATUS ret; - pDriver = gpfnRedOsBDevInit(bVolNum); - if(pDriver != NULL) + ( void ) mode; + + if( ( gpfnRedOsBDevInit == NULL ) || ( gapFDriver[ bVolNum ] != NULL ) ) { - F_PHY geom; - int iErr; + ret = -RED_EINVAL; + } + else + { + F_DRIVER * pDriver; - /* Validate that the geometry is consistent with the volume - configuration. - */ - iErr = pDriver->getphy(pDriver, &geom); - if(iErr == 0) + pDriver = gpfnRedOsBDevInit( bVolNum ); + + if( pDriver != NULL ) { - if( (geom.bytes_per_sector != gaRedVolConf[bVolNum].ulSectorSize) - || (geom.number_of_sectors < gaRedVolConf[bVolNum].ullSectorCount)) + F_PHY geom; + int iErr; + + /* Validate that the geometry is consistent with the volume + * configuration. + */ + iErr = pDriver->getphy( pDriver, &geom ); + + if( iErr == 0 ) { - ret = -RED_EINVAL; + if( ( geom.bytes_per_sector != gaRedVolConf[ bVolNum ].ulSectorSize ) || + ( geom.number_of_sectors < gaRedVolConf[ bVolNum ].ullSectorCount ) ) + { + ret = -RED_EINVAL; + } + else + { + gapFDriver[ bVolNum ] = pDriver; + ret = 0; + } } else { - gapFDriver[bVolNum] = pDriver; - ret = 0; + ret = -RED_EIO; + } + + if( ret != 0 ) + { + pDriver->release( pDriver ); } } else { ret = -RED_EIO; } + } - if(ret != 0) - { - pDriver->release(pDriver); - } - } - else - { - ret = -RED_EIO; - } + return ret; } - return ret; -} - /** @brief Uninitialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - uninitialized. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskClose( - uint8_t bVolNum) -{ - REDSTATUS ret; - - if(gapFDriver[bVolNum] == NULL) + * + * @param bVolNum The volume number of the volume whose block device is being + * uninitialized. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskClose( uint8_t bVolNum ) { - ret = -RED_EINVAL; - } - else - { - gapFDriver[bVolNum]->release(gapFDriver[bVolNum]); - gapFDriver[bVolNum] = NULL; + REDSTATUS ret; - ret = 0; - } + if( gapFDriver[ bVolNum ] == NULL ) + { + ret = -RED_EINVAL; + } + else + { + gapFDriver[ bVolNum ]->release( gapFDriver[ bVolNum ] ); + gapFDriver[ bVolNum ] = NULL; - return ret; -} + ret = 0; + } + + return ret; + } /** @brief Read sectors from a disk. - - @param bVolNum The volume number of the volume whose block device - is being read from. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to read. - @param pBuffer The buffer into which to read the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS DiskRead( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - void *pBuffer) -{ - REDSTATUS ret = 0; - F_DRIVER *pDriver = gapFDriver[bVolNum]; - - if(pDriver == NULL) + * + * @param bVolNum The volume number of the volume whose block device + * is being read from. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to read. + * @param pBuffer The buffer into which to read the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS DiskRead( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void * pBuffer ) { - ret = -RED_EINVAL; - } - else - { - uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer); - uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; - uint32_t ulSectorIdx; - int iErr; + REDSTATUS ret = 0; + F_DRIVER * pDriver = gapFDriver[ bVolNum ]; - for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++) + if( pDriver == NULL ) { - iErr = pDriver->readsector(pDriver, &pbBuffer[ulSectorIdx * ulSectorSize], - CAST_ULONG(ullSectorStart + ulSectorIdx)); - if(iErr != 0) + ret = -RED_EINVAL; + } + else + { + uint8_t * pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR( pBuffer ); + uint32_t ulSectorSize = gaRedVolConf[ bVolNum ].ulSectorSize; + uint32_t ulSectorIdx; + int iErr; + + for( ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++ ) { - ret = -RED_EIO; - break; + iErr = pDriver->readsector( pDriver, &pbBuffer[ ulSectorIdx * ulSectorSize ], + CAST_ULONG( ullSectorStart + ulSectorIdx ) ); + + if( iErr != 0 ) + { + ret = -RED_EIO; + break; + } } } + + return ret; } - return ret; -} + #if REDCONF_READ_ONLY == 0 -#if REDCONF_READ_ONLY == 0 /** @brief Write sectors to a disk. - - @param bVolNum The volume number of the volume whose block device - is being written to. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to write. - @param pBuffer The buffer from which to write the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL The block device is not open. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS DiskWrite( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - const void *pBuffer) -{ - REDSTATUS ret = 0; - F_DRIVER *pDriver = gapFDriver[bVolNum]; - - if(pDriver == NULL) - { - ret = -RED_EINVAL; - } - else - { - const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); - uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; - uint32_t ulSectorIdx; - int iErr; - - for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++) + * + * @param bVolNum The volume number of the volume whose block device + * is being written to. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to write. + * @param pBuffer The buffer from which to write the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL The block device is not open. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS DiskWrite( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void * pBuffer ) { - /* We have to cast pbBuffer to non-const since the writesector - prototype is flawed, using a non-const pointer for the buffer. - */ - iErr = pDriver->writesector(pDriver, CAST_AWAY_CONST(uint8_t, &pbBuffer[ulSectorIdx * ulSectorSize]), - CAST_ULONG(ullSectorStart + ulSectorIdx)); - if(iErr != 0) - { - ret = -RED_EIO; - break; - } - } - } + REDSTATUS ret = 0; + F_DRIVER * pDriver = gapFDriver[ bVolNum ]; - return ret; -} + if( pDriver == NULL ) + { + ret = -RED_EINVAL; + } + else + { + const uint8_t * pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pBuffer ); + uint32_t ulSectorSize = gaRedVolConf[ bVolNum ].ulSectorSize; + uint32_t ulSectorIdx; + int iErr; + + for( ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++ ) + { + /* We have to cast pbBuffer to non-const since the writesector + * prototype is flawed, using a non-const pointer for the buffer. + */ + iErr = pDriver->writesector( pDriver, CAST_AWAY_CONST( uint8_t, &pbBuffer[ ulSectorIdx * ulSectorSize ] ), + CAST_ULONG( ullSectorStart + ulSectorIdx ) ); + + if( iErr != 0 ) + { + ret = -RED_EIO; + break; + } + } + } + + return ret; + } /** @brief Flush any caches beneath the file system. + * + * @param bVolNum The volume number of the volume whose block device is being + * flushed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskFlush( uint8_t bVolNum ) + { + REDSTATUS ret; - @param bVolNum The volume number of the volume whose block device is being - flushed. + if( gapFDriver[ bVolNum ] == NULL ) + { + ret = -RED_EINVAL; + } + else + { + /* The F_DRIVER interface does not include a flush function, so to be + * reliable the F_DRIVER implementation must use synchronous writes. + */ + ret = 0; + } - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskFlush( - uint8_t bVolNum) -{ - REDSTATUS ret; - - if(gapFDriver[bVolNum] == NULL) - { - ret = -RED_EINVAL; - } - else - { - /* The F_DRIVER interface does not include a flush function, so to be - reliable the F_DRIVER implementation must use synchronous writes. - */ - ret = 0; - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ + return ret; + } + #endif /* REDCONF_READ_ONLY == 0 */ #elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_FATFS -#include -#include + #include + #include /* disk_read() and disk_write() use an unsigned 8-bit value to specify the - sector count, so no transfer can be larger than 255 sectors. -*/ -#define MAX_SECTOR_TRANSFER UINT8_MAX + * sector count, so no transfer can be larger than 255 sectors. + */ + #define MAX_SECTOR_TRANSFER UINT8_MAX /** @brief Initialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - initialized. - @param mode The open mode, indicating the type of access required. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS DiskOpen( - uint8_t bVolNum, - BDEVOPENMODE mode) -{ - DSTATUS status; - uint32_t ulTries; - REDSTATUS ret = 0; - - /* With some implementations of disk_initialize(), such as the one - implemented by Atmel for the ASF, the first time the disk is opened, the - SD card can take a while to get ready, in which time disk_initialize() - returns an error. Try numerous times, waiting half a second after each - failure. Empirically, this has been observed to succeed on the second - try, so trying 10x more than that provides a margin of error. - */ - for(ulTries = 0U; ulTries < 20U; ulTries++) + * + * @param bVolNum The volume number of the volume whose block device is being + * initialized. + * @param mode The open mode, indicating the type of access required. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS DiskOpen( uint8_t bVolNum, + BDEVOPENMODE mode ) { - /* Assuming that the volume number is also the correct drive number. - If this is not the case in your environment, a static constant array - can be declared to map volume numbers to the correct driver number. - */ - status = disk_initialize(bVolNum); - if(status == 0) + DSTATUS status; + uint32_t ulTries; + REDSTATUS ret = 0; + + /* With some implementations of disk_initialize(), such as the one + * implemented by Atmel for the ASF, the first time the disk is opened, the + * SD card can take a while to get ready, in which time disk_initialize() + * returns an error. Try numerous times, waiting half a second after each + * failure. Empirically, this has been observed to succeed on the second + * try, so trying 10x more than that provides a margin of error. + */ + for( ulTries = 0U; ulTries < 20U; ulTries++ ) { - break; + /* Assuming that the volume number is also the correct drive number. + * If this is not the case in your environment, a static constant array + * can be declared to map volume numbers to the correct driver number. + */ + status = disk_initialize( bVolNum ); + + if( status == 0 ) + { + break; + } + + vTaskDelay( 500U / portTICK_PERIOD_MS ); } - vTaskDelay(500U / portTICK_PERIOD_MS); - } - - if(status != 0) - { - ret = -RED_EIO; - } - - /* Retrieve the sector size and sector count to ensure they are compatible - with our compile-time geometry. - */ - if(ret == 0) - { - WORD wSectorSize; - DWORD dwSectorCount; - DRESULT result; - - result = disk_ioctl(bVolNum, GET_SECTOR_SIZE, &wSectorSize); - if(result == RES_OK) + if( status != 0 ) { - result = disk_ioctl(bVolNum, GET_SECTOR_COUNT, &dwSectorCount); - if(result == RES_OK) + ret = -RED_EIO; + } + + /* Retrieve the sector size and sector count to ensure they are compatible + * with our compile-time geometry. + */ + if( ret == 0 ) + { + WORD wSectorSize; + DWORD dwSectorCount; + DRESULT result; + + result = disk_ioctl( bVolNum, GET_SECTOR_SIZE, &wSectorSize ); + + if( result == RES_OK ) { - if( (wSectorSize != gaRedVolConf[bVolNum].ulSectorSize) - || (dwSectorCount < gaRedVolConf[bVolNum].ullSectorCount)) + result = disk_ioctl( bVolNum, GET_SECTOR_COUNT, &dwSectorCount ); + + if( result == RES_OK ) { - ret = -RED_EINVAL; + if( ( wSectorSize != gaRedVolConf[ bVolNum ].ulSectorSize ) || + ( dwSectorCount < gaRedVolConf[ bVolNum ].ullSectorCount ) ) + { + ret = -RED_EINVAL; + } + } + else + { + ret = -RED_EIO; } } else @@ -658,896 +670,889 @@ static REDSTATUS DiskOpen( ret = -RED_EIO; } } - else - { - ret = -RED_EIO; - } - } - return ret; -} + return ret; + } /** @brief Uninitialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - uninitialized. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskClose( - uint8_t bVolNum) -{ - (void)bVolNum; - return 0; -} + * + * @param bVolNum The volume number of the volume whose block device is being + * uninitialized. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskClose( uint8_t bVolNum ) + { + ( void ) bVolNum; + return 0; + } /** @brief Read sectors from a disk. - - @param bVolNum The volume number of the volume whose block device - is being read from. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to read. - @param pBuffer The buffer into which to read the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS DiskRead( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - void *pBuffer) -{ - REDSTATUS ret = 0; - uint32_t ulSectorIdx = 0U; - uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; - uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer); - - while(ulSectorIdx < ulSectorCount) + * + * @param bVolNum The volume number of the volume whose block device + * is being read from. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to read. + * @param pBuffer The buffer into which to read the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS DiskRead( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void * pBuffer ) { - uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER); - DRESULT result; + REDSTATUS ret = 0; + uint32_t ulSectorIdx = 0U; + uint32_t ulSectorSize = gaRedVolConf[ bVolNum ].ulSectorSize; + uint8_t * pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR( pBuffer ); - result = disk_read(bVolNum, &pbBuffer[ulSectorIdx * ulSectorSize], (DWORD)(ullSectorStart + ulSectorIdx), (BYTE)ulTransfer); - if(result != RES_OK) + while( ulSectorIdx < ulSectorCount ) { - ret = -RED_EIO; - break; + uint32_t ulTransfer = REDMIN( ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER ); + DRESULT result; + + result = disk_read( bVolNum, &pbBuffer[ ulSectorIdx * ulSectorSize ], ( DWORD ) ( ullSectorStart + ulSectorIdx ), ( BYTE ) ulTransfer ); + + if( result != RES_OK ) + { + ret = -RED_EIO; + break; + } + + ulSectorIdx += ulTransfer; } - ulSectorIdx += ulTransfer; + return ret; } - return ret; -} + #if REDCONF_READ_ONLY == 0 -#if REDCONF_READ_ONLY == 0 /** @brief Write sectors to a disk. - - @param bVolNum The volume number of the volume whose block device - is being written to. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to write. - @param pBuffer The buffer from which to write the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS DiskWrite( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - const void *pBuffer) -{ - REDSTATUS ret = 0; - uint32_t ulSectorIdx = 0U; - uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; - const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); - - while(ulSectorIdx < ulSectorCount) - { - uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER); - DRESULT result; - - result = disk_write(bVolNum, &pbBuffer[ulSectorIdx * ulSectorSize], (DWORD)(ullSectorStart + ulSectorIdx), (BYTE)ulTransfer); - if(result != RES_OK) + * + * @param bVolNum The volume number of the volume whose block device + * is being written to. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to write. + * @param pBuffer The buffer from which to write the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS DiskWrite( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void * pBuffer ) { - ret = -RED_EIO; - break; + REDSTATUS ret = 0; + uint32_t ulSectorIdx = 0U; + uint32_t ulSectorSize = gaRedVolConf[ bVolNum ].ulSectorSize; + const uint8_t * pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pBuffer ); + + while( ulSectorIdx < ulSectorCount ) + { + uint32_t ulTransfer = REDMIN( ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER ); + DRESULT result; + + result = disk_write( bVolNum, &pbBuffer[ ulSectorIdx * ulSectorSize ], ( DWORD ) ( ullSectorStart + ulSectorIdx ), ( BYTE ) ulTransfer ); + + if( result != RES_OK ) + { + ret = -RED_EIO; + break; + } + + ulSectorIdx += ulTransfer; + } + + return ret; } - ulSectorIdx += ulTransfer; - } - - return ret; -} - /** @brief Flush any caches beneath the file system. + * + * @param bVolNum The volume number of the volume whose block device is being + * flushed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskFlush( uint8_t bVolNum ) + { + REDSTATUS ret; + DRESULT result; - @param bVolNum The volume number of the volume whose block device is being - flushed. + result = disk_ioctl( bVolNum, CTRL_SYNC, NULL ); - @return A negated ::REDSTATUS code indicating the operation result. + if( result == RES_OK ) + { + ret = 0; + } + else + { + ret = -RED_EIO; + } - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskFlush( - uint8_t bVolNum) -{ - REDSTATUS ret; - DRESULT result; - - result = disk_ioctl(bVolNum, CTRL_SYNC, NULL); - if(result == RES_OK) - { - ret = 0; - } - else - { - ret = -RED_EIO; - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ + return ret; + } + #endif /* REDCONF_READ_ONLY == 0 */ #elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_ATMEL_SDMMC -#include + #include -#include -#include -#include -#include + #include + #include + #include + #include /* sd_mmc_mem_2_ram_multi() and sd_mmc_ram_2_mem_multi() use an unsigned - 16-bit value to specify the sector count, so no transfer can be larger - than UINT16_MAX sectors. -*/ -#define MAX_SECTOR_TRANSFER UINT16_MAX + * 16-bit value to specify the sector count, so no transfer can be larger + * than UINT16_MAX sectors. + */ + #define MAX_SECTOR_TRANSFER UINT16_MAX /** @brief Initialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - initialized. - @param mode The open mode, indicating the type of access required. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EROFS The device is read-only media and write access was - requested. -*/ -static REDSTATUS DiskOpen( - uint8_t bVolNum, - BDEVOPENMODE mode) -{ - REDSTATUS ret = 0; - uint32_t ulTries; - Ctrl_status cs; - - /* Note: Assuming the volume number is the same as the SD card slot. The - ASF SD/MMC driver supports two SD slots. This implementation will need - to be modified if multiple volumes share a single SD card. - */ - - /* The first time the disk is opened, the SD card can take a while to get - ready, in which time sd_mmc_test_unit_ready() returns either CTRL_BUSY - or CTRL_NO_PRESENT. Try numerous times, waiting half a second after - each failure. Empirically, this has been observed to succeed on the - second try, so trying 10x more than that provides a margin of error. - */ - for(ulTries = 0U; ulTries < 20U; ulTries++) + * + * @param bVolNum The volume number of the volume whose block device is being + * initialized. + * @param mode The open mode, indicating the type of access required. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EROFS The device is read-only media and write access was + * requested. + */ + static REDSTATUS DiskOpen( uint8_t bVolNum, + BDEVOPENMODE mode ) { - cs = sd_mmc_test_unit_ready(bVolNum); - if((cs != CTRL_NO_PRESENT) && (cs != CTRL_BUSY)) + REDSTATUS ret = 0; + uint32_t ulTries; + Ctrl_status cs; + + /* Note: Assuming the volume number is the same as the SD card slot. The + * ASF SD/MMC driver supports two SD slots. This implementation will need + * to be modified if multiple volumes share a single SD card. + */ + + /* The first time the disk is opened, the SD card can take a while to get + * ready, in which time sd_mmc_test_unit_ready() returns either CTRL_BUSY + * or CTRL_NO_PRESENT. Try numerous times, waiting half a second after + * each failure. Empirically, this has been observed to succeed on the + * second try, so trying 10x more than that provides a margin of error. + */ + for( ulTries = 0U; ulTries < 20U; ulTries++ ) { - break; + cs = sd_mmc_test_unit_ready( bVolNum ); + + if( ( cs != CTRL_NO_PRESENT ) && ( cs != CTRL_BUSY ) ) + { + break; + } + + vTaskDelay( 500U / portTICK_PERIOD_MS ); } - vTaskDelay(500U / portTICK_PERIOD_MS); + if( cs == CTRL_GOOD ) + { + #if REDCONF_READ_ONLY == 0 + if( mode != BDEV_O_RDONLY ) + { + if( sd_mmc_wr_protect( bVolNum ) ) + { + ret = -RED_EROFS; + } + } + + if( ret == 0 ) + #endif + { + uint32_t ulSectorLast; + + IGNORE_ERRORS( sd_mmc_read_capacity( bVolNum, &ulSectorLast ) ); + + /* The ASF SD/MMC driver only supports 512-byte sectors. + */ + if( ( gaRedVolConf[ bVolNum ].ulSectorSize != 512U ) || + ( ( ( uint64_t ) ulSectorLast + 1U ) < gaRedVolConf[ bVolNum ].ullSectorCount ) ) + { + ret = -RED_EINVAL; + } + } + } + else + { + ret = -RED_EIO; + } + + return ret; } - if(cs == CTRL_GOOD) + +/** @brief Uninitialize a disk. + * + * @param bVolNum The volume number of the volume whose block device is being + * uninitialized. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskClose( uint8_t bVolNum ) { - #if REDCONF_READ_ONLY == 0 - if(mode != BDEV_O_RDONLY) + ( void ) bVolNum; + return 0; + } + + +/** @brief Read sectors from a disk. + * + * @param bVolNum The volume number of the volume whose block device + * is being read from. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to read. + * @param pBuffer The buffer into which to read the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskRead( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void * pBuffer ) + { + REDSTATUS ret = 0; + uint32_t ulSectorIdx = 0U; + uint32_t ulSectorSize = gaRedVolConf[ bVolNum ].ulSectorSize; + uint8_t * pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR( pBuffer ); + + while( ulSectorIdx < ulSectorCount ) { - if(sd_mmc_wr_protect(bVolNum)) + uint32_t ulTransfer = REDMIN( ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER ); + Ctrl_status cs; + + cs = sd_mmc_mem_2_ram_multi( bVolNum, ( uint32_t ) ( ullSectorStart + ulSectorIdx ), + ( uint16_t ) ulTransfer, &pbBuffer[ ulSectorIdx * ulSectorSize ] ); + + if( cs != CTRL_GOOD ) { - ret = -RED_EROFS; + ret = -RED_EIO; + break; + } + + ulSectorIdx += ulTransfer; + } + + return ret; + } + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Write sectors to a disk. + * + * @param bVolNum The volume number of the volume whose block device + * is being written to. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to write. + * @param pBuffer The buffer from which to write the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskWrite( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void * pBuffer ) + { + REDSTATUS ret = 0; + uint32_t ulSectorIdx = 0U; + uint32_t ulSectorSize = gaRedVolConf[ bVolNum ].ulSectorSize; + const uint8_t * pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pBuffer ); + + while( ulSectorIdx < ulSectorCount ) + { + uint32_t ulTransfer = REDMIN( ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER ); + Ctrl_status cs; + + cs = sd_mmc_ram_2_mem_multi( bVolNum, ( uint32_t ) ( ullSectorStart + ulSectorIdx ), + ( uint16_t ) ulTransfer, &pbBuffer[ ulSectorIdx * ulSectorSize ] ); + + if( cs != CTRL_GOOD ) + { + ret = -RED_EIO; + break; + } + + ulSectorIdx += ulTransfer; + } + + return ret; + } + + +/** @brief Flush any caches beneath the file system. + * + * @param bVolNum The volume number of the volume whose block device is being + * flushed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskFlush( uint8_t bVolNum ) + { + REDSTATUS ret; + Ctrl_status cs; + + /* The ASF SD/MMC driver appears to write sectors synchronously, so it + * should be fine to do nothing and return success. However, Atmel's + * implementation of the FatFs diskio.c file does the equivalent of the + * below when the disk is flushed. Just in case this is important for some + * non-obvious reason, do the same. + */ + cs = sd_mmc_test_unit_ready( bVolNum ); + + if( cs == CTRL_GOOD ) + { + ret = 0; + } + else + { + ret = -RED_EIO; + } + + return ret; + } + #endif /* REDCONF_READ_ONLY == 0 */ + +#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_STM32_SDIO + + #ifdef USE_STM324xG_EVAL + #include + #include + #elif defined( USE_STM32746G_DISCO ) + #include + #include + #else + +/* If you are using a compatible STM32 device other than the two listed above + * and you have SD card driver headers, you can try adding them to the above + * list. + */ + #error "Unsupported device." + #endif + + #if REDCONF_VOLUME_COUNT > 1 + #error "The STM32 SDIO block device implementation does not support multiple volumes." + #endif + + + #ifndef USE_HAL_DRIVER + #error "The STM32 StdPeriph driver is not supported. Please use the HAL driver or modify the Reliance Edge block device interface." + #endif + + +/** @brief Number of times to call BSP_SD_GetStatus() before timing out and + * returning an error. + * + * See ::CheckStatus(). + * + * NOTE: Datalight has not observed a scenario where BSP_SD_GetStatus() + * returns SD_TRANSFER_BUSY after a transfer command returns successfully. + * Set SD_STATUS_TIMEOUT to 0U to skip checking BSP_SD_GetStatus(). + */ + #define SD_STATUS_TIMEOUT ( 100000U ) + +/** @brief 4-byte aligned buffer to use for DMA transfers when passed in + * an unaligned buffer. + */ + static uint32_t gaulAlignedBuffer[ 512U / sizeof( uint32_t ) ]; + + + #if SD_STATUS_TIMEOUT > 0U + static REDSTATUS CheckStatus( void ); + #endif + + +/** @brief Initialize a disk. + * + * @param bVolNum The volume number of the volume whose block device is being + * initialized. + * @param mode The open mode, indicating the type of access required. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO No SD card was found; or BSP_SD_Init() failed. + * @retval -RED_EINVAL The SD card's block size is not the same as the + * configured sector size; or the SD card is not large + * enough for the volume; or the volume size is above + * 4GiB, meaning that part of it cannot be accessed + * through the STM32 SDIO driver. + */ + static REDSTATUS DiskOpen( uint8_t bVolNum, + BDEVOPENMODE mode ) + { + REDSTATUS ret = 0; + static bool fSdInitted = false; + + ( void ) mode; + + if( !fSdInitted ) + { + if( BSP_SD_Init() == MSD_OK ) + { + fSdInitted = true; } } - if(ret == 0) - #endif + if( !fSdInitted ) { - uint32_t ulSectorLast; + /* Above initialization attempt failed. + */ + ret = -RED_EIO; + } + else if( BSP_SD_IsDetected() == SD_NOT_PRESENT ) + { + ret = -RED_EIO; + } + else + { + uint32_t ulSectorSize = gaRedVolConf[ bVolNum ].ulSectorSize; + HAL_SD_CardInfoTypedef sdCardInfo = { { 0 } }; - IGNORE_ERRORS(sd_mmc_read_capacity(bVolNum, &ulSectorLast)); + BSP_SD_GetCardInfo( &sdCardInfo ); - /* The ASF SD/MMC driver only supports 512-byte sectors. - */ - if( (gaRedVolConf[bVolNum].ulSectorSize != 512U) - || (((uint64_t)ulSectorLast + 1U) < gaRedVolConf[bVolNum].ullSectorCount)) + /* Note: the actual card block size is sdCardInfo.CardBlockSize, + * but the interface only supports a 512 byte block size. Further, + * one card has been observed to report a 1024-byte block size, + * but it worked fine with a 512-byte Reliance Edge ulSectorSize. + */ + if( ( ulSectorSize != 512U ) || + ( sdCardInfo.CardCapacity < ( gaRedVolConf[ bVolNum ].ullSectorCount * ulSectorSize ) ) ) { ret = -RED_EINVAL; } } - } - else - { - ret = -RED_EIO; - } - return ret; -} + return ret; + } /** @brief Uninitialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - uninitialized. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskClose( - uint8_t bVolNum) -{ - (void)bVolNum; - return 0; -} + * + * @param bVolNum The volume number of the volume whose block device is being + * uninitialized. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskClose( uint8_t bVolNum ) + { + ( void ) bVolNum; + return 0; + } /** @brief Read sectors from a disk. - - @param bVolNum The volume number of the volume whose block device - is being read from. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to read. - @param pBuffer The buffer into which to read the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskRead( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - void *pBuffer) -{ - REDSTATUS ret = 0; - uint32_t ulSectorIdx = 0U; - uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; - uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer); - - while(ulSectorIdx < ulSectorCount) + * + * @param bVolNum The volume number of the volume whose block device + * is being read from. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to read. + * @param pBuffer The buffer into which to read the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS DiskRead( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void * pBuffer ) { - uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER); - Ctrl_status cs; + REDSTATUS redStat = 0; + uint32_t ulSectorSize = gaRedVolConf[ bVolNum ].ulSectorSize; + uint8_t bSdError; - cs = sd_mmc_mem_2_ram_multi(bVolNum, (uint32_t)(ullSectorStart + ulSectorIdx), - (uint16_t)ulTransfer, &pbBuffer[ulSectorIdx * ulSectorSize]); - if(cs != CTRL_GOOD) + if( IS_UINT32_ALIGNED_PTR( pBuffer ) ) { - ret = -RED_EIO; - break; - } + bSdError = BSP_SD_ReadBlocks_DMA( CAST_UINT32_PTR( pBuffer ), ullSectorStart * ulSectorSize, ulSectorSize, ulSectorCount ); - ulSectorIdx += ulTransfer; - } - - return ret; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Write sectors to a disk. - - @param bVolNum The volume number of the volume whose block device - is being written to. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to write. - @param pBuffer The buffer from which to write the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskWrite( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - const void *pBuffer) -{ - REDSTATUS ret = 0; - uint32_t ulSectorIdx = 0U; - uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; - const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); - - while(ulSectorIdx < ulSectorCount) - { - uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER); - Ctrl_status cs; - - cs = sd_mmc_ram_2_mem_multi(bVolNum, (uint32_t)(ullSectorStart + ulSectorIdx), - (uint16_t)ulTransfer, &pbBuffer[ulSectorIdx * ulSectorSize]); - if(cs != CTRL_GOOD) - { - ret = -RED_EIO; - break; - } - - ulSectorIdx += ulTransfer; - } - - return ret; -} - - -/** @brief Flush any caches beneath the file system. - - @param bVolNum The volume number of the volume whose block device is being - flushed. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskFlush( - uint8_t bVolNum) -{ - REDSTATUS ret; - Ctrl_status cs; - - /* The ASF SD/MMC driver appears to write sectors synchronously, so it - should be fine to do nothing and return success. However, Atmel's - implementation of the FatFs diskio.c file does the equivalent of the - below when the disk is flushed. Just in case this is important for some - non-obvious reason, do the same. - */ - cs = sd_mmc_test_unit_ready(bVolNum); - if(cs == CTRL_GOOD) - { - ret = 0; - } - else - { - ret = -RED_EIO; - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ - -#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_STM32_SDIO - -#ifdef USE_STM324xG_EVAL - #include - #include -#elif defined(USE_STM32746G_DISCO) - #include - #include -#else - /* If you are using a compatible STM32 device other than the two listed above - and you have SD card driver headers, you can try adding them to the above - list. - */ - #error "Unsupported device." -#endif - -#if REDCONF_VOLUME_COUNT > 1 - #error "The STM32 SDIO block device implementation does not support multiple volumes." -#endif - - -#ifndef USE_HAL_DRIVER - #error "The STM32 StdPeriph driver is not supported. Please use the HAL driver or modify the Reliance Edge block device interface." -#endif - - -/** @brief Number of times to call BSP_SD_GetStatus() before timing out and - returning an error. - - See ::CheckStatus(). - - NOTE: Datalight has not observed a scenario where BSP_SD_GetStatus() - returns SD_TRANSFER_BUSY after a transfer command returns successfully. - Set SD_STATUS_TIMEOUT to 0U to skip checking BSP_SD_GetStatus(). -*/ -#define SD_STATUS_TIMEOUT (100000U) - -/** @brief 4-byte aligned buffer to use for DMA transfers when passed in - an unaligned buffer. -*/ -static uint32_t gaulAlignedBuffer[512U / sizeof(uint32_t)]; - - -#if SD_STATUS_TIMEOUT > 0U -static REDSTATUS CheckStatus(void); -#endif - - -/** @brief Initialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - initialized. - @param mode The open mode, indicating the type of access required. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO No SD card was found; or BSP_SD_Init() failed. - @retval -RED_EINVAL The SD card's block size is not the same as the - configured sector size; or the SD card is not large - enough for the volume; or the volume size is above - 4GiB, meaning that part of it cannot be accessed - through the STM32 SDIO driver. -*/ -static REDSTATUS DiskOpen( - uint8_t bVolNum, - BDEVOPENMODE mode) -{ - REDSTATUS ret = 0; - static bool fSdInitted = false; - - (void) mode; - - if(!fSdInitted) - { - if(BSP_SD_Init() == MSD_OK) - { - fSdInitted = true; - } - } - - if(!fSdInitted) - { - /* Above initialization attempt failed. - */ - ret = -RED_EIO; - } - else if(BSP_SD_IsDetected() == SD_NOT_PRESENT) - { - ret = -RED_EIO; - } - else - { - uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; - HAL_SD_CardInfoTypedef sdCardInfo = {{0}}; - - BSP_SD_GetCardInfo(&sdCardInfo); - - /* Note: the actual card block size is sdCardInfo.CardBlockSize, - but the interface only supports a 512 byte block size. Further, - one card has been observed to report a 1024-byte block size, - but it worked fine with a 512-byte Reliance Edge ulSectorSize. - */ - if( (ulSectorSize != 512U) - || (sdCardInfo.CardCapacity < (gaRedVolConf[bVolNum].ullSectorCount * ulSectorSize))) - { - ret = -RED_EINVAL; - } - } - - return ret; -} - - -/** @brief Uninitialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - uninitialized. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskClose( - uint8_t bVolNum) -{ - (void)bVolNum; - return 0; -} - - -/** @brief Read sectors from a disk. - - @param bVolNum The volume number of the volume whose block device - is being read from. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to read. - @param pBuffer The buffer into which to read the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS DiskRead( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - void *pBuffer) -{ - REDSTATUS redStat = 0; - uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; - uint8_t bSdError; - - if(IS_UINT32_ALIGNED_PTR(pBuffer)) - { - bSdError = BSP_SD_ReadBlocks_DMA(CAST_UINT32_PTR(pBuffer), ullSectorStart * ulSectorSize, ulSectorSize, ulSectorCount); - - if(bSdError != MSD_OK) - { - redStat = -RED_EIO; - } - #if SD_STATUS_TIMEOUT > 0U - else - { - redStat = CheckStatus(); - } - #endif - } - else - { - uint32_t ulSectorIdx; - - for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++) - { - bSdError = BSP_SD_ReadBlocks_DMA(gaulAlignedBuffer, (ullSectorStart + ulSectorIdx) * ulSectorSize, ulSectorSize, 1U); - - if(bSdError != MSD_OK) + if( bSdError != MSD_OK ) { redStat = -RED_EIO; } - #if SD_STATUS_TIMEOUT > 0U - else - { - redStat = CheckStatus(); - } - #endif - if(redStat == 0) - { - uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer); - - RedMemCpy(&pbBuffer[ulSectorIdx * ulSectorSize], gaulAlignedBuffer, ulSectorSize); - } - else - { - break; - } + #if SD_STATUS_TIMEOUT > 0U + else + { + redStat = CheckStatus(); + } + #endif } - } - - return redStat; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Write sectors to a disk. - - @param bVolNum The volume number of the volume whose block device - is being written to. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to write. - @param pBuffer The buffer from which to write the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS DiskWrite( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - const void *pBuffer) -{ - REDSTATUS redStat = 0; - uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; - uint8_t bSdError; - - if(IS_UINT32_ALIGNED_PTR(pBuffer)) - { - bSdError = BSP_SD_WriteBlocks_DMA(CAST_UINT32_PTR(CAST_AWAY_CONST(void, pBuffer)), ullSectorStart * ulSectorSize, - ulSectorSize, ulSectorCount); - - if(bSdError != MSD_OK) - { - redStat = -RED_EIO; - } - #if SD_STATUS_TIMEOUT > 0U else { - redStat = CheckStatus(); - } - #endif - } - else - { - uint32_t ulSectorIdx; + uint32_t ulSectorIdx; - for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++) - { - const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); - - RedMemCpy(gaulAlignedBuffer, &pbBuffer[ulSectorIdx * ulSectorSize], ulSectorSize); - - bSdError = BSP_SD_WriteBlocks_DMA(gaulAlignedBuffer, (ullSectorStart + ulSectorIdx) * ulSectorSize, ulSectorSize, 1U); - - if(bSdError != MSD_OK) + for( ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++ ) { - redStat = -RED_EIO; + bSdError = BSP_SD_ReadBlocks_DMA( gaulAlignedBuffer, ( ullSectorStart + ulSectorIdx ) * ulSectorSize, ulSectorSize, 1U ); + + if( bSdError != MSD_OK ) + { + redStat = -RED_EIO; + } + + #if SD_STATUS_TIMEOUT > 0U + else + { + redStat = CheckStatus(); + } + #endif + + if( redStat == 0 ) + { + uint8_t * pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR( pBuffer ); + + RedMemCpy( &pbBuffer[ ulSectorIdx * ulSectorSize ], gaulAlignedBuffer, ulSectorSize ); + } + else + { + break; + } + } + } + + return redStat; + } + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Write sectors to a disk. + * + * @param bVolNum The volume number of the volume whose block device + * is being written to. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to write. + * @param pBuffer The buffer from which to write the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS DiskWrite( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void * pBuffer ) + { + REDSTATUS redStat = 0; + uint32_t ulSectorSize = gaRedVolConf[ bVolNum ].ulSectorSize; + uint8_t bSdError; + + if( IS_UINT32_ALIGNED_PTR( pBuffer ) ) + { + bSdError = BSP_SD_WriteBlocks_DMA( CAST_UINT32_PTR( CAST_AWAY_CONST( void, pBuffer ) ), ullSectorStart * ulSectorSize, + ulSectorSize, ulSectorCount ); + + if( bSdError != MSD_OK ) + { + redStat = -RED_EIO; + } + + #if SD_STATUS_TIMEOUT > 0U + else + { + redStat = CheckStatus(); + } + #endif } - #if SD_STATUS_TIMEOUT > 0U else { - redStat = CheckStatus(); - } - #endif + uint32_t ulSectorIdx; - if(redStat != 0) - { - break; + for( ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++ ) + { + const uint8_t * pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pBuffer ); + + RedMemCpy( gaulAlignedBuffer, &pbBuffer[ ulSectorIdx * ulSectorSize ], ulSectorSize ); + + bSdError = BSP_SD_WriteBlocks_DMA( gaulAlignedBuffer, ( ullSectorStart + ulSectorIdx ) * ulSectorSize, ulSectorSize, 1U ); + + if( bSdError != MSD_OK ) + { + redStat = -RED_EIO; + } + + #if SD_STATUS_TIMEOUT > 0U + else + { + redStat = CheckStatus(); + } + #endif + + if( redStat != 0 ) + { + break; + } + } } + + return redStat; } - } - - return redStat; -} /** @brief Flush any caches beneath the file system. - - @param bVolNum The volume number of the volume whose block device is being - flushed. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskFlush( - uint8_t bVolNum) -{ - /* Disk transfer is synchronous; nothing to flush. - */ - (void) bVolNum; - return 0; -} + * + * @param bVolNum The volume number of the volume whose block device is being + * flushed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskFlush( uint8_t bVolNum ) + { + /* Disk transfer is synchronous; nothing to flush. + */ + ( void ) bVolNum; + return 0; + } -#if SD_STATUS_TIMEOUT > 0U + #if SD_STATUS_TIMEOUT > 0U + /** @brief Wait until BSP_SD_GetStatus returns SD_TRANSFER_OK. + * + * This function calls BSP_SD_GetStatus repeatedly as long as it returns + * SD_TRANSFER_BUSY up to SD_STATUS_TIMEOUT times. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 SD_TRANSFER_OK was returned. + * @retval -RED_EIO SD_TRANSFER_ERROR received, or timed out waiting for + * SD_TRANSFER_OK. + */ + static REDSTATUS CheckStatus( void ) + { + REDSTATUS redStat = 0; + uint32_t ulTimeout = SD_STATUS_TIMEOUT; + HAL_SD_TransferStateTypedef transferState; - This function calls BSP_SD_GetStatus repeatedly as long as it returns - SD_TRANSFER_BUSY up to SD_STATUS_TIMEOUT times. + do + { + transferState = BSP_SD_GetStatus(); + ulTimeout--; + } while( ( transferState == SD_TRANSFER_BUSY ) && ( ulTimeout > 0U ) ); - @return A negated ::REDSTATUS code indicating the operation result. + if( transferState != SD_TRANSFER_OK ) + { + redStat = -RED_EIO; + } - @retval 0 SD_TRANSFER_OK was returned. - @retval -RED_EIO SD_TRANSFER_ERROR received, or timed out waiting for - SD_TRANSFER_OK. -*/ -static REDSTATUS CheckStatus(void) -{ - REDSTATUS redStat = 0; - uint32_t ulTimeout = SD_STATUS_TIMEOUT; - HAL_SD_TransferStateTypedef transferState; + return redStat; + } + #endif /* if SD_STATUS_TIMEOUT > 0U */ - do - { - transferState = BSP_SD_GetStatus(); - ulTimeout--; - } while((transferState == SD_TRANSFER_BUSY) && (ulTimeout > 0U)); - - if(transferState != SD_TRANSFER_OK) - { - redStat = -RED_EIO; - } - - return redStat; -} -#endif - -#endif /* REDCONF_READ_ONLY == 0 */ + #endif /* REDCONF_READ_ONLY == 0 */ #elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_RAM_DISK -#include /* For ALLOCATE_CLEARED_MEMORY(), which expands to calloc(). */ + #include /* For ALLOCATE_CLEARED_MEMORY(), which expands to calloc(). */ -static uint8_t *gapbRamDisk[REDCONF_VOLUME_COUNT]; + static uint8_t * gapbRamDisk[ REDCONF_VOLUME_COUNT ]; /** @brief Initialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - initialized. - @param mode The open mode, indicating the type of access required. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS DiskOpen( - uint8_t bVolNum, - BDEVOPENMODE mode) -{ - REDSTATUS ret = 0; - - (void)mode; - - if(gapbRamDisk[bVolNum] == NULL) + * + * @param bVolNum The volume number of the volume whose block device is being + * initialized. + * @param mode The open mode, indicating the type of access required. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS DiskOpen( uint8_t bVolNum, + BDEVOPENMODE mode ) { - gapbRamDisk[bVolNum] = ALLOCATE_CLEARED_MEMORY(gaRedVolume[bVolNum].ulBlockCount, REDCONF_BLOCK_SIZE); - if(gapbRamDisk[bVolNum] == NULL) - { - ret = -RED_EIO; - } - } + REDSTATUS ret = 0; - return ret; -} + ( void ) mode; + + if( gapbRamDisk[ bVolNum ] == NULL ) + { + gapbRamDisk[ bVolNum ] = ALLOCATE_CLEARED_MEMORY( gaRedVolume[ bVolNum ].ulBlockCount, REDCONF_BLOCK_SIZE ); + + if( gapbRamDisk[ bVolNum ] == NULL ) + { + ret = -RED_EIO; + } + } + + return ret; + } /** @brief Uninitialize a disk. - - @param bVolNum The volume number of the volume whose block device is being - uninitialized. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskClose( - uint8_t bVolNum) -{ - REDSTATUS ret; - - if(gapbRamDisk[bVolNum] == NULL) + * + * @param bVolNum The volume number of the volume whose block device is being + * uninitialized. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskClose( uint8_t bVolNum ) { - ret = -RED_EINVAL; - } - else - { - /* This implementation uses dynamically allocated memory, but must - retain previously written data after the block device is closed, and - thus the memory cannot be freed and will remain allocated until - reboot. - */ - ret = 0; - } + REDSTATUS ret; - return ret; -} + if( gapbRamDisk[ bVolNum ] == NULL ) + { + ret = -RED_EINVAL; + } + else + { + /* This implementation uses dynamically allocated memory, but must + * retain previously written data after the block device is closed, and + * thus the memory cannot be freed and will remain allocated until + * reboot. + */ + ret = 0; + } + + return ret; + } /** @brief Read sectors from a disk. - - @param bVolNum The volume number of the volume whose block device - is being read from. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to read. - @param pBuffer The buffer into which to read the sector data. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskRead( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - void *pBuffer) -{ - REDSTATUS ret; - - if(gapbRamDisk[bVolNum] == NULL) + * + * @param bVolNum The volume number of the volume whose block device + * is being read from. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to read. + * @param pBuffer The buffer into which to read the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskRead( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void * pBuffer ) { - ret = -RED_EINVAL; - } - else - { - uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize; - uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize; + REDSTATUS ret; - RedMemCpy(pBuffer, &gapbRamDisk[bVolNum][ullByteOffset], ulByteCount); + if( gapbRamDisk[ bVolNum ] == NULL ) + { + ret = -RED_EINVAL; + } + else + { + uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[ bVolNum ].ulSectorSize; + uint32_t ulByteCount = ulSectorCount * gaRedVolConf[ bVolNum ].ulSectorSize; - ret = 0; + RedMemCpy( pBuffer, &gapbRamDisk[ bVolNum ][ ullByteOffset ], ulByteCount ); + + ret = 0; + } + + return ret; } - return ret; -} + #if REDCONF_READ_ONLY == 0 -#if REDCONF_READ_ONLY == 0 /** @brief Write sectors to a disk. + * + * @param bVolNum The volume number of the volume whose block device + * is being written to. + * @param ullSectorStart The starting sector number. + * @param ulSectorCount The number of sectors to write. + * @param pBuffer The buffer from which to write the sector data. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskWrite( uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void * pBuffer ) + { + REDSTATUS ret; - @param bVolNum The volume number of the volume whose block device - is being written to. - @param ullSectorStart The starting sector number. - @param ulSectorCount The number of sectors to write. - @param pBuffer The buffer from which to write the sector data. + if( gapbRamDisk[ bVolNum ] == NULL ) + { + ret = -RED_EINVAL; + } + else + { + uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[ bVolNum ].ulSectorSize; + uint32_t ulByteCount = ulSectorCount * gaRedVolConf[ bVolNum ].ulSectorSize; - @return A negated ::REDSTATUS code indicating the operation result. + RedMemCpy( &gapbRamDisk[ bVolNum ][ ullByteOffset ], pBuffer, ulByteCount ); - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskWrite( - uint8_t bVolNum, - uint64_t ullSectorStart, - uint32_t ulSectorCount, - const void *pBuffer) -{ - REDSTATUS ret; + ret = 0; + } - if(gapbRamDisk[bVolNum] == NULL) - { - ret = -RED_EINVAL; - } - else - { - uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize; - uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize; - - RedMemCpy(&gapbRamDisk[bVolNum][ullByteOffset], pBuffer, ulByteCount); - - ret = 0; - } - - return ret; -} + return ret; + } /** @brief Flush any caches beneath the file system. + * + * @param bVolNum The volume number of the volume whose block device is being + * flushed. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + static REDSTATUS DiskFlush( uint8_t bVolNum ) + { + REDSTATUS ret; - @param bVolNum The volume number of the volume whose block device is being - flushed. + if( gapbRamDisk[ bVolNum ] == NULL ) + { + ret = -RED_EINVAL; + } + else + { + ret = 0; + } - @return A negated ::REDSTATUS code indicating the operation result. + return ret; + } + #endif /* REDCONF_READ_ONLY == 0 */ - @retval 0 Operation was successful. -*/ -static REDSTATUS DiskFlush( - uint8_t bVolNum) -{ - REDSTATUS ret; +#else /* if BDEV_EXAMPLE_IMPLEMENTATION == BDEV_F_DRIVER */ - if(gapbRamDisk[bVolNum] == NULL) - { - ret = -RED_EINVAL; - } - else - { - ret = 0; - } - - return ret; -} -#endif /* REDCONF_READ_ONLY == 0 */ - -#else - -#error "Invalid BDEV_EXAMPLE_IMPLEMENTATION value" + #error "Invalid BDEV_EXAMPLE_IMPLEMENTATION value" #endif /* BDEV_EXAMPLE_IMPLEMENTATION == ... */ - diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osclock.c b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osclock.c index cf09d1717..d94cf688e 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osclock.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osclock.c @@ -1,79 +1,80 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements real-time clock functions. -*/ -#include - - -/** @brief Initialize the real time clock. - - The behavior of calling this function when the RTC is already initialized - is undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -REDSTATUS RedOsClockInit(void) -{ - return 0; -} - - -/** @brief Uninitialize the real time clock. - - The behavior of calling this function when the RTC is not initialized is - undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -REDSTATUS RedOsClockUninit(void) -{ - return 0; -} - - -/** @brief Get the date/time. - - The behavior of calling this function when the RTC is not initialized is - undefined. - - @return The number of seconds since January 1, 1970 excluding leap seconds - (in other words, standard Unix time). If the resolution or epoch - of the RTC is different than this, the implementation must convert - it to the expected representation. -*/ -uint32_t RedOsClockGetTime(void) -{ - /* FreeRTOS does not provide an RTC abstraction since most of the systems - it targets have no RTC hardware. If your hardware includes an RTC that - you would like to use, this function must be customized. - */ - return 0; -} - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements real-time clock functions. + */ +#include + + +/** @brief Initialize the real time clock. + * + * The behavior of calling this function when the RTC is already initialized + * is undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ +REDSTATUS RedOsClockInit( void ) +{ + return 0; +} + + +/** @brief Uninitialize the real time clock. + * + * The behavior of calling this function when the RTC is not initialized is + * undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ +REDSTATUS RedOsClockUninit( void ) +{ + return 0; +} + + +/** @brief Get the date/time. + * + * The behavior of calling this function when the RTC is not initialized is + * undefined. + * + * @return The number of seconds since January 1, 1970 excluding leap seconds + * (in other words, standard Unix time). If the resolution or epoch + * of the RTC is different than this, the implementation must convert + * it to the expected representation. + */ +uint32_t RedOsClockGetTime( void ) +{ + /* FreeRTOS does not provide an RTC abstraction since most of the systems + * it targets have no RTC hardware. If your hardware includes an RTC that + * you would like to use, this function must be customized. + */ + return 0; +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osmutex.c b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osmutex.c index 68cd0eda0..d24a0274b 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osmutex.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osmutex.c @@ -1,30 +1,32 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Implements a synchronization object to provide mutual exclusion. -*/ + * @brief Implements a synchronization object to provide mutual exclusion. + */ #include #include @@ -34,101 +36,100 @@ #if REDCONF_TASK_COUNT > 1U -static SemaphoreHandle_t xMutex; -#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1) -static StaticSemaphore_t xMutexBuffer; -#endif + static SemaphoreHandle_t xMutex; + #if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) + static StaticSemaphore_t xMutexBuffer; + #endif /** @brief Initialize the mutex. - - After initialization, the mutex is in the released state. - - The behavior of calling this function when the mutex is still initialized - is undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -REDSTATUS RedOsMutexInit(void) -{ - REDSTATUS ret = 0; - - #if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1) - xMutex = xSemaphoreCreateMutexStatic(&xMutexBuffer); - - if(xMutex == NULL) + * + * After initialization, the mutex is in the released state. + * + * The behavior of calling this function when the mutex is still initialized + * is undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + REDSTATUS RedOsMutexInit( void ) { - /* The only error case for xSemaphoreCreateMutexStatic is that the mutex - buffer parameter is NULL, which is not the case. - */ - REDERROR(); - ret = -RED_EINVAL; - } - - #else - xMutex = xSemaphoreCreateMutex(); - if(xMutex == NULL) - { - ret = -RED_ENOMEM; + REDSTATUS ret = 0; + + #if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) + xMutex = xSemaphoreCreateMutexStatic( &xMutexBuffer ); + + if( xMutex == NULL ) + { + /* The only error case for xSemaphoreCreateMutexStatic is that the mutex + * buffer parameter is NULL, which is not the case. + */ + REDERROR(); + ret = -RED_EINVAL; + } + #else + xMutex = xSemaphoreCreateMutex(); + + if( xMutex == NULL ) + { + ret = -RED_ENOMEM; + } + #endif /* if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + + return ret; } - #endif - - return ret; -} /** @brief Uninitialize the mutex. + * + * The behavior of calling this function when the mutex is not initialized is + * undefined; likewise, the behavior of uninitializing the mutex when it is + * in the acquired state is undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ + REDSTATUS RedOsMutexUninit( void ) + { + vSemaphoreDelete( xMutex ); + xMutex = NULL; - The behavior of calling this function when the mutex is not initialized is - undefined; likewise, the behavior of uninitializing the mutex when it is - in the acquired state is undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -REDSTATUS RedOsMutexUninit(void) -{ - vSemaphoreDelete(xMutex); - xMutex = NULL; - - return 0; -} + return 0; + } /** @brief Acquire the mutex. - - The behavior of calling this function when the mutex is not initialized is - undefined; likewise, the behavior of recursively acquiring the mutex is - undefined. -*/ -void RedOsMutexAcquire(void) -{ - while(xSemaphoreTake(xMutex, portMAX_DELAY) != pdTRUE) + * + * The behavior of calling this function when the mutex is not initialized is + * undefined; likewise, the behavior of recursively acquiring the mutex is + * undefined. + */ + void RedOsMutexAcquire( void ) { + while( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdTRUE ) + { + } } -} /** @brief Release the mutex. + * + * The behavior is undefined in the following cases: + * + * - Releasing the mutex when the mutex is not initialized. + * - Releasing the mutex when it is not in the acquired state. + * - Releasing the mutex from a task or thread other than the one which + * acquired the mutex. + */ + void RedOsMutexRelease( void ) + { + BaseType_t xSuccess; - The behavior is undefined in the following cases: - - - Releasing the mutex when the mutex is not initialized. - - Releasing the mutex when it is not in the acquired state. - - Releasing the mutex from a task or thread other than the one which - acquired the mutex. -*/ -void RedOsMutexRelease(void) -{ - BaseType_t xSuccess; - - xSuccess = xSemaphoreGive(xMutex); - REDASSERT(xSuccess == pdTRUE); - IGNORE_ERRORS(xSuccess); -} - -#endif + xSuccess = xSemaphoreGive( xMutex ); + REDASSERT( xSuccess == pdTRUE ); + IGNORE_ERRORS( xSuccess ); + } +#endif /* if REDCONF_TASK_COUNT > 1U */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osoutput.c b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osoutput.c index f4938903c..ddad36f12 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osoutput.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osoutput.c @@ -1,70 +1,70 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements outputting a character string. -*/ -#include - -#if REDCONF_OUTPUT == 1 - -#include - - -/** @brief Write a string to a user-visible output location. - - Write a null-terminated string to the serial port, console, terminal, or - other display device, such that the text is visible to the user. - - @param pszString A null-terminated string. -*/ -void RedOsOutputString( - const char *pszString) -{ - if(pszString == NULL) - { - REDERROR(); - } - else - { - uint32_t ulIdx = 0U; - - while(pszString[ulIdx] != '\0') - { - OUTPUT_CHARACTER(pszString[ulIdx]); - - /* Serial output often requires a \r to print newlines correctly. - */ - if(pszString[ulIdx] == '\n') - { - OUTPUT_CHARACTER('\r'); - } - - ulIdx++; - } - } -} - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements outputting a character string. + */ +#include + +#if REDCONF_OUTPUT == 1 + + #include + + +/** @brief Write a string to a user-visible output location. + * + * Write a null-terminated string to the serial port, console, terminal, or + * other display device, such that the text is visible to the user. + * + * @param pszString A null-terminated string. + */ + void RedOsOutputString( const char * pszString ) + { + if( pszString == NULL ) + { + REDERROR(); + } + else + { + uint32_t ulIdx = 0U; + + while( pszString[ ulIdx ] != '\0' ) + { + OUTPUT_CHARACTER( pszString[ ulIdx ] ); + + /* Serial output often requires a \r to print newlines correctly. + */ + if( pszString[ ulIdx ] == '\n' ) + { + OUTPUT_CHARACTER( '\r' ); + } + + ulIdx++; + } + } + } + +#endif /* if REDCONF_OUTPUT == 1 */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/ostask.c b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/ostask.c index 799c15228..a29fe9e86 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/ostask.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/ostask.c @@ -1,68 +1,69 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements task functions. -*/ -#include -#include - -#include - -#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1) - -#include - -#if INCLUDE_xTaskGetCurrentTaskHandle != 1 - #error "INCLUDE_xTaskGetCurrentTaskHandle must be 1 when REDCONF_TASK_COUNT > 1 and REDCONF_API_POSIX == 1" -#endif - - -/** @brief Get the current task ID. - - This task ID must be unique for all tasks using the file system. - - @return The task ID. Must not be 0. -*/ -uint32_t RedOsTaskId(void) -{ - /* Simply casting the xTaskGetCurrentTaskHandle() return value results in - warnings from some compilers, so use variables. - */ - TaskHandle_t xTask = xTaskGetCurrentTaskHandle(); - uintptr_t taskptr = CAST_TASK_PTR_TO_UINTPTR(xTask); - uint32_t ulTaskPtr = (uint32_t)taskptr; - - /* Assert no information was lost casting from uintptr_t to uint32_t. - */ - REDASSERT(ulTaskPtr == taskptr); - - /* NULL is a valid task handle in FreeRTOS, so add one to all task IDs. - */ - REDASSERT((ulTaskPtr + 1U) != 0U); - return ulTaskPtr + 1U; -} - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements task functions. + */ +#include +#include + +#include + +#if ( REDCONF_TASK_COUNT > 1U ) && ( REDCONF_API_POSIX == 1 ) + + #include + + #if INCLUDE_xTaskGetCurrentTaskHandle != 1 + #error "INCLUDE_xTaskGetCurrentTaskHandle must be 1 when REDCONF_TASK_COUNT > 1 and REDCONF_API_POSIX == 1" + #endif + + +/** @brief Get the current task ID. + * + * This task ID must be unique for all tasks using the file system. + * + * @return The task ID. Must not be 0. + */ + uint32_t RedOsTaskId( void ) + { + /* Simply casting the xTaskGetCurrentTaskHandle() return value results in + * warnings from some compilers, so use variables. + */ + TaskHandle_t xTask = xTaskGetCurrentTaskHandle(); + uintptr_t taskptr = CAST_TASK_PTR_TO_UINTPTR( xTask ); + uint32_t ulTaskPtr = ( uint32_t ) taskptr; + + /* Assert no information was lost casting from uintptr_t to uint32_t. + */ + REDASSERT( ulTaskPtr == taskptr ); + + /* NULL is a valid task handle in FreeRTOS, so add one to all task IDs. + */ + REDASSERT( ( ulTaskPtr + 1U ) != 0U ); + return ulTaskPtr + 1U; + } + +#endif /* if ( REDCONF_TASK_COUNT > 1U ) && ( REDCONF_API_POSIX == 1 ) */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/ostimestamp.c b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/ostimestamp.c index d019d3ac8..6626040cf 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/ostimestamp.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/ostimestamp.c @@ -1,109 +1,109 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements timestamp functions. - - The functionality implemented herein is not needed for the file system - driver, only to provide accurate results with performance tests. -*/ -#include -#include - -#include - - -/* configTICK_RATE_HZ is almost always 100, 250, 500, or 1000. If - 1000000U % configTICK_RATE_HZ != 0, then RedOsTimePassed() will be a - little inaccurate. -*/ -#define MICROSECS_PER_TICK (1000000U / configTICK_RATE_HZ) - - -/** @brief Initialize the timestamp service. - - The behavior of invoking this function when timestamps are already - initialized is undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_ENOSYS The timestamp service has not been implemented. -*/ -REDSTATUS RedOsTimestampInit(void) -{ - return 0; -} - - -/** @brief Uninitialize the timestamp service. - - The behavior of invoking this function when timestamps are not initialized - is undefined. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. -*/ -REDSTATUS RedOsTimestampUninit(void) -{ - return 0; -} - - -/** @brief Retrieve a timestamp. - - The behavior of invoking this function when timestamps are not initialized - is undefined - - @return A timestamp which can later be passed to RedOsTimePassed() to - determine the amount of time which passed between the two calls. -*/ -REDTIMESTAMP RedOsTimestamp(void) -{ - return xTaskGetTickCount(); -} - - -/** @brief Determine how much time has passed since a timestamp was retrieved. - - The behavior of invoking this function when timestamps are not initialized - is undefined. - - @param tsSince A timestamp acquired earlier via RedOsTimestamp(). - - @return The number of microseconds which have passed since @p tsSince. -*/ -uint64_t RedOsTimePassed( - REDTIMESTAMP tsSince) -{ - /* This works even if the tick count has wrapped around, provided it has - only wrapped around once. - */ - uint32_t ulTicksPassed = (uint32_t)xTaskGetTickCount() - tsSince; - uint64_t ullMicrosecs = (uint64_t)ulTicksPassed * MICROSECS_PER_TICK; - - return ullMicrosecs; -} - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements timestamp functions. + * + * The functionality implemented herein is not needed for the file system + * driver, only to provide accurate results with performance tests. + */ +#include +#include + +#include + + +/* configTICK_RATE_HZ is almost always 100, 250, 500, or 1000. If + * 1000000U % configTICK_RATE_HZ != 0, then RedOsTimePassed() will be a + * little inaccurate. + */ +#define MICROSECS_PER_TICK ( 1000000U / configTICK_RATE_HZ ) + + +/** @brief Initialize the timestamp service. + * + * The behavior of invoking this function when timestamps are already + * initialized is undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_ENOSYS The timestamp service has not been implemented. + */ +REDSTATUS RedOsTimestampInit( void ) +{ + return 0; +} + + +/** @brief Uninitialize the timestamp service. + * + * The behavior of invoking this function when timestamps are not initialized + * is undefined. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + */ +REDSTATUS RedOsTimestampUninit( void ) +{ + return 0; +} + + +/** @brief Retrieve a timestamp. + * + * The behavior of invoking this function when timestamps are not initialized + * is undefined + * + * @return A timestamp which can later be passed to RedOsTimePassed() to + * determine the amount of time which passed between the two calls. + */ +REDTIMESTAMP RedOsTimestamp( void ) +{ + return xTaskGetTickCount(); +} + + +/** @brief Determine how much time has passed since a timestamp was retrieved. + * + * The behavior of invoking this function when timestamps are not initialized + * is undefined. + * + * @param tsSince A timestamp acquired earlier via RedOsTimestamp(). + * + * @return The number of microseconds which have passed since @p tsSince. + */ +uint64_t RedOsTimePassed( REDTIMESTAMP tsSince ) +{ + /* This works even if the tick count has wrapped around, provided it has + * only wrapped around once. + */ + uint32_t ulTicksPassed = ( uint32_t ) xTaskGetTickCount() - tsSince; + uint64_t ullMicrosecs = ( uint64_t ) ulTicksPassed * MICROSECS_PER_TICK; + + return ullMicrosecs; +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/posix/path.c b/FreeRTOS-Plus/Source/Reliance-Edge/posix/path.c index ecdf0a7b8..894b3a29c 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/posix/path.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/posix/path.c @@ -1,448 +1,445 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements path utilities for the POSIX-like API layer. -*/ -#include - -#if REDCONF_API_POSIX == 1 - -#include -#include -#include -#include - - -static bool IsRootDir(const char *pszLocalPath); -static bool PathHasMoreNames(const char *pszPathIdx); - - -/** @brief Split a path into its component parts: a volume and a volume-local - path. - - @param pszPath The path to split. - @param pbVolNum On successful return, if non-NULL, populated with - the volume number extracted from the path. - @param ppszLocalPath On successful return, populated with the - volume-local path: the path stripped of any volume - path prefixing. If this parameter is NULL, that - indicates there should be no local path, and any - characters beyond the prefix (other than path - separators) are treated as an error. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p pszPath is `NULL`. - @retval -RED_ENOENT @p pszPath could not be matched to any volume; or - @p ppszLocalPath is NULL but @p pszPath includes a local - path. -*/ -REDSTATUS RedPathSplit( - const char *pszPath, - uint8_t *pbVolNum, - const char **ppszLocalPath) -{ - REDSTATUS ret = 0; - - if(pszPath == NULL) - { - ret = -RED_EINVAL; - } - else - { - const char *pszLocalPath = pszPath; - uint8_t bMatchVol = UINT8_MAX; - uint32_t ulMatchLen = 0U; - uint8_t bDefaultVolNum = UINT8_MAX; - uint8_t bVolNum; - - for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++) - { - const char *pszPrefix = gaRedVolConf[bVolNum].pszPathPrefix; - uint32_t ulPrefixLen = RedStrLen(pszPrefix); - - if(ulPrefixLen == 0U) - { - /* A volume with a path prefix of an empty string is the - default volume, used when the path does not match the - prefix of any other volume. - - The default volume should only be found once. During - initialization, RedCoreInit() ensures that all volume - prefixes are unique (including empty prefixes). - */ - REDASSERT(bDefaultVolNum == UINT8_MAX); - bDefaultVolNum = bVolNum; - } - /* For a path to match, it must either be the prefix exactly, or - be followed by a path separator character. Thus, with a volume - prefix of "/foo", both "/foo" and "/foo/bar" are matches, but - "/foobar" is not. - */ - else if( (RedStrNCmp(pszPath, pszPrefix, ulPrefixLen) == 0) - && ((pszPath[ulPrefixLen] == '\0') || (pszPath[ulPrefixLen] == REDCONF_PATH_SEPARATOR))) - { - /* The length of this match should never exactly equal the - length of a previous match: that would require a duplicate - volume name, which should have been detected during init. - */ - REDASSERT(ulPrefixLen != ulMatchLen); - - /* If multiple prefixes match, the longest takes precedence. - Thus, if there are two prefixes "Flash" and "Flash/Backup", - the path "Flash/Backup/" will not be erroneously matched - with the "Flash" volume. - */ - if(ulPrefixLen > ulMatchLen) - { - bMatchVol = bVolNum; - ulMatchLen = ulPrefixLen; - } - } - else - { - /* No match, keep looking. - */ - } - } - - if(bMatchVol != UINT8_MAX) - { - /* The path matched a volume path prefix. - */ - bVolNum = bMatchVol; - pszLocalPath = &pszPath[ulMatchLen]; - } - else if(bDefaultVolNum != UINT8_MAX) - { - /* The path didn't match any of the prefixes, but one of the - volumes has a path prefix of "", so an unprefixed path is - assigned to that volume. - */ - bVolNum = bDefaultVolNum; - REDASSERT(pszLocalPath == pszPath); - } - else - { - /* The path cannot be assigned a volume. - */ - ret = -RED_ENOENT; - } - - if(ret == 0) - { - if(pbVolNum != NULL) - { - *pbVolNum = bVolNum; - } - - if(ppszLocalPath != NULL) - { - *ppszLocalPath = pszLocalPath; - } - else - { - /* If no local path is expected, then the string should either - terminate after the path prefix or the local path should name - the root directory. Allowing path separators here means that - red_mount("/data/") is OK with a path prefix of "/data". - */ - if(pszLocalPath[0U] != '\0') - { - if(!IsRootDir(pszLocalPath)) - { - ret = -RED_ENOENT; - } - } - } - } - } - - return ret; -} - - -/** @brief Lookup the inode named by the given path. - - @param pszLocalPath The path to lookup; this is a local path, without any - volume prefix. - @param pulInode On successful return, populated with the number of the - inode named by @p pszLocalPath. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulInode is - `NULL`. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOENT @p pszLocalPath is an empty string; or - @p pszLocalPath does not name an existing file - or directory. - @retval -RED_ENOTDIR A component of the path other than the last is - not a directory. - @retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is - longer than #REDCONF_NAME_MAX. -*/ -REDSTATUS RedPathLookup( - const char *pszLocalPath, - uint32_t *pulInode) -{ - REDSTATUS ret; - - if((pszLocalPath == NULL) || (pulInode == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(pszLocalPath[0U] == '\0') - { - ret = -RED_ENOENT; - } - else if(IsRootDir(pszLocalPath)) - { - ret = 0; - *pulInode = INODE_ROOTDIR; - } - else - { - uint32_t ulPInode; - const char *pszName; - - ret = RedPathToName(pszLocalPath, &ulPInode, &pszName); - - if(ret == 0) - { - ret = RedCoreLookup(ulPInode, pszName, pulInode); - } - } - - return ret; -} - - -/** @brief Given a path, return the parent inode number and a pointer to the - last component in the path (the name). - - @param pszLocalPath The path to examine; this is a local path, without any - volume prefix. - @param pulPInode On successful return, populated with the inode number of - the parent directory of the last component in the path. - For example, with the path "a/b/c", populated with the - inode number of "b". - @param ppszName On successful return, populated with a pointer to the - last component in the path. For example, with the path - "a/b/c", populated with a pointer to "c". - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulPInode is - `NULL`; or @p ppszName is `NULL`; or the path - names the root directory. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENOENT @p pszLocalPath is an empty string; or a - component of the path other than the last does - not exist. - @retval -RED_ENOTDIR A component of the path other than the last is - not a directory. - @retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is - longer than #REDCONF_NAME_MAX. -*/ -REDSTATUS RedPathToName( - const char *pszLocalPath, - uint32_t *pulPInode, - const char **ppszName) -{ - REDSTATUS ret; - - if((pszLocalPath == NULL) || (pulPInode == NULL) || (ppszName == NULL)) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(IsRootDir(pszLocalPath)) - { - ret = -RED_EINVAL; - } - else if(pszLocalPath[0U] == '\0') - { - ret = -RED_ENOENT; - } - else - { - uint32_t ulInode = INODE_ROOTDIR; - uint32_t ulPInode = INODE_INVALID; - uint32_t ulPathIdx = 0U; - uint32_t ulLastNameIdx = 0U; - - ret = 0; - - do - { - uint32_t ulNameLen; - - /* Skip over path separators, to get pszLocalPath[ulPathIdx] - pointing at the next name. - */ - while(pszLocalPath[ulPathIdx] == REDCONF_PATH_SEPARATOR) - { - ulPathIdx++; - } - - if(pszLocalPath[ulPathIdx] == '\0') - { - break; - } - - /* Point ulLastNameIdx at the first character of the name; after - we exit the loop, it will point at the first character of the - last name in the path. - */ - ulLastNameIdx = ulPathIdx; - - /* Point ulPInode at the parent inode: either the root inode - (first pass) or the inode of the previous name. After we exit - the loop, this will point at the parent inode of the last name. - */ - ulPInode = ulInode; - - ulNameLen = RedNameLen(&pszLocalPath[ulPathIdx]); - - /* Lookup the inode of the name, unless we are at the last name in - the path: we don't care whether the last name exists or not. - */ - if(PathHasMoreNames(&pszLocalPath[ulPathIdx + ulNameLen])) - { - ret = RedCoreLookup(ulPInode, &pszLocalPath[ulPathIdx], &ulInode); - } - - /* Move on to the next path element. - */ - if(ret == 0) - { - ulPathIdx += ulNameLen; - } - } - while(ret == 0); - - if(ret == 0) - { - *pulPInode = ulPInode; - *ppszName = &pszLocalPath[ulLastNameIdx]; - } - } - - return ret; -} - - -/** @brief Determine whether a path names the root directory. - - @param pszLocalPath The path to examine; this is a local path, without any - volume prefix. - - @return Returns whether @p pszLocalPath names the root directory. - - @retval true @p pszLocalPath names the root directory. - @retval false @p pszLocalPath does not name the root directory. -*/ -static bool IsRootDir( - const char *pszLocalPath) -{ - bool fRet; - - if(pszLocalPath == NULL) - { - REDERROR(); - fRet = false; - } - else - { - uint32_t ulIdx = 0U; - - /* A string containing nothing but path separators (usually only one) - names the root directory. An empty string does *not* name the root - directory, since in POSIX empty strings typically elicit -RED_ENOENT - errors. - */ - while(pszLocalPath[ulIdx] == REDCONF_PATH_SEPARATOR) - { - ulIdx++; - } - - fRet = (ulIdx > 0U) && (pszLocalPath[ulIdx] == '\0'); - } - - return fRet; -} - - -/** @brief Determine whether there are more names in a path. - - Example | Result - ------- | ------ - "" false - "/" false - "//" false - "a" true - "/a" true - "//a" true - - @param pszPathIdx The path to examine, incremented to the point of - interest. - - @return Returns whether there are more names in @p pszPathIdx. - - @retval true @p pszPathIdx has more names. - @retval false @p pszPathIdx has no more names. -*/ -static bool PathHasMoreNames( - const char *pszPathIdx) -{ - bool fRet; - - if(pszPathIdx == NULL) - { - REDERROR(); - fRet = false; - } - else - { - uint32_t ulIdx = 0U; - - while(pszPathIdx[ulIdx] == REDCONF_PATH_SEPARATOR) - { - ulIdx++; - } - - fRet = pszPathIdx[ulIdx] != '\0'; - } - - return fRet; -} - -#endif /* REDCONF_API_POSIX */ - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements path utilities for the POSIX-like API layer. + */ +#include + +#if REDCONF_API_POSIX == 1 + + #include + #include + #include + #include + + + static bool IsRootDir( const char * pszLocalPath ); + static bool PathHasMoreNames( const char * pszPathIdx ); + + +/** @brief Split a path into its component parts: a volume and a volume-local + * path. + * + * @param pszPath The path to split. + * @param pbVolNum On successful return, if non-NULL, populated with + * the volume number extracted from the path. + * @param ppszLocalPath On successful return, populated with the + * volume-local path: the path stripped of any volume + * path prefixing. If this parameter is NULL, that + * indicates there should be no local path, and any + * characters beyond the prefix (other than path + * separators) are treated as an error. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p pszPath is `NULL`. + * @retval -RED_ENOENT @p pszPath could not be matched to any volume; or + * @p ppszLocalPath is NULL but @p pszPath includes a local + * path. + */ + REDSTATUS RedPathSplit( const char * pszPath, + uint8_t * pbVolNum, + const char ** ppszLocalPath ) + { + REDSTATUS ret = 0; + + if( pszPath == NULL ) + { + ret = -RED_EINVAL; + } + else + { + const char * pszLocalPath = pszPath; + uint8_t bMatchVol = UINT8_MAX; + uint32_t ulMatchLen = 0U; + uint8_t bDefaultVolNum = UINT8_MAX; + uint8_t bVolNum; + + for( bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++ ) + { + const char * pszPrefix = gaRedVolConf[ bVolNum ].pszPathPrefix; + uint32_t ulPrefixLen = RedStrLen( pszPrefix ); + + if( ulPrefixLen == 0U ) + { + /* A volume with a path prefix of an empty string is the + * default volume, used when the path does not match the + * prefix of any other volume. + * + * The default volume should only be found once. During + * initialization, RedCoreInit() ensures that all volume + * prefixes are unique (including empty prefixes). + */ + REDASSERT( bDefaultVolNum == UINT8_MAX ); + bDefaultVolNum = bVolNum; + } + + /* For a path to match, it must either be the prefix exactly, or + * be followed by a path separator character. Thus, with a volume + * prefix of "/foo", both "/foo" and "/foo/bar" are matches, but + * "/foobar" is not. + */ + else if( ( RedStrNCmp( pszPath, pszPrefix, ulPrefixLen ) == 0 ) && + ( ( pszPath[ ulPrefixLen ] == '\0' ) || ( pszPath[ ulPrefixLen ] == REDCONF_PATH_SEPARATOR ) ) ) + { + /* The length of this match should never exactly equal the + * length of a previous match: that would require a duplicate + * volume name, which should have been detected during init. + */ + REDASSERT( ulPrefixLen != ulMatchLen ); + + /* If multiple prefixes match, the longest takes precedence. + * Thus, if there are two prefixes "Flash" and "Flash/Backup", + * the path "Flash/Backup/" will not be erroneously matched + * with the "Flash" volume. + */ + if( ulPrefixLen > ulMatchLen ) + { + bMatchVol = bVolNum; + ulMatchLen = ulPrefixLen; + } + } + else + { + /* No match, keep looking. + */ + } + } + + if( bMatchVol != UINT8_MAX ) + { + /* The path matched a volume path prefix. + */ + bVolNum = bMatchVol; + pszLocalPath = &pszPath[ ulMatchLen ]; + } + else if( bDefaultVolNum != UINT8_MAX ) + { + /* The path didn't match any of the prefixes, but one of the + * volumes has a path prefix of "", so an unprefixed path is + * assigned to that volume. + */ + bVolNum = bDefaultVolNum; + REDASSERT( pszLocalPath == pszPath ); + } + else + { + /* The path cannot be assigned a volume. + */ + ret = -RED_ENOENT; + } + + if( ret == 0 ) + { + if( pbVolNum != NULL ) + { + *pbVolNum = bVolNum; + } + + if( ppszLocalPath != NULL ) + { + *ppszLocalPath = pszLocalPath; + } + else + { + /* If no local path is expected, then the string should either + * terminate after the path prefix or the local path should name + * the root directory. Allowing path separators here means that + * red_mount("/data/") is OK with a path prefix of "/data". + */ + if( pszLocalPath[ 0U ] != '\0' ) + { + if( !IsRootDir( pszLocalPath ) ) + { + ret = -RED_ENOENT; + } + } + } + } + } + + return ret; + } + + +/** @brief Lookup the inode named by the given path. + * + * @param pszLocalPath The path to lookup; this is a local path, without any + * volume prefix. + * @param pulInode On successful return, populated with the number of the + * inode named by @p pszLocalPath. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulInode is + * `NULL`. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOENT @p pszLocalPath is an empty string; or + * @p pszLocalPath does not name an existing file + * or directory. + * @retval -RED_ENOTDIR A component of the path other than the last is + * not a directory. + * @retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is + * longer than #REDCONF_NAME_MAX. + */ + REDSTATUS RedPathLookup( const char * pszLocalPath, + uint32_t * pulInode ) + { + REDSTATUS ret; + + if( ( pszLocalPath == NULL ) || ( pulInode == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( pszLocalPath[ 0U ] == '\0' ) + { + ret = -RED_ENOENT; + } + else if( IsRootDir( pszLocalPath ) ) + { + ret = 0; + *pulInode = INODE_ROOTDIR; + } + else + { + uint32_t ulPInode; + const char * pszName; + + ret = RedPathToName( pszLocalPath, &ulPInode, &pszName ); + + if( ret == 0 ) + { + ret = RedCoreLookup( ulPInode, pszName, pulInode ); + } + } + + return ret; + } + + +/** @brief Given a path, return the parent inode number and a pointer to the + * last component in the path (the name). + * + * @param pszLocalPath The path to examine; this is a local path, without any + * volume prefix. + * @param pulPInode On successful return, populated with the inode number of + * the parent directory of the last component in the path. + * For example, with the path "a/b/c", populated with the + * inode number of "b". + * @param ppszName On successful return, populated with a pointer to the + * last component in the path. For example, with the path + * "a/b/c", populated with a pointer to "c". + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulPInode is + * `NULL`; or @p ppszName is `NULL`; or the path + * names the root directory. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENOENT @p pszLocalPath is an empty string; or a + * component of the path other than the last does + * not exist. + * @retval -RED_ENOTDIR A component of the path other than the last is + * not a directory. + * @retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is + * longer than #REDCONF_NAME_MAX. + */ + REDSTATUS RedPathToName( const char * pszLocalPath, + uint32_t * pulPInode, + const char ** ppszName ) + { + REDSTATUS ret; + + if( ( pszLocalPath == NULL ) || ( pulPInode == NULL ) || ( ppszName == NULL ) ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( IsRootDir( pszLocalPath ) ) + { + ret = -RED_EINVAL; + } + else if( pszLocalPath[ 0U ] == '\0' ) + { + ret = -RED_ENOENT; + } + else + { + uint32_t ulInode = INODE_ROOTDIR; + uint32_t ulPInode = INODE_INVALID; + uint32_t ulPathIdx = 0U; + uint32_t ulLastNameIdx = 0U; + + ret = 0; + + do + { + uint32_t ulNameLen; + + /* Skip over path separators, to get pszLocalPath[ulPathIdx] + * pointing at the next name. + */ + while( pszLocalPath[ ulPathIdx ] == REDCONF_PATH_SEPARATOR ) + { + ulPathIdx++; + } + + if( pszLocalPath[ ulPathIdx ] == '\0' ) + { + break; + } + + /* Point ulLastNameIdx at the first character of the name; after + * we exit the loop, it will point at the first character of the + * last name in the path. + */ + ulLastNameIdx = ulPathIdx; + + /* Point ulPInode at the parent inode: either the root inode + * (first pass) or the inode of the previous name. After we exit + * the loop, this will point at the parent inode of the last name. + */ + ulPInode = ulInode; + + ulNameLen = RedNameLen( &pszLocalPath[ ulPathIdx ] ); + + /* Lookup the inode of the name, unless we are at the last name in + * the path: we don't care whether the last name exists or not. + */ + if( PathHasMoreNames( &pszLocalPath[ ulPathIdx + ulNameLen ] ) ) + { + ret = RedCoreLookup( ulPInode, &pszLocalPath[ ulPathIdx ], &ulInode ); + } + + /* Move on to the next path element. + */ + if( ret == 0 ) + { + ulPathIdx += ulNameLen; + } + } + while( ret == 0 ); + + if( ret == 0 ) + { + *pulPInode = ulPInode; + *ppszName = &pszLocalPath[ ulLastNameIdx ]; + } + } + + return ret; + } + + +/** @brief Determine whether a path names the root directory. + * + * @param pszLocalPath The path to examine; this is a local path, without any + * volume prefix. + * + * @return Returns whether @p pszLocalPath names the root directory. + * + * @retval true @p pszLocalPath names the root directory. + * @retval false @p pszLocalPath does not name the root directory. + */ + static bool IsRootDir( const char * pszLocalPath ) + { + bool fRet; + + if( pszLocalPath == NULL ) + { + REDERROR(); + fRet = false; + } + else + { + uint32_t ulIdx = 0U; + + /* A string containing nothing but path separators (usually only one) + * names the root directory. An empty string does *not* name the root + * directory, since in POSIX empty strings typically elicit -RED_ENOENT + * errors. + */ + while( pszLocalPath[ ulIdx ] == REDCONF_PATH_SEPARATOR ) + { + ulIdx++; + } + + fRet = ( ulIdx > 0U ) && ( pszLocalPath[ ulIdx ] == '\0' ); + } + + return fRet; + } + + +/** @brief Determine whether there are more names in a path. + * + * Example | Result + * ------- | ------ + * "" false + * "/" false + * "//" false + * "a" true + * "/a" true + * "//a" true + * + * @param pszPathIdx The path to examine, incremented to the point of + * interest. + * + * @return Returns whether there are more names in @p pszPathIdx. + * + * @retval true @p pszPathIdx has more names. + * @retval false @p pszPathIdx has no more names. + */ + static bool PathHasMoreNames( const char * pszPathIdx ) + { + bool fRet; + + if( pszPathIdx == NULL ) + { + REDERROR(); + fRet = false; + } + else + { + uint32_t ulIdx = 0U; + + while( pszPathIdx[ ulIdx ] == REDCONF_PATH_SEPARATOR ) + { + ulIdx++; + } + + fRet = pszPathIdx[ ulIdx ] != '\0'; + } + + return fRet; + } + +#endif /* REDCONF_API_POSIX */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/posix/posix.c b/FreeRTOS-Plus/Source/Reliance-Edge/posix/posix.c index 7a21f0696..fe660e5a7 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/posix/posix.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/posix/posix.c @@ -1,3088 +1,3115 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implementation of the the Reliance Edge POSIX-like API. -*/ - -#include - -#if REDCONF_API_POSIX == 1 - -/** @defgroup red_group_posix The POSIX-like File System Interface - @{ -*/ - -#include -#include -#include -#include - - -/*------------------------------------------------------------------- - File Descriptors --------------------------------------------------------------------*/ - -#define FD_GEN_BITS 11U /* File descriptor bits for mount generation. */ -#define FD_VOL_BITS 8U /* File descriptor bits for volume number. */ -#define FD_IDX_BITS 12U /* File descriptor bits for handle index. */ - -/* 31 bits available: file descriptors are int32_t, but the sign bit must - always be zero. -*/ -#if (FD_GEN_BITS + FD_VOL_BITS + FD_IDX_BITS) > 31U - #error "Internal error: too many file descriptor bits!" -#endif - -/* Maximum values for file descriptor components. -*/ -#define FD_GEN_MAX ((1UL << FD_GEN_BITS) - 1U) -#define FD_VOL_MAX ((1UL << FD_VOL_BITS) - 1U) -#define FD_IDX_MAX ((1UL << FD_IDX_BITS) - 1U) - -#if REDCONF_VOLUME_COUNT > FD_VOL_MAX - #error "Error: Too many file system volumes!" -#endif -#if REDCONF_HANDLE_COUNT > (FD_IDX_MAX + 1U) - #error "Error: Too many file system handles!" -#endif - -/* File descriptors must never be negative; and must never be zero, one, or - two, to avoid confusion with STDIN, STDOUT, and STDERR. -*/ -#define FD_MIN (3) - -/*------------------------------------------------------------------- - Handles --------------------------------------------------------------------*/ - -/* Mask of all RED_O_* values. -*/ -#define RED_O_MASK (RED_O_RDONLY|RED_O_WRONLY|RED_O_RDWR|RED_O_APPEND|RED_O_CREAT|RED_O_EXCL|RED_O_TRUNC) - -#define HFLAG_DIRECTORY 0x01U /* Handle is for a directory. */ -#define HFLAG_READABLE 0x02U /* Handle is readable. */ -#define HFLAG_WRITEABLE 0x04U /* Handle is writeable. */ -#define HFLAG_APPENDING 0x08U /* Handle was opened in append mode. */ - -/* @brief Handle structure, used to implement file descriptors and directory - streams. -*/ -typedef struct sREDHANDLE -{ - uint32_t ulInode; /**< Inode number; 0 if handle is available. */ - uint8_t bVolNum; /**< Volume containing the inode. */ - uint8_t bFlags; /**< Handle flags (type and mode). */ - uint64_t ullOffset; /**< File or directory offset. */ - #if REDCONF_API_POSIX_READDIR == 1 - REDDIRENT dirent; /**< Dirent structure returned by red_readdir(). */ - #endif -} REDHANDLE; - -/*------------------------------------------------------------------- - Tasks --------------------------------------------------------------------*/ - -#if REDCONF_TASK_COUNT > 1U -/* @brief Per-task information. -*/ -typedef struct -{ - uint32_t ulTaskId; /**< ID of the task which owns this slot; 0 if free. */ - REDSTATUS iErrno; /**< Last error value. */ -} TASKSLOT; -#endif - -/*------------------------------------------------------------------- - Local Prototypes --------------------------------------------------------------------*/ - -#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) -static REDSTATUS UnlinkSub(const char *pszPath, FTYPE type); -#endif -static REDSTATUS FildesOpen(const char *pszPath, uint32_t ulOpenMode, FTYPE type, int32_t *piFildes); -static REDSTATUS FildesClose(int32_t iFildes); -static REDSTATUS FildesToHandle(int32_t iFildes, FTYPE expectedType, REDHANDLE **ppHandle); -static int32_t FildesPack(uint16_t uHandleIdx, uint8_t bVolNum); -static void FildesUnpack(int32_t iFildes, uint16_t *puHandleIdx, uint8_t *pbVolNum, uint16_t *puGeneration); -#if REDCONF_API_POSIX_READDIR == 1 -static bool DirStreamIsValid(const REDDIR *pDirStream); -#endif -static REDSTATUS PosixEnter(void); -static void PosixLeave(void); -static REDSTATUS ModeTypeCheck(uint16_t uMode, FTYPE expectedType); -#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) || ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1))) -static REDSTATUS InodeUnlinkCheck(uint32_t ulInode); -#endif -#if REDCONF_TASK_COUNT > 1U -static REDSTATUS TaskRegister(uint32_t *pulTaskIdx); -#endif -static int32_t PosixReturn(REDSTATUS iError); - -/*------------------------------------------------------------------- - Globals --------------------------------------------------------------------*/ - -static bool gfPosixInited; /* Whether driver is initialized. */ -static REDHANDLE gaHandle[REDCONF_HANDLE_COUNT]; /* Array of all handles. */ -#if REDCONF_TASK_COUNT > 1U -static TASKSLOT gaTask[REDCONF_TASK_COUNT]; /* Array of task slots. */ -#endif - -/* Array of volume mount "generations". These are incremented for a volume - each time that volume is mounted. The generation number (along with the - volume number) is incorporated into the file descriptors; a stale file - descriptor from a previous mount can be detected since it will include a - stale generation number. -*/ -static uint16_t gauGeneration[REDCONF_VOLUME_COUNT]; - - -/*------------------------------------------------------------------- - Public API --------------------------------------------------------------------*/ - -/** @brief Initialize the Reliance Edge file system driver. - - Prepares the Reliance Edge file system driver to be used. Must be the first - Reliance Edge function to be invoked: no volumes can be mounted or formatted - until the driver has been initialized. - - If this function is called when the Reliance Edge driver is already - initialized, it does nothing and returns success. - - This function is not thread safe: attempting to initialize from multiple - threads could leave things in a bad state. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EINVAL: The volume path prefix configuration is invalid. -*/ -int32_t red_init(void) -{ - REDSTATUS ret; - - if(gfPosixInited) - { - ret = 0; - } - else - { - ret = RedCoreInit(); - if(ret == 0) - { - RedMemSet(gaHandle, 0U, sizeof(gaHandle)); - - #if REDCONF_TASK_COUNT > 1U - RedMemSet(gaTask, 0U, sizeof(gaTask)); - #endif - - gfPosixInited = true; - } - } - - return PosixReturn(ret); -} - - -/** @brief Uninitialize the Reliance Edge file system driver. - - Tears down the Reliance Edge file system driver. Cannot be used until all - Reliance Edge volumes are unmounted. A subsequent call to red_init() will - initialize the driver again. - - If this function is called when the Reliance Edge driver is already - uninitialized, it does nothing and returns success. - - This function is not thread safe: attempting to uninitialize from multiple - threads could leave things in a bad state. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBUSY: At least one volume is still mounted. -*/ -int32_t red_uninit(void) -{ - REDSTATUS ret; - - if(gfPosixInited) - { - ret = PosixEnter(); - - if(ret == 0) - { - uint8_t bVolNum; - - for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++) - { - if(gaRedVolume[bVolNum].fMounted) - { - ret = -RED_EBUSY; - break; - } - } - - if(ret == 0) - { - /* All volumes are unmounted. Mark the driver as - uninitialized before releasing the FS mutex, to avoid any - race condition where a volume could be mounted and then the - driver uninitialized with a mounted volume. - */ - gfPosixInited = false; - } - - /* The FS mutex must be released before we uninitialize the core, - since the FS mutex needs to be in the released state when it - gets uninitialized. - - Don't use PosixLeave(), since it asserts gfPosixInited is true. - */ - #if REDCONF_TASK_COUNT > 1U - RedOsMutexRelease(); - #endif - } - - if(ret == 0) - { - ret = RedCoreUninit(); - - /* Not good if the above fails, since things might be partly, but - not entirely, torn down, and there might not be a way back to - a valid driver state. - */ - REDASSERT(ret == 0); - } - } - else - { - ret = 0; - } - - return PosixReturn(ret); -} - - -/** @brief Mount a file system volume. - - Prepares the file system volume to be accessed. Mount will fail if the - volume has never been formatted, or if the on-disk format is inconsistent - with the compile-time configuration. - - An error is returned if the volume is already mounted. - - @param pszVolume A path prefix identifying the volume to mount. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBUSY: Volume is already mounted. - - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized. - - #RED_EIO: Volume not formatted, improperly formatted, or corrupt. - - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_mount( - const char *pszVolume) -{ - REDSTATUS ret; - - ret = PosixEnter(); - - if(ret == 0) - { - uint8_t bVolNum; - - ret = RedPathSplit(pszVolume, &bVolNum, NULL); - - /* The core will return success if the volume is already mounted, so - check for that condition here to propagate the error. - */ - if((ret == 0) && gaRedVolume[bVolNum].fMounted) - { - ret = -RED_EBUSY; - } - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreVolMount(); - } - - if(ret == 0) - { - /* Increment the mount generation, invalidating file descriptors - from previous mounts. Note that while the generation numbers - are stored in 16-bit values, we have less than 16-bits to store - generations in the file descriptors, so we must wrap-around - manually. - */ - gauGeneration[bVolNum]++; - if(gauGeneration[bVolNum] > FD_GEN_MAX) - { - /* Wrap-around to one, rather than zero. The generation is - stored in the top bits of the file descriptor, and doing - this means that low numbers are never valid file - descriptors. This implements the requirement that 0, 1, - and 2 are never valid file descriptors, thereby avoiding - confusion with STDIN, STDOUT, and STDERR. - */ - gauGeneration[bVolNum] = 1U; - } - } - - PosixLeave(); - } - - return PosixReturn(ret); -} - - -/** @brief Unmount a file system volume. - - This function discards the in-memory state for the file system and marks it - as unmounted. Subsequent attempts to access the volume will fail until the - volume is mounted again. - - If unmount automatic transaction points are enabled, this function will - commit a transaction point prior to unmounting. If unmount automatic - transaction points are disabled, this function will unmount without - transacting, effectively discarding the working state. - - Before unmounting, this function will wait for any active file system - thread to complete by acquiring the FS mutex. The volume will be marked as - unmounted before the FS mutex is released, so subsequent FS threads will - possibly block and then see an error when attempting to access a volume - which is unmounting or unmounted. If the volume has open handles, the - unmount will fail. - - An error is returned if the volume is already unmounted. - - @param pszVolume A path prefix identifying the volume to unmount. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBUSY: There are still open handles for this file system volume. - - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized; or - the volume is already unmounted. - - #RED_EIO: I/O error during unmount automatic transaction point. - - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_umount( - const char *pszVolume) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - uint8_t bVolNum; - - ret = RedPathSplit(pszVolume, &bVolNum, NULL); - - /* The core will return success if the volume is already unmounted, so - check for that condition here to propagate the error. - */ - if((ret == 0) && !gaRedVolume[bVolNum].fMounted) - { - ret = -RED_EINVAL; - } - - if(ret == 0) - { - uint16_t uHandleIdx; - - /* Do not unmount the volume if it still has open handles. - */ - for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++) - { - const REDHANDLE *pHandle = &gaHandle[uHandleIdx]; - - if((pHandle->ulInode != INODE_INVALID) && (pHandle->bVolNum == bVolNum)) - { - ret = -RED_EBUSY; - break; - } - } - } - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreVolUnmount(); - } - - PosixLeave(); - } - - return PosixReturn(ret); -} - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1) -/** @brief Format a file system volume. - - Uses the statically defined volume configuration. After calling this - function, the volume needs to be mounted -- see red_mount(). - - An error is returned if the volume is mounted. - - @param pszVolume A path prefix identifying the volume to format. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBUSY: Volume is mounted. - - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized. - - #RED_EIO: I/O error formatting the volume. - - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_format( - const char *pszVolume) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - uint8_t bVolNum; - - ret = RedPathSplit(pszVolume, &bVolNum, NULL); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreVolFormat(); - } - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -#if REDCONF_READ_ONLY == 0 -/** @brief Commit a transaction point. - - Reliance Edge is a transactional file system. All modifications, of both - metadata and filedata, are initially working state. A transaction point - is a process whereby the working state atomically becomes the committed - state, replacing the previous committed state. Whenever Reliance Edge is - mounted, including after power loss, the state of the file system after - mount is the most recent committed state. Nothing from the committed - state is ever missing, and nothing from the working state is ever included. - - @param pszVolume A path prefix identifying the volume to transact. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`. - - #RED_EIO: I/O error during the transaction point. - - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_transact( - const char *pszVolume) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - uint8_t bVolNum; - - ret = RedPathSplit(pszVolume, &bVolNum, NULL); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreVolTransact(); - } - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -#if REDCONF_READ_ONLY == 0 -/** @brief Update the transaction mask. - - The following events are available: - - - #RED_TRANSACT_UMOUNT - - #RED_TRANSACT_CREAT - - #RED_TRANSACT_UNLINK - - #RED_TRANSACT_MKDIR - - #RED_TRANSACT_RENAME - - #RED_TRANSACT_LINK - - #RED_TRANSACT_CLOSE - - #RED_TRANSACT_WRITE - - #RED_TRANSACT_FSYNC - - #RED_TRANSACT_TRUNCATE - - #RED_TRANSACT_VOLFULL - - The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all - automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask - of all transaction flags, excluding those representing excluded - functionality. - - Attempting to enable events for excluded functionality will result in an - error. - - @param pszVolume The path prefix of the volume whose transaction mask is - being changed. - @param ulEventMask A bitwise-OR'd mask of automatic transaction events to - be set as the current transaction mode. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or - @p ulEventMask contains invalid bits. - - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_settransmask( - const char *pszVolume, - uint32_t ulEventMask) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - uint8_t bVolNum; - - ret = RedPathSplit(pszVolume, &bVolNum, NULL); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreTransMaskSet(ulEventMask); - } - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -/** @brief Read the transaction mask. - - If the volume is read-only, the returned event mask is always zero. - - @param pszVolume The path prefix of the volume whose transaction mask is - being retrieved. - @param pulEventMask Populated with a bitwise-OR'd mask of automatic - transaction events which represent the current - transaction mode for the volume. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or - @p pulEventMask is `NULL`. - - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_gettransmask( - const char *pszVolume, - uint32_t *pulEventMask) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - uint8_t bVolNum; - - ret = RedPathSplit(pszVolume, &bVolNum, NULL); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreTransMaskGet(pulEventMask); - } - - PosixLeave(); - } - - return PosixReturn(ret); -} - - -/** @brief Query file system status information. - - @p pszVolume should name a valid volume prefix or a valid root directory; - this differs from POSIX statvfs, where any existing file or directory is a - valid path. - - @param pszVolume The path prefix of the volume to query. - @param pStatvfs The buffer to populate with volume information. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or - @p pStatvfs is `NULL`. - - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_statvfs( - const char *pszVolume, - REDSTATFS *pStatvfs) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - uint8_t bVolNum; - - ret = RedPathSplit(pszVolume, &bVolNum, NULL); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreVolStat(pStatvfs); - } - - PosixLeave(); - } - - return PosixReturn(ret); -} - - -/** @brief Open a file or directory. - - Exactly one file access mode must be specified: - - - #RED_O_RDONLY: Open for reading only. - - #RED_O_WRONLY: Open for writing only. - - #RED_O_RDWR: Open for reading and writing. - - Directories can only be opened with `RED_O_RDONLY`. - - The following flags may also be used: - - - #RED_O_APPEND: Set the file offset to the end-of-file prior to each - write. - - #RED_O_CREAT: Create the named file if it does not exist. - - #RED_O_EXCL: In combination with `RED_O_CREAT`, return an error if the - path already exists. - - #RED_O_TRUNC: Truncate the opened file to size zero. Only supported when - #REDCONF_API_POSIX_FTRUNCATE is true. - - #RED_O_CREAT, #RED_O_EXCL, and #RED_O_TRUNC are invalid with #RED_O_RDONLY. - #RED_O_EXCL is invalid without #RED_O_CREAT. - - If the volume is read-only, #RED_O_RDONLY is the only valid open flag; use - of any other flag will result in an error. - - If #RED_O_TRUNC frees data which is in the committed state, it will not - return to free space until after a transaction point. - - The returned file descriptor must later be closed with red_close(). - - Unlike POSIX open, there is no optional third argument for the permissions - (which Reliance Edge does not use) and other open flags (like `O_SYNC`) are - not supported. - - @param pszPath The path to the file or directory. - @param ulOpenMode The open flags (mask of `RED_O_` values). - - @return On success, a nonnegative file descriptor is returned. On error, - -1 is returned and #red_errno is set appropriately. - - Errno values - - #RED_EEXIST: Using #RED_O_CREAT and #RED_O_EXCL, and the indicated path - already exists. - - #RED_EINVAL: @p ulOpenMode is invalid; or @p pszPath is `NULL`; or the - volume containing the path is not mounted. - - #RED_EIO: A disk I/O error occurred. - - #RED_EISDIR: The path names a directory and @p ulOpenMode includes - #RED_O_WRONLY or #RED_O_RDWR. - - #RED_EMFILE: There are no available file descriptors. - - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than - #REDCONF_NAME_MAX. - - #RED_ENFILE: Attempting to create a file but the file system has used all - available inode slots. - - #RED_ENOENT: #RED_O_CREAT is not set and the named file does not exist; or - #RED_O_CREAT is set and the parent directory does not exist; or the - volume does not exist; or the @p pszPath argument, after removing the - volume prefix, points to an empty string. - - #RED_ENOSPC: The file does not exist and #RED_O_CREAT was specified, but - there is insufficient free space to expand the directory or to create the - new file. - - #RED_ENOTDIR: A component of the prefix in @p pszPath does not name a - directory. - - #RED_EROFS: The path resides on a read-only file system and a write - operation was requested. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_open( - const char *pszPath, - uint32_t ulOpenMode) -{ - int32_t iFildes = -1; /* Init'd to quiet warnings. */ - REDSTATUS ret; - - #if REDCONF_READ_ONLY == 1 - if(ulOpenMode != RED_O_RDONLY) - { - ret = -RED_EROFS; - } - #else - if( (ulOpenMode != (ulOpenMode & RED_O_MASK)) - || ((ulOpenMode & (RED_O_RDONLY|RED_O_WRONLY|RED_O_RDWR)) == 0U) - || (((ulOpenMode & RED_O_RDONLY) != 0U) && ((ulOpenMode & (RED_O_WRONLY|RED_O_RDWR)) != 0U)) - || (((ulOpenMode & RED_O_WRONLY) != 0U) && ((ulOpenMode & (RED_O_RDONLY|RED_O_RDWR)) != 0U)) - || (((ulOpenMode & RED_O_RDWR) != 0U) && ((ulOpenMode & (RED_O_RDONLY|RED_O_WRONLY)) != 0U)) - || (((ulOpenMode & (RED_O_TRUNC|RED_O_CREAT|RED_O_EXCL)) != 0U) && ((ulOpenMode & RED_O_RDONLY) != 0U)) - || (((ulOpenMode & RED_O_EXCL) != 0U) && ((ulOpenMode & RED_O_CREAT) == 0U))) - { - ret = -RED_EINVAL; - } - #if REDCONF_API_POSIX_FTRUNCATE == 0 - else if((ulOpenMode & RED_O_TRUNC) != 0U) - { - ret = -RED_EINVAL; - } - #endif - #endif - else - { - ret = PosixEnter(); - } - - if(ret == 0) - { - ret = FildesOpen(pszPath, ulOpenMode, FTYPE_EITHER, &iFildes); - - PosixLeave(); - } - - if(ret != 0) - { - iFildes = PosixReturn(ret); - } - - return iFildes; -} - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1) -/** @brief Delete a file or directory. - - The given name is deleted and the link count of the corresponding inode is - decremented. If the link count falls to zero (no remaining hard links), - the inode will be deleted. - - Unlike POSIX unlink, deleting a file or directory with open handles (file - descriptors or directory streams) will fail with an #RED_EBUSY error. This - only applies when deleting an inode with a link count of one; if a file has - multiple names (hard links), all but the last name may be deleted even if - the file is open. - - If the path names a directory which is not empty, the unlink will fail. - - If the deletion frees data in the committed state, it will not return to - free space until after a transaction point. - - Unlike POSIX unlink, this function can fail when the disk is full. To fix - this, transact and try again: Reliance Edge guarantees that it is possible - to delete at least one file or directory after a transaction point. If disk - full automatic transactions are enabled, this will happen automatically. - - @param pszPath The path of the file or directory to delete. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBUSY: @p pszPath points to an inode with open handles and a link - count of one. - - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is - not mounted. - - #RED_EIO: A disk I/O error occurred. - - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than - #REDCONF_NAME_MAX. - - #RED_ENOENT: The path does not name an existing file; or the @p pszPath - argument, after removing the volume prefix, points to an empty string. - - #RED_ENOTDIR: A component of the path prefix is not a directory. - - #RED_ENOTEMPTY: The path names a directory which is not empty. - - #RED_ENOSPC: The file system does not have enough space to modify the - parent directory to perform the deletion. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_unlink( - const char *pszPath) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - ret = UnlinkSub(pszPath, FTYPE_EITHER); - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_MKDIR == 1) -/** @brief Create a new directory. - - Unlike POSIX mkdir, this function has no second argument for the - permissions (which Reliance Edge does not use). - - @param pszPath The name and location of the directory to create. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EEXIST: @p pszPath points to an existing file or directory. - - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is - not mounted. - - #RED_EIO: A disk I/O error occurred. - - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than - #REDCONF_NAME_MAX. - - #RED_ENOENT: A component of the path prefix does not name an existing - directory; or the @p pszPath argument, after removing the volume prefix, - points to an empty string. - - #RED_ENOSPC: The file system does not have enough space for the new - directory or to extend the parent directory of the new directory. - - #RED_ENOTDIR: A component of the path prefix is not a directory. - - #RED_EROFS: The parent directory resides on a read-only file system. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_mkdir( - const char *pszPath) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - const char *pszLocalPath; - uint8_t bVolNum; - - ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - const char *pszName; - uint32_t ulPInode; - - ret = RedPathToName(pszLocalPath, &ulPInode, &pszName); - - if(ret == 0) - { - uint32_t ulInode; - - ret = RedCoreCreate(ulPInode, pszName, true, &ulInode); - } - } - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RMDIR == 1) -/** @brief Delete a directory. - - The given directory name is deleted and the corresponding directory inode - will be deleted. - - Unlike POSIX rmdir, deleting a directory with open handles (file - descriptors or directory streams) will fail with an #RED_EBUSY error. - - If the path names a directory which is not empty, the deletion will fail. - If the path names the root directory of a file system volume, the deletion - will fail. - - If the path names a regular file, the deletion will fail. This provides - type checking and may be useful in cases where an application knows the - path to be deleted should name a directory. - - If the deletion frees data in the committed state, it will not return to - free space until after a transaction point. - - Unlike POSIX rmdir, this function can fail when the disk is full. To fix - this, transact and try again: Reliance Edge guarantees that it is possible - to delete at least one file or directory after a transaction point. If disk - full automatic transactions are enabled, this will happen automatically. - - @param pszPath The path of the directory to delete. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBUSY: @p pszPath points to a directory with open handles. - - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is - not mounted. - - #RED_EIO: A disk I/O error occurred. - - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than - #REDCONF_NAME_MAX. - - #RED_ENOENT: The path does not name an existing directory; or the - @p pszPath argument, after removing the volume prefix, points to an empty - string. - - #RED_ENOTDIR: A component of the path is not a directory. - - #RED_ENOTEMPTY: The path names a directory which is not empty. - - #RED_ENOSPC: The file system does not have enough space to modify the - parent directory to perform the deletion. - - #RED_EROFS: The directory to be removed resides on a read-only file - system. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_rmdir( - const char *pszPath) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - ret = UnlinkSub(pszPath, FTYPE_DIR); - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) -/** @brief Rename a file or directory. - - Both paths must reside on the same file system volume. Attempting to use - this API to move a file to a different volume will result in an error. - - If @p pszNewPath names an existing file or directory, the behavior depends - on the configuration. If #REDCONF_RENAME_ATOMIC is false, and if the - destination name exists, this function always fails and sets #red_errno to - #RED_EEXIST. This behavior is contrary to POSIX. - - If #REDCONF_RENAME_ATOMIC is true, and if the new name exists, then in one - atomic operation, @p pszNewPath is unlinked and @p pszOldPath is renamed to - @p pszNewPath. Both @p pszNewPath and @p pszOldPath must be of the same - type (both files or both directories). As with red_unlink(), if - @p pszNewPath is a directory, it must be empty. The major exception to this - behavior is that if both @p pszOldPath and @p pszNewPath are links to the - same inode, then the rename does nothing and both names continue to exist. - Unlike POSIX rename, if @p pszNewPath points to an inode with a link count - of one and open handles (file descriptors or directory streams), the - rename will fail with #RED_EBUSY. - - If the rename deletes the old destination, it may free data in the - committed state, which will not return to free space until after a - transaction point. Similarly, if the deleted inode was part of the - committed state, the inode slot will not be available until after a - transaction point. - - @param pszOldPath The path of the file or directory to rename. - @param pszNewPath The new name and location after the rename. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBUSY: #REDCONF_RENAME_ATOMIC is true and @p pszNewPath points to an - inode with open handles and a link count of one. - - #RED_EEXIST: #REDCONF_RENAME_ATOMIC is false and @p pszNewPath exists. - - #RED_EINVAL: @p pszOldPath is `NULL`; or @p pszNewPath is `NULL`; or the - volume containing the path is not mounted. - - #RED_EIO: A disk I/O error occurred. - - #RED_EISDIR: The @p pszNewPath argument names a directory and the - @p pszOldPath argument names a non-directory. - - #RED_ENAMETOOLONG: The length of a component of either @p pszOldPath or - @p pszNewPath is longer than #REDCONF_NAME_MAX. - - #RED_ENOENT: The link named by @p pszOldPath does not name an existing - entry; or either @p pszOldPath or @p pszNewPath, after removing the volume - prefix, point to an empty string. - - #RED_ENOTDIR: A component of either path prefix is not a directory; or - @p pszOldPath names a directory and @p pszNewPath names a file. - - #RED_ENOTEMPTY: The path named by @p pszNewPath is a directory which is - not empty. - - #RED_ENOSPC: The file system does not have enough space to extend the - directory that would contain @p pszNewPath. - - #RED_EROFS: The directory to be removed resides on a read-only file - system. - - #RED_EUSERS: Cannot become a file system user: too many users. - - #RED_EXDEV: @p pszOldPath and @p pszNewPath are on different file system - volumes. -*/ -int32_t red_rename( - const char *pszOldPath, - const char *pszNewPath) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - const char *pszOldLocalPath; - uint8_t bOldVolNum; - - ret = RedPathSplit(pszOldPath, &bOldVolNum, &pszOldLocalPath); - - if(ret == 0) - { - const char *pszNewLocalPath; - uint8_t bNewVolNum; - - ret = RedPathSplit(pszNewPath, &bNewVolNum, &pszNewLocalPath); - - if((ret == 0) && (bOldVolNum != bNewVolNum)) - { - ret = -RED_EXDEV; - } - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bOldVolNum); - } - #endif - - if(ret == 0) - { - const char *pszOldName; - uint32_t ulOldPInode; - - ret = RedPathToName(pszOldLocalPath, &ulOldPInode, &pszOldName); - - if(ret == 0) - { - const char *pszNewName; - uint32_t ulNewPInode; - - ret = RedPathToName(pszNewLocalPath, &ulNewPInode, &pszNewName); - - #if REDCONF_RENAME_ATOMIC == 1 - if(ret == 0) - { - uint32_t ulDestInode; - - ret = RedCoreLookup(ulNewPInode, pszNewName, &ulDestInode); - if(ret == 0) - { - ret = InodeUnlinkCheck(ulDestInode); - } - else if(ret == -RED_ENOENT) - { - ret = 0; - } - else - { - /* Unexpected error, nothing to do. - */ - } - } - #endif - - if(ret == 0) - { - ret = RedCoreRename(ulOldPInode, pszOldName, ulNewPInode, pszNewName); - } - } - } - } - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_LINK == 1) -/** @brief Create a hard link. - - This creates an additional name (link) for the file named by @p pszPath. - The new name refers to the same file with the same contents. If a name is - deleted, but the underlying file has other names, the file continues to - exist. The link count (accessible via red_fstat()) indicates the number of - names that a file has. All of a file's names are on equal footing: there - is nothing special about the original name. - - If @p pszPath names a directory, the operation will fail. - - @param pszPath The path indicating the inode for the new link. - @param pszHardLink The name and location for the new link. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EEXIST: @p pszHardLink resolves to an existing file. - - #RED_EINVAL: @p pszPath or @p pszHardLink is `NULL`; or the volume - containing the paths is not mounted. - - #RED_EIO: A disk I/O error occurred. - - #RED_EMLINK: Creating the link would exceed the maximum link count of the - inode named by @p pszPath. - - #RED_ENAMETOOLONG: The length of a component of either @p pszPath or - @p pszHardLink is longer than #REDCONF_NAME_MAX. - - #RED_ENOENT: A component of either path prefix does not exist; or the file - named by @p pszPath does not exist; or either @p pszPath or - @p pszHardLink, after removing the volume prefix, point to an empty - string. - - #RED_ENOSPC: There is insufficient free space to expand the directory that - would contain the link. - - #RED_ENOTDIR: A component of either path prefix is not a directory. - - #RED_EPERM: The @p pszPath argument names a directory. - - #RED_EROFS: The requested link requires writing in a directory on a - read-only file system. - - #RED_EUSERS: Cannot become a file system user: too many users. - - #RED_EXDEV: @p pszPath and @p pszHardLink are on different file system - volumes. -*/ -int32_t red_link( - const char *pszPath, - const char *pszHardLink) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - const char *pszLocalPath; - uint8_t bVolNum; - - ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath); - - if(ret == 0) - { - const char *pszLinkLocalPath; - uint8_t bLinkVolNum; - - ret = RedPathSplit(pszHardLink, &bLinkVolNum, &pszLinkLocalPath); - - if((ret == 0) && (bVolNum != bLinkVolNum)) - { - ret = -RED_EXDEV; - } - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - uint32_t ulInode; - - ret = RedPathLookup(pszLocalPath, &ulInode); - - if(ret == 0) - { - const char *pszLinkName; - uint32_t ulLinkPInode; - - ret = RedPathToName(pszLinkLocalPath, &ulLinkPInode, &pszLinkName); - - if(ret == 0) - { - ret = RedCoreLink(ulLinkPInode, pszLinkName, ulInode); - } - } - } - } - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -/** @brief Close a file descriptor. - - @param iFildes The file descriptor to close. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBADF: @p iFildes is not a valid file descriptor. - - #RED_EIO: A disk I/O error occurred. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_close( - int32_t iFildes) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - ret = FildesClose(iFildes); - - PosixLeave(); - } - - return PosixReturn(ret); -} - - -/** @brief Read from an open file. - - The read takes place at the file offset associated with @p iFildes and - advances the file offset by the number of bytes actually read. - - Data which has not yet been written, but which is before the end-of-file - (sparse data), will read as zeroes. A short read -- where the number of - bytes read is less than requested -- indicates that the requested read was - partially or, if zero bytes were read, entirely beyond the end-of-file. - - @param iFildes The file descriptor from which to read. - @param pBuffer The buffer to populate with data read. Must be at least - @p ulLength bytes in size. - @param ulLength Number of bytes to attempt to read. - - @return On success, returns a nonnegative value indicating the number of - bytes actually read. On error, -1 is returned and #red_errno is - set appropriately. - - Errno values - - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open - for reading. - - #RED_EINVAL: @p pBuffer is `NULL`; or @p ulLength exceeds INT32_MAX and - cannot be returned properly. - - #RED_EIO: A disk I/O error occurred. - - #RED_EISDIR: The @p iFildes is a file descriptor for a directory. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_read( - int32_t iFildes, - void *pBuffer, - uint32_t ulLength) -{ - uint32_t ulLenRead = 0U; - REDSTATUS ret; - int32_t iReturn; - - if(ulLength > (uint32_t)INT32_MAX) - { - ret = -RED_EINVAL; - } - else - { - ret = PosixEnter(); - } - - if(ret == 0) - { - REDHANDLE *pHandle; - - ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle); - - if((ret == 0) && ((pHandle->bFlags & HFLAG_READABLE) == 0U)) - { - ret = -RED_EBADF; - } - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(pHandle->bVolNum); - } - #endif - - if(ret == 0) - { - ulLenRead = ulLength; - ret = RedCoreFileRead(pHandle->ulInode, pHandle->ullOffset, &ulLenRead, pBuffer); - } - - if(ret == 0) - { - REDASSERT(ulLenRead <= ulLength); - - pHandle->ullOffset += ulLenRead; - } - - PosixLeave(); - } - - if(ret == 0) - { - iReturn = (int32_t)ulLenRead; - } - else - { - iReturn = PosixReturn(ret); - } - - return iReturn; -} - - -#if REDCONF_READ_ONLY == 0 -/** @brief Write to an open file. - - The write takes place at the file offset associated with @p iFildes and - advances the file offset by the number of bytes actually written. - Alternatively, if @p iFildes was opened with #RED_O_APPEND, the file offset - is set to the end-of-file before the write begins, and likewise advances by - the number of bytes actually written. - - A short write -- where the number of bytes written is less than requested - -- indicates either that the file system ran out of space but was still - able to write some of the request; or that the request would have caused - the file to exceed the maximum file size, but some of the data could be - written prior to the file size limit. - - If an error is returned (-1), either none of the data was written or a - critical error occurred (like an I/O error) and the file system volume will - be read-only. - - @param iFildes The file descriptor to write to. - @param pBuffer The buffer containing the data to be written. Must be at - least @p ulLength bytes in size. - @param ulLength Number of bytes to attempt to write. - - @return On success, returns a nonnegative value indicating the number of - bytes actually written. On error, -1 is returned and #red_errno is - set appropriately. - - Errno values - - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open - for writing. This includes the case where the file descriptor is for a - directory. - - #RED_EFBIG: No data can be written to the current file offset since the - resulting file size would exceed the maximum file size. - - #RED_EINVAL: @p pBuffer is `NULL`; or @p ulLength exceeds INT32_MAX and - cannot be returned properly. - - #RED_EIO: A disk I/O error occurred. - - #RED_ENOSPC: No data can be written because there is insufficient free - space. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_write( - int32_t iFildes, - const void *pBuffer, - uint32_t ulLength) -{ - uint32_t ulLenWrote = 0U; - REDSTATUS ret; - int32_t iReturn; - - if(ulLength > (uint32_t)INT32_MAX) - { - ret = -RED_EINVAL; - } - else - { - ret = PosixEnter(); - } - - if(ret == 0) - { - REDHANDLE *pHandle; - - ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle); - if(ret == -RED_EISDIR) - { - /* POSIX says that if a file descriptor is not writable, the - errno should be -RED_EBADF. Directory file descriptors are - never writable, and unlike for read(), the spec does not - list -RED_EISDIR as an allowed errno. Therefore -RED_EBADF - takes precedence. - */ - ret = -RED_EBADF; - } - - if((ret == 0) && ((pHandle->bFlags & HFLAG_WRITEABLE) == 0U)) - { - ret = -RED_EBADF; - } - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(pHandle->bVolNum); - } - #endif - - if((ret == 0) && ((pHandle->bFlags & HFLAG_APPENDING) != 0U)) - { - REDSTAT s; - - ret = RedCoreStat(pHandle->ulInode, &s); - if(ret == 0) - { - pHandle->ullOffset = s.st_size; - } - } - - if(ret == 0) - { - ulLenWrote = ulLength; - ret = RedCoreFileWrite(pHandle->ulInode, pHandle->ullOffset, &ulLenWrote, pBuffer); - } - - if(ret == 0) - { - REDASSERT(ulLenWrote <= ulLength); - - pHandle->ullOffset += ulLenWrote; - } - - PosixLeave(); - } - - if(ret == 0) - { - iReturn = (int32_t)ulLenWrote; - } - else - { - iReturn = PosixReturn(ret); - } - - return iReturn; -} -#endif - - -#if REDCONF_READ_ONLY == 0 -/** @brief Synchronizes changes to a file. - - Commits all changes associated with a file or directory (including file - data, directory contents, and metadata) to permanent storage. This - function will not return until the operation is complete. - - In the current implementation, this function has global effect. All dirty - buffers are flushed and a transaction point is committed. Fsyncing one - file effectively fsyncs all files. - - If fsync automatic transactions have been disabled, this function does - nothing and returns success. In the current implementation, this is the - only real difference between this function and red_transact(): this - function can be configured to do nothing, whereas red_transact() is - unconditional. - - Applications written for portability should avoid assuming red_fsync() - effects all files, and use red_fsync() on each file that needs to be - synchronized. - - Passing read-only file descriptors to this function is permitted. - - @param iFildes The file descriptor to synchronize. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBADF: The @p iFildes argument is not a valid file descriptor. - - #RED_EIO: A disk I/O error occurred. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_fsync( - int32_t iFildes) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - REDHANDLE *pHandle; - - ret = FildesToHandle(iFildes, FTYPE_EITHER, &pHandle); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(pHandle->bVolNum); - } - #endif - - /* No core event for fsync, so this transaction flag needs to be - implemented here. - */ - if(ret == 0) - { - uint32_t ulTransMask; - - ret = RedCoreTransMaskGet(&ulTransMask); - - if((ret == 0) && ((ulTransMask & RED_TRANSACT_FSYNC) != 0U)) - { - ret = RedCoreVolTransact(); - } - } - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -/** @brief Move the read/write file offset. - - The file offset of the @p iFildes file descriptor is set to @p llOffset, - relative to some starting position. The available positions are: - - - ::RED_SEEK_SET Seek from the start of the file. In other words, - @p llOffset becomes the new file offset. - - ::RED_SEEK_CUR Seek from the current file offset. In other words, - @p llOffset is added to the current file offset. - - ::RED_SEEK_END Seek from the end-of-file. In other words, the new file - offset is the file size plus @p llOffset. - - Since @p llOffset is signed (can be negative), it is possible to seek - backward with ::RED_SEEK_CUR or ::RED_SEEK_END. - - It is permitted to seek beyond the end-of-file; this does not increase the - file size (a subsequent red_write() call would). - - Unlike POSIX lseek, this function cannot be used with directory file - descriptors. - - @param iFildes The file descriptor whose offset is to be updated. - @param llOffset The new file offset, relative to @p whence. - @param whence The location from which @p llOffset should be applied. - - @return On success, returns the new file position, measured in bytes from - the beginning of the file. On error, -1 is returned and #red_errno - is set appropriately. - - Errno values - - #RED_EBADF: The @p iFildes argument is not an open file descriptor. - - #RED_EINVAL: @p whence is not a valid `RED_SEEK_` value; or the resulting - file offset would be negative or beyond the maximum file size. - - #RED_EIO: A disk I/O error occurred. - - #RED_EISDIR: The @p iFildes argument is a file descriptor for a directory. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int64_t red_lseek( - int32_t iFildes, - int64_t llOffset, - REDWHENCE whence) -{ - REDSTATUS ret; - int64_t llReturn = -1; /* Init'd to quiet warnings. */ - - ret = PosixEnter(); - if(ret == 0) - { - int64_t llFrom = 0; /* Init'd to quiet warnings. */ - REDHANDLE *pHandle; - - /* Unlike POSIX, we disallow lseek() on directory handles. - */ - ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(pHandle->bVolNum); - } - #endif - - if(ret == 0) - { - switch(whence) - { - /* Seek from the beginning of the file. - */ - case RED_SEEK_SET: - llFrom = 0; - break; - - /* Seek from the current file offset. - */ - case RED_SEEK_CUR: - REDASSERT(pHandle->ullOffset <= (uint64_t)INT64_MAX); - llFrom = (int64_t)pHandle->ullOffset; - break; - - /* Seek from the end of the file. - */ - case RED_SEEK_END: - { - REDSTAT s; - - ret = RedCoreStat(pHandle->ulInode, &s); - if(ret == 0) - { - REDASSERT(s.st_size <= (uint64_t)INT64_MAX); - llFrom = (int64_t)s.st_size; - } - - break; - } - - default: - ret = -RED_EINVAL; - break; - } - } - - if(ret == 0) - { - REDASSERT(llFrom >= 0); - - /* Avoid signed integer overflow from llFrom + llOffset with large - values of llOffset and nonzero llFrom values. Underflow isn't - possible since llFrom is nonnegative. - */ - if((llOffset > 0) && (((uint64_t)llFrom + (uint64_t)llOffset) > (uint64_t)INT64_MAX)) - { - ret = -RED_EINVAL; - } - else - { - int64_t llNewOffset = llFrom + llOffset; - - if((llNewOffset < 0) || ((uint64_t)llNewOffset > gpRedVolume->ullMaxInodeSize)) - { - /* Invalid file offset. - */ - ret = -RED_EINVAL; - } - else - { - pHandle->ullOffset = (uint64_t)llNewOffset; - llReturn = llNewOffset; - } - } - } - - PosixLeave(); - } - - if(ret != 0) - { - llReturn = PosixReturn(ret); - } - - return llReturn; -} - - -#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1) -/** @brief Truncate a file to a specified length. - - Allows the file size to be increased, decreased, or to remain the same. If - the file size is increased, the new area is sparse (will read as zeroes). - If the file size is decreased, the data beyond the new end-of-file will - return to free space once it is no longer part of the committed state - (either immediately or after the next transaction point). - - The value of the file offset is not modified by this function. - - Unlike POSIX ftruncate, this function can fail when the disk is full if - @p ullSize is non-zero. If decreasing the file size, this can be fixed by - transacting and trying again: Reliance Edge guarantees that it is possible - to perform a truncate of at least one file that decreases the file size - after a transaction point. If disk full transactions are enabled, this will - happen automatically. - - @param iFildes The file descriptor of the file to truncate. - @param ullSize The new size of the file. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open - for writing. This includes the case where the file descriptor is for a - directory. - - #RED_EFBIG: @p ullSize exceeds the maximum file size. - - #RED_EIO: A disk I/O error occurred. - - #RED_ENOSPC: Insufficient free space to perform the truncate. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_ftruncate( - int32_t iFildes, - uint64_t ullSize) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - REDHANDLE *pHandle; - - ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle); - if(ret == -RED_EISDIR) - { - /* Similar to red_write() (see comment there), the RED_EBADF error - for a non-writable file descriptor takes precedence. - */ - ret = -RED_EBADF; - } - - if((ret == 0) && ((pHandle->bFlags & HFLAG_WRITEABLE) == 0U)) - { - ret = -RED_EBADF; - } - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(pHandle->bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreFileTruncate(pHandle->ulInode, ullSize); - } - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif - - -/** @brief Get the status of a file or directory. - - See the ::REDSTAT type for the details of the information returned. - - @param iFildes An open file descriptor for the file whose information is - to be retrieved. - @param pStat Pointer to a ::REDSTAT buffer to populate. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBADF: The @p iFildes argument is not a valid file descriptor. - - #RED_EINVAL: @p pStat is `NULL`. - - #RED_EIO: A disk I/O error occurred. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_fstat( - int32_t iFildes, - REDSTAT *pStat) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - REDHANDLE *pHandle; - - ret = FildesToHandle(iFildes, FTYPE_EITHER, &pHandle); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(pHandle->bVolNum); - } - #endif - - if(ret == 0) - { - ret = RedCoreStat(pHandle->ulInode, pStat); - } - - PosixLeave(); - } - - return PosixReturn(ret); -} - - -#if REDCONF_API_POSIX_READDIR == 1 -/** @brief Open a directory stream for reading. - - @param pszPath The path of the directory to open. - - @return On success, returns a pointer to a ::REDDIR object that can be used - with red_readdir() and red_closedir(). On error, returns `NULL` - and #red_errno is set appropriately. - - Errno values - - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is - not mounted. - - #RED_EIO: A disk I/O error occurred. - - #RED_ENOENT: A component of @p pszPath does not exist; or the @p pszPath - argument, after removing the volume prefix, points to an empty string. - - #RED_ENOTDIR: A component of @p pszPath is a not a directory. - - #RED_EMFILE: There are no available file descriptors. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -REDDIR *red_opendir( - const char *pszPath) -{ - int32_t iFildes; - REDSTATUS ret; - REDDIR *pDir = NULL; - - ret = PosixEnter(); - if(ret == 0) - { - ret = FildesOpen(pszPath, RED_O_RDONLY, FTYPE_DIR, &iFildes); - if(ret == 0) - { - uint16_t uHandleIdx; - - FildesUnpack(iFildes, &uHandleIdx, NULL, NULL); - pDir = &gaHandle[uHandleIdx]; - } - - PosixLeave(); - } - - REDASSERT((pDir == NULL) == (ret != 0)); - - if(pDir == NULL) - { - red_errno = -ret; - } - - return pDir; -} - - -/** @brief Read from a directory stream. - - The ::REDDIRENT pointer returned by this function will be overwritten by - subsequent calls on the same @p pDir. Calls with other ::REDDIR objects - will *not* modify the returned ::REDDIRENT. - - If files are added to the directory after it is opened, the new files may - or may not be returned by this function. If files are deleted, the deleted - files will not be returned. - - This function (like its POSIX equivalent) returns `NULL` in two cases: on - error and when the end of the directory is reached. To distinguish between - these two cases, the application should set #red_errno to zero before - calling this function, and if `NULL` is returned, check if #red_errno is - still zero. If it is, the end of the directory was reached; otherwise, - there was an error. - - @param pDirStream The directory stream to read from. - - @return On success, returns a pointer to a ::REDDIRENT object which is - populated with directory entry information read from the directory. - On error, returns `NULL` and #red_errno is set appropriately. If at - the end of the directory, returns `NULL` but #red_errno is not - modified. - - Errno values - - #RED_EBADF: @p pDirStream is not an open directory stream. - - #RED_EIO: A disk I/O error occurred. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -REDDIRENT *red_readdir( - REDDIR *pDirStream) -{ - REDSTATUS ret; - REDDIRENT *pDirEnt = NULL; - - ret = PosixEnter(); - if(ret == 0) - { - if(!DirStreamIsValid(pDirStream)) - { - ret = -RED_EBADF; - } - #if REDCONF_VOLUME_COUNT > 1U - else - { - ret = RedCoreVolSetCurrent(pDirStream->bVolNum); - } - #endif - - if(ret == 0) - { - uint32_t ulDirPosition; - - /* To save memory, the directory position is stored in the same - location as the file offset. This would be a bit cleaner using - a union, but MISRA-C:2012 Rule 19.2 disallows unions. - */ - REDASSERT(pDirStream->ullOffset <= UINT32_MAX); - ulDirPosition = (uint32_t)pDirStream->ullOffset; - - ret = RedCoreDirRead(pDirStream->ulInode, &ulDirPosition, pDirStream->dirent.d_name, &pDirStream->dirent.d_ino); - - pDirStream->ullOffset = ulDirPosition; - - if(ret == 0) - { - /* POSIX extension: return stat information with the dirent. - */ - ret = RedCoreStat(pDirStream->dirent.d_ino, &pDirStream->dirent.d_stat); - if(ret == 0) - { - pDirEnt = &pDirStream->dirent; - } - } - else if(ret == -RED_ENOENT) - { - /* Reached the end of the directory; return NULL but do not set - errno. - */ - ret = 0; - } - else - { - /* Miscellaneous error; return NULL and set errno (done below). - */ - } - } - - PosixLeave(); - } - - if(ret != 0) - { - REDASSERT(pDirEnt == NULL); - - red_errno = -ret; - } - - return pDirEnt; -} - - -/** @brief Rewind a directory stream to read it from the beginning. - - Similar to closing the directory object and opening it again, but without - the need for the path. - - Since this function (like its POSIX equivalent) cannot return an error, - it takes no action in error conditions, such as when @p pDirStream is - invalid. - - @param pDirStream The directory stream to rewind. -*/ -void red_rewinddir( - REDDIR *pDirStream) -{ - if(PosixEnter() == 0) - { - if(DirStreamIsValid(pDirStream)) - { - pDirStream->ullOffset = 0U; - } - - PosixLeave(); - } -} - - -/** @brief Close a directory stream. - - After calling this function, @p pDirStream should no longer be used. - - @param pDirStream The directory stream to close. - - @return On success, zero is returned. On error, -1 is returned and - #red_errno is set appropriately. - - Errno values - - #RED_EBADF: @p pDirStream is not an open directory stream. - - #RED_EUSERS: Cannot become a file system user: too many users. -*/ -int32_t red_closedir( - REDDIR *pDirStream) -{ - REDSTATUS ret; - - ret = PosixEnter(); - if(ret == 0) - { - if(DirStreamIsValid(pDirStream)) - { - /* Mark this handle as unused. - */ - pDirStream->ulInode = INODE_INVALID; - } - else - { - ret = -RED_EBADF; - } - - PosixLeave(); - } - - return PosixReturn(ret); -} -#endif /* REDCONF_API_POSIX_READDIR */ - - -/** @brief Pointer to where the last file system error (errno) is stored. - - This function is intended to be used via the #red_errno macro, or a similar - user-defined macro, that can be used both as an lvalue (writable) and an - rvalue (readable). - - Under normal circumstances, the errno for each task is stored in a - different location. Applications do not need to worry about one task - obliterating an error value that another task needed to read. This task - errno for is initially zero. When one of the POSIX-like APIs returns an - indication of error, the location for the calling task will be populated - with the error value. - - In some circumstances, this function will return a pointer to a global - errno location which is shared by multiple tasks. If the calling task is - not registered as a file system user and all of the task slots are full, - there can be no task-specific errno, so the global pointer is returned. - Likewise, if the file system driver is uninitialized, there are no - registered file system users and this function always returns the pointer - to the global errno. Under these circumstances, multiple tasks - manipulating errno could be problematic. - - This function never returns `NULL` under any circumstances. The #red_errno - macro unconditionally dereferences the return value from this function, so - returning `NULL` could result in a fault. - - @return Pointer to where the errno value is stored for this task. -*/ -REDSTATUS *red_errnoptr(void) -{ - /* The global errno value, used in single-task configurations and when the - caller is not (and cannot become) a file system user (which includes - when the driver is uninitialized). - */ - static REDSTATUS iGlobalErrno = 0; - - #if REDCONF_TASK_COUNT == 1U - - return &iGlobalErrno; - - #else - - REDSTATUS *piErrno; - - if(gfPosixInited) - { - uint32_t ulTaskId = RedOsTaskId(); - uint32_t ulIdx; - - REDASSERT(ulTaskId != 0U); - - /* If this task has used the file system before, it will already have - a task slot, which includes the task-specific errno. - */ - RedOsMutexAcquire(); - - for(ulIdx = 0U; ulIdx < REDCONF_TASK_COUNT; ulIdx++) - { - if(gaTask[ulIdx].ulTaskId == ulTaskId) - { - break; - } - } - - RedOsMutexRelease(); - - if(ulIdx == REDCONF_TASK_COUNT) - { - REDSTATUS ret; - - /* This task is not a file system user, so try to register it as - one. This FS mutex must be held in order to register. - */ - RedOsMutexAcquire(); - - ret = TaskRegister(&ulIdx); - - RedOsMutexRelease(); - - if(ret == 0) - { - REDASSERT(gaTask[ulIdx].ulTaskId == RedOsTaskId()); - REDASSERT(gaTask[ulIdx].iErrno == 0); - - piErrno = &gaTask[ulIdx].iErrno; - } - else - { - /* Unable to register; use the global errno. - */ - piErrno = &iGlobalErrno; - } - } - else - { - piErrno = &gaTask[ulIdx].iErrno; - } - } - else - { - /* There are no registered file system tasks when the driver is - uninitialized, so use the global errno. - */ - piErrno = &iGlobalErrno; - } - - /* This function is not allowed to return NULL. - */ - REDASSERT(piErrno != NULL); - return piErrno; - - #endif -} -/** @} */ - -/*------------------------------------------------------------------- - Helper Functions --------------------------------------------------------------------*/ - -#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) - -/** @brief Remove a link to a file or directory. - - If the link count becomes zero, the file or directory is deleted. - - @param pszPath Path of the link to remove. - @param type The expected type of the path: file, directory, or either. - An error is returned if the expected type is file or - directory and does not match the path. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval -RED_EBUSY @p pszPath points to an inode with open handles - and a link count of one. - @retval -RED_EINVAL @p pszPath is `NULL`; or the volume containing - the path is not mounted. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_EISDIR @p type is ::FTYPE_FILE and the path names a - directory. - @retval -RED_ENAMETOOLONG @p pszName is too long. - @retval -RED_ENOENT The path does not name an existing file; or - @p pszPath, after removing the volume prefix, - points to an empty string. - @retval -RED_ENOTDIR @p type is ::FTYPE_DIR and the path does not - name a directory. - @retval -RED_ENOTEMPTY @p pszPath is a directory which is not empty. - @retval -RED_ENOSPC The file system does not have enough space to - modify the parent directory to perform the - deletion. -*/ -static REDSTATUS UnlinkSub( - const char *pszPath, - FTYPE type) -{ - uint8_t bVolNum; - const char *pszLocalPath; - REDSTATUS ret; - - ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath); - - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(bVolNum); - } - #endif - - if(ret == 0) - { - const char *pszName; - uint32_t ulPInode; - - ret = RedPathToName(pszLocalPath, &ulPInode, &pszName); - - if(ret == 0) - { - uint32_t ulInode; - - ret = RedCoreLookup(ulPInode, pszName, &ulInode); - - /* ModeTypeCheck() always passes when the type is FTYPE_EITHER, so - skip stat'ing the inode in that case. - */ - if((ret == 0) && (type != FTYPE_EITHER)) - { - REDSTAT InodeStat; - - ret = RedCoreStat(ulInode, &InodeStat); - if(ret == 0) - { - ret = ModeTypeCheck(InodeStat.st_mode, type); - } - } - - if(ret == 0) - { - ret = InodeUnlinkCheck(ulInode); - } - - if(ret == 0) - { - ret = RedCoreUnlink(ulPInode, pszName); - } - } - } - - return ret; -} -#endif /* (REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) */ - - -/** @brief Get a file descriptor for a path. - - @param pszPath Path to a file to open. - @param ulOpenMode The RED_O_* flags the descriptor is opened with. - @param type Indicates the expected descriptor type: file, directory, - or either. - @param piFildes On successful return, populated with the file - descriptor. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL @p piFildes is `NULL`; or @p pszPath is `NULL`; - or the volume is not mounted. - @retval -RED_EMFILE There are no available handles. - @retval -RED_EEXIST Using #RED_O_CREAT and #RED_O_EXCL, and the - indicated path already exists. - @retval -RED_EISDIR The path names a directory and @p ulOpenMode - includes #RED_O_WRONLY or #RED_O_RDWR. - @retval -RED_ENOENT #RED_O_CREAT is not set and the named file does - not exist; or #RED_O_CREAT is set and the parent - directory does not exist; or the volume does not - exist; or the @p pszPath argument, after - removing the volume prefix, points to an empty - string. - @retval -RED_EIO A disk I/O error occurred. - @retval -RED_ENAMETOOLONG The length of a component of @p pszPath is - longer than #REDCONF_NAME_MAX. - @retval -RED_ENFILE Attempting to create a file but the file system - has used all available inode slots. - @retval -RED_ENOSPC The file does not exist and #RED_O_CREAT was - specified, but there is insufficient free space - to expand the directory or to create the new - file. - @retval -RED_ENOTDIR A component of the prefix in @p pszPath does not - name a directory. - @retval -RED_EROFS The path resides on a read-only file system and - a write operation was requested. -*/ -static REDSTATUS FildesOpen( - const char *pszPath, - uint32_t ulOpenMode, - FTYPE type, - int32_t *piFildes) -{ - uint8_t bVolNum; - const char *pszLocalPath; - REDSTATUS ret; - - ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath); - - if(ret == 0) - { - if(piFildes == NULL) - { - ret = -RED_EINVAL; - } - #if REDCONF_READ_ONLY == 0 - else if(gaRedVolume[bVolNum].fReadOnly && (ulOpenMode != RED_O_RDONLY)) - { - ret = -RED_EROFS; - } - #endif - else - { - uint16_t uHandleIdx; - REDHANDLE *pHandle = NULL; - - /* Search for an unused handle. - */ - for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++) - { - if(gaHandle[uHandleIdx].ulInode == INODE_INVALID) - { - pHandle = &gaHandle[uHandleIdx]; - break; - } - } - - /* Error if all the handles are in use. - */ - if(pHandle == NULL) - { - ret = -RED_EMFILE; - } - else - { - bool fCreated = false; - uint16_t uMode = 0U; - uint32_t ulInode = 0U; /* Init'd to quiet warnings. */ - - #if REDCONF_VOLUME_COUNT > 1U - ret = RedCoreVolSetCurrent(bVolNum); - if(ret == 0) - #endif - { - #if REDCONF_READ_ONLY == 0 - if((ulOpenMode & RED_O_CREAT) != 0U) - { - uint32_t ulPInode; - const char *pszName; - - ret = RedPathToName(pszLocalPath, &ulPInode, &pszName); - if(ret == 0) - { - ret = RedCoreCreate(ulPInode, pszName, false, &ulInode); - if(ret == 0) - { - fCreated = true; - } - else if((ret == -RED_EEXIST) && ((ulOpenMode & RED_O_EXCL) == 0U)) - { - /* If the path already exists and that's OK, - lookup its inode number. - */ - ret = RedCoreLookup(ulPInode, pszName, &ulInode); - } - else - { - /* No action, just propagate the error. - */ - } - } - } - else - #endif - { - ret = RedPathLookup(pszLocalPath, &ulInode); - } - } - - /* If we created the inode, none of the below stuff is - necessary. This is important from an error handling - perspective -- we do not need code to delete the created - inode on error. - */ - if(!fCreated) - { - if(ret == 0) - { - REDSTAT s; - - ret = RedCoreStat(ulInode, &s); - if(ret == 0) - { - uMode = s.st_mode; - } - } - - /* Error if the inode is not of the expected type. - */ - if(ret == 0) - { - ret = ModeTypeCheck(uMode, type); - } - - /* Directories must always be opened with O_RDONLY. - */ - if((ret == 0) && RED_S_ISDIR(uMode) && ((ulOpenMode & RED_O_RDONLY) == 0U)) - { - ret = -RED_EISDIR; - } - - #if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1) - if((ret == 0) && ((ulOpenMode & RED_O_TRUNC) != 0U)) - { - ret = RedCoreFileTruncate(ulInode, UINT64_SUFFIX(0)); - } - #endif - } - - if(ret == 0) - { - int32_t iFildes; - - RedMemSet(pHandle, 0U, sizeof(*pHandle)); - - /* Populate this handle, marking it as in use. - */ - pHandle->ulInode = ulInode; - pHandle->bVolNum = bVolNum; - - if(RED_S_ISDIR(uMode)) - { - pHandle->bFlags |= HFLAG_DIRECTORY; - } - - if(((ulOpenMode & RED_O_RDONLY) != 0U) || ((ulOpenMode & RED_O_RDWR) != 0U)) - { - pHandle->bFlags |= HFLAG_READABLE; - } - - #if REDCONF_READ_ONLY == 0 - if(((ulOpenMode & RED_O_WRONLY) != 0U) || ((ulOpenMode & RED_O_RDWR) != 0U)) - { - pHandle->bFlags |= HFLAG_WRITEABLE; - } - - if((ulOpenMode & RED_O_APPEND) != 0U) - { - pHandle->bFlags |= HFLAG_APPENDING; - } - #endif - - iFildes = FildesPack(uHandleIdx, bVolNum); - if(iFildes == -1) - { - /* It should be impossible to get here, unless there - is memory corruption. - */ - REDERROR(); - ret = -RED_EFUBAR; - } - else - { - *piFildes = iFildes; - } - } - } - } - } - - return ret; -} - - -/** @brief Close a file descriptor. - - @param iFildes The file descriptor to close. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p iFildes is not a valid file descriptor. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS FildesClose( - int32_t iFildes) -{ - REDHANDLE *pHandle; - REDSTATUS ret; - - ret = FildesToHandle(iFildes, FTYPE_EITHER, &pHandle); - - #if REDCONF_READ_ONLY == 0 - #if REDCONF_VOLUME_COUNT > 1U - if(ret == 0) - { - ret = RedCoreVolSetCurrent(pHandle->bVolNum); - } - #endif - - /* No core event for close, so this transaction flag needs to be - implemented here. - */ - if(ret == 0) - { - uint32_t ulTransMask; - - ret = RedCoreTransMaskGet(&ulTransMask); - - if((ret == 0) && ((ulTransMask & RED_TRANSACT_CLOSE) != 0U)) - { - ret = RedCoreVolTransact(); - } - } - #endif - - if(ret == 0) - { - /* Mark this handle as unused. - */ - pHandle->ulInode = INODE_INVALID; - } - - return ret; -} - - -/** @brief Convert a file descriptor into a handle pointer. - - Also validates the file descriptor. - - @param iFildes The file descriptor for which to get a handle. - @param expectedType The expected type of the file descriptor: ::FTYPE_DIR, - ::FTYPE_FILE, or ::FTYPE_EITHER. - @param ppHandle On successful return, populated with a pointer to the - handle associated with @p iFildes. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p iFildes is not a valid file descriptor. - @retval -RED_EINVAL @p ppHandle is `NULL`. - @retval -RED_EISDIR Expected a file, but the file descriptor is for a - directory. - @retval -RED_ENOTDIR Expected a directory, but the file descriptor is for - a file. -*/ -static REDSTATUS FildesToHandle( - int32_t iFildes, - FTYPE expectedType, - REDHANDLE **ppHandle) -{ - REDSTATUS ret; - - if(ppHandle == NULL) - { - REDERROR(); - ret = -RED_EINVAL; - } - else if(iFildes < FD_MIN) - { - ret = -RED_EBADF; - } - else - { - uint16_t uHandleIdx; - uint8_t bVolNum; - uint16_t uGeneration; - - FildesUnpack(iFildes, &uHandleIdx, &bVolNum, &uGeneration); - - if( (uHandleIdx >= REDCONF_HANDLE_COUNT) - || (bVolNum >= REDCONF_VOLUME_COUNT) - || (gaHandle[uHandleIdx].ulInode == INODE_INVALID) - || (gaHandle[uHandleIdx].bVolNum != bVolNum) - || (gauGeneration[bVolNum] != uGeneration)) - { - ret = -RED_EBADF; - } - else if((expectedType == FTYPE_FILE) && ((gaHandle[uHandleIdx].bFlags & HFLAG_DIRECTORY) != 0U)) - { - ret = -RED_EISDIR; - } - else if((expectedType == FTYPE_DIR) && ((gaHandle[uHandleIdx].bFlags & HFLAG_DIRECTORY) == 0U)) - { - ret = -RED_ENOTDIR; - } - else - { - *ppHandle = &gaHandle[uHandleIdx]; - ret = 0; - } - } - - return ret; -} - - -/** @brief Pack a file descriptor. - - @param uHandleIdx The index of the file handle that will be associated - with this file descriptor. - @param bVolNum The volume which contains the file or directory this - file descriptor was opened against. - - @return The packed file descriptor. -*/ -static int32_t FildesPack( - uint16_t uHandleIdx, - uint8_t bVolNum) -{ - int32_t iFildes; - - if((uHandleIdx >= REDCONF_HANDLE_COUNT) || (bVolNum >= REDCONF_VOLUME_COUNT)) - { - REDERROR(); - iFildes = -1; - } - else - { - uint32_t ulFdBits; - - REDASSERT(gauGeneration[bVolNum] <= FD_GEN_MAX); - REDASSERT(gauGeneration[bVolNum] != 0U); - - ulFdBits = gauGeneration[bVolNum]; - ulFdBits <<= FD_VOL_BITS; - ulFdBits |= bVolNum; - ulFdBits <<= FD_IDX_BITS; - ulFdBits |= uHandleIdx; - - iFildes = (int32_t)ulFdBits; - - if(iFildes < FD_MIN) - { - REDERROR(); - iFildes = -1; - } - } - - return iFildes; -} - - -/** @brief Unpack a file descriptor. - - @param iFildes The file descriptor to unpack. - @param puHandleIdx If non-NULL, populated with the handle index extracted - from the file descriptor. - @param pbVolNum If non-NULL, populated with the volume number extracted - from the file descriptor. - @param puGeneration If non-NULL, populated with the generation number - extracted from the file descriptor. -*/ -static void FildesUnpack( - int32_t iFildes, - uint16_t *puHandleIdx, - uint8_t *pbVolNum, - uint16_t *puGeneration) -{ - uint32_t ulFdBits = (uint32_t)iFildes; - - REDASSERT(iFildes >= FD_MIN); - - if(puHandleIdx != NULL) - { - *puHandleIdx = (uint16_t)(ulFdBits & FD_IDX_MAX); - } - - ulFdBits >>= FD_IDX_BITS; - - if(pbVolNum != NULL) - { - *pbVolNum = (uint8_t)(ulFdBits & FD_VOL_MAX); - } - - ulFdBits >>= FD_VOL_BITS; - - if(puGeneration != NULL) - { - *puGeneration = (uint16_t)(ulFdBits & FD_GEN_MAX); - } -} - - -#if REDCONF_API_POSIX_READDIR == 1 -/** @brief Validate a directory stream object. - - @param pDirStream The directory stream to validate. - - @return Whether the directory stream is valid. - - @retval true The directory stream object appears valid. - @retval false The directory stream object is invalid. -*/ -static bool DirStreamIsValid( - const REDDIR *pDirStream) -{ - bool fRet = true; - - if(pDirStream == NULL) - { - fRet = false; - } - else - { - uint16_t uHandleIdx; - - /* pDirStream should be a pointer to one of the handles. - - A good compiler will optimize this loop into a bounds check and an - alignment check. - */ - for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++) - { - if(pDirStream == &gaHandle[uHandleIdx]) - { - break; - } - } - - if(uHandleIdx < REDCONF_HANDLE_COUNT) - { - /* The handle must be in use, have a valid volume number, and be a - directory handle. - */ - if( (pDirStream->ulInode == INODE_INVALID) - || (pDirStream->bVolNum >= REDCONF_VOLUME_COUNT) - || ((pDirStream->bFlags & HFLAG_DIRECTORY) == 0U)) - { - fRet = false; - } - } - else - { - /* pDirStream is a non-null pointer, but it is not a pointer to one - of our handles. - */ - fRet = false; - } - } - - return fRet; -} -#endif - - -/** @brief Enter the file system driver. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EINVAL The file system driver is uninitialized. - @retval -RED_EUSERS Cannot become a file system user: too many users. -*/ -static REDSTATUS PosixEnter(void) -{ - REDSTATUS ret; - - if(gfPosixInited) - { - #if REDCONF_TASK_COUNT > 1U - RedOsMutexAcquire(); - - ret = TaskRegister(NULL); - if(ret != 0) - { - RedOsMutexRelease(); - } - #else - ret = 0; - #endif - } - else - { - ret = -RED_EINVAL; - } - - return ret; -} - - -/** @brief Leave the file system driver. -*/ -static void PosixLeave(void) -{ - /* If the driver was uninitialized, PosixEnter() should have failed and we - should not be calling PosixLeave(). - */ - REDASSERT(gfPosixInited); - - #if REDCONF_TASK_COUNT > 1U - RedOsMutexRelease(); - #endif -} - - -/** @brief Check that a mode is consistent with the given expected type. - - @param uMode An inode mode, indicating whether the inode is a file - or a directory. - @param expectedType The expected type: ::FTYPE_FILE, ::FTYPE_DIR, or - ::FTYPE_EITHER. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EISDIR Expected type is file, actual type is directory. - @retval -RED_ENOTDIR Expected type is directory, actual type is file. -*/ -static REDSTATUS ModeTypeCheck( - uint16_t uMode, - FTYPE expectedType) -{ - REDSTATUS ret; - - if((expectedType == FTYPE_FILE) && RED_S_ISDIR(uMode)) - { - /* Expected file, found directory. - */ - ret = -RED_EISDIR; - } - else if((expectedType == FTYPE_DIR) && RED_S_ISREG(uMode)) - { - /* Expected directory, found file. - */ - ret = -RED_ENOTDIR; - } - else - { - /* No expected type or found what we expected. - */ - ret = 0; - } - - return ret; -} - - -#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) || ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1))) -/** @brief Check whether an inode can be unlinked. - - If an inode has a link count of 1 (meaning unlinking another name would - result in the deletion of the inode) and open handles, it cannot be deleted - since this would break open handles. - - @param ulInode The inode whose name is to be unlinked. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EBADF @p ulInode is not a valid inode. - @retval -RED_EBUSY The inode has a link count of one and open handles. - @retval -RED_EIO A disk I/O error occurred. -*/ -static REDSTATUS InodeUnlinkCheck( - uint32_t ulInode) -{ - uint16_t uHandleIdx; - REDSTATUS ret; - - #if REDCONF_API_POSIX_LINK == 0 - ret = 0; - #else - REDSTAT InodeStat; - - ret = RedCoreStat(ulInode, &InodeStat); - - /* We only need to check for open handles if the inode is down to its last - link. If it has multiple links, the inode will continue to exist, so - deleting the name will not break the open handles. - */ - if((ret == 0) && (InodeStat.st_nlink == 1U)) - #endif - { - for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++) - { - if((gaHandle[uHandleIdx].ulInode == ulInode) && (gaHandle[uHandleIdx].bVolNum == gbRedVolNum)) - { - ret = -RED_EBUSY; - break; - } - } - } - - return ret; -} -#endif - - -#if REDCONF_TASK_COUNT > 1U -/** @brief Register a task as a file system user, if it is not already - registered as one. - - The caller must hold the FS mutex. - - @param pulTaskIdx On successful return, if non-NULL, populated with the - index of the task slot assigned to the calling task. - This is populated whether or not the task had already - been registered. - - @return A negated ::REDSTATUS code indicating the operation result. - - @retval 0 Operation was successful. - @retval -RED_EUSERS Cannot become a file system user: too many users. -*/ -static REDSTATUS TaskRegister( - uint32_t *pulTaskIdx) -{ - uint32_t ulTaskId = RedOsTaskId(); - uint32_t ulFirstFreeIdx = REDCONF_TASK_COUNT; - uint32_t ulIdx; - REDSTATUS ret; - - REDASSERT(ulTaskId != 0U); - - /* Scan the task slots to determine if the task is registered as a file - system task. - */ - for(ulIdx = 0U; ulIdx < REDCONF_TASK_COUNT; ulIdx++) - { - if(gaTask[ulIdx].ulTaskId == ulTaskId) - { - break; - } - - if((ulFirstFreeIdx == REDCONF_TASK_COUNT) && (gaTask[ulIdx].ulTaskId == 0U)) - { - ulFirstFreeIdx = ulIdx; - } - } - - if(ulIdx == REDCONF_TASK_COUNT) - { - /* Task not already registered. - */ - if(ulFirstFreeIdx == REDCONF_TASK_COUNT) - { - /* Cannot register task, no more slots. - */ - ret = -RED_EUSERS; - } - else - { - /* Registering task. - */ - ulIdx = ulFirstFreeIdx; - gaTask[ulIdx].ulTaskId = ulTaskId; - ret = 0; - } - } - else - { - /* Task already registered. - */ - ret = 0; - } - - if((ret == 0) && (pulTaskIdx != NULL)) - { - *pulTaskIdx = ulIdx; - } - - return ret; -} -#endif /* REDCONF_TASK_COUNT > 1U */ - - -/** @brief Convert an error value into a simple 0 or -1 return. - - This function is simple, but what it does is needed in many places. It - returns zero if @p iError is zero (meaning success) or it returns -1 if - @p iError is nonzero (meaning error). Also, if @p iError is nonzero, it - is saved in red_errno. - - @param iError The error value. - - @return Returns 0 if @p iError is 0; otherwise, returns -1. -*/ -static int32_t PosixReturn( - REDSTATUS iError) -{ - int32_t iReturn; - - if(iError == 0) - { - iReturn = 0; - } - else - { - iReturn = -1; - - /* The errors should be negative, and errno positive. - */ - REDASSERT(iError < 0); - red_errno = -iError; - } - - return iReturn; -} - - -#endif /* REDCONF_API_POSIX == 1 */ - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implementation of the the Reliance Edge POSIX-like API. + */ + +#include + +#if REDCONF_API_POSIX == 1 + +/** @defgroup red_group_posix The POSIX-like File System Interface + * @{ + */ + + #include + #include + #include + #include + + +/*------------------------------------------------------------------- + * File Descriptors + * -------------------------------------------------------------------*/ + + #define FD_GEN_BITS 11U /* File descriptor bits for mount generation. */ + #define FD_VOL_BITS 8U /* File descriptor bits for volume number. */ + #define FD_IDX_BITS 12U /* File descriptor bits for handle index. */ + +/* 31 bits available: file descriptors are int32_t, but the sign bit must + * always be zero. + */ + #if ( FD_GEN_BITS + FD_VOL_BITS + FD_IDX_BITS ) > 31U + #error "Internal error: too many file descriptor bits!" + #endif + +/* Maximum values for file descriptor components. + */ + #define FD_GEN_MAX ( ( 1UL << FD_GEN_BITS ) - 1U ) + #define FD_VOL_MAX ( ( 1UL << FD_VOL_BITS ) - 1U ) + #define FD_IDX_MAX ( ( 1UL << FD_IDX_BITS ) - 1U ) + + #if REDCONF_VOLUME_COUNT > FD_VOL_MAX + #error "Error: Too many file system volumes!" + #endif + #if REDCONF_HANDLE_COUNT > ( FD_IDX_MAX + 1U ) + #error "Error: Too many file system handles!" + #endif + +/* File descriptors must never be negative; and must never be zero, one, or + * two, to avoid confusion with STDIN, STDOUT, and STDERR. + */ + #define FD_MIN ( 3 ) + +/*------------------------------------------------------------------- + * Handles + * -------------------------------------------------------------------*/ + +/* Mask of all RED_O_* values. + */ + #define RED_O_MASK ( RED_O_RDONLY | RED_O_WRONLY | RED_O_RDWR | RED_O_APPEND | RED_O_CREAT | RED_O_EXCL | RED_O_TRUNC ) + + #define HFLAG_DIRECTORY 0x01U /* Handle is for a directory. */ + #define HFLAG_READABLE 0x02U /* Handle is readable. */ + #define HFLAG_WRITEABLE 0x04U /* Handle is writeable. */ + #define HFLAG_APPENDING 0x08U /* Handle was opened in append mode. */ + +/* @brief Handle structure, used to implement file descriptors and directory + * streams. + */ + typedef struct sREDHANDLE + { + uint32_t ulInode; /**< Inode number; 0 if handle is available. */ + uint8_t bVolNum; /**< Volume containing the inode. */ + uint8_t bFlags; /**< Handle flags (type and mode). */ + uint64_t ullOffset; /**< File or directory offset. */ + #if REDCONF_API_POSIX_READDIR == 1 + REDDIRENT dirent; /**< Dirent structure returned by red_readdir(). */ + #endif + } REDHANDLE; + +/*------------------------------------------------------------------- + * Tasks + * -------------------------------------------------------------------*/ + + #if REDCONF_TASK_COUNT > 1U + +/* @brief Per-task information. + */ + typedef struct + { + uint32_t ulTaskId; /**< ID of the task which owns this slot; 0 if free. */ + REDSTATUS iErrno; /**< Last error value. */ + } TASKSLOT; + #endif + +/*------------------------------------------------------------------- + * Local Prototypes + * -------------------------------------------------------------------*/ + + #if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX_UNLINK == 1 ) || ( REDCONF_API_POSIX_RMDIR == 1 ) ) + static REDSTATUS UnlinkSub( const char * pszPath, + FTYPE type ); + #endif + static REDSTATUS FildesOpen( const char * pszPath, + uint32_t ulOpenMode, + FTYPE type, + int32_t * piFildes ); + static REDSTATUS FildesClose( int32_t iFildes ); + static REDSTATUS FildesToHandle( int32_t iFildes, + FTYPE expectedType, + REDHANDLE ** ppHandle ); + static int32_t FildesPack( uint16_t uHandleIdx, + uint8_t bVolNum ); + static void FildesUnpack( int32_t iFildes, + uint16_t * puHandleIdx, + uint8_t * pbVolNum, + uint16_t * puGeneration ); + #if REDCONF_API_POSIX_READDIR == 1 + static bool DirStreamIsValid( const REDDIR * pDirStream ); + #endif + static REDSTATUS PosixEnter( void ); + static void PosixLeave( void ); + static REDSTATUS ModeTypeCheck( uint16_t uMode, + FTYPE expectedType ); + #if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX_UNLINK == 1 ) || ( REDCONF_API_POSIX_RMDIR == 1 ) || ( ( REDCONF_API_POSIX_RENAME == 1 ) && ( REDCONF_RENAME_ATOMIC == 1 ) ) ) + static REDSTATUS InodeUnlinkCheck( uint32_t ulInode ); + #endif + #if REDCONF_TASK_COUNT > 1U + static REDSTATUS TaskRegister( uint32_t * pulTaskIdx ); + #endif + static int32_t PosixReturn( REDSTATUS iError ); + +/*------------------------------------------------------------------- + * Globals + * -------------------------------------------------------------------*/ + + static bool gfPosixInited; /* Whether driver is initialized. */ + static REDHANDLE gaHandle[ REDCONF_HANDLE_COUNT ]; /* Array of all handles. */ + #if REDCONF_TASK_COUNT > 1U + static TASKSLOT gaTask[ REDCONF_TASK_COUNT ]; /* Array of task slots. */ + #endif + +/* Array of volume mount "generations". These are incremented for a volume + * each time that volume is mounted. The generation number (along with the + * volume number) is incorporated into the file descriptors; a stale file + * descriptor from a previous mount can be detected since it will include a + * stale generation number. + */ + static uint16_t gauGeneration[ REDCONF_VOLUME_COUNT ]; + + +/*------------------------------------------------------------------- + * Public API + * -------------------------------------------------------------------*/ + +/** @brief Initialize the Reliance Edge file system driver. + * + * Prepares the Reliance Edge file system driver to be used. Must be the first + * Reliance Edge function to be invoked: no volumes can be mounted or formatted + * until the driver has been initialized. + * + * If this function is called when the Reliance Edge driver is already + * initialized, it does nothing and returns success. + * + * This function is not thread safe: attempting to initialize from multiple + * threads could leave things in a bad state. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EINVAL: The volume path prefix configuration is invalid. + */ + int32_t red_init( void ) + { + REDSTATUS ret; + + if( gfPosixInited ) + { + ret = 0; + } + else + { + ret = RedCoreInit(); + + if( ret == 0 ) + { + RedMemSet( gaHandle, 0U, sizeof( gaHandle ) ); + + #if REDCONF_TASK_COUNT > 1U + RedMemSet( gaTask, 0U, sizeof( gaTask ) ); + #endif + + gfPosixInited = true; + } + } + + return PosixReturn( ret ); + } + + +/** @brief Uninitialize the Reliance Edge file system driver. + * + * Tears down the Reliance Edge file system driver. Cannot be used until all + * Reliance Edge volumes are unmounted. A subsequent call to red_init() will + * initialize the driver again. + * + * If this function is called when the Reliance Edge driver is already + * uninitialized, it does nothing and returns success. + * + * This function is not thread safe: attempting to uninitialize from multiple + * threads could leave things in a bad state. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBUSY: At least one volume is still mounted. + */ + int32_t red_uninit( void ) + { + REDSTATUS ret; + + if( gfPosixInited ) + { + ret = PosixEnter(); + + if( ret == 0 ) + { + uint8_t bVolNum; + + for( bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++ ) + { + if( gaRedVolume[ bVolNum ].fMounted ) + { + ret = -RED_EBUSY; + break; + } + } + + if( ret == 0 ) + { + /* All volumes are unmounted. Mark the driver as + * uninitialized before releasing the FS mutex, to avoid any + * race condition where a volume could be mounted and then the + * driver uninitialized with a mounted volume. + */ + gfPosixInited = false; + } + + /* The FS mutex must be released before we uninitialize the core, + * since the FS mutex needs to be in the released state when it + * gets uninitialized. + * + * Don't use PosixLeave(), since it asserts gfPosixInited is true. + */ + #if REDCONF_TASK_COUNT > 1U + RedOsMutexRelease(); + #endif + } + + if( ret == 0 ) + { + ret = RedCoreUninit(); + + /* Not good if the above fails, since things might be partly, but + * not entirely, torn down, and there might not be a way back to + * a valid driver state. + */ + REDASSERT( ret == 0 ); + } + } + else + { + ret = 0; + } + + return PosixReturn( ret ); + } + + +/** @brief Mount a file system volume. + * + * Prepares the file system volume to be accessed. Mount will fail if the + * volume has never been formatted, or if the on-disk format is inconsistent + * with the compile-time configuration. + * + * An error is returned if the volume is already mounted. + * + * @param pszVolume A path prefix identifying the volume to mount. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBUSY: Volume is already mounted. + * - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized. + * - #RED_EIO: Volume not formatted, improperly formatted, or corrupt. + * - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_mount( const char * pszVolume ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + uint8_t bVolNum; + + ret = RedPathSplit( pszVolume, &bVolNum, NULL ); + + /* The core will return success if the volume is already mounted, so + * check for that condition here to propagate the error. + */ + if( ( ret == 0 ) && gaRedVolume[ bVolNum ].fMounted ) + { + ret = -RED_EBUSY; + } + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + ret = RedCoreVolMount(); + } + + if( ret == 0 ) + { + /* Increment the mount generation, invalidating file descriptors + * from previous mounts. Note that while the generation numbers + * are stored in 16-bit values, we have less than 16-bits to store + * generations in the file descriptors, so we must wrap-around + * manually. + */ + gauGeneration[ bVolNum ]++; + + if( gauGeneration[ bVolNum ] > FD_GEN_MAX ) + { + /* Wrap-around to one, rather than zero. The generation is + * stored in the top bits of the file descriptor, and doing + * this means that low numbers are never valid file + * descriptors. This implements the requirement that 0, 1, + * and 2 are never valid file descriptors, thereby avoiding + * confusion with STDIN, STDOUT, and STDERR. + */ + gauGeneration[ bVolNum ] = 1U; + } + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + + +/** @brief Unmount a file system volume. + * + * This function discards the in-memory state for the file system and marks it + * as unmounted. Subsequent attempts to access the volume will fail until the + * volume is mounted again. + * + * If unmount automatic transaction points are enabled, this function will + * commit a transaction point prior to unmounting. If unmount automatic + * transaction points are disabled, this function will unmount without + * transacting, effectively discarding the working state. + * + * Before unmounting, this function will wait for any active file system + * thread to complete by acquiring the FS mutex. The volume will be marked as + * unmounted before the FS mutex is released, so subsequent FS threads will + * possibly block and then see an error when attempting to access a volume + * which is unmounting or unmounted. If the volume has open handles, the + * unmount will fail. + * + * An error is returned if the volume is already unmounted. + * + * @param pszVolume A path prefix identifying the volume to unmount. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBUSY: There are still open handles for this file system volume. + * - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized; or + * the volume is already unmounted. + * - #RED_EIO: I/O error during unmount automatic transaction point. + * - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_umount( const char * pszVolume ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + uint8_t bVolNum; + + ret = RedPathSplit( pszVolume, &bVolNum, NULL ); + + /* The core will return success if the volume is already unmounted, so + * check for that condition here to propagate the error. + */ + if( ( ret == 0 ) && !gaRedVolume[ bVolNum ].fMounted ) + { + ret = -RED_EINVAL; + } + + if( ret == 0 ) + { + uint16_t uHandleIdx; + + /* Do not unmount the volume if it still has open handles. + */ + for( uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++ ) + { + const REDHANDLE * pHandle = &gaHandle[ uHandleIdx ]; + + if( ( pHandle->ulInode != INODE_INVALID ) && ( pHandle->bVolNum == bVolNum ) ) + { + ret = -RED_EBUSY; + break; + } + } + } + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + ret = RedCoreVolUnmount(); + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_FORMAT == 1 ) + +/** @brief Format a file system volume. + * + * Uses the statically defined volume configuration. After calling this + * function, the volume needs to be mounted -- see red_mount(). + * + * An error is returned if the volume is mounted. + * + * @param pszVolume A path prefix identifying the volume to format. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBUSY: Volume is mounted. + * - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized. + * - #RED_EIO: I/O error formatting the volume. + * - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_format( const char * pszVolume ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + uint8_t bVolNum; + + ret = RedPathSplit( pszVolume, &bVolNum, NULL ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + ret = RedCoreVolFormat(); + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_FORMAT == 1 ) */ + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Commit a transaction point. + * + * Reliance Edge is a transactional file system. All modifications, of both + * metadata and filedata, are initially working state. A transaction point + * is a process whereby the working state atomically becomes the committed + * state, replacing the previous committed state. Whenever Reliance Edge is + * mounted, including after power loss, the state of the file system after + * mount is the most recent committed state. Nothing from the committed + * state is ever missing, and nothing from the working state is ever included. + * + * @param pszVolume A path prefix identifying the volume to transact. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`. + * - #RED_EIO: I/O error during the transaction point. + * - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_transact( const char * pszVolume ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + uint8_t bVolNum; + + ret = RedPathSplit( pszVolume, &bVolNum, NULL ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + ret = RedCoreVolTransact(); + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if REDCONF_READ_ONLY == 0 */ + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Update the transaction mask. + * + * The following events are available: + * + * - #RED_TRANSACT_UMOUNT + * - #RED_TRANSACT_CREAT + * - #RED_TRANSACT_UNLINK + * - #RED_TRANSACT_MKDIR + * - #RED_TRANSACT_RENAME + * - #RED_TRANSACT_LINK + * - #RED_TRANSACT_CLOSE + * - #RED_TRANSACT_WRITE + * - #RED_TRANSACT_FSYNC + * - #RED_TRANSACT_TRUNCATE + * - #RED_TRANSACT_VOLFULL + * + * The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all + * automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask + * of all transaction flags, excluding those representing excluded + * functionality. + * + * Attempting to enable events for excluded functionality will result in an + * error. + * + * @param pszVolume The path prefix of the volume whose transaction mask is + * being changed. + * @param ulEventMask A bitwise-OR'd mask of automatic transaction events to + * be set as the current transaction mode. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or + * @p ulEventMask contains invalid bits. + * - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_settransmask( const char * pszVolume, + uint32_t ulEventMask ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + uint8_t bVolNum; + + ret = RedPathSplit( pszVolume, &bVolNum, NULL ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + ret = RedCoreTransMaskSet( ulEventMask ); + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if REDCONF_READ_ONLY == 0 */ + + +/** @brief Read the transaction mask. + * + * If the volume is read-only, the returned event mask is always zero. + * + * @param pszVolume The path prefix of the volume whose transaction mask is + * being retrieved. + * @param pulEventMask Populated with a bitwise-OR'd mask of automatic + * transaction events which represent the current + * transaction mode for the volume. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or + * @p pulEventMask is `NULL`. + * - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_gettransmask( const char * pszVolume, + uint32_t * pulEventMask ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + uint8_t bVolNum; + + ret = RedPathSplit( pszVolume, &bVolNum, NULL ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + ret = RedCoreTransMaskGet( pulEventMask ); + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + + +/** @brief Query file system status information. + * + * @p pszVolume should name a valid volume prefix or a valid root directory; + * this differs from POSIX statvfs, where any existing file or directory is a + * valid path. + * + * @param pszVolume The path prefix of the volume to query. + * @param pStatvfs The buffer to populate with volume information. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or + * @p pStatvfs is `NULL`. + * - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_statvfs( const char * pszVolume, + REDSTATFS * pStatvfs ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + uint8_t bVolNum; + + ret = RedPathSplit( pszVolume, &bVolNum, NULL ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + ret = RedCoreVolStat( pStatvfs ); + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + + +/** @brief Open a file or directory. + * + * Exactly one file access mode must be specified: + * + * - #RED_O_RDONLY: Open for reading only. + * - #RED_O_WRONLY: Open for writing only. + * - #RED_O_RDWR: Open for reading and writing. + * + * Directories can only be opened with `RED_O_RDONLY`. + * + * The following flags may also be used: + * + * - #RED_O_APPEND: Set the file offset to the end-of-file prior to each + * write. + * - #RED_O_CREAT: Create the named file if it does not exist. + * - #RED_O_EXCL: In combination with `RED_O_CREAT`, return an error if the + * path already exists. + * - #RED_O_TRUNC: Truncate the opened file to size zero. Only supported when + #REDCONF_API_POSIX_FTRUNCATE is true. + * + #RED_O_CREAT, #RED_O_EXCL, and #RED_O_TRUNC are invalid with #RED_O_RDONLY. + #RED_O_EXCL is invalid without #RED_O_CREAT. + * + * If the volume is read-only, #RED_O_RDONLY is the only valid open flag; use + * of any other flag will result in an error. + * + * If #RED_O_TRUNC frees data which is in the committed state, it will not + * return to free space until after a transaction point. + * + * The returned file descriptor must later be closed with red_close(). + * + * Unlike POSIX open, there is no optional third argument for the permissions + * (which Reliance Edge does not use) and other open flags (like `O_SYNC`) are + * not supported. + * + * @param pszPath The path to the file or directory. + * @param ulOpenMode The open flags (mask of `RED_O_` values). + * + * @return On success, a nonnegative file descriptor is returned. On error, + * -1 is returned and #red_errno is set appropriately. + * + * Errno values + * - #RED_EEXIST: Using #RED_O_CREAT and #RED_O_EXCL, and the indicated path + * already exists. + * - #RED_EINVAL: @p ulOpenMode is invalid; or @p pszPath is `NULL`; or the + * volume containing the path is not mounted. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_EISDIR: The path names a directory and @p ulOpenMode includes + #RED_O_WRONLY or #RED_O_RDWR. + * - #RED_EMFILE: There are no available file descriptors. + * - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than + #REDCONF_NAME_MAX. + * - #RED_ENFILE: Attempting to create a file but the file system has used all + * available inode slots. + * - #RED_ENOENT: #RED_O_CREAT is not set and the named file does not exist; or + #RED_O_CREAT is set and the parent directory does not exist; or the + * volume does not exist; or the @p pszPath argument, after removing the + * volume prefix, points to an empty string. + * - #RED_ENOSPC: The file does not exist and #RED_O_CREAT was specified, but + * there is insufficient free space to expand the directory or to create the + * new file. + * - #RED_ENOTDIR: A component of the prefix in @p pszPath does not name a + * directory. + * - #RED_EROFS: The path resides on a read-only file system and a write + * operation was requested. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_open( const char * pszPath, + uint32_t ulOpenMode ) + { + int32_t iFildes = -1; /* Init'd to quiet warnings. */ + REDSTATUS ret; + + #if REDCONF_READ_ONLY == 1 + if( ulOpenMode != RED_O_RDONLY ) + { + ret = -RED_EROFS; + } + #else + if( ( ulOpenMode != ( ulOpenMode & RED_O_MASK ) ) || + ( ( ulOpenMode & ( RED_O_RDONLY | RED_O_WRONLY | RED_O_RDWR ) ) == 0U ) || + ( ( ( ulOpenMode & RED_O_RDONLY ) != 0U ) && ( ( ulOpenMode & ( RED_O_WRONLY | RED_O_RDWR ) ) != 0U ) ) || + ( ( ( ulOpenMode & RED_O_WRONLY ) != 0U ) && ( ( ulOpenMode & ( RED_O_RDONLY | RED_O_RDWR ) ) != 0U ) ) || + ( ( ( ulOpenMode & RED_O_RDWR ) != 0U ) && ( ( ulOpenMode & ( RED_O_RDONLY | RED_O_WRONLY ) ) != 0U ) ) || + ( ( ( ulOpenMode & ( RED_O_TRUNC | RED_O_CREAT | RED_O_EXCL ) ) != 0U ) && ( ( ulOpenMode & RED_O_RDONLY ) != 0U ) ) || + ( ( ( ulOpenMode & RED_O_EXCL ) != 0U ) && ( ( ulOpenMode & RED_O_CREAT ) == 0U ) ) ) + { + ret = -RED_EINVAL; + } + + #if REDCONF_API_POSIX_FTRUNCATE == 0 + else if( ( ulOpenMode & RED_O_TRUNC ) != 0U ) + { + ret = -RED_EINVAL; + } + #endif + #endif /* if REDCONF_READ_ONLY == 1 */ + else + { + ret = PosixEnter(); + } + + if( ret == 0 ) + { + ret = FildesOpen( pszPath, ulOpenMode, FTYPE_EITHER, &iFildes ); + + PosixLeave(); + } + + if( ret != 0 ) + { + iFildes = PosixReturn( ret ); + } + + return iFildes; + } + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_UNLINK == 1 ) + +/** @brief Delete a file or directory. + * + * The given name is deleted and the link count of the corresponding inode is + * decremented. If the link count falls to zero (no remaining hard links), + * the inode will be deleted. + * + * Unlike POSIX unlink, deleting a file or directory with open handles (file + * descriptors or directory streams) will fail with an #RED_EBUSY error. This + * only applies when deleting an inode with a link count of one; if a file has + * multiple names (hard links), all but the last name may be deleted even if + * the file is open. + * + * If the path names a directory which is not empty, the unlink will fail. + * + * If the deletion frees data in the committed state, it will not return to + * free space until after a transaction point. + * + * Unlike POSIX unlink, this function can fail when the disk is full. To fix + * this, transact and try again: Reliance Edge guarantees that it is possible + * to delete at least one file or directory after a transaction point. If disk + * full automatic transactions are enabled, this will happen automatically. + * + * @param pszPath The path of the file or directory to delete. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBUSY: @p pszPath points to an inode with open handles and a link + * count of one. + * - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is + * not mounted. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than + #REDCONF_NAME_MAX. + * - #RED_ENOENT: The path does not name an existing file; or the @p pszPath + * argument, after removing the volume prefix, points to an empty string. + * - #RED_ENOTDIR: A component of the path prefix is not a directory. + * - #RED_ENOTEMPTY: The path names a directory which is not empty. + * - #RED_ENOSPC: The file system does not have enough space to modify the + * parent directory to perform the deletion. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_unlink( const char * pszPath ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + ret = UnlinkSub( pszPath, FTYPE_EITHER ); + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_UNLINK == 1 ) */ + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_MKDIR == 1 ) + +/** @brief Create a new directory. + * + * Unlike POSIX mkdir, this function has no second argument for the + * permissions (which Reliance Edge does not use). + * + * @param pszPath The name and location of the directory to create. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EEXIST: @p pszPath points to an existing file or directory. + * - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is + * not mounted. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than + #REDCONF_NAME_MAX. + * - #RED_ENOENT: A component of the path prefix does not name an existing + * directory; or the @p pszPath argument, after removing the volume prefix, + * points to an empty string. + * - #RED_ENOSPC: The file system does not have enough space for the new + * directory or to extend the parent directory of the new directory. + * - #RED_ENOTDIR: A component of the path prefix is not a directory. + * - #RED_EROFS: The parent directory resides on a read-only file system. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_mkdir( const char * pszPath ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + const char * pszLocalPath; + uint8_t bVolNum; + + ret = RedPathSplit( pszPath, &bVolNum, &pszLocalPath ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + const char * pszName; + uint32_t ulPInode; + + ret = RedPathToName( pszLocalPath, &ulPInode, &pszName ); + + if( ret == 0 ) + { + uint32_t ulInode; + + ret = RedCoreCreate( ulPInode, pszName, true, &ulInode ); + } + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_MKDIR == 1 ) */ + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RMDIR == 1 ) + +/** @brief Delete a directory. + * + * The given directory name is deleted and the corresponding directory inode + * will be deleted. + * + * Unlike POSIX rmdir, deleting a directory with open handles (file + * descriptors or directory streams) will fail with an #RED_EBUSY error. + * + * If the path names a directory which is not empty, the deletion will fail. + * If the path names the root directory of a file system volume, the deletion + * will fail. + * + * If the path names a regular file, the deletion will fail. This provides + * type checking and may be useful in cases where an application knows the + * path to be deleted should name a directory. + * + * If the deletion frees data in the committed state, it will not return to + * free space until after a transaction point. + * + * Unlike POSIX rmdir, this function can fail when the disk is full. To fix + * this, transact and try again: Reliance Edge guarantees that it is possible + * to delete at least one file or directory after a transaction point. If disk + * full automatic transactions are enabled, this will happen automatically. + * + * @param pszPath The path of the directory to delete. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBUSY: @p pszPath points to a directory with open handles. + * - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is + * not mounted. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than + #REDCONF_NAME_MAX. + * - #RED_ENOENT: The path does not name an existing directory; or the + * @p pszPath argument, after removing the volume prefix, points to an empty + * string. + * - #RED_ENOTDIR: A component of the path is not a directory. + * - #RED_ENOTEMPTY: The path names a directory which is not empty. + * - #RED_ENOSPC: The file system does not have enough space to modify the + * parent directory to perform the deletion. + * - #RED_EROFS: The directory to be removed resides on a read-only file + * system. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_rmdir( const char * pszPath ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + ret = UnlinkSub( pszPath, FTYPE_DIR ); + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RMDIR == 1 ) */ + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RENAME == 1 ) + +/** @brief Rename a file or directory. + * + * Both paths must reside on the same file system volume. Attempting to use + * this API to move a file to a different volume will result in an error. + * + * If @p pszNewPath names an existing file or directory, the behavior depends + * on the configuration. If #REDCONF_RENAME_ATOMIC is false, and if the + * destination name exists, this function always fails and sets #red_errno to + #RED_EEXIST. This behavior is contrary to POSIX. + * + * If #REDCONF_RENAME_ATOMIC is true, and if the new name exists, then in one + * atomic operation, @p pszNewPath is unlinked and @p pszOldPath is renamed to + * @p pszNewPath. Both @p pszNewPath and @p pszOldPath must be of the same + * type (both files or both directories). As with red_unlink(), if + * @p pszNewPath is a directory, it must be empty. The major exception to this + * behavior is that if both @p pszOldPath and @p pszNewPath are links to the + * same inode, then the rename does nothing and both names continue to exist. + * Unlike POSIX rename, if @p pszNewPath points to an inode with a link count + * of one and open handles (file descriptors or directory streams), the + * rename will fail with #RED_EBUSY. + * + * If the rename deletes the old destination, it may free data in the + * committed state, which will not return to free space until after a + * transaction point. Similarly, if the deleted inode was part of the + * committed state, the inode slot will not be available until after a + * transaction point. + * + * @param pszOldPath The path of the file or directory to rename. + * @param pszNewPath The new name and location after the rename. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBUSY: #REDCONF_RENAME_ATOMIC is true and @p pszNewPath points to an + * inode with open handles and a link count of one. + * - #RED_EEXIST: #REDCONF_RENAME_ATOMIC is false and @p pszNewPath exists. + * - #RED_EINVAL: @p pszOldPath is `NULL`; or @p pszNewPath is `NULL`; or the + * volume containing the path is not mounted. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_EISDIR: The @p pszNewPath argument names a directory and the + * @p pszOldPath argument names a non-directory. + * - #RED_ENAMETOOLONG: The length of a component of either @p pszOldPath or + * @p pszNewPath is longer than #REDCONF_NAME_MAX. + * - #RED_ENOENT: The link named by @p pszOldPath does not name an existing + * entry; or either @p pszOldPath or @p pszNewPath, after removing the volume + * prefix, point to an empty string. + * - #RED_ENOTDIR: A component of either path prefix is not a directory; or + * @p pszOldPath names a directory and @p pszNewPath names a file. + * - #RED_ENOTEMPTY: The path named by @p pszNewPath is a directory which is + * not empty. + * - #RED_ENOSPC: The file system does not have enough space to extend the + * directory that would contain @p pszNewPath. + * - #RED_EROFS: The directory to be removed resides on a read-only file + * system. + * - #RED_EUSERS: Cannot become a file system user: too many users. + * - #RED_EXDEV: @p pszOldPath and @p pszNewPath are on different file system + * volumes. + */ + int32_t red_rename( const char * pszOldPath, + const char * pszNewPath ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + const char * pszOldLocalPath; + uint8_t bOldVolNum; + + ret = RedPathSplit( pszOldPath, &bOldVolNum, &pszOldLocalPath ); + + if( ret == 0 ) + { + const char * pszNewLocalPath; + uint8_t bNewVolNum; + + ret = RedPathSplit( pszNewPath, &bNewVolNum, &pszNewLocalPath ); + + if( ( ret == 0 ) && ( bOldVolNum != bNewVolNum ) ) + { + ret = -RED_EXDEV; + } + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bOldVolNum ); + } + #endif + + if( ret == 0 ) + { + const char * pszOldName; + uint32_t ulOldPInode; + + ret = RedPathToName( pszOldLocalPath, &ulOldPInode, &pszOldName ); + + if( ret == 0 ) + { + const char * pszNewName; + uint32_t ulNewPInode; + + ret = RedPathToName( pszNewLocalPath, &ulNewPInode, &pszNewName ); + + #if REDCONF_RENAME_ATOMIC == 1 + if( ret == 0 ) + { + uint32_t ulDestInode; + + ret = RedCoreLookup( ulNewPInode, pszNewName, &ulDestInode ); + + if( ret == 0 ) + { + ret = InodeUnlinkCheck( ulDestInode ); + } + else if( ret == -RED_ENOENT ) + { + ret = 0; + } + else + { + /* Unexpected error, nothing to do. + */ + } + } + #endif /* if REDCONF_RENAME_ATOMIC == 1 */ + + if( ret == 0 ) + { + ret = RedCoreRename( ulOldPInode, pszOldName, ulNewPInode, pszNewName ); + } + } + } + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RENAME == 1 ) */ + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_LINK == 1 ) + +/** @brief Create a hard link. + * + * This creates an additional name (link) for the file named by @p pszPath. + * The new name refers to the same file with the same contents. If a name is + * deleted, but the underlying file has other names, the file continues to + * exist. The link count (accessible via red_fstat()) indicates the number of + * names that a file has. All of a file's names are on equal footing: there + * is nothing special about the original name. + * + * If @p pszPath names a directory, the operation will fail. + * + * @param pszPath The path indicating the inode for the new link. + * @param pszHardLink The name and location for the new link. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EEXIST: @p pszHardLink resolves to an existing file. + * - #RED_EINVAL: @p pszPath or @p pszHardLink is `NULL`; or the volume + * containing the paths is not mounted. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_EMLINK: Creating the link would exceed the maximum link count of the + * inode named by @p pszPath. + * - #RED_ENAMETOOLONG: The length of a component of either @p pszPath or + * @p pszHardLink is longer than #REDCONF_NAME_MAX. + * - #RED_ENOENT: A component of either path prefix does not exist; or the file + * named by @p pszPath does not exist; or either @p pszPath or + * @p pszHardLink, after removing the volume prefix, point to an empty + * string. + * - #RED_ENOSPC: There is insufficient free space to expand the directory that + * would contain the link. + * - #RED_ENOTDIR: A component of either path prefix is not a directory. + * - #RED_EPERM: The @p pszPath argument names a directory. + * - #RED_EROFS: The requested link requires writing in a directory on a + * read-only file system. + * - #RED_EUSERS: Cannot become a file system user: too many users. + * - #RED_EXDEV: @p pszPath and @p pszHardLink are on different file system + * volumes. + */ + int32_t red_link( const char * pszPath, + const char * pszHardLink ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + const char * pszLocalPath; + uint8_t bVolNum; + + ret = RedPathSplit( pszPath, &bVolNum, &pszLocalPath ); + + if( ret == 0 ) + { + const char * pszLinkLocalPath; + uint8_t bLinkVolNum; + + ret = RedPathSplit( pszHardLink, &bLinkVolNum, &pszLinkLocalPath ); + + if( ( ret == 0 ) && ( bVolNum != bLinkVolNum ) ) + { + ret = -RED_EXDEV; + } + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + uint32_t ulInode; + + ret = RedPathLookup( pszLocalPath, &ulInode ); + + if( ret == 0 ) + { + const char * pszLinkName; + uint32_t ulLinkPInode; + + ret = RedPathToName( pszLinkLocalPath, &ulLinkPInode, &pszLinkName ); + + if( ret == 0 ) + { + ret = RedCoreLink( ulLinkPInode, pszLinkName, ulInode ); + } + } + } + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_LINK == 1 ) */ + + +/** @brief Close a file descriptor. + * + * @param iFildes The file descriptor to close. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBADF: @p iFildes is not a valid file descriptor. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_close( int32_t iFildes ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + ret = FildesClose( iFildes ); + + PosixLeave(); + } + + return PosixReturn( ret ); + } + + +/** @brief Read from an open file. + * + * The read takes place at the file offset associated with @p iFildes and + * advances the file offset by the number of bytes actually read. + * + * Data which has not yet been written, but which is before the end-of-file + * (sparse data), will read as zeroes. A short read -- where the number of + * bytes read is less than requested -- indicates that the requested read was + * partially or, if zero bytes were read, entirely beyond the end-of-file. + * + * @param iFildes The file descriptor from which to read. + * @param pBuffer The buffer to populate with data read. Must be at least + * @p ulLength bytes in size. + * @param ulLength Number of bytes to attempt to read. + * + * @return On success, returns a nonnegative value indicating the number of + * bytes actually read. On error, -1 is returned and #red_errno is + * set appropriately. + * + * Errno values + * - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open + * for reading. + * - #RED_EINVAL: @p pBuffer is `NULL`; or @p ulLength exceeds INT32_MAX and + * cannot be returned properly. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_EISDIR: The @p iFildes is a file descriptor for a directory. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_read( int32_t iFildes, + void * pBuffer, + uint32_t ulLength ) + { + uint32_t ulLenRead = 0U; + REDSTATUS ret; + int32_t iReturn; + + if( ulLength > ( uint32_t ) INT32_MAX ) + { + ret = -RED_EINVAL; + } + else + { + ret = PosixEnter(); + } + + if( ret == 0 ) + { + REDHANDLE * pHandle; + + ret = FildesToHandle( iFildes, FTYPE_FILE, &pHandle ); + + if( ( ret == 0 ) && ( ( pHandle->bFlags & HFLAG_READABLE ) == 0U ) ) + { + ret = -RED_EBADF; + } + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( pHandle->bVolNum ); + } + #endif + + if( ret == 0 ) + { + ulLenRead = ulLength; + ret = RedCoreFileRead( pHandle->ulInode, pHandle->ullOffset, &ulLenRead, pBuffer ); + } + + if( ret == 0 ) + { + REDASSERT( ulLenRead <= ulLength ); + + pHandle->ullOffset += ulLenRead; + } + + PosixLeave(); + } + + if( ret == 0 ) + { + iReturn = ( int32_t ) ulLenRead; + } + else + { + iReturn = PosixReturn( ret ); + } + + return iReturn; + } + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Write to an open file. + * + * The write takes place at the file offset associated with @p iFildes and + * advances the file offset by the number of bytes actually written. + * Alternatively, if @p iFildes was opened with #RED_O_APPEND, the file offset + * is set to the end-of-file before the write begins, and likewise advances by + * the number of bytes actually written. + * + * A short write -- where the number of bytes written is less than requested + * -- indicates either that the file system ran out of space but was still + * able to write some of the request; or that the request would have caused + * the file to exceed the maximum file size, but some of the data could be + * written prior to the file size limit. + * + * If an error is returned (-1), either none of the data was written or a + * critical error occurred (like an I/O error) and the file system volume will + * be read-only. + * + * @param iFildes The file descriptor to write to. + * @param pBuffer The buffer containing the data to be written. Must be at + * least @p ulLength bytes in size. + * @param ulLength Number of bytes to attempt to write. + * + * @return On success, returns a nonnegative value indicating the number of + * bytes actually written. On error, -1 is returned and #red_errno is + * set appropriately. + * + * Errno values + * - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open + * for writing. This includes the case where the file descriptor is for a + * directory. + * - #RED_EFBIG: No data can be written to the current file offset since the + * resulting file size would exceed the maximum file size. + * - #RED_EINVAL: @p pBuffer is `NULL`; or @p ulLength exceeds INT32_MAX and + * cannot be returned properly. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_ENOSPC: No data can be written because there is insufficient free + * space. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_write( int32_t iFildes, + const void * pBuffer, + uint32_t ulLength ) + { + uint32_t ulLenWrote = 0U; + REDSTATUS ret; + int32_t iReturn; + + if( ulLength > ( uint32_t ) INT32_MAX ) + { + ret = -RED_EINVAL; + } + else + { + ret = PosixEnter(); + } + + if( ret == 0 ) + { + REDHANDLE * pHandle; + + ret = FildesToHandle( iFildes, FTYPE_FILE, &pHandle ); + + if( ret == -RED_EISDIR ) + { + /* POSIX says that if a file descriptor is not writable, the + * errno should be -RED_EBADF. Directory file descriptors are + * never writable, and unlike for read(), the spec does not + * list -RED_EISDIR as an allowed errno. Therefore -RED_EBADF + * takes precedence. + */ + ret = -RED_EBADF; + } + + if( ( ret == 0 ) && ( ( pHandle->bFlags & HFLAG_WRITEABLE ) == 0U ) ) + { + ret = -RED_EBADF; + } + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( pHandle->bVolNum ); + } + #endif + + if( ( ret == 0 ) && ( ( pHandle->bFlags & HFLAG_APPENDING ) != 0U ) ) + { + REDSTAT s; + + ret = RedCoreStat( pHandle->ulInode, &s ); + + if( ret == 0 ) + { + pHandle->ullOffset = s.st_size; + } + } + + if( ret == 0 ) + { + ulLenWrote = ulLength; + ret = RedCoreFileWrite( pHandle->ulInode, pHandle->ullOffset, &ulLenWrote, pBuffer ); + } + + if( ret == 0 ) + { + REDASSERT( ulLenWrote <= ulLength ); + + pHandle->ullOffset += ulLenWrote; + } + + PosixLeave(); + } + + if( ret == 0 ) + { + iReturn = ( int32_t ) ulLenWrote; + } + else + { + iReturn = PosixReturn( ret ); + } + + return iReturn; + } + #endif /* if REDCONF_READ_ONLY == 0 */ + + + #if REDCONF_READ_ONLY == 0 + +/** @brief Synchronizes changes to a file. + * + * Commits all changes associated with a file or directory (including file + * data, directory contents, and metadata) to permanent storage. This + * function will not return until the operation is complete. + * + * In the current implementation, this function has global effect. All dirty + * buffers are flushed and a transaction point is committed. Fsyncing one + * file effectively fsyncs all files. + * + * If fsync automatic transactions have been disabled, this function does + * nothing and returns success. In the current implementation, this is the + * only real difference between this function and red_transact(): this + * function can be configured to do nothing, whereas red_transact() is + * unconditional. + * + * Applications written for portability should avoid assuming red_fsync() + * effects all files, and use red_fsync() on each file that needs to be + * synchronized. + * + * Passing read-only file descriptors to this function is permitted. + * + * @param iFildes The file descriptor to synchronize. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBADF: The @p iFildes argument is not a valid file descriptor. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_fsync( int32_t iFildes ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + REDHANDLE * pHandle; + + ret = FildesToHandle( iFildes, FTYPE_EITHER, &pHandle ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( pHandle->bVolNum ); + } + #endif + + /* No core event for fsync, so this transaction flag needs to be + * implemented here. + */ + if( ret == 0 ) + { + uint32_t ulTransMask; + + ret = RedCoreTransMaskGet( &ulTransMask ); + + if( ( ret == 0 ) && ( ( ulTransMask & RED_TRANSACT_FSYNC ) != 0U ) ) + { + ret = RedCoreVolTransact(); + } + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if REDCONF_READ_ONLY == 0 */ + + +/** @brief Move the read/write file offset. + * + * The file offset of the @p iFildes file descriptor is set to @p llOffset, + * relative to some starting position. The available positions are: + * + * - ::RED_SEEK_SET Seek from the start of the file. In other words, + * @p llOffset becomes the new file offset. + * - ::RED_SEEK_CUR Seek from the current file offset. In other words, + * @p llOffset is added to the current file offset. + * - ::RED_SEEK_END Seek from the end-of-file. In other words, the new file + * offset is the file size plus @p llOffset. + * + * Since @p llOffset is signed (can be negative), it is possible to seek + * backward with ::RED_SEEK_CUR or ::RED_SEEK_END. + * + * It is permitted to seek beyond the end-of-file; this does not increase the + * file size (a subsequent red_write() call would). + * + * Unlike POSIX lseek, this function cannot be used with directory file + * descriptors. + * + * @param iFildes The file descriptor whose offset is to be updated. + * @param llOffset The new file offset, relative to @p whence. + * @param whence The location from which @p llOffset should be applied. + * + * @return On success, returns the new file position, measured in bytes from + * the beginning of the file. On error, -1 is returned and #red_errno + * is set appropriately. + * + * Errno values + * - #RED_EBADF: The @p iFildes argument is not an open file descriptor. + * - #RED_EINVAL: @p whence is not a valid `RED_SEEK_` value; or the resulting + * file offset would be negative or beyond the maximum file size. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_EISDIR: The @p iFildes argument is a file descriptor for a directory. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int64_t red_lseek( int32_t iFildes, + int64_t llOffset, + REDWHENCE whence ) + { + REDSTATUS ret; + int64_t llReturn = -1; /* Init'd to quiet warnings. */ + + ret = PosixEnter(); + + if( ret == 0 ) + { + int64_t llFrom = 0; /* Init'd to quiet warnings. */ + REDHANDLE * pHandle; + + /* Unlike POSIX, we disallow lseek() on directory handles. + */ + ret = FildesToHandle( iFildes, FTYPE_FILE, &pHandle ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( pHandle->bVolNum ); + } + #endif + + if( ret == 0 ) + { + switch( whence ) + { + /* Seek from the beginning of the file. + */ + case RED_SEEK_SET: + llFrom = 0; + break; + + /* Seek from the current file offset. + */ + case RED_SEEK_CUR: + REDASSERT( pHandle->ullOffset <= ( uint64_t ) INT64_MAX ); + llFrom = ( int64_t ) pHandle->ullOffset; + break; + + /* Seek from the end of the file. + */ + case RED_SEEK_END: + { + REDSTAT s; + + ret = RedCoreStat( pHandle->ulInode, &s ); + + if( ret == 0 ) + { + REDASSERT( s.st_size <= ( uint64_t ) INT64_MAX ); + llFrom = ( int64_t ) s.st_size; + } + + break; + } + + default: + ret = -RED_EINVAL; + break; + } + } + + if( ret == 0 ) + { + REDASSERT( llFrom >= 0 ); + + /* Avoid signed integer overflow from llFrom + llOffset with large + * values of llOffset and nonzero llFrom values. Underflow isn't + * possible since llFrom is nonnegative. + */ + if( ( llOffset > 0 ) && ( ( ( uint64_t ) llFrom + ( uint64_t ) llOffset ) > ( uint64_t ) INT64_MAX ) ) + { + ret = -RED_EINVAL; + } + else + { + int64_t llNewOffset = llFrom + llOffset; + + if( ( llNewOffset < 0 ) || ( ( uint64_t ) llNewOffset > gpRedVolume->ullMaxInodeSize ) ) + { + /* Invalid file offset. + */ + ret = -RED_EINVAL; + } + else + { + pHandle->ullOffset = ( uint64_t ) llNewOffset; + llReturn = llNewOffset; + } + } + } + + PosixLeave(); + } + + if( ret != 0 ) + { + llReturn = PosixReturn( ret ); + } + + return llReturn; + } + + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_FTRUNCATE == 1 ) + +/** @brief Truncate a file to a specified length. + * + * Allows the file size to be increased, decreased, or to remain the same. If + * the file size is increased, the new area is sparse (will read as zeroes). + * If the file size is decreased, the data beyond the new end-of-file will + * return to free space once it is no longer part of the committed state + * (either immediately or after the next transaction point). + * + * The value of the file offset is not modified by this function. + * + * Unlike POSIX ftruncate, this function can fail when the disk is full if + * @p ullSize is non-zero. If decreasing the file size, this can be fixed by + * transacting and trying again: Reliance Edge guarantees that it is possible + * to perform a truncate of at least one file that decreases the file size + * after a transaction point. If disk full transactions are enabled, this will + * happen automatically. + * + * @param iFildes The file descriptor of the file to truncate. + * @param ullSize The new size of the file. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open + * for writing. This includes the case where the file descriptor is for a + * directory. + * - #RED_EFBIG: @p ullSize exceeds the maximum file size. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_ENOSPC: Insufficient free space to perform the truncate. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_ftruncate( int32_t iFildes, + uint64_t ullSize ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + REDHANDLE * pHandle; + + ret = FildesToHandle( iFildes, FTYPE_FILE, &pHandle ); + + if( ret == -RED_EISDIR ) + { + /* Similar to red_write() (see comment there), the RED_EBADF error + * for a non-writable file descriptor takes precedence. + */ + ret = -RED_EBADF; + } + + if( ( ret == 0 ) && ( ( pHandle->bFlags & HFLAG_WRITEABLE ) == 0U ) ) + { + ret = -RED_EBADF; + } + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( pHandle->bVolNum ); + } + #endif + + if( ret == 0 ) + { + ret = RedCoreFileTruncate( pHandle->ulInode, ullSize ); + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_FTRUNCATE == 1 ) */ + + +/** @brief Get the status of a file or directory. + * + * See the ::REDSTAT type for the details of the information returned. + * + * @param iFildes An open file descriptor for the file whose information is + * to be retrieved. + * @param pStat Pointer to a ::REDSTAT buffer to populate. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBADF: The @p iFildes argument is not a valid file descriptor. + * - #RED_EINVAL: @p pStat is `NULL`. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_fstat( int32_t iFildes, + REDSTAT * pStat ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + REDHANDLE * pHandle; + + ret = FildesToHandle( iFildes, FTYPE_EITHER, &pHandle ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( pHandle->bVolNum ); + } + #endif + + if( ret == 0 ) + { + ret = RedCoreStat( pHandle->ulInode, pStat ); + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + + + #if REDCONF_API_POSIX_READDIR == 1 + +/** @brief Open a directory stream for reading. + * + * @param pszPath The path of the directory to open. + * + * @return On success, returns a pointer to a ::REDDIR object that can be used + * with red_readdir() and red_closedir(). On error, returns `NULL` + * and #red_errno is set appropriately. + * + * Errno values + * - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is + * not mounted. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_ENOENT: A component of @p pszPath does not exist; or the @p pszPath + * argument, after removing the volume prefix, points to an empty string. + * - #RED_ENOTDIR: A component of @p pszPath is a not a directory. + * - #RED_EMFILE: There are no available file descriptors. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + REDDIR * red_opendir( const char * pszPath ) + { + int32_t iFildes; + REDSTATUS ret; + REDDIR * pDir = NULL; + + ret = PosixEnter(); + + if( ret == 0 ) + { + ret = FildesOpen( pszPath, RED_O_RDONLY, FTYPE_DIR, &iFildes ); + + if( ret == 0 ) + { + uint16_t uHandleIdx; + + FildesUnpack( iFildes, &uHandleIdx, NULL, NULL ); + pDir = &gaHandle[ uHandleIdx ]; + } + + PosixLeave(); + } + + REDASSERT( ( pDir == NULL ) == ( ret != 0 ) ); + + if( pDir == NULL ) + { + red_errno = -ret; + } + + return pDir; + } + + +/** @brief Read from a directory stream. + * + * The ::REDDIRENT pointer returned by this function will be overwritten by + * subsequent calls on the same @p pDir. Calls with other ::REDDIR objects + * will *not* modify the returned ::REDDIRENT. + * + * If files are added to the directory after it is opened, the new files may + * or may not be returned by this function. If files are deleted, the deleted + * files will not be returned. + * + * This function (like its POSIX equivalent) returns `NULL` in two cases: on + * error and when the end of the directory is reached. To distinguish between + * these two cases, the application should set #red_errno to zero before + * calling this function, and if `NULL` is returned, check if #red_errno is + * still zero. If it is, the end of the directory was reached; otherwise, + * there was an error. + * + * @param pDirStream The directory stream to read from. + * + * @return On success, returns a pointer to a ::REDDIRENT object which is + * populated with directory entry information read from the directory. + * On error, returns `NULL` and #red_errno is set appropriately. If at + * the end of the directory, returns `NULL` but #red_errno is not + * modified. + * + * Errno values + * - #RED_EBADF: @p pDirStream is not an open directory stream. + * - #RED_EIO: A disk I/O error occurred. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + REDDIRENT * red_readdir( REDDIR * pDirStream ) + { + REDSTATUS ret; + REDDIRENT * pDirEnt = NULL; + + ret = PosixEnter(); + + if( ret == 0 ) + { + if( !DirStreamIsValid( pDirStream ) ) + { + ret = -RED_EBADF; + } + + #if REDCONF_VOLUME_COUNT > 1U + else + { + ret = RedCoreVolSetCurrent( pDirStream->bVolNum ); + } + #endif + + if( ret == 0 ) + { + uint32_t ulDirPosition; + + /* To save memory, the directory position is stored in the same + * location as the file offset. This would be a bit cleaner using + * a union, but MISRA-C:2012 Rule 19.2 disallows unions. + */ + REDASSERT( pDirStream->ullOffset <= UINT32_MAX ); + ulDirPosition = ( uint32_t ) pDirStream->ullOffset; + + ret = RedCoreDirRead( pDirStream->ulInode, &ulDirPosition, pDirStream->dirent.d_name, &pDirStream->dirent.d_ino ); + + pDirStream->ullOffset = ulDirPosition; + + if( ret == 0 ) + { + /* POSIX extension: return stat information with the dirent. + */ + ret = RedCoreStat( pDirStream->dirent.d_ino, &pDirStream->dirent.d_stat ); + + if( ret == 0 ) + { + pDirEnt = &pDirStream->dirent; + } + } + else if( ret == -RED_ENOENT ) + { + /* Reached the end of the directory; return NULL but do not set + * errno. + */ + ret = 0; + } + else + { + /* Miscellaneous error; return NULL and set errno (done below). + */ + } + } + + PosixLeave(); + } + + if( ret != 0 ) + { + REDASSERT( pDirEnt == NULL ); + + red_errno = -ret; + } + + return pDirEnt; + } + + +/** @brief Rewind a directory stream to read it from the beginning. + * + * Similar to closing the directory object and opening it again, but without + * the need for the path. + * + * Since this function (like its POSIX equivalent) cannot return an error, + * it takes no action in error conditions, such as when @p pDirStream is + * invalid. + * + * @param pDirStream The directory stream to rewind. + */ + void red_rewinddir( REDDIR * pDirStream ) + { + if( PosixEnter() == 0 ) + { + if( DirStreamIsValid( pDirStream ) ) + { + pDirStream->ullOffset = 0U; + } + + PosixLeave(); + } + } + + +/** @brief Close a directory stream. + * + * After calling this function, @p pDirStream should no longer be used. + * + * @param pDirStream The directory stream to close. + * + * @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + * + * Errno values + * - #RED_EBADF: @p pDirStream is not an open directory stream. + * - #RED_EUSERS: Cannot become a file system user: too many users. + */ + int32_t red_closedir( REDDIR * pDirStream ) + { + REDSTATUS ret; + + ret = PosixEnter(); + + if( ret == 0 ) + { + if( DirStreamIsValid( pDirStream ) ) + { + /* Mark this handle as unused. + */ + pDirStream->ulInode = INODE_INVALID; + } + else + { + ret = -RED_EBADF; + } + + PosixLeave(); + } + + return PosixReturn( ret ); + } + #endif /* REDCONF_API_POSIX_READDIR */ + + +/** @brief Pointer to where the last file system error (errno) is stored. + * + * This function is intended to be used via the #red_errno macro, or a similar + * user-defined macro, that can be used both as an lvalue (writable) and an + * rvalue (readable). + * + * Under normal circumstances, the errno for each task is stored in a + * different location. Applications do not need to worry about one task + * obliterating an error value that another task needed to read. This task + * errno for is initially zero. When one of the POSIX-like APIs returns an + * indication of error, the location for the calling task will be populated + * with the error value. + * + * In some circumstances, this function will return a pointer to a global + * errno location which is shared by multiple tasks. If the calling task is + * not registered as a file system user and all of the task slots are full, + * there can be no task-specific errno, so the global pointer is returned. + * Likewise, if the file system driver is uninitialized, there are no + * registered file system users and this function always returns the pointer + * to the global errno. Under these circumstances, multiple tasks + * manipulating errno could be problematic. + * + * This function never returns `NULL` under any circumstances. The #red_errno + * macro unconditionally dereferences the return value from this function, so + * returning `NULL` could result in a fault. + * + * @return Pointer to where the errno value is stored for this task. + */ + REDSTATUS * red_errnoptr( void ) + { + /* The global errno value, used in single-task configurations and when the + * caller is not (and cannot become) a file system user (which includes + * when the driver is uninitialized). + */ + static REDSTATUS iGlobalErrno = 0; + + #if REDCONF_TASK_COUNT == 1U + return &iGlobalErrno; + #else + REDSTATUS * piErrno; + + if( gfPosixInited ) + { + uint32_t ulTaskId = RedOsTaskId(); + uint32_t ulIdx; + + REDASSERT( ulTaskId != 0U ); + + /* If this task has used the file system before, it will already have + * a task slot, which includes the task-specific errno. + */ + RedOsMutexAcquire(); + + for( ulIdx = 0U; ulIdx < REDCONF_TASK_COUNT; ulIdx++ ) + { + if( gaTask[ ulIdx ].ulTaskId == ulTaskId ) + { + break; + } + } + + RedOsMutexRelease(); + + if( ulIdx == REDCONF_TASK_COUNT ) + { + REDSTATUS ret; + + /* This task is not a file system user, so try to register it as + * one. This FS mutex must be held in order to register. + */ + RedOsMutexAcquire(); + + ret = TaskRegister( &ulIdx ); + + RedOsMutexRelease(); + + if( ret == 0 ) + { + REDASSERT( gaTask[ ulIdx ].ulTaskId == RedOsTaskId() ); + REDASSERT( gaTask[ ulIdx ].iErrno == 0 ); + + piErrno = &gaTask[ ulIdx ].iErrno; + } + else + { + /* Unable to register; use the global errno. + */ + piErrno = &iGlobalErrno; + } + } + else + { + piErrno = &gaTask[ ulIdx ].iErrno; + } + } + else + { + /* There are no registered file system tasks when the driver is + * uninitialized, so use the global errno. + */ + piErrno = &iGlobalErrno; + } + + /* This function is not allowed to return NULL. + */ + REDASSERT( piErrno != NULL ); + return piErrno; + #endif /* if REDCONF_TASK_COUNT == 1U */ + } +/** @} */ + +/*------------------------------------------------------------------- + * Helper Functions + * -------------------------------------------------------------------*/ + + #if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX_UNLINK == 1 ) || ( REDCONF_API_POSIX_RMDIR == 1 ) ) + +/** @brief Remove a link to a file or directory. + * + * If the link count becomes zero, the file or directory is deleted. + * + * @param pszPath Path of the link to remove. + * @param type The expected type of the path: file, directory, or either. + * An error is returned if the expected type is file or + * directory and does not match the path. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval -RED_EBUSY @p pszPath points to an inode with open handles + * and a link count of one. + * @retval -RED_EINVAL @p pszPath is `NULL`; or the volume containing + * the path is not mounted. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_EISDIR @p type is ::FTYPE_FILE and the path names a + * directory. + * @retval -RED_ENAMETOOLONG @p pszName is too long. + * @retval -RED_ENOENT The path does not name an existing file; or + * @p pszPath, after removing the volume prefix, + * points to an empty string. + * @retval -RED_ENOTDIR @p type is ::FTYPE_DIR and the path does not + * name a directory. + * @retval -RED_ENOTEMPTY @p pszPath is a directory which is not empty. + * @retval -RED_ENOSPC The file system does not have enough space to + * modify the parent directory to perform the + * deletion. + */ + static REDSTATUS UnlinkSub( const char * pszPath, + FTYPE type ) + { + uint8_t bVolNum; + const char * pszLocalPath; + REDSTATUS ret; + + ret = RedPathSplit( pszPath, &bVolNum, &pszLocalPath ); + + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( bVolNum ); + } + #endif + + if( ret == 0 ) + { + const char * pszName; + uint32_t ulPInode; + + ret = RedPathToName( pszLocalPath, &ulPInode, &pszName ); + + if( ret == 0 ) + { + uint32_t ulInode; + + ret = RedCoreLookup( ulPInode, pszName, &ulInode ); + + /* ModeTypeCheck() always passes when the type is FTYPE_EITHER, so + * skip stat'ing the inode in that case. + */ + if( ( ret == 0 ) && ( type != FTYPE_EITHER ) ) + { + REDSTAT InodeStat; + + ret = RedCoreStat( ulInode, &InodeStat ); + + if( ret == 0 ) + { + ret = ModeTypeCheck( InodeStat.st_mode, type ); + } + } + + if( ret == 0 ) + { + ret = InodeUnlinkCheck( ulInode ); + } + + if( ret == 0 ) + { + ret = RedCoreUnlink( ulPInode, pszName ); + } + } + } + + return ret; + } + #endif /* (REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) */ + + +/** @brief Get a file descriptor for a path. + * + * @param pszPath Path to a file to open. + * @param ulOpenMode The RED_O_* flags the descriptor is opened with. + * @param type Indicates the expected descriptor type: file, directory, + * or either. + * @param piFildes On successful return, populated with the file + * descriptor. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL @p piFildes is `NULL`; or @p pszPath is `NULL`; + * or the volume is not mounted. + * @retval -RED_EMFILE There are no available handles. + * @retval -RED_EEXIST Using #RED_O_CREAT and #RED_O_EXCL, and the + * indicated path already exists. + * @retval -RED_EISDIR The path names a directory and @p ulOpenMode + * includes #RED_O_WRONLY or #RED_O_RDWR. + * @retval -RED_ENOENT #RED_O_CREAT is not set and the named file does + * not exist; or #RED_O_CREAT is set and the parent + * directory does not exist; or the volume does not + * exist; or the @p pszPath argument, after + * removing the volume prefix, points to an empty + * string. + * @retval -RED_EIO A disk I/O error occurred. + * @retval -RED_ENAMETOOLONG The length of a component of @p pszPath is + * longer than #REDCONF_NAME_MAX. + * @retval -RED_ENFILE Attempting to create a file but the file system + * has used all available inode slots. + * @retval -RED_ENOSPC The file does not exist and #RED_O_CREAT was + * specified, but there is insufficient free space + * to expand the directory or to create the new + * file. + * @retval -RED_ENOTDIR A component of the prefix in @p pszPath does not + * name a directory. + * @retval -RED_EROFS The path resides on a read-only file system and + * a write operation was requested. + */ + static REDSTATUS FildesOpen( const char * pszPath, + uint32_t ulOpenMode, + FTYPE type, + int32_t * piFildes ) + { + uint8_t bVolNum; + const char * pszLocalPath; + REDSTATUS ret; + + ret = RedPathSplit( pszPath, &bVolNum, &pszLocalPath ); + + if( ret == 0 ) + { + if( piFildes == NULL ) + { + ret = -RED_EINVAL; + } + + #if REDCONF_READ_ONLY == 0 + else if( gaRedVolume[ bVolNum ].fReadOnly && ( ulOpenMode != RED_O_RDONLY ) ) + { + ret = -RED_EROFS; + } + #endif + else + { + uint16_t uHandleIdx; + REDHANDLE * pHandle = NULL; + + /* Search for an unused handle. + */ + for( uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++ ) + { + if( gaHandle[ uHandleIdx ].ulInode == INODE_INVALID ) + { + pHandle = &gaHandle[ uHandleIdx ]; + break; + } + } + + /* Error if all the handles are in use. + */ + if( pHandle == NULL ) + { + ret = -RED_EMFILE; + } + else + { + bool fCreated = false; + uint16_t uMode = 0U; + uint32_t ulInode = 0U; /* Init'd to quiet warnings. */ + + #if REDCONF_VOLUME_COUNT > 1U + ret = RedCoreVolSetCurrent( bVolNum ); + + if( ret == 0 ) + #endif + { + #if REDCONF_READ_ONLY == 0 + if( ( ulOpenMode & RED_O_CREAT ) != 0U ) + { + uint32_t ulPInode; + const char * pszName; + + ret = RedPathToName( pszLocalPath, &ulPInode, &pszName ); + + if( ret == 0 ) + { + ret = RedCoreCreate( ulPInode, pszName, false, &ulInode ); + + if( ret == 0 ) + { + fCreated = true; + } + else if( ( ret == -RED_EEXIST ) && ( ( ulOpenMode & RED_O_EXCL ) == 0U ) ) + { + /* If the path already exists and that's OK, + * lookup its inode number. + */ + ret = RedCoreLookup( ulPInode, pszName, &ulInode ); + } + else + { + /* No action, just propagate the error. + */ + } + } + } + else + #endif /* if REDCONF_READ_ONLY == 0 */ + { + ret = RedPathLookup( pszLocalPath, &ulInode ); + } + } + + /* If we created the inode, none of the below stuff is + * necessary. This is important from an error handling + * perspective -- we do not need code to delete the created + * inode on error. + */ + if( !fCreated ) + { + if( ret == 0 ) + { + REDSTAT s; + + ret = RedCoreStat( ulInode, &s ); + + if( ret == 0 ) + { + uMode = s.st_mode; + } + } + + /* Error if the inode is not of the expected type. + */ + if( ret == 0 ) + { + ret = ModeTypeCheck( uMode, type ); + } + + /* Directories must always be opened with O_RDONLY. + */ + if( ( ret == 0 ) && RED_S_ISDIR( uMode ) && ( ( ulOpenMode & RED_O_RDONLY ) == 0U ) ) + { + ret = -RED_EISDIR; + } + + #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_FTRUNCATE == 1 ) + if( ( ret == 0 ) && ( ( ulOpenMode & RED_O_TRUNC ) != 0U ) ) + { + ret = RedCoreFileTruncate( ulInode, UINT64_SUFFIX( 0 ) ); + } + #endif + } + + if( ret == 0 ) + { + int32_t iFildes; + + RedMemSet( pHandle, 0U, sizeof( *pHandle ) ); + + /* Populate this handle, marking it as in use. + */ + pHandle->ulInode = ulInode; + pHandle->bVolNum = bVolNum; + + if( RED_S_ISDIR( uMode ) ) + { + pHandle->bFlags |= HFLAG_DIRECTORY; + } + + if( ( ( ulOpenMode & RED_O_RDONLY ) != 0U ) || ( ( ulOpenMode & RED_O_RDWR ) != 0U ) ) + { + pHandle->bFlags |= HFLAG_READABLE; + } + + #if REDCONF_READ_ONLY == 0 + if( ( ( ulOpenMode & RED_O_WRONLY ) != 0U ) || ( ( ulOpenMode & RED_O_RDWR ) != 0U ) ) + { + pHandle->bFlags |= HFLAG_WRITEABLE; + } + + if( ( ulOpenMode & RED_O_APPEND ) != 0U ) + { + pHandle->bFlags |= HFLAG_APPENDING; + } + #endif + + iFildes = FildesPack( uHandleIdx, bVolNum ); + + if( iFildes == -1 ) + { + /* It should be impossible to get here, unless there + * is memory corruption. + */ + REDERROR(); + ret = -RED_EFUBAR; + } + else + { + *piFildes = iFildes; + } + } + } + } + } + + return ret; + } + + +/** @brief Close a file descriptor. + * + * @param iFildes The file descriptor to close. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p iFildes is not a valid file descriptor. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS FildesClose( int32_t iFildes ) + { + REDHANDLE * pHandle; + REDSTATUS ret; + + ret = FildesToHandle( iFildes, FTYPE_EITHER, &pHandle ); + + #if REDCONF_READ_ONLY == 0 + #if REDCONF_VOLUME_COUNT > 1U + if( ret == 0 ) + { + ret = RedCoreVolSetCurrent( pHandle->bVolNum ); + } + #endif + + /* No core event for close, so this transaction flag needs to be + * implemented here. + */ + if( ret == 0 ) + { + uint32_t ulTransMask; + + ret = RedCoreTransMaskGet( &ulTransMask ); + + if( ( ret == 0 ) && ( ( ulTransMask & RED_TRANSACT_CLOSE ) != 0U ) ) + { + ret = RedCoreVolTransact(); + } + } + #endif /* if REDCONF_READ_ONLY == 0 */ + + if( ret == 0 ) + { + /* Mark this handle as unused. + */ + pHandle->ulInode = INODE_INVALID; + } + + return ret; + } + + +/** @brief Convert a file descriptor into a handle pointer. + * + * Also validates the file descriptor. + * + * @param iFildes The file descriptor for which to get a handle. + * @param expectedType The expected type of the file descriptor: ::FTYPE_DIR, + * ::FTYPE_FILE, or ::FTYPE_EITHER. + * @param ppHandle On successful return, populated with a pointer to the + * handle associated with @p iFildes. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p iFildes is not a valid file descriptor. + * @retval -RED_EINVAL @p ppHandle is `NULL`. + * @retval -RED_EISDIR Expected a file, but the file descriptor is for a + * directory. + * @retval -RED_ENOTDIR Expected a directory, but the file descriptor is for + * a file. + */ + static REDSTATUS FildesToHandle( int32_t iFildes, + FTYPE expectedType, + REDHANDLE ** ppHandle ) + { + REDSTATUS ret; + + if( ppHandle == NULL ) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( iFildes < FD_MIN ) + { + ret = -RED_EBADF; + } + else + { + uint16_t uHandleIdx; + uint8_t bVolNum; + uint16_t uGeneration; + + FildesUnpack( iFildes, &uHandleIdx, &bVolNum, &uGeneration ); + + if( ( uHandleIdx >= REDCONF_HANDLE_COUNT ) || + ( bVolNum >= REDCONF_VOLUME_COUNT ) || + ( gaHandle[ uHandleIdx ].ulInode == INODE_INVALID ) || + ( gaHandle[ uHandleIdx ].bVolNum != bVolNum ) || + ( gauGeneration[ bVolNum ] != uGeneration ) ) + { + ret = -RED_EBADF; + } + else if( ( expectedType == FTYPE_FILE ) && ( ( gaHandle[ uHandleIdx ].bFlags & HFLAG_DIRECTORY ) != 0U ) ) + { + ret = -RED_EISDIR; + } + else if( ( expectedType == FTYPE_DIR ) && ( ( gaHandle[ uHandleIdx ].bFlags & HFLAG_DIRECTORY ) == 0U ) ) + { + ret = -RED_ENOTDIR; + } + else + { + *ppHandle = &gaHandle[ uHandleIdx ]; + ret = 0; + } + } + + return ret; + } + + +/** @brief Pack a file descriptor. + * + * @param uHandleIdx The index of the file handle that will be associated + * with this file descriptor. + * @param bVolNum The volume which contains the file or directory this + * file descriptor was opened against. + * + * @return The packed file descriptor. + */ + static int32_t FildesPack( uint16_t uHandleIdx, + uint8_t bVolNum ) + { + int32_t iFildes; + + if( ( uHandleIdx >= REDCONF_HANDLE_COUNT ) || ( bVolNum >= REDCONF_VOLUME_COUNT ) ) + { + REDERROR(); + iFildes = -1; + } + else + { + uint32_t ulFdBits; + + REDASSERT( gauGeneration[ bVolNum ] <= FD_GEN_MAX ); + REDASSERT( gauGeneration[ bVolNum ] != 0U ); + + ulFdBits = gauGeneration[ bVolNum ]; + ulFdBits <<= FD_VOL_BITS; + ulFdBits |= bVolNum; + ulFdBits <<= FD_IDX_BITS; + ulFdBits |= uHandleIdx; + + iFildes = ( int32_t ) ulFdBits; + + if( iFildes < FD_MIN ) + { + REDERROR(); + iFildes = -1; + } + } + + return iFildes; + } + + +/** @brief Unpack a file descriptor. + * + * @param iFildes The file descriptor to unpack. + * @param puHandleIdx If non-NULL, populated with the handle index extracted + * from the file descriptor. + * @param pbVolNum If non-NULL, populated with the volume number extracted + * from the file descriptor. + * @param puGeneration If non-NULL, populated with the generation number + * extracted from the file descriptor. + */ + static void FildesUnpack( int32_t iFildes, + uint16_t * puHandleIdx, + uint8_t * pbVolNum, + uint16_t * puGeneration ) + { + uint32_t ulFdBits = ( uint32_t ) iFildes; + + REDASSERT( iFildes >= FD_MIN ); + + if( puHandleIdx != NULL ) + { + *puHandleIdx = ( uint16_t ) ( ulFdBits & FD_IDX_MAX ); + } + + ulFdBits >>= FD_IDX_BITS; + + if( pbVolNum != NULL ) + { + *pbVolNum = ( uint8_t ) ( ulFdBits & FD_VOL_MAX ); + } + + ulFdBits >>= FD_VOL_BITS; + + if( puGeneration != NULL ) + { + *puGeneration = ( uint16_t ) ( ulFdBits & FD_GEN_MAX ); + } + } + + + #if REDCONF_API_POSIX_READDIR == 1 + +/** @brief Validate a directory stream object. + * + * @param pDirStream The directory stream to validate. + * + * @return Whether the directory stream is valid. + * + * @retval true The directory stream object appears valid. + * @retval false The directory stream object is invalid. + */ + static bool DirStreamIsValid( const REDDIR * pDirStream ) + { + bool fRet = true; + + if( pDirStream == NULL ) + { + fRet = false; + } + else + { + uint16_t uHandleIdx; + + /* pDirStream should be a pointer to one of the handles. + * + * A good compiler will optimize this loop into a bounds check and an + * alignment check. + */ + for( uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++ ) + { + if( pDirStream == &gaHandle[ uHandleIdx ] ) + { + break; + } + } + + if( uHandleIdx < REDCONF_HANDLE_COUNT ) + { + /* The handle must be in use, have a valid volume number, and be a + * directory handle. + */ + if( ( pDirStream->ulInode == INODE_INVALID ) || + ( pDirStream->bVolNum >= REDCONF_VOLUME_COUNT ) || + ( ( pDirStream->bFlags & HFLAG_DIRECTORY ) == 0U ) ) + { + fRet = false; + } + } + else + { + /* pDirStream is a non-null pointer, but it is not a pointer to one + * of our handles. + */ + fRet = false; + } + } + + return fRet; + } + #endif /* if REDCONF_API_POSIX_READDIR == 1 */ + + +/** @brief Enter the file system driver. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EINVAL The file system driver is uninitialized. + * @retval -RED_EUSERS Cannot become a file system user: too many users. + */ + static REDSTATUS PosixEnter( void ) + { + REDSTATUS ret; + + if( gfPosixInited ) + { + #if REDCONF_TASK_COUNT > 1U + RedOsMutexAcquire(); + + ret = TaskRegister( NULL ); + + if( ret != 0 ) + { + RedOsMutexRelease(); + } + #else + ret = 0; + #endif + } + else + { + ret = -RED_EINVAL; + } + + return ret; + } + + +/** @brief Leave the file system driver. + */ + static void PosixLeave( void ) + { + /* If the driver was uninitialized, PosixEnter() should have failed and we + * should not be calling PosixLeave(). + */ + REDASSERT( gfPosixInited ); + + #if REDCONF_TASK_COUNT > 1U + RedOsMutexRelease(); + #endif + } + + +/** @brief Check that a mode is consistent with the given expected type. + * + * @param uMode An inode mode, indicating whether the inode is a file + * or a directory. + * @param expectedType The expected type: ::FTYPE_FILE, ::FTYPE_DIR, or + * ::FTYPE_EITHER. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EISDIR Expected type is file, actual type is directory. + * @retval -RED_ENOTDIR Expected type is directory, actual type is file. + */ + static REDSTATUS ModeTypeCheck( uint16_t uMode, + FTYPE expectedType ) + { + REDSTATUS ret; + + if( ( expectedType == FTYPE_FILE ) && RED_S_ISDIR( uMode ) ) + { + /* Expected file, found directory. + */ + ret = -RED_EISDIR; + } + else if( ( expectedType == FTYPE_DIR ) && RED_S_ISREG( uMode ) ) + { + /* Expected directory, found file. + */ + ret = -RED_ENOTDIR; + } + else + { + /* No expected type or found what we expected. + */ + ret = 0; + } + + return ret; + } + + + #if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX_UNLINK == 1 ) || ( REDCONF_API_POSIX_RMDIR == 1 ) || ( ( REDCONF_API_POSIX_RENAME == 1 ) && ( REDCONF_RENAME_ATOMIC == 1 ) ) ) + +/** @brief Check whether an inode can be unlinked. + * + * If an inode has a link count of 1 (meaning unlinking another name would + * result in the deletion of the inode) and open handles, it cannot be deleted + * since this would break open handles. + * + * @param ulInode The inode whose name is to be unlinked. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EBADF @p ulInode is not a valid inode. + * @retval -RED_EBUSY The inode has a link count of one and open handles. + * @retval -RED_EIO A disk I/O error occurred. + */ + static REDSTATUS InodeUnlinkCheck( uint32_t ulInode ) + { + uint16_t uHandleIdx; + REDSTATUS ret; + + #if REDCONF_API_POSIX_LINK == 0 + ret = 0; + #else + REDSTAT InodeStat; + + ret = RedCoreStat( ulInode, &InodeStat ); + + /* We only need to check for open handles if the inode is down to its last + * link. If it has multiple links, the inode will continue to exist, so + * deleting the name will not break the open handles. + */ + if( ( ret == 0 ) && ( InodeStat.st_nlink == 1U ) ) + #endif + { + for( uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++ ) + { + if( ( gaHandle[ uHandleIdx ].ulInode == ulInode ) && ( gaHandle[ uHandleIdx ].bVolNum == gbRedVolNum ) ) + { + ret = -RED_EBUSY; + break; + } + } + } + + return ret; + } + #endif /* if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX_UNLINK == 1 ) || ( REDCONF_API_POSIX_RMDIR == 1 ) || ( ( REDCONF_API_POSIX_RENAME == 1 ) && ( REDCONF_RENAME_ATOMIC == 1 ) ) ) */ + + + #if REDCONF_TASK_COUNT > 1U + +/** @brief Register a task as a file system user, if it is not already + * registered as one. + * + * The caller must hold the FS mutex. + * + * @param pulTaskIdx On successful return, if non-NULL, populated with the + * index of the task slot assigned to the calling task. + * This is populated whether or not the task had already + * been registered. + * + * @return A negated ::REDSTATUS code indicating the operation result. + * + * @retval 0 Operation was successful. + * @retval -RED_EUSERS Cannot become a file system user: too many users. + */ + static REDSTATUS TaskRegister( uint32_t * pulTaskIdx ) + { + uint32_t ulTaskId = RedOsTaskId(); + uint32_t ulFirstFreeIdx = REDCONF_TASK_COUNT; + uint32_t ulIdx; + REDSTATUS ret; + + REDASSERT( ulTaskId != 0U ); + + /* Scan the task slots to determine if the task is registered as a file + * system task. + */ + for( ulIdx = 0U; ulIdx < REDCONF_TASK_COUNT; ulIdx++ ) + { + if( gaTask[ ulIdx ].ulTaskId == ulTaskId ) + { + break; + } + + if( ( ulFirstFreeIdx == REDCONF_TASK_COUNT ) && ( gaTask[ ulIdx ].ulTaskId == 0U ) ) + { + ulFirstFreeIdx = ulIdx; + } + } + + if( ulIdx == REDCONF_TASK_COUNT ) + { + /* Task not already registered. + */ + if( ulFirstFreeIdx == REDCONF_TASK_COUNT ) + { + /* Cannot register task, no more slots. + */ + ret = -RED_EUSERS; + } + else + { + /* Registering task. + */ + ulIdx = ulFirstFreeIdx; + gaTask[ ulIdx ].ulTaskId = ulTaskId; + ret = 0; + } + } + else + { + /* Task already registered. + */ + ret = 0; + } + + if( ( ret == 0 ) && ( pulTaskIdx != NULL ) ) + { + *pulTaskIdx = ulIdx; + } + + return ret; + } + #endif /* REDCONF_TASK_COUNT > 1U */ + + +/** @brief Convert an error value into a simple 0 or -1 return. + * + * This function is simple, but what it does is needed in many places. It + * returns zero if @p iError is zero (meaning success) or it returns -1 if + * @p iError is nonzero (meaning error). Also, if @p iError is nonzero, it + * is saved in red_errno. + * + * @param iError The error value. + * + * @return Returns 0 if @p iError is 0; otherwise, returns -1. + */ + static int32_t PosixReturn( REDSTATUS iError ) + { + int32_t iReturn; + + if( iError == 0 ) + { + iReturn = 0; + } + else + { + iReturn = -1; + + /* The errors should be negative, and errno positive. + */ + REDASSERT( iError < 0 ); + red_errno = -iError; + } + + return iReturn; + } + + +#endif /* REDCONF_API_POSIX == 1 */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/fsstress.c b/FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/fsstress.c index abc2aa960..e5d6773d1 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/fsstress.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/fsstress.c @@ -29,12 +29,13 @@ * * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -/** @file - @brief File system stress test. - This version of SGI fsstress has been modified to be single-threaded and to - work with the Reliance Edge POSIX-like API. -*/ +/** @file + * @brief File system stress test. + * + * This version of SGI fsstress has been modified to be single-threaded and to + * work with the Reliance Edge POSIX-like API. + */ #include #include #include @@ -47,2004 +48,2600 @@ #if FSSTRESS_SUPPORTED -#include "redposixcompat.h" + #include "redposixcompat.h" -#include -#include -#include -#include -#include -#include + #include + #include + #include + #include + #include + #include -#if REDCONF_CHECKER == 1 -#include -#endif + #if REDCONF_CHECKER == 1 + #include + #endif /* Create POSIX types. Use #define to avoid name conflicts in those - environments where the type names already exist. -*/ -#define off_t int64_t -#define off64_t off_t -#define ino_t uint32_t -#define mode_t uint16_t -#define __int64_t int64_t + * environments where the type names already exist. + */ + #define off_t int64_t + #define off64_t off_t + #define ino_t uint32_t + #define mode_t uint16_t + #define __int64_t int64_t /** @brief Generate a random number. - - @return A nonnegative random number. -*/ -#define random() ((int)(RedRand32(NULL) & 0x7FFFFFFF)) + * + * @return A nonnegative random number. + */ + #define random() ( ( int ) ( RedRand32( NULL ) & 0x7FFFFFFF ) ) /** @brief Seed the random number generator. -*/ -#define srandom(seed) RedRandSeed(seed) + */ + #define srandom( seed ) RedRandSeed( seed ) -#define _exit(status) exit(status) -#define getpagesize() 4096U -#define getpid() 1 + #define _exit( status ) exit( status ) + #define getpagesize() 4096U + #define getpid() 1 /** @brief Determine the maximum file size. - - This is used for the MAXFSSIZE macro. -*/ -static uint64_t MaxFileSize(void) -{ - REDSTATFS info; - int32_t iStatus; - REDSTATUS errnoSave = errno; - uint64_t ullMaxFileSize; - - iStatus = red_statvfs("", &info); - if(iStatus == 0) + * + * This is used for the MAXFSSIZE macro. + */ + static uint64_t MaxFileSize( void ) { - ullMaxFileSize = info.f_maxfsize; - } - else - { - /* This function does not change errno. - */ - errno = errnoSave; + REDSTATFS info; + int32_t iStatus; + REDSTATUS errnoSave = errno; + uint64_t ullMaxFileSize; - ullMaxFileSize = 0x7FFFFFFFU; - } + iStatus = red_statvfs( "", &info ); - return ullMaxFileSize; -} + if( iStatus == 0 ) + { + ullMaxFileSize = info.f_maxfsize; + } + else + { + /* This function does not change errno. + */ + errno = errnoSave; + + ullMaxFileSize = 0x7FFFFFFFU; + } + + return ullMaxFileSize; + } /*------------------------------------------------------------------- - Simulated current working directory support --------------------------------------------------------------------*/ + * Simulated current working directory support + * -------------------------------------------------------------------*/ /* Forward declaration for red_chdir(). -*/ -static int red_stat(const char *pszPath, REDSTAT *pStat); + */ + static int red_stat( const char * pszPath, + REDSTAT * pStat ); /* The simulated CWD functions. -*/ -#undef chdir -#undef getcwd -#define chdir(path) red_chdir(path) -#define getcwd(buf, size) red_getcwd(buf, size) + */ + #undef chdir + #undef getcwd + #define chdir( path ) red_chdir( path ) + #define getcwd( buf, size ) red_getcwd( buf, size ) /* Redefine the path-based APIs to call MakeFullPath() on their arguments - since there is no CWD support in the red_*() APIs. -*/ -#undef open -#undef unlink -#undef mkdir -#undef rmdir -#undef rename -#undef link -#undef opendir -#define open(path, oflag) red_open(MakeFullPath(path), oflag) -#define unlink(path) red_unlink(MakeFullPath(path)) -#define mkdir(path) red_mkdir(MakeFullPath(path)) -#define rmdir(path) red_rmdir(MakeFullPath(path)) -#define rename(old, new) red_rename(MakeFullPath(old), MakeFullPath(new)) -#define link(path, hardlink) red_link(MakeFullPath(path), MakeFullPath(hardlink)) -#define opendir(path) red_opendir(MakeFullPath(path)) + * since there is no CWD support in the red_*() APIs. + */ + #undef open + #undef unlink + #undef mkdir + #undef rmdir + #undef rename + #undef link + #undef opendir + #define open( path, oflag ) red_open( MakeFullPath( path ), oflag ) + #define unlink( path ) red_unlink( MakeFullPath( path ) ) + #define mkdir( path ) red_mkdir( MakeFullPath( path ) ) + #define rmdir( path ) red_rmdir( MakeFullPath( path ) ) + #define rename( old, new ) red_rename( MakeFullPath( old ), MakeFullPath( new ) ) + #define link( path, hardlink ) red_link( MakeFullPath( path ), MakeFullPath( hardlink ) ) + #define opendir( path ) red_opendir( MakeFullPath( path ) ) -#define FSSTRESS_BUF_SIZE 1024U + #define FSSTRESS_BUF_SIZE 1024U /* Stores the simulated current working directory. -*/ -static char szLocalCwd[FSSTRESS_BUF_SIZE] = "/"; + */ + static char szLocalCwd[ FSSTRESS_BUF_SIZE ] = "/"; /** @brief Change the current working directory. - - This function only supports a subset of what is possible with POSIX chdir(). - - @param pszPath The new current working directory. - - @return Upon successful completion, 0 shall be returned. Otherwise, -1 - shall be returned, and errno shall be set to indicate the error. -*/ -static int red_chdir( - const char *pszPath) -{ - uint32_t ulIdx; - int iErrno = 0; - - if(strcmp(pszPath, "..") == 0) + * + * This function only supports a subset of what is possible with POSIX chdir(). + * + * @param pszPath The new current working directory. + * + * @return Upon successful completion, 0 shall be returned. Otherwise, -1 + * shall be returned, and errno shall be set to indicate the error. + */ + static int red_chdir( const char * pszPath ) { - uint32_t ulLastSlashIdx = 0U; + uint32_t ulIdx; + int iErrno = 0; - /* Chop off the last path separator and everything after it, so that - "/foo/bar/baz" becomes "/foo/bar", moving the CWD up one directory. - */ - for(ulIdx = 0U; szLocalCwd[ulIdx] != '\0'; ulIdx++) + if( strcmp( pszPath, ".." ) == 0 ) { - if(szLocalCwd[ulIdx] == '/') + uint32_t ulLastSlashIdx = 0U; + + /* Chop off the last path separator and everything after it, so that + * "/foo/bar/baz" becomes "/foo/bar", moving the CWD up one directory. + */ + for( ulIdx = 0U; szLocalCwd[ ulIdx ] != '\0'; ulIdx++ ) { - ulLastSlashIdx = ulIdx; + if( szLocalCwd[ ulIdx ] == '/' ) + { + ulLastSlashIdx = ulIdx; + } } - } - if(ulLastSlashIdx != 0U) - { - szLocalCwd[ulLastSlashIdx] = '\0'; - } - } - else - { - char szOldCwd[FSSTRESS_BUF_SIZE]; - - /* chdir() must have no effect on the CWD if it fails, so save the CWD - so we can revert it if necessary. - */ - strcpy(szOldCwd, szLocalCwd); - - if(pszPath[0U] == '/') - { - if(strlen(pszPath) >= sizeof(szLocalCwd)) + if( ulLastSlashIdx != 0U ) { - iErrno = RED_ENAMETOOLONG; - } - else - { - strcpy(szLocalCwd, pszPath); + szLocalCwd[ ulLastSlashIdx ] = '\0'; } } else { - ulIdx = strlen(szLocalCwd); + char szOldCwd[ FSSTRESS_BUF_SIZE ]; - if((ulIdx + 1U + strlen(pszPath)) >= sizeof(szLocalCwd)) + /* chdir() must have no effect on the CWD if it fails, so save the CWD + * so we can revert it if necessary. + */ + strcpy( szOldCwd, szLocalCwd ); + + if( pszPath[ 0U ] == '/' ) { - iErrno = RED_ENAMETOOLONG; - } - else - { - if(szLocalCwd[1U] != '\0') + if( strlen( pszPath ) >= sizeof( szLocalCwd ) ) { - szLocalCwd[ulIdx] = '/'; - ulIdx++; + iErrno = RED_ENAMETOOLONG; + } + else + { + strcpy( szLocalCwd, pszPath ); } - - strcpy(&szLocalCwd[ulIdx], pszPath); - } - } - - if(iErrno == 0) - { - REDSTAT s; - int iStatus; - - iStatus = red_stat(szLocalCwd, &s); - if(iStatus != 0) - { - iErrno = errno; - } - else if(!S_ISDIR(s.st_mode)) - { - iErrno = RED_ENOTDIR; } else { - /* No error, new CWD checks out. - */ + ulIdx = strlen( szLocalCwd ); + + if( ( ulIdx + 1U + strlen( pszPath ) ) >= sizeof( szLocalCwd ) ) + { + iErrno = RED_ENAMETOOLONG; + } + else + { + if( szLocalCwd[ 1U ] != '\0' ) + { + szLocalCwd[ ulIdx ] = '/'; + ulIdx++; + } + + strcpy( &szLocalCwd[ ulIdx ], pszPath ); + } + } + + if( iErrno == 0 ) + { + REDSTAT s; + int iStatus; + + iStatus = red_stat( szLocalCwd, &s ); + + if( iStatus != 0 ) + { + iErrno = errno; + } + else if( !S_ISDIR( s.st_mode ) ) + { + iErrno = RED_ENOTDIR; + } + else + { + /* No error, new CWD checks out. + */ + } + } + + if( iErrno != 0 ) + { + strcpy( szLocalCwd, szOldCwd ); } } - if(iErrno != 0) + if( iErrno != 0 ) { - strcpy(szLocalCwd, szOldCwd); + errno = iErrno; } - } - if(iErrno != 0) - { - errno = iErrno; + return iErrno == 0 ? 0 : -1; } - return iErrno == 0 ? 0 : -1; -} - /** @brief Retrieve the current working directory. - - @param pszBuf On successful return, populated with the current working - directory. If NULL, memory will be allocated for the CWD - and returned by this function. - @param nSize The size of @p pszBuf. - - @return On success, if @p pszBuf was non-NULL, returns @p pszBuf; if - @p pszBuf was NULL, returns an allocated buffer populated with the - CWD which must be freed by the caller. On failure, returns NULL - and errno will be set. -*/ -static char *red_getcwd( - char *pszBuf, - size_t nSize) -{ - char *pszRet; - - if(pszBuf == NULL) + * + * @param pszBuf On successful return, populated with the current working + * directory. If NULL, memory will be allocated for the CWD + * and returned by this function. + * @param nSize The size of @p pszBuf. + * + * @return On success, if @p pszBuf was non-NULL, returns @p pszBuf; if + * @p pszBuf was NULL, returns an allocated buffer populated with the + * CWD which must be freed by the caller. On failure, returns NULL + * and errno will be set. + */ + static char * red_getcwd( char * pszBuf, + size_t nSize ) { - pszRet = malloc(strlen(szLocalCwd) + 1U); - if(pszRet == NULL) + char * pszRet; + + if( pszBuf == NULL ) { - errno = RED_ENOMEM; + pszRet = malloc( strlen( szLocalCwd ) + 1U ); + + if( pszRet == NULL ) + { + errno = RED_ENOMEM; + } + else + { + strcpy( pszRet, szLocalCwd ); + } + } + else if( nSize < strlen( szLocalCwd ) + 1U ) + { + errno = RED_ERANGE; + pszRet = NULL; } else { - strcpy(pszRet, szLocalCwd); + strcpy( pszBuf, szLocalCwd ); + pszRet = pszBuf; } - } - else if(nSize < strlen(szLocalCwd) + 1U) - { - errno = RED_ERANGE; - pszRet = NULL; - } - else - { - strcpy(pszBuf, szLocalCwd); - pszRet = pszBuf; - } - return pszRet; -} + return pszRet; + } /** @brief Make a relative path into a fully qualified path. - - @param pszName The relative path. - - @return On success, a pointer to a fully qualified path. On error, NULL. -*/ -static const char *MakeFullPath( - const char *pszName) -{ - #define MAXVOLNAME 64U /* Enough for most configs. */ - static char aszFullPath[2U][MAXVOLNAME + 1U + FSSTRESS_BUF_SIZE]; - static uint32_t ulWhich = 0U; - - char *pszFullPath = aszFullPath[ulWhich]; - const char *pszVolume = gpRedVolConf->pszPathPrefix; - int32_t iLen; - - if(pszName[0U] == '/') + * + * @param pszName The relative path. + * + * @return On success, a pointer to a fully qualified path. On error, NULL. + */ + static const char * MakeFullPath( const char * pszName ) { - iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s%s", pszVolume, pszName); - } - else if(strcmp(pszName, ".") == 0U) - { - iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s%s", pszVolume, szLocalCwd); - } - else if((szLocalCwd[0U] == '/') && (szLocalCwd[1U] == '\0')) - { - iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s/%s", pszVolume, pszName); - } - else - { - iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s%s/%s", pszVolume, szLocalCwd, pszName); - } + #define MAXVOLNAME 64U /* Enough for most configs. */ + static char aszFullPath[ 2U ][ MAXVOLNAME + 1U + FSSTRESS_BUF_SIZE ]; + static uint32_t ulWhich = 0U; - if(iLen == -1) - { - /* Insufficient path buffer space. - */ - pszFullPath = NULL; - } - else - { - /* Toggle between two full path arrays; a kluge to make rename() and - link() work correctly. - */ - ulWhich ^= 1U; - } + char * pszFullPath = aszFullPath[ ulWhich ]; + const char * pszVolume = gpRedVolConf->pszPathPrefix; + int32_t iLen; - return pszFullPath; -} + if( pszName[ 0U ] == '/' ) + { + iLen = RedSNPrintf( pszFullPath, sizeof( aszFullPath[ 0U ] ), "%s%s", pszVolume, pszName ); + } + else if( strcmp( pszName, "." ) == 0U ) + { + iLen = RedSNPrintf( pszFullPath, sizeof( aszFullPath[ 0U ] ), "%s%s", pszVolume, szLocalCwd ); + } + else if( ( szLocalCwd[ 0U ] == '/' ) && ( szLocalCwd[ 1U ] == '\0' ) ) + { + iLen = RedSNPrintf( pszFullPath, sizeof( aszFullPath[ 0U ] ), "%s/%s", pszVolume, pszName ); + } + else + { + iLen = RedSNPrintf( pszFullPath, sizeof( aszFullPath[ 0U ] ), "%s%s/%s", pszVolume, szLocalCwd, pszName ); + } + + if( iLen == -1 ) + { + /* Insufficient path buffer space. + */ + pszFullPath = NULL; + } + else + { + /* Toggle between two full path arrays; a kluge to make rename() and + * link() work correctly. + */ + ulWhich ^= 1U; + } + + return pszFullPath; + } /*------------------------------------------------------------------- - POSIX functions not implemented by the RED POSIX-like API --------------------------------------------------------------------*/ + * POSIX functions not implemented by the RED POSIX-like API + * -------------------------------------------------------------------*/ -#define stat(p, s) red_stat(p, s) -#define stat64(p, s) stat(p, s) -#define lstat(p, s) stat(p, s) -#define lstat64(p, s) stat(p, s) -#define truncate(p, s) red_truncate(p, s) -#define truncate64(p, s) truncate(p, s) + #define stat( p, s ) red_stat( p, s ) + #define stat64( p, s ) stat( p, s ) + #define lstat( p, s ) stat( p, s ) + #define lstat64( p, s ) stat( p, s ) + #define truncate( p, s ) red_truncate( p, s ) + #define truncate64( p, s ) truncate( p, s ) /** @brief Get the status of a file or directory. -*/ -static int red_stat( - const char *pszPath, - REDSTAT *pStat) -{ - int iFd; - int iRet; - - iFd = open(pszPath, O_RDONLY); - iRet = iFd; - if(iFd != -1) + */ + static int red_stat( const char * pszPath, + REDSTAT * pStat ) { - iRet = fstat(iFd, pStat); + int iFd; + int iRet; - (void)close(iFd); + iFd = open( pszPath, O_RDONLY ); + iRet = iFd; + + if( iFd != -1 ) + { + iRet = fstat( iFd, pStat ); + + ( void ) close( iFd ); + } + + return iRet; } - return iRet; -} - /** @brief Truncate a file to a specified length. -*/ -static int red_truncate( - const char *pszPath, - off_t llSize) -{ - int iFd; - int iRet; - - iFd = open(pszPath, O_WRONLY); - iRet = iFd; - if(iFd != -1) + */ + static int red_truncate( const char * pszPath, + off_t llSize ) { - iRet = ftruncate(iFd, llSize); + int iFd; + int iRet; - (void)close(iFd); + iFd = open( pszPath, O_WRONLY ); + iRet = iFd; + + if( iFd != -1 ) + { + iRet = ftruncate( iFd, llSize ); + + ( void ) close( iFd ); + } + + return iRet; } - return iRet; -} - /*------------------------------------------------------------------- - Begin ported fsstress code --------------------------------------------------------------------*/ + * Begin ported fsstress code + * -------------------------------------------------------------------*/ /* Stuff from xfscompat.h */ -#define MAXNAMELEN (REDCONF_NAME_MAX+1U) /* Assumed to include NUL */ + #define MAXNAMELEN ( REDCONF_NAME_MAX + 1U ) /* Assumed to include NUL */ -struct dioattr { - int d_miniosz, d_maxiosz, d_mem; -}; + struct dioattr + { + int d_miniosz, d_maxiosz, d_mem; + }; -#define MIN(a,b) ((a)<(b) ? (a):(b)) -#define MAX(a,b) ((a)>(b) ? (a):(b)) + #define MIN( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) ) + #define MAX( a, b ) ( ( a ) > ( b ) ? ( a ) : ( b ) ) /* End xfscompat.h */ -typedef enum { - OP_CREAT, - OP_FDATASYNC, - OP_FSYNC, - OP_GETDENTS, - OP_LINK, - OP_MKDIR, - OP_READ, - OP_RENAME, - OP_RMDIR, - OP_STAT, - OP_TRUNCATE, - OP_UNLINK, - OP_WRITE, - #if REDCONF_CHECKER == 1 - OP_CHECK, - #endif - OP_LAST -} opty_t; + typedef enum + { + OP_CREAT, + OP_FDATASYNC, + OP_FSYNC, + OP_GETDENTS, + OP_LINK, + OP_MKDIR, + OP_READ, + OP_RENAME, + OP_RMDIR, + OP_STAT, + OP_TRUNCATE, + OP_UNLINK, + OP_WRITE, + #if REDCONF_CHECKER == 1 + OP_CHECK, + #endif + OP_LAST + } opty_t; -typedef void (*opfnc_t) (int, long); + typedef void (* opfnc_t) ( int, + long ); -typedef struct opdesc { - opty_t op; - const char *name; - opfnc_t func; - int freq; - int iswrite; -} opdesc_t; + typedef struct opdesc + { + opty_t op; + const char * name; + opfnc_t func; + int freq; + int iswrite; + } opdesc_t; -typedef struct fent { - int id; - int parent; -} fent_t; + typedef struct fent + { + int id; + int parent; + } fent_t; -typedef struct flist { - int nfiles; - int nslots; - int tag; - fent_t *fents; -} flist_t; + typedef struct flist + { + int nfiles; + int nslots; + int tag; + fent_t * fents; + } flist_t; -typedef struct pathname { - int len; - char *path; -} pathname_t; + typedef struct pathname + { + int len; + char * path; + } pathname_t; -#define FT_DIR 0 -#define FT_DIRm (1 << FT_DIR) -#define FT_REG 1 -#define FT_REGm (1 << FT_REG) -#define FT_SYM 2 -#define FT_SYMm (1 << FT_SYM) -#define FT_DEV 3 -#define FT_DEVm (1 << FT_DEV) -#define FT_RTF 4 -#define FT_RTFm (1 << FT_RTF) -#define FT_nft 5 -#define FT_ANYm ((1 << FT_nft) - 1) -#define FT_REGFILE (FT_REGm | FT_RTFm) -#define FT_NOTDIR (FT_ANYm & ~FT_DIRm) + #define FT_DIR 0 + #define FT_DIRm ( 1 << FT_DIR ) + #define FT_REG 1 + #define FT_REGm ( 1 << FT_REG ) + #define FT_SYM 2 + #define FT_SYMm ( 1 << FT_SYM ) + #define FT_DEV 3 + #define FT_DEVm ( 1 << FT_DEV ) + #define FT_RTF 4 + #define FT_RTFm ( 1 << FT_RTF ) + #define FT_nft 5 + #define FT_ANYm ( ( 1 << FT_nft ) - 1 ) + #define FT_REGFILE ( FT_REGm | FT_RTFm ) + #define FT_NOTDIR ( FT_ANYm & ~FT_DIRm ) -#define FLIST_SLOT_INCR 16 -#define NDCACHE 64 + #define FLIST_SLOT_INCR 16 + #define NDCACHE 64 -#define MAXFSIZE MaxFileSize() + #define MAXFSIZE MaxFileSize() -static void creat_f(int opno, long r); -static void fdatasync_f(int opno, long r); -static void fsync_f(int opno, long r); -static void getdents_f(int opno, long r); -static void link_f(int opno, long r); -static void mkdir_f(int opno, long r); -static void read_f(int opno, long r); -static void rename_f(int opno, long r); -static void rmdir_f(int opno, long r); -static void stat_f(int opno, long r); -static void truncate_f(int opno, long r); -static void unlink_f(int opno, long r); -static void write_f(int opno, long r); -#if REDCONF_CHECKER == 1 -static void check_f(int opno, long r); -#endif + static void creat_f( int opno, + long r ); + static void fdatasync_f( int opno, + long r ); + static void fsync_f( int opno, + long r ); + static void getdents_f( int opno, + long r ); + static void link_f( int opno, + long r ); + static void mkdir_f( int opno, + long r ); + static void read_f( int opno, + long r ); + static void rename_f( int opno, + long r ); + static void rmdir_f( int opno, + long r ); + static void stat_f( int opno, + long r ); + static void truncate_f( int opno, + long r ); + static void unlink_f( int opno, + long r ); + static void write_f( int opno, + long r ); + #if REDCONF_CHECKER == 1 + static void check_f( int opno, + long r ); + #endif -static opdesc_t ops[] = { - {OP_CREAT, "creat", creat_f, 4, 1}, - {OP_FDATASYNC, "fdatasync", fdatasync_f, 1, 1}, - {OP_FSYNC, "fsync", fsync_f, 1, 1}, - {OP_GETDENTS, "getdents", getdents_f, 1, 0}, - {OP_LINK, "link", link_f, 1, 1}, - {OP_MKDIR, "mkdir", mkdir_f, 2, 1}, - {OP_READ, "read", read_f, 1, 0}, - {OP_RENAME, "rename", rename_f, 2, 1}, - {OP_RMDIR, "rmdir", rmdir_f, 1, 1}, - {OP_STAT, "stat", stat_f, 1, 0}, - {OP_TRUNCATE, "truncate", truncate_f, 2, 1}, - {OP_UNLINK, "unlink", unlink_f, 1, 1}, - {OP_WRITE, "write", write_f, 4, 1}, - #if REDCONF_CHECKER == 1 - {OP_CHECK, "check", check_f, 1, 1}, - #endif -}, *ops_end; + static opdesc_t ops[] = + { + { OP_CREAT, "creat", creat_f, 4, 1 }, + { OP_FDATASYNC, "fdatasync", fdatasync_f, 1, 1 }, + { OP_FSYNC, "fsync", fsync_f, 1, 1 }, + { OP_GETDENTS, "getdents", getdents_f, 1, 0 }, + { OP_LINK, "link", link_f, 1, 1 }, + { OP_MKDIR, "mkdir", mkdir_f, 2, 1 }, + { OP_READ, "read", read_f, 1, 0 }, + { OP_RENAME, "rename", rename_f, 2, 1 }, + { OP_RMDIR, "rmdir", rmdir_f, 1, 1 }, + { OP_STAT, "stat", stat_f, 1, 0 }, + { OP_TRUNCATE, "truncate", truncate_f, 2, 1 }, + { OP_UNLINK, "unlink", unlink_f, 1, 1 }, + { OP_WRITE, "write", write_f, 4, 1 }, + #if REDCONF_CHECKER == 1 + { OP_CHECK, "check", check_f, 1, 1 }, + #endif + }, * ops_end; -static flist_t flist[FT_nft] = { - {0, 0, 'd', NULL}, - {0, 0, 'f', NULL}, - {0, 0, 'l', NULL}, - {0, 0, 'c', NULL}, - {0, 0, 'r', NULL}, -}; + static flist_t flist[ FT_nft ] = + { + { 0, 0, 'd', NULL }, + { 0, 0, 'f', NULL }, + { 0, 0, 'l', NULL }, + { 0, 0, 'c', NULL }, + { 0, 0, 'r', NULL }, + }; -static int dcache[NDCACHE]; -static opty_t *freq_table; -static int freq_table_size; -static char *homedir; -static int *ilist; -static int ilistlen; -static off64_t maxfsize; -static int namerand; -static int nameseq; -static int nops; -static int operations = 1; -static int procid; -static int rtpct; -static unsigned long seed = 0; -static ino_t top_ino; -static int verbose = 0; + static int dcache[ NDCACHE ]; + static opty_t * freq_table; + static int freq_table_size; + static char * homedir; + static int * ilist; + static int ilistlen; + static off64_t maxfsize; + static int namerand; + static int nameseq; + static int nops; + static int operations = 1; + static int procid; + static int rtpct; + static unsigned long seed = 0; + static ino_t top_ino; + static int verbose = 0; -static int delete_tree(const char *path); -static void add_to_flist(int fd, int it, int parent); -static void append_pathname(pathname_t *name, const char *str); -static void check_cwd(void); -static int creat_path(pathname_t *name, mode_t mode); -static void dcache_enter(int dirid, int slot); -static void dcache_init(void); -static fent_t *dcache_lookup(int dirid); -static void dcache_purge(int dirid); -static void del_from_flist(int ft, int slot); -static void doproc(void); -static void fent_to_name(pathname_t *name, flist_t *flp, fent_t *fep); -static void fix_parent(int oldid, int newid); -static void free_pathname(pathname_t *name); -static int generate_fname(fent_t *fep, int ft, pathname_t *name, int *idp, int *v); -static int get_fname(int which, long r, pathname_t *name, flist_t **flpp, fent_t **fepp, int *v); -static void init_pathname(pathname_t *name); -static int link_path(pathname_t *name1, pathname_t *name2); -static int lstat64_path(pathname_t *name, REDSTAT *sbuf); -static void make_freq_table(void); -static int mkdir_path(pathname_t *name, mode_t mode); -static void namerandpad(int id, char *buf, int len); -static int open_path(pathname_t *name, int oflag); -static DIR *opendir_path(pathname_t *name); -static int rename_path(pathname_t *name1, pathname_t *name2); -static int rmdir_path(pathname_t *name); -static void separate_pathname(pathname_t *name, char *buf, pathname_t *newname); -static int stat64_path(pathname_t *name, REDSTAT *sbuf); -static int truncate64_path(pathname_t *name, off64_t length); -static int unlink_path(pathname_t *name); -static void usage(const char *progname); + static int delete_tree( const char * path ); + static void add_to_flist( int fd, + int it, + int parent ); + static void append_pathname( pathname_t * name, + const char * str ); + static void check_cwd( void ); + static int creat_path( pathname_t * name, + mode_t mode ); + static void dcache_enter( int dirid, + int slot ); + static void dcache_init( void ); + static fent_t * dcache_lookup( int dirid ); + static void dcache_purge( int dirid ); + static void del_from_flist( int ft, + int slot ); + static void doproc( void ); + static void fent_to_name( pathname_t * name, + flist_t * flp, + fent_t * fep ); + static void fix_parent( int oldid, + int newid ); + static void free_pathname( pathname_t * name ); + static int generate_fname( fent_t * fep, + int ft, + pathname_t * name, + int * idp, + int * v ); + static int get_fname( int which, + long r, + pathname_t * name, + flist_t ** flpp, + fent_t ** fepp, + int * v ); + static void init_pathname( pathname_t * name ); + static int link_path( pathname_t * name1, + pathname_t * name2 ); + static int lstat64_path( pathname_t * name, + REDSTAT * sbuf ); + static void make_freq_table( void ); + static int mkdir_path( pathname_t * name, + mode_t mode ); + static void namerandpad( int id, + char * buf, + int len ); + static int open_path( pathname_t * name, + int oflag ); + static DIR * opendir_path( pathname_t * name ); + static int rename_path( pathname_t * name1, + pathname_t * name2 ); + static int rmdir_path( pathname_t * name ); + static void separate_pathname( pathname_t * name, + char * buf, + pathname_t * newname ); + static int stat64_path( pathname_t * name, + REDSTAT * sbuf ); + static int truncate64_path( pathname_t * name, + off64_t length ); + static int unlink_path( pathname_t * name ); + static void usage( const char * progname ); /** @brief Parse parameters for fsstress. - - @param argc The number of arguments from main(). - @param argv The vector of arguments from main(). - @param pParam Populated with the fsstress parameters. - @param pbVolNum If non-NULL, populated with the volume number. - @param ppszDevice If non-NULL, populated with the device name argument or - NULL if no device argument is provided. - - @return The result of parsing the parameters. -*/ -PARAMSTATUS FsstressParseParams( - int argc, - char *argv[], - FSSTRESSPARAM *pParam, - uint8_t *pbVolNum, - const char **ppszDevice) -{ - int c; - uint8_t bVolNum; - const REDOPTION aLongopts[] = + * + * @param argc The number of arguments from main(). + * @param argv The vector of arguments from main(). + * @param pParam Populated with the fsstress parameters. + * @param pbVolNum If non-NULL, populated with the volume number. + * @param ppszDevice If non-NULL, populated with the device name argument or + * NULL if no device argument is provided. + * + * @return The result of parsing the parameters. + */ + PARAMSTATUS FsstressParseParams( int argc, + char * argv[], + FSSTRESSPARAM * pParam, + uint8_t * pbVolNum, + const char ** ppszDevice ) { - { "no-cleanup", red_no_argument, NULL, 'c' }, - { "loops", red_required_argument, NULL, 'l' }, - { "nops", red_required_argument, NULL, 'n' }, - { "namepad", red_no_argument, NULL, 'r' }, - { "seed", red_required_argument, NULL, 's' }, - { "verbose", red_no_argument, NULL, 'v' }, - { "dev", red_required_argument, NULL, 'D' }, - { "help", red_no_argument, NULL, 'H' }, - { NULL } - }; - - /* If run without parameters, treat as a help request. - */ - if(argc <= 1) - { - goto Help; - } - - /* Assume no device argument to start with. - */ - if(ppszDevice != NULL) - { - *ppszDevice = NULL; - } - - /* Set default parameters. - */ - FsstressDefaultParams(pParam); - - while((c = RedGetoptLong(argc, argv, "cl:n:rs:vD:H", aLongopts, NULL)) != -1) - { - switch(c) + int c; + uint8_t bVolNum; + const REDOPTION aLongopts[] = { - case 'c': /* --no-cleanup */ - pParam->fNoCleanup = true; - break; - case 'l': /* --loops */ - pParam->ulLoops = RedAtoI(red_optarg); - break; - case 'n': /* --nops */ - pParam->ulNops = RedAtoI(red_optarg); - break; - case 'r': /* --namepad */ - pParam->fNamePad = true; - break; - case 's': /* --seed */ - pParam->ulSeed = RedAtoI(red_optarg); - break; - case 'v': /* --verbose */ - pParam->fVerbose = true; - break; - case 'D': /* --dev */ - if(ppszDevice != NULL) - { - *ppszDevice = red_optarg; - } - break; - case 'H': /* --help */ - goto Help; - case '?': /* Unknown or ambiguous option */ - case ':': /* Option missing required argument */ - default: - goto BadOpt; - } - } + { "no-cleanup", red_no_argument, NULL, 'c' }, + { "loops", red_required_argument, NULL, 'l' }, + { "nops", red_required_argument, NULL, 'n' }, + { "namepad", red_no_argument, NULL, 'r' }, + { "seed", red_required_argument, NULL, 's' }, + { "verbose", red_no_argument, NULL, 'v' }, + { "dev", red_required_argument, NULL, 'D' }, + { "help", red_no_argument, NULL, 'H' }, + { NULL } + }; - /* RedGetoptLong() has permuted argv to move all non-option arguments to - the end. We expect to find a volume identifier. - */ - if(red_optind >= argc) - { - RedPrintf("Missing volume argument\n"); - goto BadOpt; - } - - bVolNum = RedFindVolumeNumber(argv[red_optind]); - if(bVolNum == REDCONF_VOLUME_COUNT) - { - RedPrintf("Error: \"%s\" is not a valid volume identifier.\n", argv[red_optind]); - goto BadOpt; - } - - if(pbVolNum != NULL) - { - *pbVolNum = bVolNum; - } - - red_optind++; /* Move past volume parameter. */ - if(red_optind < argc) - { - int32_t ii; - - for(ii = red_optind; ii < argc; ii++) + /* If run without parameters, treat as a help request. + */ + if( argc <= 1 ) { - RedPrintf("Error: Unexpected command-line argument \"%s\".\n", argv[ii]); + goto Help; } - goto BadOpt; + /* Assume no device argument to start with. + */ + if( ppszDevice != NULL ) + { + *ppszDevice = NULL; + } + + /* Set default parameters. + */ + FsstressDefaultParams( pParam ); + + while( ( c = RedGetoptLong( argc, argv, "cl:n:rs:vD:H", aLongopts, NULL ) ) != -1 ) + { + switch( c ) + { + case 'c': /* --no-cleanup */ + pParam->fNoCleanup = true; + break; + + case 'l': /* --loops */ + pParam->ulLoops = RedAtoI( red_optarg ); + break; + + case 'n': /* --nops */ + pParam->ulNops = RedAtoI( red_optarg ); + break; + + case 'r': /* --namepad */ + pParam->fNamePad = true; + break; + + case 's': /* --seed */ + pParam->ulSeed = RedAtoI( red_optarg ); + break; + + case 'v': /* --verbose */ + pParam->fVerbose = true; + break; + + case 'D': /* --dev */ + + if( ppszDevice != NULL ) + { + *ppszDevice = red_optarg; + } + + break; + + case 'H': /* --help */ + goto Help; + + case '?': /* Unknown or ambiguous option */ + case ':': /* Option missing required argument */ + default: + goto BadOpt; + } + } + + /* RedGetoptLong() has permuted argv to move all non-option arguments to + * the end. We expect to find a volume identifier. + */ + if( red_optind >= argc ) + { + RedPrintf( "Missing volume argument\n" ); + goto BadOpt; + } + + bVolNum = RedFindVolumeNumber( argv[ red_optind ] ); + + if( bVolNum == REDCONF_VOLUME_COUNT ) + { + RedPrintf( "Error: \"%s\" is not a valid volume identifier.\n", argv[ red_optind ] ); + goto BadOpt; + } + + if( pbVolNum != NULL ) + { + *pbVolNum = bVolNum; + } + + red_optind++; /* Move past volume parameter. */ + + if( red_optind < argc ) + { + int32_t ii; + + for( ii = red_optind; ii < argc; ii++ ) + { + RedPrintf( "Error: Unexpected command-line argument \"%s\".\n", argv[ ii ] ); + } + + goto BadOpt; + } + + return PARAMSTATUS_OK; + +BadOpt: + + RedPrintf( "%s - invalid parameters\n", argv[ 0U ] ); + usage( argv[ 0U ] ); + return PARAMSTATUS_BAD; + +Help: + + usage( argv[ 0U ] ); + return PARAMSTATUS_HELP; } - return PARAMSTATUS_OK; - - BadOpt: - - RedPrintf("%s - invalid parameters\n", argv[0U]); - usage(argv[0U]); - return PARAMSTATUS_BAD; - - Help: - - usage(argv[0U]); - return PARAMSTATUS_HELP; -} - /** @brief Set default fsstress parameters. - - @param pParam Populated with the default fsstress parameters. -*/ -void FsstressDefaultParams( - FSSTRESSPARAM *pParam) -{ - RedMemSet(pParam, 0U, sizeof(*pParam)); - pParam->ulLoops = 1U; - pParam->ulNops = 10000U; -} + * + * @param pParam Populated with the default fsstress parameters. + */ + void FsstressDefaultParams( FSSTRESSPARAM * pParam ) + { + RedMemSet( pParam, 0U, sizeof( *pParam ) ); + pParam->ulLoops = 1U; + pParam->ulNops = 10000U; + } /** @brief Start fsstress. + * + * @param pParam fsstress parameters, either from FsstressParseParams() or + * constructed programatically. + * + * @return Zero on success, otherwise nonzero. + */ + int FsstressStart( const FSSTRESSPARAM * pParam ) + { + char buf[ 10 ]; + int fd; + int i; + int cleanup; + int loops; + int loopcntr = 1; - @param pParam fsstress parameters, either from FsstressParseParams() or - constructed programatically. + nops = sizeof( ops ) / sizeof( ops[ 0 ] ); + ops_end = &ops[ nops ]; - @return Zero on success, otherwise nonzero. -*/ -int FsstressStart( - const FSSTRESSPARAM *pParam) -{ - char buf[10]; - int fd; - int i; - int cleanup; - int loops; - int loopcntr = 1; + /* Copy the already-parsed parameters into the traditional variables. + */ + cleanup = pParam->fNoCleanup ? 1 : 0; + loops = pParam->ulLoops; + operations = pParam->ulNops; + namerand = pParam->fNamePad ? 1 : 0; + seed = pParam->ulSeed; + verbose = pParam->fVerbose ? 1 : 0; - nops = sizeof(ops) / sizeof(ops[0]); - ops_end = &ops[nops]; + make_freq_table(); - /* Copy the already-parsed parameters into the traditional variables. - */ - cleanup = pParam->fNoCleanup ? 1 : 0; - loops = pParam->ulLoops; - operations = pParam->ulNops; - namerand = pParam->fNamePad ? 1 : 0; - seed = pParam->ulSeed; - verbose = pParam->fVerbose ? 1 : 0; + while( ( loopcntr <= loops ) || ( loops == 0 ) ) + { + RedSNPrintf( buf, sizeof( buf ), "fss%x", getpid() ); + fd = creat( buf, 0666 ); + maxfsize = ( off64_t ) MAXFSIZE; + dcache_init(); - make_freq_table(); - - while ((loopcntr <= loops) || (loops == 0)) { - RedSNPrintf(buf, sizeof(buf), "fss%x", getpid()); - fd = creat(buf, 0666); - maxfsize = (off64_t) MAXFSIZE; - dcache_init(); - if (!seed) { - seed = (unsigned long)RedOsClockGetTime(); - RedPrintf("seed = %ld\n", seed); - } - close(fd); - unlink(buf); - procid = 0; - doproc(); - if (cleanup == 0) { - delete_tree("/"); - for (i = 0; i < FT_nft; i++) { - flist[i].nslots = 0; - flist[i].nfiles = 0; - free(flist[i].fents); - flist[i].fents = NULL; + if( !seed ) + { + seed = ( unsigned long ) RedOsClockGetTime(); + RedPrintf( "seed = %ld\n", seed ); } + + close( fd ); + unlink( buf ); + procid = 0; + doproc(); + + if( cleanup == 0 ) + { + delete_tree( "/" ); + + for( i = 0; i < FT_nft; i++ ) + { + flist[ i ].nslots = 0; + flist[ i ].nfiles = 0; + free( flist[ i ].fents ); + flist[ i ].fents = NULL; + } + } + + loopcntr++; } - loopcntr++; - } - return 0; -} -static int delete_tree(const char *path) -{ - REDSTAT sb; - DIR *dp; - REDDIRENT *dep; - char *childpath; - size_t len; - int e; - - e = stat(path, &sb); - if (e) - return errno; - - if (!S_ISDIR(sb.st_mode)) - return unlink(path) ? errno : 0; - - dp = opendir(path); - if (dp == NULL) - return errno; - - while((dep = readdir(dp)) != NULL) { - len = strlen(path) + 1 + strlen(dep->d_name) + 1; - childpath = malloc(len); - - strcpy(childpath, path); - if (childpath[strlen(childpath) - 1] != '/') - strcat(childpath, "/"); - strcat(childpath, dep->d_name); - - e = delete_tree(childpath); - - free(childpath); - - if (e) - break; - } - - if (e == 0 && strcmp(path, "/") != 0) { - e = rmdir(path) ? errno : 0; - } - closedir(dp); - return e; -} - -static void add_to_flist(int ft, int id, int parent) -{ - fent_t *fep; - flist_t *ftp; - - ftp = &flist[ft]; - if (ftp->nfiles == ftp->nslots) { - ftp->nslots += FLIST_SLOT_INCR; - ftp->fents = realloc(ftp->fents, ftp->nslots * sizeof(fent_t)); - } - fep = &ftp->fents[ftp->nfiles++]; - fep->id = id; - fep->parent = parent; -} - -static void append_pathname(pathname_t *name, const char *str) -{ - int len; - - len = strlen(str); -#ifdef DEBUG - if (len && *str == '/' && name->len == 0) { - RedPrintf("fsstress: append_pathname failure\n"); - chdir(homedir); - abort(); - - } -#endif - name->path = realloc(name->path, name->len + 1 + len); - strcpy(&name->path[name->len], str); - name->len += len; -} - -static void check_cwd(void) -{ -#ifdef DEBUG - REDSTAT statbuf; - - if (stat64(".", &statbuf) == 0 && statbuf.st_ino == top_ino) - return; - chdir(homedir); - RedPrintf("fsstress: check_cwd failure\n"); - abort(); - -#endif -} - -static int creat_path(pathname_t *name, mode_t mode) -{ - char buf[MAXNAMELEN]; - pathname_t newname; - int rval; - - rval = creat(name->path, mode); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name, buf, &newname); - if (chdir(buf) == 0) { - rval = creat_path(&newname, mode); - chdir(".."); - } - free_pathname(&newname); - return rval; -} - -static void dcache_enter(int dirid, int slot) -{ - dcache[dirid % NDCACHE] = slot; -} - -static void dcache_init(void) -{ - int i; - - for (i = 0; i < NDCACHE; i++) - dcache[i] = -1; -} - -static fent_t *dcache_lookup(int dirid) -{ - fent_t *fep; - int i; - - i = dcache[dirid % NDCACHE]; - if (i >= 0 && (fep = &flist[FT_DIR].fents[i])->id == dirid) - return fep; - return NULL; -} - -static void dcache_purge(int dirid) -{ - int *dcp; - - dcp = &dcache[dirid % NDCACHE]; - if (*dcp >= 0 && flist[FT_DIR].fents[*dcp].id == dirid) - *dcp = -1; -} - -static void del_from_flist(int ft, int slot) -{ - flist_t *ftp; - - ftp = &flist[ft]; - if (ft == FT_DIR) - dcache_purge(ftp->fents[slot].id); - if (slot != ftp->nfiles - 1) { - if (ft == FT_DIR) - dcache_purge(ftp->fents[ftp->nfiles - 1].id); - ftp->fents[slot] = ftp->fents[--ftp->nfiles]; - } else - ftp->nfiles--; -} - -static fent_t *dirid_to_fent(int dirid) -{ - fent_t *efep; - fent_t *fep; - flist_t *flp; - - if ((fep = dcache_lookup(dirid))) - return fep; - flp = &flist[FT_DIR]; - for (fep = flp->fents, efep = &fep[flp->nfiles]; fep < efep; fep++) { - if (fep->id == dirid) { - dcache_enter(dirid, (int)(fep - flp->fents)); - return fep; - } - } - return NULL; -} - -static void doproc(void) -{ - REDSTAT statbuf; - char buf[10]; - int opno; - opdesc_t *p; - - RedSNPrintf(buf, sizeof(buf), "p%x", procid); - (void)mkdir(buf); - if (chdir(buf) < 0 || stat64(".", &statbuf) < 0) { - perror(buf); - _exit(1); - } - top_ino = statbuf.st_ino; - homedir = getcwd(NULL, 0); - seed += procid; - srandom(seed); - if (namerand) - namerand = random(); - for (opno = 0; opno < operations; opno++) { - p = &ops[freq_table[random() % freq_table_size]]; - if ((unsigned long)p->func < 4096) - abort(); - - p->func(opno, random()); - } - free(homedir); -} - -static void fent_to_name(pathname_t *name, flist_t *flp, fent_t *fep) -{ - char buf[MAXNAMELEN]; - int i; - fent_t *pfep; - - if (fep == NULL) - return; - if (fep->parent != -1) { - pfep = dirid_to_fent(fep->parent); - fent_to_name(name, &flist[FT_DIR], pfep); - append_pathname(name, "/"); - } - i = RedSNPrintf(buf, sizeof(buf), "%c%x", flp->tag, fep->id); - namerandpad(fep->id, buf, i); - append_pathname(name, buf); -} - -static void fix_parent(int oldid, int newid) -{ - fent_t *fep; - flist_t *flp; - int i; - int j; - - for (i = 0, flp = flist; i < FT_nft; i++, flp++) { - for (j = 0, fep = flp->fents; j < flp->nfiles; j++, fep++) { - if (fep->parent == oldid) - fep->parent = newid; - } - } -} - -static void free_pathname(pathname_t *name) -{ - if (name->path) { - free(name->path); - name->path = NULL; - name->len = 0; - } -} - -static int generate_fname(fent_t *fep, int ft, pathname_t *name, int *idp, int *v) -{ - char buf[MAXNAMELEN]; - flist_t *flp; - int id; - int j; - int len; - - flp = &flist[ft]; - len = RedSNPrintf(buf, sizeof(buf), "%c%x", flp->tag, id = nameseq++); - namerandpad(id, buf, len); - if (fep) { - fent_to_name(name, &flist[FT_DIR], fep); - append_pathname(name, "/"); - } - append_pathname(name, buf); - *idp = id; - *v = verbose; - for (j = 0; !*v && j < ilistlen; j++) { - if (ilist[j] == id) { - *v = 1; - break; - } - } - return 1; -} - -static int -get_fname(int which, long r, pathname_t *name, flist_t **flpp, fent_t **fepp, int *v) -{ - int c; - fent_t *fep; - flist_t *flp; - int i; - int j; - int x; - - for (i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++) { - if (which & (1 << i)) - c += flp->nfiles; - } - if (c == 0) { - if (flpp) - *flpp = NULL; - if (fepp) - *fepp = NULL; - *v = verbose; return 0; } - x = (int)(r % c); - for (i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++) { - if (which & (1 << i)) { - if (x < c + flp->nfiles) { - fep = &flp->fents[x - c]; - if (name) - fent_to_name(name, flp, fep); - if (flpp) - *flpp = flp; - if (fepp) - *fepp = fep; - *v = verbose; - for (j = 0; !*v && j < ilistlen; j++) { - if (ilist[j] == fep->id) { - *v = 1; - break; + + static int delete_tree( const char * path ) + { + REDSTAT sb; + DIR * dp; + REDDIRENT * dep; + char * childpath; + size_t len; + int e; + + e = stat( path, &sb ); + + if( e ) + { + return errno; + } + + if( !S_ISDIR( sb.st_mode ) ) + { + return unlink( path ) ? errno : 0; + } + + dp = opendir( path ); + + if( dp == NULL ) + { + return errno; + } + + while( ( dep = readdir( dp ) ) != NULL ) + { + len = strlen( path ) + 1 + strlen( dep->d_name ) + 1; + childpath = malloc( len ); + + strcpy( childpath, path ); + + if( childpath[ strlen( childpath ) - 1 ] != '/' ) + { + strcat( childpath, "/" ); + } + + strcat( childpath, dep->d_name ); + + e = delete_tree( childpath ); + + free( childpath ); + + if( e ) + { + break; + } + } + + if( ( e == 0 ) && ( strcmp( path, "/" ) != 0 ) ) + { + e = rmdir( path ) ? errno : 0; + } + + closedir( dp ); + return e; + } + + static void add_to_flist( int ft, + int id, + int parent ) + { + fent_t * fep; + flist_t * ftp; + + ftp = &flist[ ft ]; + + if( ftp->nfiles == ftp->nslots ) + { + ftp->nslots += FLIST_SLOT_INCR; + ftp->fents = realloc( ftp->fents, ftp->nslots * sizeof( fent_t ) ); + } + + fep = &ftp->fents[ ftp->nfiles++ ]; + fep->id = id; + fep->parent = parent; + } + + static void append_pathname( pathname_t * name, + const char * str ) + { + int len; + + len = strlen( str ); + #ifdef DEBUG + if( len && ( *str == '/' ) && ( name->len == 0 ) ) + { + RedPrintf( "fsstress: append_pathname failure\n" ); + chdir( homedir ); + abort(); + } + #endif + name->path = realloc( name->path, name->len + 1 + len ); + strcpy( &name->path[ name->len ], str ); + name->len += len; + } + + static void check_cwd( void ) + { + #ifdef DEBUG + REDSTAT statbuf; + + if( ( stat64( ".", &statbuf ) == 0 ) && ( statbuf.st_ino == top_ino ) ) + { + return; + } + + chdir( homedir ); + RedPrintf( "fsstress: check_cwd failure\n" ); + abort(); + #endif /* ifdef DEBUG */ + } + + static int creat_path( pathname_t * name, + mode_t mode ) + { + char buf[ MAXNAMELEN ]; + pathname_t newname; + int rval; + + rval = creat( name->path, mode ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name, buf, &newname ); + + if( chdir( buf ) == 0 ) + { + rval = creat_path( &newname, mode ); + chdir( ".." ); + } + + free_pathname( &newname ); + return rval; + } + + static void dcache_enter( int dirid, + int slot ) + { + dcache[ dirid % NDCACHE ] = slot; + } + + static void dcache_init( void ) + { + int i; + + for( i = 0; i < NDCACHE; i++ ) + { + dcache[ i ] = -1; + } + } + + static fent_t * dcache_lookup( int dirid ) + { + fent_t * fep; + int i; + + i = dcache[ dirid % NDCACHE ]; + + if( ( i >= 0 ) && ( ( fep = &flist[ FT_DIR ].fents[ i ] )->id == dirid ) ) + { + return fep; + } + + return NULL; + } + + static void dcache_purge( int dirid ) + { + int * dcp; + + dcp = &dcache[ dirid % NDCACHE ]; + + if( ( *dcp >= 0 ) && ( flist[ FT_DIR ].fents[ *dcp ].id == dirid ) ) + { + *dcp = -1; + } + } + + static void del_from_flist( int ft, + int slot ) + { + flist_t * ftp; + + ftp = &flist[ ft ]; + + if( ft == FT_DIR ) + { + dcache_purge( ftp->fents[ slot ].id ); + } + + if( slot != ftp->nfiles - 1 ) + { + if( ft == FT_DIR ) + { + dcache_purge( ftp->fents[ ftp->nfiles - 1 ].id ); + } + + ftp->fents[ slot ] = ftp->fents[ --ftp->nfiles ]; + } + else + { + ftp->nfiles--; + } + } + + static fent_t * dirid_to_fent( int dirid ) + { + fent_t * efep; + fent_t * fep; + flist_t * flp; + + if( ( fep = dcache_lookup( dirid ) ) ) + { + return fep; + } + + flp = &flist[ FT_DIR ]; + + for( fep = flp->fents, efep = &fep[ flp->nfiles ]; fep < efep; fep++ ) + { + if( fep->id == dirid ) + { + dcache_enter( dirid, ( int ) ( fep - flp->fents ) ); + return fep; + } + } + + return NULL; + } + + static void doproc( void ) + { + REDSTAT statbuf; + char buf[ 10 ]; + int opno; + opdesc_t * p; + + RedSNPrintf( buf, sizeof( buf ), "p%x", procid ); + ( void ) mkdir( buf ); + + if( ( chdir( buf ) < 0 ) || ( stat64( ".", &statbuf ) < 0 ) ) + { + perror( buf ); + _exit( 1 ); + } + + top_ino = statbuf.st_ino; + homedir = getcwd( NULL, 0 ); + seed += procid; + srandom( seed ); + + if( namerand ) + { + namerand = random(); + } + + for( opno = 0; opno < operations; opno++ ) + { + p = &ops[ freq_table[ random() % freq_table_size ] ]; + + if( ( unsigned long ) p->func < 4096 ) + { + abort(); + } + + p->func( opno, random() ); + } + + free( homedir ); + } + + static void fent_to_name( pathname_t * name, + flist_t * flp, + fent_t * fep ) + { + char buf[ MAXNAMELEN ]; + int i; + fent_t * pfep; + + if( fep == NULL ) + { + return; + } + + if( fep->parent != -1 ) + { + pfep = dirid_to_fent( fep->parent ); + fent_to_name( name, &flist[ FT_DIR ], pfep ); + append_pathname( name, "/" ); + } + + i = RedSNPrintf( buf, sizeof( buf ), "%c%x", flp->tag, fep->id ); + namerandpad( fep->id, buf, i ); + append_pathname( name, buf ); + } + + static void fix_parent( int oldid, + int newid ) + { + fent_t * fep; + flist_t * flp; + int i; + int j; + + for( i = 0, flp = flist; i < FT_nft; i++, flp++ ) + { + for( j = 0, fep = flp->fents; j < flp->nfiles; j++, fep++ ) + { + if( fep->parent == oldid ) + { + fep->parent = newid; + } + } + } + } + + static void free_pathname( pathname_t * name ) + { + if( name->path ) + { + free( name->path ); + name->path = NULL; + name->len = 0; + } + } + + static int generate_fname( fent_t * fep, + int ft, + pathname_t * name, + int * idp, + int * v ) + { + char buf[ MAXNAMELEN ]; + flist_t * flp; + int id; + int j; + int len; + + flp = &flist[ ft ]; + len = RedSNPrintf( buf, sizeof( buf ), "%c%x", flp->tag, id = nameseq++ ); + namerandpad( id, buf, len ); + + if( fep ) + { + fent_to_name( name, &flist[ FT_DIR ], fep ); + append_pathname( name, "/" ); + } + + append_pathname( name, buf ); + *idp = id; + *v = verbose; + + for( j = 0; !*v && j < ilistlen; j++ ) + { + if( ilist[ j ] == id ) + { + *v = 1; + break; + } + } + + return 1; + } + + static int get_fname( int which, + long r, + pathname_t * name, + flist_t ** flpp, + fent_t ** fepp, + int * v ) + { + int c; + fent_t * fep; + flist_t * flp; + int i; + int j; + int x; + + for( i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++ ) + { + if( which & ( 1 << i ) ) + { + c += flp->nfiles; + } + } + + if( c == 0 ) + { + if( flpp ) + { + *flpp = NULL; + } + + if( fepp ) + { + *fepp = NULL; + } + + *v = verbose; + return 0; + } + + x = ( int ) ( r % c ); + + for( i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++ ) + { + if( which & ( 1 << i ) ) + { + if( x < c + flp->nfiles ) + { + fep = &flp->fents[ x - c ]; + + if( name ) + { + fent_to_name( name, flp, fep ); + } + + if( flpp ) + { + *flpp = flp; + } + + if( fepp ) + { + *fepp = fep; + } + + *v = verbose; + + for( j = 0; !*v && j < ilistlen; j++ ) + { + if( ilist[ j ] == fep->id ) + { + *v = 1; + break; + } + } + + return 1; + } + + c += flp->nfiles; + } + } + + #ifdef DEBUG + RedPrintf( "fsstress: get_fname failure\n" ); + abort(); + #endif + return -1; + } + + static void init_pathname( pathname_t * name ) + { + name->len = 0; + name->path = NULL; + } + + static int link_path( pathname_t * name1, + pathname_t * name2 ) + { + char buf1[ MAXNAMELEN ]; + char buf2[ MAXNAMELEN ]; + int down1; + pathname_t newname1; + pathname_t newname2; + int rval; + + rval = link( name1->path, name2->path ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name1, buf1, &newname1 ); + separate_pathname( name2, buf2, &newname2 ); + + if( strcmp( buf1, buf2 ) == 0 ) + { + if( chdir( buf1 ) == 0 ) + { + rval = link_path( &newname1, &newname2 ); + chdir( ".." ); + } + } + else + { + if( strcmp( buf1, ".." ) == 0 ) + { + down1 = 0; + } + else if( strcmp( buf2, ".." ) == 0 ) + { + down1 = 1; + } + else if( strlen( buf1 ) == 0 ) + { + down1 = 0; + } + else if( strlen( buf2 ) == 0 ) + { + down1 = 1; + } + else + { + down1 = MAX( newname1.len, 3 + name2->len ) <= + MAX( 3 + name1->len, newname2.len ); + } + + if( down1 ) + { + free_pathname( &newname2 ); + append_pathname( &newname2, "../" ); + append_pathname( &newname2, name2->path ); + + if( chdir( buf1 ) == 0 ) + { + rval = link_path( &newname1, &newname2 ); + chdir( ".." ); + } + } + else + { + free_pathname( &newname1 ); + append_pathname( &newname1, "../" ); + append_pathname( &newname1, name1->path ); + + if( chdir( buf2 ) == 0 ) + { + rval = link_path( &newname1, &newname2 ); + chdir( ".." ); + } + } + } + + free_pathname( &newname1 ); + free_pathname( &newname2 ); + return rval; + } + + static int lstat64_path( pathname_t * name, + REDSTAT * sbuf ) + { + char buf[ MAXNAMELEN ]; + pathname_t newname; + int rval; + + rval = lstat64( name->path, sbuf ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name, buf, &newname ); + + if( chdir( buf ) == 0 ) + { + rval = lstat64_path( &newname, sbuf ); + chdir( ".." ); + } + + free_pathname( &newname ); + return rval; + } + + static void make_freq_table( void ) + { + int f; + int i; + opdesc_t * p; + + for( p = ops, f = 0; p < ops_end; p++ ) + { + f += p->freq; + } + + freq_table = malloc( f * sizeof( *freq_table ) ); + freq_table_size = f; + + for( p = ops, i = 0; p < ops_end; p++ ) + { + for( f = 0; f < p->freq; f++, i++ ) + { + freq_table[ i ] = p->op; + } + } + } + + static int mkdir_path( pathname_t * name, + mode_t mode ) + { + char buf[ MAXNAMELEN ]; + pathname_t newname; + int rval; + + rval = mkdir( name->path ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name, buf, &newname ); + + if( chdir( buf ) == 0 ) + { + rval = mkdir_path( &newname, mode ); + chdir( ".." ); + } + + free_pathname( &newname ); + return rval; + } + + static void namerandpad( int id, + char * buf, + int len ) + { + int bucket; + static int buckets[ 8 ] = { 0 }; + static int bucket_count = 0; + int bucket_value; + int i; + int padlen; + int padmod; + + if( namerand == 0 ) + { + return; + } + + /* buckets[] used to be a statically initialized array with the following + * initializer: { 2, 4, 8, 16, 32, 64, 128, MAXNAMELEN - 1 } + * + * The problem is that with Reliance Edge, the maximum name length might be + * less than 128. So the below code populates buckets[] in a similar + * fashion but avoids name lengths longer than the maximum. For example, + * if the max name is 20, the resulting array is { 2, 4, 8, 16, 20 }. + */ + if( !bucket_count ) + { + bucket_count = sizeof( buckets ) / sizeof( buckets[ 0 ] ); + bucket_value = 2; + + for( i = 0; i < bucket_count; i++ ) + { + if( ( bucket_value > 128 ) || ( bucket_value >= ( int ) MAXNAMELEN - 1 ) ) + { + break; + } + + buckets[ i ] = bucket_value; + bucket_value *= 2; + } + + if( i < bucket_count ) + { + buckets[ i ] = MAXNAMELEN - 1; + i++; + } + + bucket_count = i; + } + + bucket = ( id ^ namerand ) % bucket_count; + padmod = buckets[ bucket ] + 1 - len; + + if( padmod <= 0 ) + { + return; + } + + padlen = ( id ^ namerand ) % padmod; + + if( padlen ) + { + memset( &buf[ len ], 'X', padlen ); + buf[ len + padlen ] = '\0'; + } + } + + static int open_path( pathname_t * name, + int oflag ) + { + char buf[ MAXNAMELEN ]; + pathname_t newname; + int rval; + + rval = open( name->path, oflag ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name, buf, &newname ); + + if( chdir( buf ) == 0 ) + { + rval = open_path( &newname, oflag ); + chdir( ".." ); + } + + free_pathname( &newname ); + return rval; + } + + static DIR * opendir_path( pathname_t * name ) + { + char buf[ MAXNAMELEN ]; + pathname_t newname; + DIR * rval; + + rval = opendir( name->path ); + + if( rval || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name, buf, &newname ); + + if( chdir( buf ) == 0 ) + { + rval = opendir_path( &newname ); + chdir( ".." ); + } + + free_pathname( &newname ); + return rval; + } + + static int rename_path( pathname_t * name1, + pathname_t * name2 ) + { + char buf1[ MAXNAMELEN ]; + char buf2[ MAXNAMELEN ]; + int down1; + pathname_t newname1; + pathname_t newname2; + int rval; + + rval = rename( name1->path, name2->path ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name1, buf1, &newname1 ); + separate_pathname( name2, buf2, &newname2 ); + + if( strcmp( buf1, buf2 ) == 0 ) + { + if( chdir( buf1 ) == 0 ) + { + rval = rename_path( &newname1, &newname2 ); + chdir( ".." ); + } + } + else + { + if( strcmp( buf1, ".." ) == 0 ) + { + down1 = 0; + } + else if( strcmp( buf2, ".." ) == 0 ) + { + down1 = 1; + } + else if( strlen( buf1 ) == 0 ) + { + down1 = 0; + } + else if( strlen( buf2 ) == 0 ) + { + down1 = 1; + } + else + { + down1 = MAX( newname1.len, 3 + name2->len ) <= + MAX( 3 + name1->len, newname2.len ); + } + + if( down1 ) + { + free_pathname( &newname2 ); + append_pathname( &newname2, "../" ); + append_pathname( &newname2, name2->path ); + + if( chdir( buf1 ) == 0 ) + { + rval = rename_path( &newname1, &newname2 ); + chdir( ".." ); + } + } + else + { + free_pathname( &newname1 ); + append_pathname( &newname1, "../" ); + append_pathname( &newname1, name1->path ); + + if( chdir( buf2 ) == 0 ) + { + rval = rename_path( &newname1, &newname2 ); + chdir( ".." ); + } + } + } + + free_pathname( &newname1 ); + free_pathname( &newname2 ); + return rval; + } + + static int rmdir_path( pathname_t * name ) + { + char buf[ MAXNAMELEN ]; + pathname_t newname; + int rval; + + rval = rmdir( name->path ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name, buf, &newname ); + + if( chdir( buf ) == 0 ) + { + rval = rmdir_path( &newname ); + chdir( ".." ); + } + + free_pathname( &newname ); + return rval; + } + + static void separate_pathname( pathname_t * name, + char * buf, + pathname_t * newname ) + { + char * slash; + + init_pathname( newname ); + slash = strchr( name->path, '/' ); + + if( slash == NULL ) + { + buf[ 0 ] = '\0'; + return; + } + + *slash = '\0'; + strcpy( buf, name->path ); + *slash = '/'; + append_pathname( newname, slash + 1 ); + } + + static int stat64_path( pathname_t * name, + REDSTAT * sbuf ) + { + char buf[ MAXNAMELEN ]; + pathname_t newname; + int rval; + + rval = stat64( name->path, sbuf ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name, buf, &newname ); + + if( chdir( buf ) == 0 ) + { + rval = stat64_path( &newname, sbuf ); + chdir( ".." ); + } + + free_pathname( &newname ); + return rval; + } + + static int truncate64_path( pathname_t * name, + off64_t length ) + { + char buf[ MAXNAMELEN ]; + pathname_t newname; + int rval; + + rval = truncate64( name->path, length ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name, buf, &newname ); + + if( chdir( buf ) == 0 ) + { + rval = truncate64_path( &newname, length ); + chdir( ".." ); + } + + free_pathname( &newname ); + return rval; + } + + static int unlink_path( pathname_t * name ) + { + char buf[ MAXNAMELEN ]; + pathname_t newname; + int rval; + + rval = unlink( name->path ); + + if( ( rval >= 0 ) || ( errno != RED_ENAMETOOLONG ) ) + { + return rval; + } + + separate_pathname( name, buf, &newname ); + + if( chdir( buf ) == 0 ) + { + rval = unlink_path( &newname ); + chdir( ".." ); + } + + free_pathname( &newname ); + return rval; + } + + static void usage( const char * progname ) + { + RedPrintf( "usage: %s VolumeID [Options]\n", progname ); + RedPrintf( "File system stress test.\n\n" ); + RedPrintf( "Where:\n" ); + RedPrintf( " VolumeID\n" ); + RedPrintf( " A volume number (e.g., 2) or a volume path prefix (e.g., VOL1: or /data)\n" ); + RedPrintf( " of the volume to test.\n" ); + RedPrintf( "And 'Options' are any of the following:\n" ); + RedPrintf( " --no-cleanup, -c\n" ); + RedPrintf( " Specifies not to remove files (cleanup) after execution\n" ); + RedPrintf( " --loops=count, -l count\n" ); + RedPrintf( " Specifies the number of times the entire test should loop. Use 0 for\n" ); + RedPrintf( " infinite. Default 1.\n" ); + RedPrintf( " --nops=count, -n count\n" ); + RedPrintf( " Specifies the number of operations to run (default 10000).\n" ); + RedPrintf( " --namepad, -r\n" ); + RedPrintf( " Specifies to use random name padding (resulting in longer names).\n" ); + RedPrintf( " --seed=value, -s value\n" ); + RedPrintf( " Specifies the seed for the random number generator (default timestamp).\n" ); + RedPrintf( " --verbose, -v\n" ); + RedPrintf( " Specifies verbose mode (without this, test is very quiet).\n" ); + RedPrintf( " --dev=devname, -D devname\n" ); + RedPrintf( " Specifies the device name. This is typically only meaningful when\n" ); + RedPrintf( " running the test on a host machine. This can be \"ram\" to test on a RAM\n" ); + RedPrintf( " disk, the path and name of a file disk (e.g., red.bin); or an OS-specific\n" ); + RedPrintf( " reference to a device (on Windows, a drive letter like G: or a device name\n" ); + RedPrintf( " like \\\\.\\PhysicalDrive7).\n" ); + RedPrintf( " --help, -H\n" ); + RedPrintf( " Prints this usage text and exits.\n\n" ); + RedPrintf( "Warning: This test will format the volume -- destroying all existing data.\n\n" ); + } + + static void creat_f( int opno, + long r ) + { + int e; + int e1; + pathname_t f; + int fd; + fent_t * fep; + int id; + int parid; + int type; + int v; + int v1; + int esz = 0; + + if( !get_fname( FT_DIRm, r, NULL, NULL, &fep, &v1 ) ) + { + parid = -1; + } + else + { + parid = fep->id; + } + + init_pathname( &f ); + type = rtpct ? ( ( int ) ( random() % 100 ) > rtpct ? FT_REG : FT_RTF ) : FT_REG; + e = generate_fname( fep, type, &f, &id, &v ); + v |= v1; + + if( !e ) + { + if( v ) + { + fent_to_name( &f, &flist[ FT_DIR ], fep ); + RedPrintf( "%d/%d: creat - no filename from %s\n", + procid, opno, f.path ); + } + + free_pathname( &f ); + return; + } + + fd = creat_path( &f, 0666 ); + e = fd < 0 ? errno : 0; + e1 = 0; + check_cwd(); + esz = 0; + + if( fd >= 0 ) + { + add_to_flist( type, id, parid ); + close( fd ); + } + + if( v ) + { + RedPrintf( "%d/%d: creat %s x:%d %d %d\n", procid, opno, f.path, + esz, e, e1 ); + } + + free_pathname( &f ); + } + + static void fdatasync_f( int opno, + long r ) + { + int e; + pathname_t f; + int fd; + int v; + + init_pathname( &f ); + + if( !get_fname( FT_REGFILE, r, &f, NULL, NULL, &v ) ) + { + if( v ) + { + RedPrintf( "%d/%d: fdatasync - no filename\n", + procid, opno ); + } + + free_pathname( &f ); + return; + } + + fd = open_path( &f, O_WRONLY ); + e = fd < 0 ? errno : 0; + check_cwd(); + + if( fd < 0 ) + { + if( v ) + { + RedPrintf( "%d/%d: fdatasync - open %s failed %d\n", + procid, opno, f.path, e ); + } + + free_pathname( &f ); + return; + } + + e = fdatasync( fd ) < 0 ? errno : 0; + + if( v ) + { + RedPrintf( "%d/%d: fdatasync %s %d\n", procid, opno, f.path, e ); + } + + free_pathname( &f ); + close( fd ); + } + + static void fsync_f( int opno, + long r ) + { + int e; + pathname_t f; + int fd; + int v; + + init_pathname( &f ); + + if( !get_fname( FT_REGFILE, r, &f, NULL, NULL, &v ) ) + { + if( v ) + { + RedPrintf( "%d/%d: fsync - no filename\n", procid, opno ); + } + + free_pathname( &f ); + return; + } + + fd = open_path( &f, O_WRONLY ); + e = fd < 0 ? errno : 0; + check_cwd(); + + if( fd < 0 ) + { + if( v ) + { + RedPrintf( "%d/%d: fsync - open %s failed %d\n", + procid, opno, f.path, e ); + } + + free_pathname( &f ); + return; + } + + e = fsync( fd ) < 0 ? errno : 0; + + if( v ) + { + RedPrintf( "%d/%d: fsync %s %d\n", procid, opno, f.path, e ); + } + + free_pathname( &f ); + close( fd ); + } + + static void getdents_f( int opno, + long r ) + { + DIR * dir; + pathname_t f; + int v; + + init_pathname( &f ); + + if( !get_fname( FT_DIRm, r, &f, NULL, NULL, &v ) ) + { + append_pathname( &f, "." ); + } + + dir = opendir_path( &f ); + check_cwd(); + + if( dir == NULL ) + { + if( v ) + { + RedPrintf( "%d/%d: getdents - can't open %s\n", + procid, opno, f.path ); + } + + free_pathname( &f ); + return; + } + + while( readdir64( dir ) != NULL ) + { + continue; + } + + if( v ) + { + RedPrintf( "%d/%d: getdents %s 0\n", procid, opno, f.path ); + } + + free_pathname( &f ); + closedir( dir ); + } + + static void link_f( int opno, + long r ) + { + int e; + pathname_t f; + fent_t * fep; + flist_t * flp; + int id; + pathname_t l; + int parid; + int v; + int v1; + + init_pathname( &f ); + + if( !get_fname( FT_NOTDIR, r, &f, &flp, NULL, &v1 ) ) + { + if( v1 ) + { + RedPrintf( "%d/%d: link - no file\n", procid, opno ); + } + + free_pathname( &f ); + return; + } + + if( !get_fname( FT_DIRm, random(), NULL, NULL, &fep, &v ) ) + { + parid = -1; + } + else + { + parid = fep->id; + } + + v |= v1; + init_pathname( &l ); + e = generate_fname( fep, ( int ) ( flp - flist ), &l, &id, &v1 ); + v |= v1; + + if( !e ) + { + if( v ) + { + fent_to_name( &l, &flist[ FT_DIR ], fep ); + RedPrintf( "%d/%d: link - no filename from %s\n", + procid, opno, l.path ); + } + + free_pathname( &l ); + free_pathname( &f ); + return; + } + + e = link_path( &f, &l ) < 0 ? errno : 0; + check_cwd(); + + if( e == 0 ) + { + add_to_flist( ( int ) ( flp - flist ), id, parid ); + } + + if( v ) + { + RedPrintf( "%d/%d: link %s %s %d\n", procid, opno, f.path, l.path, + e ); + } + + free_pathname( &l ); + free_pathname( &f ); + } + + static void mkdir_f( int opno, + long r ) + { + int e; + pathname_t f; + fent_t * fep; + int id; + int parid; + int v; + int v1; + + if( !get_fname( FT_DIRm, r, NULL, NULL, &fep, &v ) ) + { + parid = -1; + } + else + { + parid = fep->id; + } + + init_pathname( &f ); + e = generate_fname( fep, FT_DIR, &f, &id, &v1 ); + v |= v1; + + if( !e ) + { + if( v ) + { + fent_to_name( &f, &flist[ FT_DIR ], fep ); + RedPrintf( "%d/%d: mkdir - no filename from %s\n", + procid, opno, f.path ); + } + + free_pathname( &f ); + return; + } + + e = mkdir_path( &f, 0777 ) < 0 ? errno : 0; + check_cwd(); + + if( e == 0 ) + { + add_to_flist( FT_DIR, id, parid ); + } + + if( v ) + { + RedPrintf( "%d/%d: mkdir %s %d\n", procid, opno, f.path, e ); + } + + free_pathname( &f ); + } + + static void read_f( int opno, + long r ) + { + char * buf; + int e; + pathname_t f; + int fd; + uint32_t len; + __int64_t lr; + off64_t off; + REDSTAT stb; + int v; + + init_pathname( &f ); + + if( !get_fname( FT_REGFILE, r, &f, NULL, NULL, &v ) ) + { + if( v ) + { + RedPrintf( "%d/%d: read - no filename\n", procid, opno ); + } + + free_pathname( &f ); + return; + } + + fd = open_path( &f, O_RDONLY ); + e = fd < 0 ? errno : 0; + check_cwd(); + + if( fd < 0 ) + { + if( v ) + { + RedPrintf( "%d/%d: read - open %s failed %d\n", + procid, opno, f.path, e ); + } + + free_pathname( &f ); + return; + } + + if( fstat64( fd, &stb ) < 0 ) + { + if( v ) + { + RedPrintf( "%d/%d: read - fstat64 %s failed %d\n", + procid, opno, f.path, errno ); + } + + free_pathname( &f ); + close( fd ); + return; + } + + if( stb.st_size == 0 ) + { + if( v ) + { + RedPrintf( "%d/%d: read - %s zero size\n", procid, opno, + f.path ); + } + + free_pathname( &f ); + close( fd ); + return; + } + + lr = ( ( __int64_t ) random() << 32 ) + random(); + off = ( off64_t ) ( lr % stb.st_size ); + lseek64( fd, off, SEEK_SET ); + len = ( random() % ( getpagesize() * 4 ) ) + 1; + buf = malloc( len ); + e = read( fd, buf, len ) < 0 ? errno : 0; + free( buf ); + + if( v ) + { + RedPrintf( "%d/%d: read %s [%lld,%ld] %d\n", + procid, opno, f.path, ( long long ) off, ( long int ) len, e ); + } + + free_pathname( &f ); + close( fd ); + } + + static void rename_f( int opno, + long r ) + { + fent_t * dfep; + int e; + pathname_t f; + fent_t * fep; + flist_t * flp; + int id; + pathname_t newf; + int oldid; + int parid; + int v; + int v1; + + init_pathname( &f ); + + if( !get_fname( FT_ANYm, r, &f, &flp, &fep, &v1 ) ) + { + if( v1 ) + { + RedPrintf( "%d/%d: rename - no filename\n", procid, opno ); + } + + free_pathname( &f ); + return; + } + + if( !get_fname( FT_DIRm, random(), NULL, NULL, &dfep, &v ) ) + { + parid = -1; + } + else + { + parid = dfep->id; + } + + v |= v1; + init_pathname( &newf ); + e = generate_fname( dfep, ( int ) ( flp - flist ), &newf, &id, &v1 ); + v |= v1; + + if( !e ) + { + if( v ) + { + fent_to_name( &f, &flist[ FT_DIR ], dfep ); + RedPrintf( "%d/%d: rename - no filename from %s\n", + procid, opno, f.path ); + } + + free_pathname( &newf ); + free_pathname( &f ); + return; + } + + e = rename_path( &f, &newf ) < 0 ? errno : 0; + check_cwd(); + + if( e == 0 ) + { + if( flp - flist == FT_DIR ) + { + oldid = fep->id; + fix_parent( oldid, id ); + } + + del_from_flist( ( int ) ( flp - flist ), ( int ) ( fep - flp->fents ) ); + add_to_flist( ( int ) ( flp - flist ), id, parid ); + } + + if( v ) + { + RedPrintf( "%d/%d: rename %s to %s %d\n", procid, opno, f.path, + newf.path, e ); + } + + free_pathname( &newf ); + free_pathname( &f ); + } + + static void rmdir_f( int opno, + long r ) + { + int e; + pathname_t f; + fent_t * fep; + int v; + + init_pathname( &f ); + + if( !get_fname( FT_DIRm, r, &f, NULL, &fep, &v ) ) + { + if( v ) + { + RedPrintf( "%d/%d: rmdir - no directory\n", procid, opno ); + } + + free_pathname( &f ); + return; + } + + e = rmdir_path( &f ) < 0 ? errno : 0; + check_cwd(); + + if( e == 0 ) + { + del_from_flist( FT_DIR, ( int ) ( fep - flist[ FT_DIR ].fents ) ); + } + + if( v ) + { + RedPrintf( "%d/%d: rmdir %s %d\n", procid, opno, f.path, e ); + } + + free_pathname( &f ); + } + + static void stat_f( int opno, + long r ) + { + int e; + pathname_t f; + REDSTAT stb; + int v; + + init_pathname( &f ); + + if( !get_fname( FT_ANYm, r, &f, NULL, NULL, &v ) ) + { + if( v ) + { + RedPrintf( "%d/%d: stat - no entries\n", procid, opno ); + } + + free_pathname( &f ); + return; + } + + e = lstat64_path( &f, &stb ) < 0 ? errno : 0; + check_cwd(); + + if( v ) + { + RedPrintf( "%d/%d: stat %s %d\n", procid, opno, f.path, e ); + } + + free_pathname( &f ); + } + + static void truncate_f( int opno, + long r ) + { + int e; + pathname_t f; + __int64_t lr; + off64_t off; + REDSTAT stb; + int v; + + init_pathname( &f ); + + if( !get_fname( FT_REGFILE, r, &f, NULL, NULL, &v ) ) + { + if( v ) + { + RedPrintf( "%d/%d: truncate - no filename\n", procid, opno ); + } + + free_pathname( &f ); + return; + } + + e = stat64_path( &f, &stb ) < 0 ? errno : 0; + check_cwd(); + + if( e > 0 ) + { + if( v ) + { + RedPrintf( "%d/%d: truncate - stat64 %s failed %d\n", + procid, opno, f.path, e ); + } + + free_pathname( &f ); + return; + } + + lr = ( ( __int64_t ) random() << 32 ) + random(); + off = lr % MIN( stb.st_size + ( 1024 * 1024 ), MAXFSIZE ); + off %= maxfsize; + e = truncate64_path( &f, off ) < 0 ? errno : 0; + check_cwd(); + + if( v ) + { + RedPrintf( "%d/%d: truncate %s %lld %d\n", procid, opno, f.path, + ( long long ) off, e ); + } + + free_pathname( &f ); + } + + static void unlink_f( int opno, + long r ) + { + int e; + pathname_t f; + fent_t * fep; + flist_t * flp; + int v; + + init_pathname( &f ); + + if( !get_fname( FT_NOTDIR, r, &f, &flp, &fep, &v ) ) + { + if( v ) + { + RedPrintf( "%d/%d: unlink - no file\n", procid, opno ); + } + + free_pathname( &f ); + return; + } + + e = unlink_path( &f ) < 0 ? errno : 0; + check_cwd(); + + if( e == 0 ) + { + del_from_flist( ( int ) ( flp - flist ), ( int ) ( fep - flp->fents ) ); + } + + if( v ) + { + RedPrintf( "%d/%d: unlink %s %d\n", procid, opno, f.path, e ); + } + + free_pathname( &f ); + } + + static void write_f( int opno, + long r ) + { + char * buf; + int e; + pathname_t f; + int fd; + uint32_t len; + __int64_t lr; + off64_t off; + REDSTAT stb; + int v; + + init_pathname( &f ); + + if( !get_fname( FT_REGm, r, &f, NULL, NULL, &v ) ) + { + if( v ) + { + RedPrintf( "%d/%d: write - no filename\n", procid, opno ); + } + + free_pathname( &f ); + return; + } + + fd = open_path( &f, O_WRONLY ); + e = fd < 0 ? errno : 0; + check_cwd(); + + if( fd < 0 ) + { + if( v ) + { + RedPrintf( "%d/%d: write - open %s failed %d\n", + procid, opno, f.path, e ); + } + + free_pathname( &f ); + return; + } + + if( fstat64( fd, &stb ) < 0 ) + { + if( v ) + { + RedPrintf( "%d/%d: write - fstat64 %s failed %d\n", + procid, opno, f.path, errno ); + } + + free_pathname( &f ); + close( fd ); + return; + } + + lr = ( ( __int64_t ) random() << 32 ) + random(); + off = ( off64_t ) ( lr % MIN( stb.st_size + ( 1024 * 1024 ), MAXFSIZE ) ); + off %= maxfsize; + lseek64( fd, off, SEEK_SET ); + len = ( random() % ( getpagesize() * 4 ) ) + 1; + buf = malloc( len ); + memset( buf, nameseq & 0xff, len ); + e = write( fd, buf, len ) < 0 ? errno : 0; + free( buf ); + + if( v ) + { + RedPrintf( "%d/%d: write %s [%lld,%ld] %d\n", + procid, opno, f.path, ( long long ) off, ( long int ) len, e ); + } + + free_pathname( &f ); + close( fd ); + } + + + #if REDCONF_CHECKER == 1 + static void check_f( int opno, + long r ) + { + int32_t ret; + const char * pszVolume = gpRedVolConf->pszPathPrefix; + + ( void ) r; + + errno = 0; + + ret = red_transact( pszVolume ); + + if( ret == 0 ) + { + ret = red_umount( pszVolume ); + + if( ret == 0 ) + { + int32_t ret2; + + errno = -RedCoreVolCheck(); + + if( errno != 0 ) + { + ret = -1; + } + + ret2 = red_mount( pszVolume ); + + if( ret == 0 ) + { + ret = ret2; + } + + if( ret2 != 0 ) + { + exit( 1 ); } } - return 1; } - c += flp->nfiles; - } - } -#ifdef DEBUG - RedPrintf("fsstress: get_fname failure\n"); - abort(); -#endif - return -1; -} - -static void init_pathname(pathname_t *name) -{ - name->len = 0; - name->path = NULL; -} - -static int link_path(pathname_t *name1, pathname_t *name2) -{ - char buf1[MAXNAMELEN]; - char buf2[MAXNAMELEN]; - int down1; - pathname_t newname1; - pathname_t newname2; - int rval; - - rval = link(name1->path, name2->path); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name1, buf1, &newname1); - separate_pathname(name2, buf2, &newname2); - if (strcmp(buf1, buf2) == 0) { - if (chdir(buf1) == 0) { - rval = link_path(&newname1, &newname2); - chdir(".."); - } - } else { - if (strcmp(buf1, "..") == 0) - down1 = 0; - else if (strcmp(buf2, "..") == 0) - down1 = 1; - else if (strlen(buf1) == 0) - down1 = 0; - else if (strlen(buf2) == 0) - down1 = 1; - else - down1 = MAX(newname1.len, 3 + name2->len) <= - MAX(3 + name1->len, newname2.len); - if (down1) { - free_pathname(&newname2); - append_pathname(&newname2, "../"); - append_pathname(&newname2, name2->path); - if (chdir(buf1) == 0) { - rval = link_path(&newname1, &newname2); - chdir(".."); - } - } else { - free_pathname(&newname1); - append_pathname(&newname1, "../"); - append_pathname(&newname1, name1->path); - if (chdir(buf2) == 0) { - rval = link_path(&newname1, &newname2); - chdir(".."); - } - } - } - free_pathname(&newname1); - free_pathname(&newname2); - return rval; -} - -static int lstat64_path(pathname_t *name, REDSTAT *sbuf) -{ - char buf[MAXNAMELEN]; - pathname_t newname; - int rval; - - rval = lstat64(name->path, sbuf); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name, buf, &newname); - if (chdir(buf) == 0) { - rval = lstat64_path(&newname, sbuf); - chdir(".."); - } - free_pathname(&newname); - return rval; -} - -static void make_freq_table(void) -{ - int f; - int i; - opdesc_t *p; - - for (p = ops, f = 0; p < ops_end; p++) - f += p->freq; - freq_table = malloc(f * sizeof(*freq_table)); - freq_table_size = f; - for (p = ops, i = 0; p < ops_end; p++) { - for (f = 0; f < p->freq; f++, i++) - freq_table[i] = p->op; - } -} - -static int mkdir_path(pathname_t *name, mode_t mode) -{ - char buf[MAXNAMELEN]; - pathname_t newname; - int rval; - - rval = mkdir(name->path); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name, buf, &newname); - if (chdir(buf) == 0) { - rval = mkdir_path(&newname, mode); - chdir(".."); - } - free_pathname(&newname); - return rval; -} - -static void namerandpad(int id, char *buf, int len) -{ - int bucket; - static int buckets[8] = {0}; - static int bucket_count = 0; - int bucket_value; - int i; - int padlen; - int padmod; - - if (namerand == 0) - return; - - /* buckets[] used to be a statically initialized array with the following - initializer: { 2, 4, 8, 16, 32, 64, 128, MAXNAMELEN - 1 } - - The problem is that with Reliance Edge, the maximum name length might be - less than 128. So the below code populates buckets[] in a similar - fashion but avoids name lengths longer than the maximum. For example, - if the max name is 20, the resulting array is { 2, 4, 8, 16, 20 }. - */ - if (!bucket_count) { - bucket_count = sizeof(buckets) / sizeof(buckets[0]); - bucket_value = 2; - for (i = 0; i < bucket_count; i++) { - if (bucket_value > 128 || bucket_value >= (int)MAXNAMELEN - 1) - break; - buckets[i] = bucket_value; - bucket_value *= 2; - } - if (i < bucket_count) { - buckets[i] = MAXNAMELEN - 1; - i++; - } - bucket_count = i; - } - - bucket = (id ^ namerand) % bucket_count; - padmod = buckets[bucket] + 1 - len; - if (padmod <= 0) - return; - padlen = (id ^ namerand) % padmod; - if (padlen) { - memset(&buf[len], 'X', padlen); - buf[len + padlen] = '\0'; - } -} - -static int open_path(pathname_t *name, int oflag) -{ - char buf[MAXNAMELEN]; - pathname_t newname; - int rval; - - rval = open(name->path, oflag); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name, buf, &newname); - if (chdir(buf) == 0) { - rval = open_path(&newname, oflag); - chdir(".."); - } - free_pathname(&newname); - return rval; -} - -static DIR *opendir_path(pathname_t *name) -{ - char buf[MAXNAMELEN]; - pathname_t newname; - DIR *rval; - - rval = opendir(name->path); - if (rval || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name, buf, &newname); - if (chdir(buf) == 0) { - rval = opendir_path(&newname); - chdir(".."); - } - free_pathname(&newname); - return rval; -} - -static int rename_path(pathname_t *name1, pathname_t *name2) -{ - char buf1[MAXNAMELEN]; - char buf2[MAXNAMELEN]; - int down1; - pathname_t newname1; - pathname_t newname2; - int rval; - - rval = rename(name1->path, name2->path); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name1, buf1, &newname1); - separate_pathname(name2, buf2, &newname2); - if (strcmp(buf1, buf2) == 0) { - if (chdir(buf1) == 0) { - rval = rename_path(&newname1, &newname2); - chdir(".."); - } - } else { - if (strcmp(buf1, "..") == 0) - down1 = 0; - else if (strcmp(buf2, "..") == 0) - down1 = 1; - else if (strlen(buf1) == 0) - down1 = 0; - else if (strlen(buf2) == 0) - down1 = 1; - else - down1 = MAX(newname1.len, 3 + name2->len) <= - MAX(3 + name1->len, newname2.len); - if (down1) { - free_pathname(&newname2); - append_pathname(&newname2, "../"); - append_pathname(&newname2, name2->path); - if (chdir(buf1) == 0) { - rval = rename_path(&newname1, &newname2); - chdir(".."); - } - } else { - free_pathname(&newname1); - append_pathname(&newname1, "../"); - append_pathname(&newname1, name1->path); - if (chdir(buf2) == 0) { - rval = rename_path(&newname1, &newname2); - chdir(".."); - } - } - } - free_pathname(&newname1); - free_pathname(&newname2); - return rval; -} - -static int rmdir_path(pathname_t *name) -{ - char buf[MAXNAMELEN]; - pathname_t newname; - int rval; - - rval = rmdir(name->path); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name, buf, &newname); - if (chdir(buf) == 0) { - rval = rmdir_path(&newname); - chdir(".."); - } - free_pathname(&newname); - return rval; -} - -static void separate_pathname(pathname_t *name, char *buf, pathname_t *newname) -{ - char *slash; - - init_pathname(newname); - slash = strchr(name->path, '/'); - if (slash == NULL) { - buf[0] = '\0'; - return; - } - *slash = '\0'; - strcpy(buf, name->path); - *slash = '/'; - append_pathname(newname, slash + 1); -} - -static int stat64_path(pathname_t *name, REDSTAT *sbuf) -{ - char buf[MAXNAMELEN]; - pathname_t newname; - int rval; - - rval = stat64(name->path, sbuf); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name, buf, &newname); - if (chdir(buf) == 0) { - rval = stat64_path(&newname, sbuf); - chdir(".."); - } - free_pathname(&newname); - return rval; -} - -static int truncate64_path(pathname_t *name, off64_t length) -{ - char buf[MAXNAMELEN]; - pathname_t newname; - int rval; - - rval = truncate64(name->path, length); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name, buf, &newname); - if (chdir(buf) == 0) { - rval = truncate64_path(&newname, length); - chdir(".."); - } - free_pathname(&newname); - return rval; -} - -static int unlink_path(pathname_t *name) -{ - char buf[MAXNAMELEN]; - pathname_t newname; - int rval; - - rval = unlink(name->path); - if (rval >= 0 || errno != RED_ENAMETOOLONG) - return rval; - separate_pathname(name, buf, &newname); - if (chdir(buf) == 0) { - rval = unlink_path(&newname); - chdir(".."); - } - free_pathname(&newname); - return rval; -} - -static void usage(const char *progname) -{ - RedPrintf("usage: %s VolumeID [Options]\n", progname); - RedPrintf("File system stress test.\n\n"); - RedPrintf("Where:\n"); - RedPrintf(" VolumeID\n"); - RedPrintf(" A volume number (e.g., 2) or a volume path prefix (e.g., VOL1: or /data)\n"); - RedPrintf(" of the volume to test.\n"); - RedPrintf("And 'Options' are any of the following:\n"); - RedPrintf(" --no-cleanup, -c\n"); - RedPrintf(" Specifies not to remove files (cleanup) after execution\n"); - RedPrintf(" --loops=count, -l count\n"); - RedPrintf(" Specifies the number of times the entire test should loop. Use 0 for\n"); - RedPrintf(" infinite. Default 1.\n"); - RedPrintf(" --nops=count, -n count\n"); - RedPrintf(" Specifies the number of operations to run (default 10000).\n"); - RedPrintf(" --namepad, -r\n"); - RedPrintf(" Specifies to use random name padding (resulting in longer names).\n"); - RedPrintf(" --seed=value, -s value\n"); - RedPrintf(" Specifies the seed for the random number generator (default timestamp).\n"); - RedPrintf(" --verbose, -v\n"); - RedPrintf(" Specifies verbose mode (without this, test is very quiet).\n"); - RedPrintf(" --dev=devname, -D devname\n"); - RedPrintf(" Specifies the device name. This is typically only meaningful when\n"); - RedPrintf(" running the test on a host machine. This can be \"ram\" to test on a RAM\n"); - RedPrintf(" disk, the path and name of a file disk (e.g., red.bin); or an OS-specific\n"); - RedPrintf(" reference to a device (on Windows, a drive letter like G: or a device name\n"); - RedPrintf(" like \\\\.\\PhysicalDrive7).\n"); - RedPrintf(" --help, -H\n"); - RedPrintf(" Prints this usage text and exits.\n\n"); - RedPrintf("Warning: This test will format the volume -- destroying all existing data.\n\n"); -} - -static void creat_f(int opno, long r) -{ - int e; - int e1; - pathname_t f; - int fd; - fent_t *fep; - int id; - int parid; - int type; - int v; - int v1; - int esz = 0; - - if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v1)) - parid = -1; - else - parid = fep->id; - init_pathname(&f); - type = rtpct ? ((int)(random() % 100) > rtpct ? FT_REG : FT_RTF) : FT_REG; - e = generate_fname(fep, type, &f, &id, &v); - v |= v1; - if (!e) { - if (v) { - fent_to_name(&f, &flist[FT_DIR], fep); - RedPrintf("%d/%d: creat - no filename from %s\n", - procid, opno, f.path); - } - free_pathname(&f); - return; - } - fd = creat_path(&f, 0666); - e = fd < 0 ? errno : 0; - e1 = 0; - check_cwd(); - esz = 0; - if (fd >= 0) { - add_to_flist(type, id, parid); - close(fd); - } - if (v) - RedPrintf("%d/%d: creat %s x:%d %d %d\n", procid, opno, f.path, - esz, e, e1); - free_pathname(&f); -} - -static void fdatasync_f(int opno, long r) -{ - int e; - pathname_t f; - int fd; - int v; - - init_pathname(&f); - if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { - if (v) - RedPrintf("%d/%d: fdatasync - no filename\n", - procid, opno); - free_pathname(&f); - return; - } - fd = open_path(&f, O_WRONLY); - e = fd < 0 ? errno : 0; - check_cwd(); - if (fd < 0) { - if (v) - RedPrintf("%d/%d: fdatasync - open %s failed %d\n", - procid, opno, f.path, e); - free_pathname(&f); - return; - } - e = fdatasync(fd) < 0 ? errno : 0; - if (v) - RedPrintf("%d/%d: fdatasync %s %d\n", procid, opno, f.path, e); - free_pathname(&f); - close(fd); -} - -static void fsync_f(int opno, long r) -{ - int e; - pathname_t f; - int fd; - int v; - - init_pathname(&f); - if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { - if (v) - RedPrintf("%d/%d: fsync - no filename\n", procid, opno); - free_pathname(&f); - return; - } - fd = open_path(&f, O_WRONLY); - e = fd < 0 ? errno : 0; - check_cwd(); - if (fd < 0) { - if (v) - RedPrintf("%d/%d: fsync - open %s failed %d\n", - procid, opno, f.path, e); - free_pathname(&f); - return; - } - e = fsync(fd) < 0 ? errno : 0; - if (v) - RedPrintf("%d/%d: fsync %s %d\n", procid, opno, f.path, e); - free_pathname(&f); - close(fd); -} - -static void getdents_f(int opno, long r) -{ - DIR *dir; - pathname_t f; - int v; - - init_pathname(&f); - if (!get_fname(FT_DIRm, r, &f, NULL, NULL, &v)) - append_pathname(&f, "."); - dir = opendir_path(&f); - check_cwd(); - if (dir == NULL) { - if (v) - RedPrintf("%d/%d: getdents - can't open %s\n", - procid, opno, f.path); - free_pathname(&f); - return; - } - while (readdir64(dir) != NULL) - continue; - if (v) - RedPrintf("%d/%d: getdents %s 0\n", procid, opno, f.path); - free_pathname(&f); - closedir(dir); -} - -static void link_f(int opno, long r) -{ - int e; - pathname_t f; - fent_t *fep; - flist_t *flp; - int id; - pathname_t l; - int parid; - int v; - int v1; - - init_pathname(&f); - if (!get_fname(FT_NOTDIR, r, &f, &flp, NULL, &v1)) { - if (v1) - RedPrintf("%d/%d: link - no file\n", procid, opno); - free_pathname(&f); - return; - } - if (!get_fname(FT_DIRm, random(), NULL, NULL, &fep, &v)) - parid = -1; - else - parid = fep->id; - v |= v1; - init_pathname(&l); - e = generate_fname(fep, (int)(flp - flist), &l, &id, &v1); - v |= v1; - if (!e) { - if (v) { - fent_to_name(&l, &flist[FT_DIR], fep); - RedPrintf("%d/%d: link - no filename from %s\n", - procid, opno, l.path); - } - free_pathname(&l); - free_pathname(&f); - return; - } - e = link_path(&f, &l) < 0 ? errno : 0; - check_cwd(); - if (e == 0) - add_to_flist((int)(flp - flist), id, parid); - if (v) - RedPrintf("%d/%d: link %s %s %d\n", procid, opno, f.path, l.path, - e); - free_pathname(&l); - free_pathname(&f); -} - -static void mkdir_f(int opno, long r) -{ - int e; - pathname_t f; - fent_t *fep; - int id; - int parid; - int v; - int v1; - - if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v)) - parid = -1; - else - parid = fep->id; - init_pathname(&f); - e = generate_fname(fep, FT_DIR, &f, &id, &v1); - v |= v1; - if (!e) { - if (v) { - fent_to_name(&f, &flist[FT_DIR], fep); - RedPrintf("%d/%d: mkdir - no filename from %s\n", - procid, opno, f.path); - } - free_pathname(&f); - return; - } - e = mkdir_path(&f, 0777) < 0 ? errno : 0; - check_cwd(); - if (e == 0) - add_to_flist(FT_DIR, id, parid); - if (v) - RedPrintf("%d/%d: mkdir %s %d\n", procid, opno, f.path, e); - free_pathname(&f); -} - -static void read_f(int opno, long r) -{ - char *buf; - int e; - pathname_t f; - int fd; - uint32_t len; - __int64_t lr; - off64_t off; - REDSTAT stb; - int v; - - init_pathname(&f); - if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { - if (v) - RedPrintf("%d/%d: read - no filename\n", procid, opno); - free_pathname(&f); - return; - } - fd = open_path(&f, O_RDONLY); - e = fd < 0 ? errno : 0; - check_cwd(); - if (fd < 0) { - if (v) - RedPrintf("%d/%d: read - open %s failed %d\n", - procid, opno, f.path, e); - free_pathname(&f); - return; - } - if (fstat64(fd, &stb) < 0) { - if (v) - RedPrintf("%d/%d: read - fstat64 %s failed %d\n", - procid, opno, f.path, errno); - free_pathname(&f); - close(fd); - return; - } - if (stb.st_size == 0) { - if (v) - RedPrintf("%d/%d: read - %s zero size\n", procid, opno, - f.path); - free_pathname(&f); - close(fd); - return; - } - lr = ((__int64_t) random() << 32) + random(); - off = (off64_t) (lr % stb.st_size); - lseek64(fd, off, SEEK_SET); - len = (random() % (getpagesize() * 4)) + 1; - buf = malloc(len); - e = read(fd, buf, len) < 0 ? errno : 0; - free(buf); - if (v) - RedPrintf("%d/%d: read %s [%lld,%ld] %d\n", - procid, opno, f.path, (long long)off, (long int)len, e); - free_pathname(&f); - close(fd); -} - -static void rename_f(int opno, long r) -{ - fent_t *dfep; - int e; - pathname_t f; - fent_t *fep; - flist_t *flp; - int id; - pathname_t newf; - int oldid; - int parid; - int v; - int v1; - - init_pathname(&f); - if (!get_fname(FT_ANYm, r, &f, &flp, &fep, &v1)) { - if (v1) - RedPrintf("%d/%d: rename - no filename\n", procid, opno); - free_pathname(&f); - return; - } - if (!get_fname(FT_DIRm, random(), NULL, NULL, &dfep, &v)) - parid = -1; - else - parid = dfep->id; - v |= v1; - init_pathname(&newf); - e = generate_fname(dfep, (int)(flp - flist), &newf, &id, &v1); - v |= v1; - if (!e) { - if (v) { - fent_to_name(&f, &flist[FT_DIR], dfep); - RedPrintf("%d/%d: rename - no filename from %s\n", - procid, opno, f.path); - } - free_pathname(&newf); - free_pathname(&f); - return; - } - e = rename_path(&f, &newf) < 0 ? errno : 0; - check_cwd(); - if (e == 0) { - if (flp - flist == FT_DIR) { - oldid = fep->id; - fix_parent(oldid, id); - } - del_from_flist((int)(flp - flist), (int)(fep - flp->fents)); - add_to_flist((int)(flp - flist), id, parid); - } - if (v) - RedPrintf("%d/%d: rename %s to %s %d\n", procid, opno, f.path, - newf.path, e); - free_pathname(&newf); - free_pathname(&f); -} - -static void rmdir_f(int opno, long r) -{ - int e; - pathname_t f; - fent_t *fep; - int v; - - init_pathname(&f); - if (!get_fname(FT_DIRm, r, &f, NULL, &fep, &v)) { - if (v) - RedPrintf("%d/%d: rmdir - no directory\n", procid, opno); - free_pathname(&f); - return; - } - e = rmdir_path(&f) < 0 ? errno : 0; - check_cwd(); - if (e == 0) - del_from_flist(FT_DIR, (int)(fep - flist[FT_DIR].fents)); - if (v) - RedPrintf("%d/%d: rmdir %s %d\n", procid, opno, f.path, e); - free_pathname(&f); -} - -static void stat_f(int opno, long r) -{ - int e; - pathname_t f; - REDSTAT stb; - int v; - - init_pathname(&f); - if (!get_fname(FT_ANYm, r, &f, NULL, NULL, &v)) { - if (v) - RedPrintf("%d/%d: stat - no entries\n", procid, opno); - free_pathname(&f); - return; - } - e = lstat64_path(&f, &stb) < 0 ? errno : 0; - check_cwd(); - if (v) - RedPrintf("%d/%d: stat %s %d\n", procid, opno, f.path, e); - free_pathname(&f); -} - -static void truncate_f(int opno, long r) -{ - int e; - pathname_t f; - __int64_t lr; - off64_t off; - REDSTAT stb; - int v; - - init_pathname(&f); - if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { - if (v) - RedPrintf("%d/%d: truncate - no filename\n", procid, opno); - free_pathname(&f); - return; - } - e = stat64_path(&f, &stb) < 0 ? errno : 0; - check_cwd(); - if (e > 0) { - if (v) - RedPrintf("%d/%d: truncate - stat64 %s failed %d\n", - procid, opno, f.path, e); - free_pathname(&f); - return; - } - lr = ((__int64_t) random() << 32) + random(); - off = lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE); - off %= maxfsize; - e = truncate64_path(&f, off) < 0 ? errno : 0; - check_cwd(); - if (v) - RedPrintf("%d/%d: truncate %s %lld %d\n", procid, opno, f.path, - (long long)off, e); - free_pathname(&f); -} - -static void unlink_f(int opno, long r) -{ - int e; - pathname_t f; - fent_t *fep; - flist_t *flp; - int v; - - init_pathname(&f); - if (!get_fname(FT_NOTDIR, r, &f, &flp, &fep, &v)) { - if (v) - RedPrintf("%d/%d: unlink - no file\n", procid, opno); - free_pathname(&f); - return; - } - e = unlink_path(&f) < 0 ? errno : 0; - check_cwd(); - if (e == 0) - del_from_flist((int)(flp - flist), (int)(fep - flp->fents)); - if (v) - RedPrintf("%d/%d: unlink %s %d\n", procid, opno, f.path, e); - free_pathname(&f); -} - -static void write_f(int opno, long r) -{ - char *buf; - int e; - pathname_t f; - int fd; - uint32_t len; - __int64_t lr; - off64_t off; - REDSTAT stb; - int v; - - init_pathname(&f); - if (!get_fname(FT_REGm, r, &f, NULL, NULL, &v)) { - if (v) - RedPrintf("%d/%d: write - no filename\n", procid, opno); - free_pathname(&f); - return; - } - fd = open_path(&f, O_WRONLY); - e = fd < 0 ? errno : 0; - check_cwd(); - if (fd < 0) { - if (v) - RedPrintf("%d/%d: write - open %s failed %d\n", - procid, opno, f.path, e); - free_pathname(&f); - return; - } - if (fstat64(fd, &stb) < 0) { - if (v) - RedPrintf("%d/%d: write - fstat64 %s failed %d\n", - procid, opno, f.path, errno); - free_pathname(&f); - close(fd); - return; - } - lr = ((__int64_t) random() << 32) + random(); - off = (off64_t) (lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE)); - off %= maxfsize; - lseek64(fd, off, SEEK_SET); - len = (random() % (getpagesize() * 4)) + 1; - buf = malloc(len); - memset(buf, nameseq & 0xff, len); - e = write(fd, buf, len) < 0 ? errno : 0; - free(buf); - if (v) - RedPrintf("%d/%d: write %s [%lld,%ld] %d\n", - procid, opno, f.path, (long long)off, (long int)len, e); - free_pathname(&f); - close(fd); -} - - -#if REDCONF_CHECKER == 1 -static void check_f(int opno, long r) -{ - int32_t ret; - const char *pszVolume = gpRedVolConf->pszPathPrefix; - - (void)r; - - errno = 0; - - ret = red_transact(pszVolume); - - if(ret == 0) - { - ret = red_umount(pszVolume); - - if(ret == 0) - { - int32_t ret2; - - errno = -RedCoreVolCheck(); - if(errno != 0) + if( verbose ) { - ret = -1; - } - - ret2 = red_mount(pszVolume); - - if(ret == 0) - { - ret = ret2; - } - - if(ret2 != 0) - { - exit(1); + RedPrintf( "%d/%d: check %s %d\n", procid, opno, pszVolume, errno ); } } - } - - if (verbose) - { - RedPrintf("%d/%d: check %s %d\n", procid, opno, pszVolume, errno); - } -} -#endif + #endif /* if REDCONF_CHECKER == 1 */ #endif /* FSSTRESS_SUPPORTED */ - diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/redposixcompat.h b/FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/redposixcompat.h index 6c59e9309..948dd2f82 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/redposixcompat.h +++ b/FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/redposixcompat.h @@ -1,152 +1,152 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Defines macros which make the Reliance Edge POSIX-like API look more - like the actual POSIX API. - - This file is intended for porting POSIX file system tests; it is not - intended for application use. -*/ -#ifndef REDPOSIXCOMPAT_H -#define REDPOSIXCOMPAT_H - - -#ifndef assert -#define assert(x) REDASSERT(x) -#endif - - -#undef O_RDONLY -#undef O_WRONLY -#undef O_RDWR -#undef O_APPEND -#undef O_CREAT -#undef O_EXCL -#undef O_TRUNC -#define O_RDONLY RED_O_RDONLY -#define O_WRONLY RED_O_WRONLY -#define O_RDWR RED_O_RDWR -#define O_APPEND RED_O_APPEND -#define O_CREAT RED_O_CREAT -#define O_EXCL RED_O_EXCL -#define O_TRUNC RED_O_TRUNC - -#undef SEEK_SET -#undef SEEK_CUR -#undef SEEK_END -#define SEEK_SET RED_SEEK_SET -#define SEEK_CUR RED_SEEK_CUR -#define SEEK_END RED_SEEK_END - -/* Old-fashioned Linux seek names. -*/ -#undef L_SET -#undef L_INCR -#undef L_XTND -#define L_SET SEEK_SET -#define L_INCR SEEK_CUR -#define L_XTND SEEK_END - -#undef S_IFDIR -#undef S_IFREG -#undef S_ISDIR -#undef S_ISREG -#define S_IFDIR RED_S_IFDIR -#define S_IFREG RED_S_IFREG -#define S_ISDIR(m) RED_S_ISDIR(m) -#define S_ISREG(m) RED_S_ISREG(m) - -#undef ST_RDONLY -#undef ST_NOSUID -#define ST_RDONLY RED_ST_RDONLY -#define ST_NOSUID RED_ST_NOSUID - -#undef open -#undef creat -#undef unlink -#undef mkdir -#undef rmdir -#undef rename -#undef link -#undef close -#undef read -#undef write -#undef fsync -#undef fdatasync -#undef lseek -#undef ftruncate -#undef fstat -#undef opendir -#undef readdir -#undef rewinddir -#undef closedir -#define open(path, oflag) red_open(path, oflag) -#define creat(path, mode) open(path, O_WRONLY|O_CREAT|O_TRUNC) -#define unlink(path) red_unlink(path) -#define mkdir(path) red_mkdir(path) -#define rmdir(path) red_rmdir(path) -#define rename(old, new) red_rename(old, new) -#define link(path, hardlink) red_link(path, hardlink) -#define close(fd) red_close(fd) -#define read(fd, buf, len) red_read(fd, buf, len) -#define write(fd, buf, len) red_write(fd, buf, len) -#define fsync(fd) red_fsync(fd) -#define fdatasync(fd) fsync(fd) -#define lseek(fd, offset, whence) red_lseek(fd, offset, whence) -#define lseek64(fd, offset, whence) lseek(fd, offset, whence) -#define ftruncate(fd, size) red_ftruncate(fd, size) -#define fstat(fd, stat) red_fstat(fd, stat) -#define fstat64(fd, stat) fstat(fd, stat) -#define opendir(path) red_opendir(path) -#define readdir(dirp) red_readdir(dirp) -#define readdir64(dirp) readdir(dirp) -#define rewinddir(dirp) red_rewinddir(dirp) -#define closedir(dirp) red_closedir(dirp) - -#undef DIR -#define DIR REDDIR - -#undef errno -#define errno (*(int *)red_errnoptr()) - -#undef memcpy -#undef memmove -#undef memset -#undef strlen -#undef strncmp -#undef strcmp -#undef strncpy -#define memcpy(d, s, l) RedMemCpy(d, s, (uint32_t)(l)) -#define memmove(d, s, l) RedMemMove(d, s, (uint32_t)(l)) -#define memset(d, c, l) RedMemSet(d, (uint8_t)(c), (uint32_t)(l)) -#define strlen(s) RedStrLen(s) -#define strncmp(s1, s2, l) RedStrNCmp(s1, s2, (uint32_t)(l)) -#define strcmp(s1, s2) RedStrCmp(s1, s2) -#define strncpy(d, s, l) RedStrNCpy(d, s, (uint32_t)(l)) - - -#endif - - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Defines macros which make the Reliance Edge POSIX-like API look more + * like the actual POSIX API. + * + * This file is intended for porting POSIX file system tests; it is not + * intended for application use. + */ +#ifndef REDPOSIXCOMPAT_H +#define REDPOSIXCOMPAT_H + + +#ifndef assert + #define assert( x ) REDASSERT( x ) +#endif + + +#undef O_RDONLY +#undef O_WRONLY +#undef O_RDWR +#undef O_APPEND +#undef O_CREAT +#undef O_EXCL +#undef O_TRUNC +#define O_RDONLY RED_O_RDONLY +#define O_WRONLY RED_O_WRONLY +#define O_RDWR RED_O_RDWR +#define O_APPEND RED_O_APPEND +#define O_CREAT RED_O_CREAT +#define O_EXCL RED_O_EXCL +#define O_TRUNC RED_O_TRUNC + +#undef SEEK_SET +#undef SEEK_CUR +#undef SEEK_END +#define SEEK_SET RED_SEEK_SET +#define SEEK_CUR RED_SEEK_CUR +#define SEEK_END RED_SEEK_END + +/* Old-fashioned Linux seek names. + */ +#undef L_SET +#undef L_INCR +#undef L_XTND +#define L_SET SEEK_SET +#define L_INCR SEEK_CUR +#define L_XTND SEEK_END + +#undef S_IFDIR +#undef S_IFREG +#undef S_ISDIR +#undef S_ISREG +#define S_IFDIR RED_S_IFDIR +#define S_IFREG RED_S_IFREG +#define S_ISDIR( m ) RED_S_ISDIR( m ) +#define S_ISREG( m ) RED_S_ISREG( m ) + +#undef ST_RDONLY +#undef ST_NOSUID +#define ST_RDONLY RED_ST_RDONLY +#define ST_NOSUID RED_ST_NOSUID + +#undef open +#undef creat +#undef unlink +#undef mkdir +#undef rmdir +#undef rename +#undef link +#undef close +#undef read +#undef write +#undef fsync +#undef fdatasync +#undef lseek +#undef ftruncate +#undef fstat +#undef opendir +#undef readdir +#undef rewinddir +#undef closedir +#define open( path, oflag ) red_open( path, oflag ) +#define creat( path, mode ) open( path, O_WRONLY | O_CREAT | O_TRUNC ) +#define unlink( path ) red_unlink( path ) +#define mkdir( path ) red_mkdir( path ) +#define rmdir( path ) red_rmdir( path ) +#define rename( old, new ) red_rename( old, new ) +#define link( path, hardlink ) red_link( path, hardlink ) +#define close( fd ) red_close( fd ) +#define read( fd, buf, len ) red_read( fd, buf, len ) +#define write( fd, buf, len ) red_write( fd, buf, len ) +#define fsync( fd ) red_fsync( fd ) +#define fdatasync( fd ) fsync( fd ) +#define lseek( fd, offset, whence ) red_lseek( fd, offset, whence ) +#define lseek64( fd, offset, whence ) lseek( fd, offset, whence ) +#define ftruncate( fd, size ) red_ftruncate( fd, size ) +#define fstat( fd, stat ) red_fstat( fd, stat ) +#define fstat64( fd, stat ) fstat( fd, stat ) +#define opendir( path ) red_opendir( path ) +#define readdir( dirp ) red_readdir( dirp ) +#define readdir64( dirp ) readdir( dirp ) +#define rewinddir( dirp ) red_rewinddir( dirp ) +#define closedir( dirp ) red_closedir( dirp ) + +#undef DIR +#define DIR REDDIR + +#undef errno +#define errno ( *( int * ) red_errnoptr() ) + +#undef memcpy +#undef memmove +#undef memset +#undef strlen +#undef strncmp +#undef strcmp +#undef strncpy +#define memcpy( d, s, l ) RedMemCpy( d, s, ( uint32_t ) ( l ) ) +#define memmove( d, s, l ) RedMemMove( d, s, ( uint32_t ) ( l ) ) +#define memset( d, c, l ) RedMemSet( d, ( uint8_t ) ( c ), ( uint32_t ) ( l ) ) +#define strlen( s ) RedStrLen( s ) +#define strncmp( s1, s2, l ) RedStrNCmp( s1, s2, ( uint32_t ) ( l ) ) +#define strcmp( s1, s2 ) RedStrCmp( s1, s2 ) +#define strncpy( d, s, l ) RedStrNCpy( d, s, ( uint32_t ) ( l ) ) + + +#endif /* ifndef REDPOSIXCOMPAT_H */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/atoi.c b/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/atoi.c index ec11e0a96..c5e1f5310 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/atoi.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/atoi.c @@ -1,62 +1,63 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Implements utilities that convert strings to numbers. -*/ + * @brief Implements utilities that convert strings to numbers. + */ #include #include -#define ISHEXDIGITU(c) (((c) >= 'A') && ((c) <= 'F')) -#define ISHEXDIGITL(c) (((c) >= 'a') && ((c) <= 'f')) -#define ISHEXDIGIT(c) (ISHEXDIGITL(c) || ISHEXDIGITU(c)) +#define ISHEXDIGITU( c ) ( ( ( c ) >= 'A' ) && ( ( c ) <= 'F' ) ) +#define ISHEXDIGITL( c ) ( ( ( c ) >= 'a' ) && ( ( c ) <= 'f' ) ) +#define ISHEXDIGIT( c ) ( ISHEXDIGITL( c ) || ISHEXDIGITU( c ) ) /** @brief Converts an ASCII number into an int32_t. - - Converts all decimal digit numbers up to the end of the string or to the - first non-numerical character. - - @note This function does *not* ignore leading white space. - - @param pszNum Pointer to a constant array of characters. - - @return The integer represented in the string. -*/ -int32_t RedAtoI( - const char *pszNum) + * + * Converts all decimal digit numbers up to the end of the string or to the + * first non-numerical character. + * + * @note This function does *not* ignore leading white space. + * + * @param pszNum Pointer to a constant array of characters. + * + * @return The integer represented in the string. + */ +int32_t RedAtoI( const char * pszNum ) { - int32_t lValue = 0; - int32_t lNegative = 1; - uint32_t ulIdx = 0U; + int32_t lValue = 0; + int32_t lNegative = 1; + uint32_t ulIdx = 0U; - if(pszNum[ulIdx] == '+') + if( pszNum[ ulIdx ] == '+' ) { ulIdx++; } - else if(pszNum[ulIdx] == '-') + else if( pszNum[ ulIdx ] == '-' ) { ulIdx++; lNegative = -1; @@ -64,13 +65,13 @@ int32_t RedAtoI( else { /* No sign, implicitly positive. - */ + */ } - while(ISDIGIT(pszNum[ulIdx])) + while( ISDIGIT( pszNum[ ulIdx ] ) ) { lValue *= 10; - lValue += pszNum[ulIdx] - '0'; + lValue += pszNum[ ulIdx ] - '0'; ulIdx++; } @@ -81,40 +82,40 @@ int32_t RedAtoI( /** @brief Convert a hexadecimal ASCII number into a uint32_t value. - - The function processes all hex digits up to a NUL-terminator, or to the - first non-hex character. Only hexadecimal digits are processed, so leading - white space, or a leading "0x" prefix are not allowed. - - If pachNum points to an empty string (points to a NUL), this function will - return NULL, and the value at *pulNum will not be modified. - - @note This function does not check for overflow. If there are more - significant digits than can be represented in a uint32_t variable, the - output is unspecified. - - @param pszNum A pointer to a constant array of hex characters. - @param pulNum A pointer to the location in which to store the uint32_t - result. Upon return, this value will be modified ONLY if - the function succeeds and the returned pointer is valid (not - NULL). - - @return A pointer to the byte following the converted number or NULL to - indicate failure. -*/ -const char *RedHtoUL( - const char *pszNum, - uint32_t *pulNum) + * + * The function processes all hex digits up to a NUL-terminator, or to the + * first non-hex character. Only hexadecimal digits are processed, so leading + * white space, or a leading "0x" prefix are not allowed. + * + * If pszNum points to an empty string (points to a NUL), this function will + * return NULL, and the value at *pulNum will not be modified. + * + * @note This function does not check for overflow. If there are more + * significant digits than can be represented in a uint32_t variable, the + * output is unspecified. + * + * @param pszNum A pointer to a constant array of hex characters. + * @param pulNum A pointer to the location in which to store the uint32_t + * result. Upon return, this value will be modified ONLY if + * the function succeeds and the returned pointer is valid (not + * NULL). + * + * @return A pointer to the byte following the converted number or NULL to + * indicate failure. + */ +const char * RedHtoUL( const char * pszNum, + uint32_t * pulNum ) { - uint64_t ullValue; - const char *pszReturn; + uint64_t ullValue; + const char * pszReturn; - pszReturn = RedHtoULL(pszNum, &ullValue); - if(pszReturn != NULL) + pszReturn = RedHtoULL( pszNum, &ullValue ); + + if( pszReturn != NULL ) { - if(ullValue < UINT32_MAX) + if( ullValue < UINT32_MAX ) { - *pulNum = (uint32_t)ullValue; + *pulNum = ( uint32_t ) ullValue; } else { @@ -127,72 +128,71 @@ const char *RedHtoUL( /** @brief Convert a hexadecimal ASCII number into a D_UINT64 value. - - The function processes all hex digits up to a NUL-terminator, or to the - first non-hex character. Only hexadecimal digits are processed, so leading - white space, or a leading "0x" prefix are not allowed. - - If pachNum points to an empty string (points to a NUL), this function will - return NULL, and the value at *pulNum will not be modified. - - @note This function does not check for overflow. If there are more - significant digits than can be represented in a uint64_t variable, the - output is unspecified. - - @param pszNum A pointer to a constant array of hex characters. - @param pullNum A pointer to the location in which to store the uint64_t - result. Upon return, this value will be modified ONLY if - the function succeeds and the returned pointer is valid (not - NULL). - - @return A pointer to the byte following the converted number, or NULL to - indicate failure. -*/ -const char *RedHtoULL( - const char *pszNum, - uint64_t *pullNum) + * + * The function processes all hex digits up to a NUL-terminator, or to the + * first non-hex character. Only hexadecimal digits are processed, so leading + * white space, or a leading "0x" prefix are not allowed. + * + * If pszNum points to an empty string (points to a NUL), this function will + * return NULL, and the value at *pulNum will not be modified. + * + * @note This function does not check for overflow. If there are more + * significant digits than can be represented in a uint64_t variable, the + * output is unspecified. + * + * @param pszNum A pointer to a constant array of hex characters. + * @param pullNum A pointer to the location in which to store the uint64_t + * result. Upon return, this value will be modified ONLY if + * the function succeeds and the returned pointer is valid (not + * NULL). + * + * @return A pointer to the byte following the converted number, or NULL to + * indicate failure. + */ +const char * RedHtoULL( const char * pszNum, + uint64_t * pullNum ) { - uint64_t ullValue = 0U; - const char *pszReturn = NULL; - uint32_t ulIdx = 0U; + uint64_t ullValue = 0U; + const char * pszReturn = NULL; + uint32_t ulIdx = 0U; - REDASSERT(pszNum != NULL); - REDASSERT(pullNum != NULL); + REDASSERT( pszNum != NULL ); + REDASSERT( pullNum != NULL ); - while(pszNum[ulIdx] != '\0') + while( pszNum[ ulIdx ] != '\0' ) { - char cDigit = pszNum[ulIdx]; + char cDigit = pszNum[ ulIdx ]; - if(ISDIGIT(cDigit)) + if( ISDIGIT( cDigit ) ) { cDigit -= '0'; } - else if(ISHEXDIGITU(cDigit)) + else if( ISHEXDIGITU( cDigit ) ) { - cDigit -= ('A' - 10); + cDigit -= ( 'A' - 10 ); } - else if(ISHEXDIGITL(cDigit)) + else if( ISHEXDIGITL( cDigit ) ) { - cDigit -= ('a' - 10); + cDigit -= ( 'a' - 10 ); } else { break; } - REDASSERT((ullValue & UINT64_SUFFIX(0xF000000000000000)) == 0U); + REDASSERT( ( ullValue & UINT64_SUFFIX( 0xF000000000000000 ) ) == 0U ); ullValue <<= 4U; ullValue += cDigit; ulIdx++; - pszReturn = &pszNum[ulIdx]; + pszReturn = &pszNum[ ulIdx ]; } /* Modify the number returned only if we found one or more valid hex - digits. - */ - if(pszReturn != NULL) + * digits. + */ + if( pszReturn != NULL ) { *pullNum = ullValue; } @@ -202,92 +202,91 @@ const char *RedHtoULL( /** @brief Convert the ASCII number to a uint32_t value. - - The number may be hex or decimal. Hex numbers must be prefixed by '0x', and - they may be upper or lower case. The conversion process will stop with the - first non hex or decimal digit. - - If the number is negative (the first character is a '-' sign), the value - will be range checked and returned as the equivalent unsigned value. - - @note This function will NOT fail for numbers which exceed the size of a - uint32_t value. - - @param pszNum A pointer to the ASCII number to convert - @param pulNum A pointer to the uint32_t location to store the result. - This value will be modified on return only if the function - succeeds and the returned pointer is valid (not NULL). - - @return A pointer to the byte following the converted number, or NULL to - indicate failure. -*/ -const char *RedNtoUL( - const char *pszNum, - uint32_t *pulNum) + * + * The number may be hex or decimal. Hex numbers must be prefixed by '0x', and + * they may be upper or lower case. The conversion process will stop with the + * first non hex or decimal digit. + * + * If the number is negative (the first character is a '-' sign), the value + * will be range checked and returned as the equivalent unsigned value. + * + * @note This function will NOT fail for numbers which exceed the size of a + * uint32_t value. + * + * @param pszNum A pointer to the ASCII number to convert + * @param pulNum A pointer to the uint32_t location to store the result. + * This value will be modified on return only if the function + * succeeds and the returned pointer is valid (not NULL). + * + * @return A pointer to the byte following the converted number, or NULL to + * indicate failure. + */ +const char * RedNtoUL( const char * pszNum, + uint32_t * pulNum ) { - bool fNegative = false; - uint32_t ulIdx = 0U; - const char *pszReturn; + bool fNegative = false; + uint32_t ulIdx = 0U; + const char * pszReturn; - REDASSERT(pszNum != NULL); - REDASSERT(pulNum != NULL); + REDASSERT( pszNum != NULL ); + REDASSERT( pulNum != NULL ); - if(pszNum[ulIdx] == '-') + if( pszNum[ ulIdx ] == '-' ) { fNegative = true; ulIdx++; } /* Hex numbers must be prefixed with '0x'. - */ - if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X'))) + */ + if( ( pszNum[ ulIdx ] == '0' ) && ( ( pszNum[ ulIdx + 1U ] == 'x' ) || ( pszNum[ ulIdx + 1U ] == 'X' ) ) ) { ulIdx += 2U; - if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx])) + if( ISDIGIT( pszNum[ ulIdx ] ) || ISHEXDIGIT( pszNum[ ulIdx ] ) ) { - pszReturn = RedHtoUL(&pszNum[ulIdx], pulNum); + pszReturn = RedHtoUL( &pszNum[ ulIdx ], pulNum ); } else { pszReturn = NULL; } } - else if(ISDIGIT(pszNum[ulIdx])) + else if( ISDIGIT( pszNum[ ulIdx ] ) ) { uint32_t ulTemp; - ulTemp = RedAtoI(&pszNum[ulIdx]); + ulTemp = RedAtoI( &pszNum[ ulIdx ] ); - while(ISDIGIT(pszNum[ulIdx])) + while( ISDIGIT( pszNum[ ulIdx ] ) ) { ulIdx++; } - if(fNegative) + if( fNegative ) { /* Fail if the number is out of range. - */ - if(ulTemp > INT32_MAX) + */ + if( ulTemp > INT32_MAX ) { pszReturn = NULL; } else { - *pulNum = -((int32_t)ulTemp); - pszReturn = &pszNum[ulIdx]; + *pulNum = -( ( int32_t ) ulTemp ); + pszReturn = &pszNum[ ulIdx ]; } } else { *pulNum = ulTemp; - pszReturn = &pszNum[ulIdx]; + pszReturn = &pszNum[ ulIdx ]; } } else { /* Return an error if there is not at least one hex or decimal digit. - */ + */ pszReturn = NULL; } @@ -295,90 +294,89 @@ const char *RedNtoUL( } -/** @brief Convert the ASCII number pointed to by pachNum to a uint64_t value. - - The number may be hex or decimal. Hex numbers must be prefixed by '0x', and - they may be upper or lower case. The conversion process will stop with the - first non hex or decimal digit. - - If the number is negative (the first character is a '-' sign), the value - will be range checked and returned as the equivalent unsigned value. - - @param pszNum A pointer to the ASCII number to convert. - @param pullNum A pointer to the uint64_t location to store the result. - This value will be modified on return only if the function - succeeds and the returned pointer is valid (not NULL). - - @return A pointer to the byte following the converted number, or NULL to - indicate failure. -*/ -const char *RedNtoULL( - const char *pszNum, - uint64_t *pullNum) +/** @brief Convert the ASCII number pointed to by pszNum to a uint64_t value. + * + * The number may be hex or decimal. Hex numbers must be prefixed by '0x', and + * they may be upper or lower case. The conversion process will stop with the + * first non hex or decimal digit. + * + * If the number is negative (the first character is a '-' sign), the value + * will be range checked and returned as the equivalent unsigned value. + * + * @param pszNum A pointer to the ASCII number to convert. + * @param pullNum A pointer to the uint64_t location to store the result. + * This value will be modified on return only if the function + * succeeds and the returned pointer is valid (not NULL). + * + * @return A pointer to the byte following the converted number, or NULL to + * indicate failure. + */ +const char * RedNtoULL( const char * pszNum, + uint64_t * pullNum ) { - bool fNegative = false; - uint32_t ulIdx = 0U; - const char *pszReturn; + bool fNegative = false; + uint32_t ulIdx = 0U; + const char * pszReturn; - REDASSERT(pszNum != NULL); - REDASSERT(pullNum != NULL); + REDASSERT( pszNum != NULL ); + REDASSERT( pullNum != NULL ); - if(pszNum[ulIdx] == '-') + if( pszNum[ ulIdx ] == '-' ) { fNegative = true; ulIdx++; } /* Hex numbers must be prefixed with '0x'. - */ - if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X'))) + */ + if( ( pszNum[ ulIdx ] == '0' ) && ( ( pszNum[ ulIdx + 1U ] == 'x' ) || ( pszNum[ ulIdx + 1U ] == 'X' ) ) ) { ulIdx += 2U; - if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx])) + if( ISDIGIT( pszNum[ ulIdx ] ) || ISHEXDIGIT( pszNum[ ulIdx ] ) ) { - pszReturn = RedHtoULL(&pszNum[ulIdx], pullNum); + pszReturn = RedHtoULL( &pszNum[ ulIdx ], pullNum ); } else { pszReturn = NULL; } } - else if(ISDIGIT(pszNum[ulIdx])) + else if( ISDIGIT( pszNum[ ulIdx ] ) ) { uint64_t ullTemp = 0U; - while(ISDIGIT(pszNum[ulIdx])) + while( ISDIGIT( pszNum[ ulIdx ] ) ) { ullTemp *= 10U; - ullTemp += pszNum[ulIdx] - '0'; + ullTemp += pszNum[ ulIdx ] - '0'; ulIdx++; } - if(fNegative) + if( fNegative ) { /* Fail if the number is out of range. - */ - if(ullTemp > INT64_MAX) + */ + if( ullTemp > INT64_MAX ) { pszReturn = NULL; } else { - *pullNum = (uint64_t)(-((int64_t)ullTemp)); - pszReturn = &pszNum[ulIdx]; + *pullNum = ( uint64_t ) ( -( ( int64_t ) ullTemp ) ); + pszReturn = &pszNum[ ulIdx ]; } } else { *pullNum = ullTemp; - pszReturn = &pszNum[ulIdx]; + pszReturn = &pszNum[ ulIdx ]; } } else { /* Return an error if there is not at least one hex or decimal digit. - */ + */ pszReturn = NULL; } @@ -387,83 +385,83 @@ const char *RedNtoULL( /** @brief Convert an ASCII hex or decimal number, which may may have a "B", - "KB", or "MB" suffix (case insensitive), to a binary value. - - Hex numbers must be prefixed with "0x". - - @note If there is no postfix, KB is assumed! - - May fail due to bad formatting or overflow. - - @param pszNum A pointer to the ASCII number to convert. - @param pulResult A pointer to a uint32_t in which to place the result. - - @return A pointer to the byte following the string, or NULL to indicate an - error. In the event of an error, *pulResult will not be modified. -*/ -const char *RedSizeToUL( - const char *pszNum, - uint32_t *pulResult) + * "KB", or "MB" suffix (case insensitive), to a binary value. + * + * Hex numbers must be prefixed with "0x". + * + * @note If there is no postfix, KB is assumed! + * + * May fail due to bad formatting or overflow. + * + * @param pszNum A pointer to the ASCII number to convert. + * @param pulResult A pointer to a uint32_t in which to place the result. + * + * @return A pointer to the byte following the string, or NULL to indicate an + * error. In the event of an error, *pulResult will not be modified. + */ +const char * RedSizeToUL( const char * pszNum, + uint32_t * pulResult ) { - uint32_t ulResult; - const char *pszSuffix; - const char *pszReturn; - uint32_t ulIdx = 0U; + uint32_t ulResult; + const char * pszSuffix; + const char * pszReturn; + uint32_t ulIdx = 0U; - REDASSERT(pszNum != NULL); - REDASSERT(pulResult != NULL); + REDASSERT( pszNum != NULL ); + REDASSERT( pulResult != NULL ); /* Do the basic hex/decimal conversion - */ - pszSuffix = RedNtoUL(pszNum, &ulResult); - if(pszSuffix != NULL) + */ + pszSuffix = RedNtoUL( pszNum, &ulResult ); + + if( pszSuffix != NULL ) { - if((pszSuffix[ulIdx] == 'B') || (pszSuffix[ulIdx] == 'b')) + if( ( pszSuffix[ ulIdx ] == 'B' ) || ( pszSuffix[ ulIdx ] == 'b' ) ) { ulIdx++; - pszReturn = &pszSuffix[ulIdx]; + pszReturn = &pszSuffix[ ulIdx ]; } - else if( ((pszSuffix[ulIdx] == 'M') || (pszSuffix[ulIdx] == 'm')) - && ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b'))) + else if( ( ( pszSuffix[ ulIdx ] == 'M' ) || ( pszSuffix[ ulIdx ] == 'm' ) ) && + ( ( pszSuffix[ ulIdx + 1U ] == 'B' ) || ( pszSuffix[ ulIdx + 1U ] == 'b' ) ) ) { ulIdx += 2U; - if(ulResult > (UINT32_MAX / (1024U * 1024U))) + if( ulResult > ( UINT32_MAX / ( 1024U * 1024U ) ) ) { pszReturn = NULL; } else { ulResult *= 1024U * 1024U; - pszReturn = &pszSuffix[ulIdx]; + pszReturn = &pszSuffix[ ulIdx ]; } } else { /* The number is either postfixed with "KB" or something - else (we don't care), but we must increment the pointer - if it is something recognize. - */ - if( ((pszSuffix[ulIdx] == 'K') || (pszSuffix[ulIdx] == 'k')) - && ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b'))) + * else (we don't care), but we must increment the pointer + * if it is something recognize. + */ + if( ( ( pszSuffix[ ulIdx ] == 'K' ) || ( pszSuffix[ ulIdx ] == 'k' ) ) && + ( ( pszSuffix[ ulIdx + 1U ] == 'B' ) || ( pszSuffix[ ulIdx + 1U ] == 'b' ) ) ) { ulIdx += 2U; } /* "B" or "MB" were not specified, so it must be "KB" - */ - if(ulResult > (UINT32_MAX / 1024U)) + */ + if( ulResult > ( UINT32_MAX / 1024U ) ) { pszReturn = NULL; } else { ulResult *= 1024UL; - pszReturn = &pszSuffix[ulIdx]; + pszReturn = &pszSuffix[ ulIdx ]; } } - if(pszReturn != NULL) + if( pszReturn != NULL ) { *pulResult = ulResult; } @@ -475,4 +473,3 @@ const char *RedSizeToUL( return pszReturn; } - diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/math.c b/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/math.c index 00f6bc331..0aed07aa3 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/math.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/math.c @@ -1,255 +1,257 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements routines for certain 64-bit math operations and simulated - floating point. + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ - RedUint64DivMod32() and RedUint64DivMod64() are derived from code at - http://www.hackersdelight.org. This web site states explicitly that "You - are free to use, copy, and distribute any of the code on this web site, - whether modified by you or not. You need not give attribution." -*/ +/** @file + * @brief Implements routines for certain 64-bit math operations and simulated + * floating point. + * + * RedUint64DivMod32() and RedUint64DivMod64() are derived from code at + * http://www.hackersdelight.org. This web site states explicitly that "You + * are free to use, copy, and distribute any of the code on this web site, + * whether modified by you or not. You need not give attribution." + */ #include #include -static uint32_t nlz64(uint64_t ullValue); +static uint32_t nlz64( uint64_t ullValue ); /** @brief Return a ratio value formatted as a floating point string accurate to - the specified number of decimal places. - - The function exists to provide floating point style output without using - any actual floating point types. - - This function may scale the numbers down to avoid overflow at the high end. - Likewise, potential divide-by-zero errors are internally avoided. Here are - some examples: - - Dividend | Divisor | DecPlaces | Result - -------- | ------- | --------- | ------ - 12133 | 28545 | 2 | "0.42" - 1539 | 506 | 2 | "3.04" - - To get a number formatted as a percentage, take the take the portion of the - total (normally the smaller part), multiply it by 100, and pass it to this - function as the Dividend, pass the "total" value to this function as the - Divisor, and specify the desired number of decimal places. - - For example, if you have a disk format overhead value of N blocks out of a - total of Y blocks on the disk, and you want to display the format overhead - as a percentage, you would use a function call - similar to: - - ~~~{.c} - RedRatio(szBuffer, sizeof(szBuffer), N*100U, Y, 2U); - ~~~ - - If N=145, Y=4096, and decimal places is 2, the resulting output would be - "3.54". - - The string returned will always be null-terminated, even if it means - stomping on the least significant decimal digit. - - If either the dividend or divisor values are zero, the string "0.0" will be - returned, with the prescribed number of decimal places. - - @note This function has "reasonable" limits which meet the needs of the - various supplemental utilities which use this function. Extremely - large ratios, or using many decimal places may not function as - desired. - - Parameters: - @param pBuffer A pointer to the buffer in which to store the null - terminated results. - @param ulBufferLen The length of the output buffer. - @param ullDividend The "total" value to divide. - @param ullDivisor The portion of ullDividend for which to calculate the - ratio (may be greater than ulDividend). - @param ulDecPlaces The number of decimal places to use, from 0 to 9. - - @return @p pBuffer. -*/ -char *RedRatio( - char *pBuffer, - uint32_t ulBufferLen, - uint64_t ullDividend, - uint64_t ullDivisor, - uint32_t ulDecPlaces) + * the specified number of decimal places. + * + * The function exists to provide floating point style output without using + * any actual floating point types. + * + * This function may scale the numbers down to avoid overflow at the high end. + * Likewise, potential divide-by-zero errors are internally avoided. Here are + * some examples: + * + * Dividend | Divisor | DecPlaces | Result + * -------- | ------- | --------- | ------ + * 12133 | 28545 | 2 | "0.42" + * 1539 | 506 | 2 | "3.04" + * + * To get a number formatted as a percentage, take the take the portion of the + * total (normally the smaller part), multiply it by 100, and pass it to this + * function as the Dividend, pass the "total" value to this function as the + * Divisor, and specify the desired number of decimal places. + * + * For example, if you have a disk format overhead value of N blocks out of a + * total of Y blocks on the disk, and you want to display the format overhead + * as a percentage, you would use a function call + * similar to: + * + * ~~~{.c} + * RedRatio(szBuffer, sizeof(szBuffer), N*100U, Y, 2U); + * ~~~ + * + * If N=145, Y=4096, and decimal places is 2, the resulting output would be + * "3.54". + * + * The string returned will always be null-terminated, even if it means + * stomping on the least significant decimal digit. + * + * If either the dividend or divisor values are zero, the string "0.0" will be + * returned, with the prescribed number of decimal places. + * + * @note This function has "reasonable" limits which meet the needs of the + * various supplemental utilities which use this function. Extremely + * large ratios, or using many decimal places may not function as + * desired. + * + * Parameters: + * @param pBuffer A pointer to the buffer in which to store the null + * terminated results. + * @param ulBufferLen The length of the output buffer. + * @param ullDividend The "total" value to divide. + * @param ullDivisor The portion of ullDividend for which to calculate the + * ratio (may be greater than ulDividend). + * @param ulDecPlaces The number of decimal places to use, from 0 to 9. + * + * @return @p pBuffer. + */ +char * RedRatio( char * pBuffer, + uint32_t ulBufferLen, + uint64_t ullDividend, + uint64_t ullDivisor, + uint32_t ulDecPlaces ) { - REDASSERT(pBuffer != NULL); - REDASSERT(ulBufferLen > 0U); - REDASSERT(ulDecPlaces <= 9U); /* arbitrary */ + REDASSERT( pBuffer != NULL ); + REDASSERT( ulBufferLen > 0U ); + REDASSERT( ulDecPlaces <= 9U ); /* arbitrary */ - if((ullDivisor > 0U) && (ullDividend > 0U)) + if( ( ullDivisor > 0U ) && ( ullDividend > 0U ) ) { - uint32_t ii; - uint32_t ulFactor = 1U; - uint64_t ullDecimal; - uint64_t ullTemp; + uint32_t ii; + uint32_t ulFactor = 1U; + uint64_t ullDecimal; + uint64_t ullTemp; - for(ii = 1U; ii <= ulDecPlaces; ii++) + for( ii = 1U; ii <= ulDecPlaces; ii++ ) { ulFactor *= 10U; } - ullDecimal = RedMulDiv64(ullDividend, ulFactor, ullDivisor); + ullDecimal = RedMulDiv64( ullDividend, ulFactor, ullDivisor ); /* Shouldn't really be calling this function in a situation where we - can overflow at this point... - */ - REDASSERT(ullDecimal != UINT64_MAX); + * can overflow at this point... + */ + REDASSERT( ullDecimal != UINT64_MAX ); - if(ullDivisor <= ullDividend) + if( ullDivisor <= ullDividend ) { uint32_t ulDecimal; - (void)RedUint64DivMod32(ullDecimal, ulFactor, &ulDecimal); + ( void ) RedUint64DivMod32( ullDecimal, ulFactor, &ulDecimal ); ullDecimal = ulDecimal; } - ullTemp = RedUint64DivMod64(ullDividend, ullDivisor, NULL); + ullTemp = RedUint64DivMod64( ullDividend, ullDivisor, NULL ); - if(ulDecPlaces > 0U) + if( ulDecPlaces > 0U ) { - RedSNPrintf(pBuffer, ulBufferLen, "%llu.%0*llu", (unsigned long long)ullTemp, - (unsigned)ulDecPlaces, (unsigned long long)ullDecimal); + RedSNPrintf( pBuffer, ulBufferLen, "%llu.%0*llu", ( unsigned long long ) ullTemp, + ( unsigned ) ulDecPlaces, ( unsigned long long ) ullDecimal ); } else { - RedSNPrintf(pBuffer, ulBufferLen, "%llu", (unsigned long long)ullTemp); + RedSNPrintf( pBuffer, ulBufferLen, "%llu", ( unsigned long long ) ullTemp ); } } else { /* If either the dividend or divisor is zero, then just output a "0.0" - string with the prescribed number of decimal places. - */ - if(ulDecPlaces > 0U) + * string with the prescribed number of decimal places. + */ + if( ulDecPlaces > 0U ) { - RedSNPrintf(pBuffer, ulBufferLen, "0.%0*u", (unsigned)ulDecPlaces, 0U); + RedSNPrintf( pBuffer, ulBufferLen, "0.%0*u", ( unsigned ) ulDecPlaces, 0U ); } else { - RedStrNCpy(pBuffer, "0", ulBufferLen); + RedStrNCpy( pBuffer, "0", ulBufferLen ); } } /* Ensure the returned buffer is always null-terminated - */ - pBuffer[ulBufferLen - 1U] = '\0'; + */ + pBuffer[ ulBufferLen - 1U ] = '\0'; return pBuffer; } /** @brief Multiply 64-bit and 32-bit numbers, and divide by a 64-bit number, - returning a 64-bit result. - - @note This function may return an approximate value if multiplying - @p ullBase and @p ulMultplier results in a number larger than 64-bits - _and_ this cannot be avoided by scaling. - - @param ullBase The base 64-bit number number. - @param ulMultiplier The 32-bit number by which to multiply. - @param ullDivisor The 64-bit number by which to divide. - - @return The 64-bit unsigned integer result. Always returns zero if either - @p ullBase or @p ulMultiplier are zero (regardless what - @p ullDivisor is). Returns UINT64_MAX if an overflow condition - occurred, or if @p ullDivisor is zero. -*/ -uint64_t RedMulDiv64( - uint64_t ullBase, - uint32_t ulMultiplier, - uint64_t ullDivisor) + * returning a 64-bit result. + * + * @note This function may return an approximate value if multiplying + * @p ullBase and @p ulMultplier results in a number larger than 64-bits + * _and_ this cannot be avoided by scaling. + * + * @param ullBase The base 64-bit number number. + * @param ulMultiplier The 32-bit number by which to multiply. + * @param ullDivisor The 64-bit number by which to divide. + * + * @return The 64-bit unsigned integer result. Always returns zero if either + * @p ullBase or @p ulMultiplier are zero (regardless what + * @p ullDivisor is). Returns UINT64_MAX if an overflow condition + * occurred, or if @p ullDivisor is zero. + */ +uint64_t RedMulDiv64( uint64_t ullBase, + uint32_t ulMultiplier, + uint64_t ullDivisor ) { uint64_t ullTemp; /* Result would always be zero if either of these are zero. Specifically - test this case before looking for a zero divisor. - */ - if((ullBase == 0U) || (ulMultiplier == 0U)) + * test this case before looking for a zero divisor. + */ + if( ( ullBase == 0U ) || ( ulMultiplier == 0U ) ) { return 0U; } - if(ullDivisor == 0U) + if( ullDivisor == 0U ) { return UINT64_MAX; } /* Since we don't have the ability (yet) to use 128-bit numbers, we jump - through the following hoops (in order) to try to determine the proper - results without losing precision: + * through the following hoops (in order) to try to determine the proper + * results without losing precision: + * + * 1) Shift the divisor and one of the multiplicands as many times as is + * necessary to reduce the scale -- only if it can be done without + * losing precision. + * 2) Divide one of the multiplicands by the divisor first, but only if it + * divides evenly, preserving precision. + * 3) Same as #2, but try it for the other multiplicand. + * 4) Last ditch, divide the larger multiplicand by the divisor first, then + * do the multiply. This lose precision. + * + * These solutions are identified as CODE-PATHs #1-4 which are used to + * identify the matching tests in dltmain.c. + * + * Note that execution might partially include CODE-PATH #1 up until + * shifting can no longer be done without losing precision. In that case, + * one of the three remaining options will be used. + */ - 1) Shift the divisor and one of the multiplicands as many times as is - necessary to reduce the scale -- only if it can be done without - losing precision. - 2) Divide one of the multiplicands by the divisor first, but only if it - divides evenly, preserving precision. - 3) Same as #2, but try it for the other multiplicand. - 4) Last ditch, divide the larger multiplicand by the divisor first, then - do the multiply. This lose precision. + ullTemp = RedUint64DivMod32( UINT64_MAX, ulMultiplier, NULL ); - These solutions are identified as CODE-PATHs #1-4 which are used to - identify the matching tests in dltmain.c. - - Note that execution might partially include CODE-PATH #1 up until - shifting can no longer be done without losing precision. In that case, - one of the three remaining options will be used. - */ - - ullTemp = RedUint64DivMod32(UINT64_MAX, ulMultiplier, NULL); - while(ullBase > ullTemp) + while( ullBase > ullTemp ) { uint64_t ullMod; uint64_t ullBaseTemp; uint64_t ullWideMultiplier; /* CODE-PATH #1 - */ + */ + /* So long as ulDivisor, and at least one of the other numbers, are - evenly divisible by 2, we can scale the numbers so the result does - not overflow the intermediate 64-bit value. - */ - if((ullDivisor & 1U) == 0U) + * evenly divisible by 2, we can scale the numbers so the result does + * not overflow the intermediate 64-bit value. + */ + if( ( ullDivisor & 1U ) == 0U ) { - if((ullBase & 1U) == 0U) + if( ( ullBase & 1U ) == 0U ) { /* CODE-PATH #1a - */ + */ ullDivisor >>= 1U; ullBase >>= 1U; continue; } - if(((ulMultiplier & 1U) == 0U) && ((ullTemp & UINT64_SUFFIX(0x8000000000000000)) == 0U)) + if( ( ( ulMultiplier & 1U ) == 0U ) && ( ( ullTemp & UINT64_SUFFIX( 0x8000000000000000 ) ) == 0U ) ) { /* CODE-PATH #1b - */ + */ ullDivisor >>= 1U; ulMultiplier >>= 1U; ullTemp <<= 1U; @@ -258,84 +260,89 @@ uint64_t RedMulDiv64( } /* If we get to this point, the above method (#1) cannot be used - because not enough of the numbers are even long enough to scale the - operands down. We'll see if either multiplicand is evenly divisble - by ulDivisor, and if so, do the divide first, then the multiply. - (Note that once we get to this point, we will never exercise the - while{} loop anymore.) - */ + * because not enough of the numbers are even long enough to scale the + * operands down. We'll see if either multiplicand is evenly divisible + * by ulDivisor, and if so, do the divide first, then the multiply. + * (Note that once we get to this point, we will never exercise the + * while{} loop anymore.) + */ /* CODE-PATH #2 - */ - ullBaseTemp = RedUint64DivMod64(ullBase, ullDivisor, &ullMod); - if(ullMod == 0U) + */ + ullBaseTemp = RedUint64DivMod64( ullBase, ullDivisor, &ullMod ); + + if( ullMod == 0U ) { /* Evenly divides, so check that we won't overflow, and finish up. - */ + */ ullBase = ullBaseTemp; - if(ullBase > ullTemp) + + if( ullBase > ullTemp ) { return UINT64_MAX; } else { /* We've validated that this will not overflow. - */ + */ ullBase *= ulMultiplier; return ullBase; } } /* CODE-PATH #3 - */ - ullWideMultiplier = RedUint64DivMod64(ulMultiplier, ullDivisor, &ullMod); - if(ullMod == 0U) + */ + ullWideMultiplier = RedUint64DivMod64( ulMultiplier, ullDivisor, &ullMod ); + + if( ullMod == 0U ) { /* Evenly divides, so check that we won't overflow, and finish up. - */ + */ /* Must recalculate ullTemp relative to ullBase - */ - ullTemp = RedUint64DivMod64(UINT64_MAX, ullBase, NULL); - if(ullWideMultiplier > ullTemp) + */ + ullTemp = RedUint64DivMod64( UINT64_MAX, ullBase, NULL ); + + if( ullWideMultiplier > ullTemp ) { return UINT64_MAX; } else { - uint32_t ulNarrowMultiplier = (uint32_t)ullWideMultiplier; + uint32_t ulNarrowMultiplier = ( uint32_t ) ullWideMultiplier; /* We've validated that this will not overflow. - */ + */ ullBase *= ulNarrowMultiplier; return ullBase; } } /* CODE-PATH #4 - - Neither of the multipliers is evenly divisible by the divisor, so - just punt and divide the larger number first, then do the final - multiply. - - All the other attempts above would preserve precision -- this is the - only case where precision may be lost. - */ + * + * Neither of the multipliers is evenly divisible by the divisor, so + * just punt and divide the larger number first, then do the final + * multiply. + * + * All the other attempts above would preserve precision -- this is the + * only case where precision may be lost. + */ /* If necessary reverse the ullBase and ulMultiplier operands so that - ullBase contains the larger of the two values. - */ - if(ullBase < ulMultiplier) + * ullBase contains the larger of the two values. + */ + if( ullBase < ulMultiplier ) { uint32_t ulTemp = ulMultiplier; - ulMultiplier = (uint32_t)ullBase; + ulMultiplier = ( uint32_t ) ullBase; ullBase = ulTemp; } - ullBase = RedUint64DivMod64(ullBase, ullDivisor, NULL); - ullTemp = RedUint64DivMod32(UINT64_MAX, ulMultiplier, NULL); - if(ullBase > ullTemp) + ullBase = RedUint64DivMod64( ullBase, ullDivisor, NULL ); + ullTemp = RedUint64DivMod32( UINT64_MAX, ulMultiplier, NULL ); + + if( ullBase > ullTemp ) { return UINT64_MAX; } @@ -347,103 +354,105 @@ uint64_t RedMulDiv64( } /* We only get to this point if either there was never any chance of - overflow, or if the pure shifting mechanism succeeded in reducing - the scale so overflow is not a problem. - */ + * overflow, or if the pure shifting mechanism succeeded in reducing + * the scale so overflow is not a problem. + */ ullBase *= ulMultiplier; - ullBase = RedUint64DivMod64(ullBase, ullDivisor, NULL); + ullBase = RedUint64DivMod64( ullBase, ullDivisor, NULL ); return ullBase; } /** @brief Divide a 64-bit value by a 32-bit value, returning the quotient and - the remainder. - - Essentially this function does the following: - - ~~~{.c} - if(pulRemainder != NULL) - { - *pulRemainder = (uint32_t)(ullDividend % ulDivisor); - } - return ullDividend / ulDivisor; - ~~~ - - However, it does so without ever actually dividing/modulating a 64-bit - value, since such operations are not allowed in all environments. - - @param ullDividend The value to divide. - @param ulDivisor The value to divide by. - @param pulRemainder Populated with the remainder; may be NULL. - - @return The quotient (result of the division). -*/ -uint64_t RedUint64DivMod32( - uint64_t ullDividend, - uint32_t ulDivisor, - uint32_t *pulRemainder) + * the remainder. + * + * Essentially this function does the following: + * + * ~~~{.c} + * if(pulRemainder != NULL) + * { + * pulRemainder = (uint32_t)(ullDividend % ulDivisor); + * } + * return ullDividend / ulDivisor; + * ~~~ + * + * However, it does so without ever actually dividing/modulating a 64-bit + * value, since such operations are not allowed in all environments. + * + * @param ullDividend The value to divide. + * @param ulDivisor The value to divide by. + * @param pulRemainder Populated with the remainder; may be NULL. + * + * @return The quotient (result of the division). + */ +uint64_t RedUint64DivMod32( uint64_t ullDividend, + uint32_t ulDivisor, + uint32_t * pulRemainder ) { - uint64_t ullQuotient; - uint32_t ulResultRemainder; + uint64_t ullQuotient; + uint32_t ulResultRemainder; /* Check for divide by zero. - */ - if(ulDivisor == 0U) + */ + if( ulDivisor == 0U ) { REDERROR(); /* Nonsense value if no asserts. - */ - ullQuotient = UINT64_SUFFIX(0xFFFFFFFFFFFFFBAD); + */ + ullQuotient = UINT64_SUFFIX( 0xFFFFFFFFFFFFFBAD ); ulResultRemainder = 0xFFFFFBADU; } - else if(ullDividend <= UINT32_MAX) + else if( ullDividend <= UINT32_MAX ) { - uint32_t ulDividend = (uint32_t)ullDividend; + uint32_t ulDividend = ( uint32_t ) ullDividend; ullQuotient = ulDividend / ulDivisor; ulResultRemainder = ulDividend % ulDivisor; } else { - uint32_t ulResultHi; - uint32_t ulResultLo; - uint32_t ulRemainder; - uint8_t bIndex; - uint32_t ulThisDivision; - uint32_t ulMask; - uint8_t ucNextValue; - uint32_t ulInterimHi, ulInterimLo; - uint32_t ulLowDword = (uint32_t)ullDividend; - uint32_t ulHighDword = (uint32_t)(ullDividend >> 32U); + uint32_t ulResultHi; + uint32_t ulResultLo; + uint32_t ulRemainder; + uint8_t bIndex; + uint32_t ulThisDivision; + uint32_t ulMask; + uint8_t ucNextValue; + uint32_t ulInterimHi, ulInterimLo; + uint32_t ulLowDword = ( uint32_t ) ullDividend; + uint32_t ulHighDword = ( uint32_t ) ( ullDividend >> 32U ); /* Compute the high part and get the remainder - */ + */ ulResultHi = ulHighDword / ulDivisor; ulResultLo = 0U; ulRemainder = ulHighDword % ulDivisor; /* Compute the low part - */ + */ ulMask = 0xFF000000U; - for(bIndex = 0U; bIndex < sizeof(uint32_t); bIndex++) + + for( bIndex = 0U; bIndex < sizeof( uint32_t ); bIndex++ ) { - ucNextValue = (uint8_t)((ulLowDword & ulMask) >> ((sizeof(uint32_t) - 1U - bIndex) * 8U)); + ucNextValue = ( uint8_t ) ( ( ulLowDword & ulMask ) >> ( ( sizeof( uint32_t ) - 1U - bIndex ) * 8U ) ); ulInterimHi = ulRemainder >> 24U; - ulInterimLo = (ulRemainder << 8U) | ucNextValue; + ulInterimLo = ( ulRemainder << 8U ) | ucNextValue; ulThisDivision = 0U; - while(ulInterimHi != 0U) + + while( ulInterimHi != 0U ) { - uint64_t ullInterim = ((uint64_t)ulInterimHi << 32U) + ulInterimLo; + uint64_t ullInterim = ( ( uint64_t ) ulInterimHi << 32U ) + ulInterimLo; ullInterim -= ulDivisor; ulThisDivision++; - ulInterimHi = (uint32_t)(ullInterim >> 32U); - ulInterimLo = (uint32_t)ullInterim; + ulInterimHi = ( uint32_t ) ( ullInterim >> 32U ); + ulInterimLo = ( uint32_t ) ullInterim; } + ulThisDivision += ulInterimLo / ulDivisor; ulRemainder = ulInterimLo % ulDivisor; ulResultLo <<= 8U; @@ -451,11 +460,11 @@ uint64_t RedUint64DivMod32( ulMask >>= 8U; } - ullQuotient = ((uint64_t)ulResultHi << 32U) + ulResultLo; - ulResultRemainder = (uint32_t)(ullDividend - (ullQuotient * ulDivisor)); + ullQuotient = ( ( uint64_t ) ulResultHi << 32U ) + ulResultLo; + ulResultRemainder = ( uint32_t ) ( ullDividend - ( ullQuotient * ulDivisor ) ); } - if(pulRemainder != NULL) + if( pulRemainder != NULL ) { *pulRemainder = ulResultRemainder; } @@ -465,79 +474,78 @@ uint64_t RedUint64DivMod32( /** @brief Divide a 64-bit value by a 64-bit value, returning the quotient and - the remainder. - - Essentially this function does the following: - - ~~~{.c} - if(pullRemainder != NULL) - { - *pullRemainder = ullDividend % ullDivisor; - } - return ullDividend / ullDivisor; - ~~~ - - However, it does so without ever actually dividing/modulating a 64-bit - value, since such operations are not allowed in all environments. - - @param ullDividend The value to divide. - @param ullDivisor The value to divide by. - @param pullRemainder Populated with the remainder; may be NULL. - - @return The quotient (result of the division). -*/ -uint64_t RedUint64DivMod64( - uint64_t ullDividend, - uint64_t ullDivisor, - uint64_t *pullRemainder) + * the remainder. + * + * Essentially this function does the following: + * + * ~~~{.c} + * if(pullRemainder != NULL) + * { + * pullRemainder = ullDividend % ullDivisor; + * } + * return ullDividend / ullDivisor; + * ~~~ + * + * However, it does so without ever actually dividing/modulating a 64-bit + * value, since such operations are not allowed in all environments. + * + * @param ullDividend The value to divide. + * @param ullDivisor The value to divide by. + * @param pullRemainder Populated with the remainder; may be NULL. + * + * @return The quotient (result of the division). + */ +uint64_t RedUint64DivMod64( uint64_t ullDividend, + uint64_t ullDivisor, + uint64_t * pullRemainder ) { /* The variables u0, u1, etc. take on only 32-bit values, but they are - declared uint64_t to avoid some compiler warning messages and to avoid - some unnecessary EXTRs that the compiler would put in, to convert - uint64_ts to ints. - */ - uint64_t u0; - uint64_t u1; - uint64_t q0; - uint64_t q1; - uint64_t ullQuotient; + * declared uint64_t to avoid some compiler warning messages and to avoid + * some unnecessary EXTRs that the compiler would put in, to convert + * uint64_ts to ints. + */ + uint64_t u0; + uint64_t u1; + uint64_t q0; + uint64_t q1; + uint64_t ullQuotient; /* First the procedure takes care of the case in which the divisor is a - 32-bit quantity. There are two subcases: (1) If the left half of the - dividend is less than the divisor, one execution of RedUint64DivMod32() - is all that is required (overflow is not possible). (2) Otherwise it - does two divisions, using the grade school method. - */ + * 32-bit quantity. There are two subcases: (1) If the left half of the + * dividend is less than the divisor, one execution of RedUint64DivMod32() + * is all that is required (overflow is not possible). (2) Otherwise it + * does two divisions, using the grade school method. + */ - if((ullDivisor >> 32U) == 0U) + if( ( ullDivisor >> 32U ) == 0U ) { - if((ullDividend >> 32U) < ullDivisor) + if( ( ullDividend >> 32U ) < ullDivisor ) { /* If ullDividend/ullDivisor cannot overflow, just do one division. - */ - ullQuotient = RedUint64DivMod32(ullDividend, (uint32_t)ullDivisor, NULL); + */ + ullQuotient = RedUint64DivMod32( ullDividend, ( uint32_t ) ullDivisor, NULL ); } else { uint32_t k; /* If ullDividend/ullDivisor would overflow: - */ + */ /* Break ullDividend up into two halves. - */ + */ u1 = ullDividend >> 32U; u0 = ullDividend & 0xFFFFFFFFU; /* First quotient digit and first remainder. - */ - q1 = RedUint64DivMod32(u1, (uint32_t)ullDivisor, &k); + */ + q1 = RedUint64DivMod32( u1, ( uint32_t ) ullDivisor, &k ); /* 2nd quot. digit. - */ - q0 = RedUint64DivMod32(((uint64_t)k << 32U) + u0, (uint32_t)ullDivisor, NULL); + */ + q0 = RedUint64DivMod32( ( ( uint64_t ) k << 32U ) + u0, ( uint32_t ) ullDivisor, NULL ); - ullQuotient = (q1 << 32U) + q0; + ullQuotient = ( q1 << 32U ) + q0; } } else @@ -545,34 +553,34 @@ uint64_t RedUint64DivMod64( uint64_t n; uint64_t v1; - n = nlz64(ullDivisor); /* 0 <= n <= 31. */ - v1 = (ullDivisor << n) >> 32U; /* Normalize the divisor so its MSB is 1. */ - u1 = ullDividend >> 1U; /* To ensure no overflow. */ + n = nlz64( ullDivisor ); /* 0 <= n <= 31. */ + v1 = ( ullDivisor << n ) >> 32U; /* Normalize the divisor so its MSB is 1. */ + u1 = ullDividend >> 1U; /* To ensure no overflow. */ /* Get quotient from divide unsigned insn. - */ - q1 = RedUint64DivMod32(u1, (uint32_t)v1, NULL); + */ + q1 = RedUint64DivMod32( u1, ( uint32_t ) v1, NULL ); - q0 = (q1 << n) >> 31U; /* Undo normalization and division of ullDividend by 2. */ + q0 = ( q1 << n ) >> 31U; /* Undo normalization and division of ullDividend by 2. */ /* Make q0 correct or too small by 1. - */ - if(q0 != 0U) + */ + if( q0 != 0U ) { q0--; } - if((ullDividend - (q0 * ullDivisor)) >= ullDivisor) + if( ( ullDividend - ( q0 * ullDivisor ) ) >= ullDivisor ) { - q0++; /* Now q0 is correct. */ + q0++; /* Now q0 is correct. */ } ullQuotient = q0; } - if(pullRemainder != NULL) + if( pullRemainder != NULL ) { - *pullRemainder = ullDividend - (ullQuotient * ullDivisor); + *pullRemainder = ullDividend - ( ullQuotient * ullDivisor ); } return ullQuotient; @@ -580,17 +588,16 @@ uint64_t RedUint64DivMod64( /** @brief Compute the number of leading zeroes in a 64-bit value. - - @param ullValue The value for which to compute the NLZ. - - @return The number of leading zeroes in @p ullValue. -*/ -static uint32_t nlz64( - uint64_t ullValue) + * + * @param ullValue The value for which to compute the NLZ. + * + * @return The number of leading zeroes in @p ullValue. + */ +static uint32_t nlz64( uint64_t ullValue ) { - uint32_t n; + uint32_t n; - if(ullValue == 0U) + if( ullValue == 0U ) { n = 64U; } @@ -600,37 +607,37 @@ static uint32_t nlz64( n = 0U; - if(x <= UINT64_SUFFIX(0x00000000FFFFFFFF)) + if( x <= UINT64_SUFFIX( 0x00000000FFFFFFFF ) ) { n += 32U; x <<= 32U; } - if(x <= UINT64_SUFFIX(0x0000FFFFFFFFFFFF)) + if( x <= UINT64_SUFFIX( 0x0000FFFFFFFFFFFF ) ) { n += 16U; x <<= 16U; } - if(x <= UINT64_SUFFIX(0x00FFFFFFFFFFFFFF)) + if( x <= UINT64_SUFFIX( 0x00FFFFFFFFFFFFFF ) ) { n += 8U; x <<= 8U; } - if(x <= UINT64_SUFFIX(0x0FFFFFFFFFFFFFFF)) + if( x <= UINT64_SUFFIX( 0x0FFFFFFFFFFFFFFF ) ) { n += 4U; x <<= 4U; } - if(x <= UINT64_SUFFIX(0x3FFFFFFFFFFFFFFF)) + if( x <= UINT64_SUFFIX( 0x3FFFFFFFFFFFFFFF ) ) { n += 2U; x <<= 2U; } - if(x <= UINT64_SUFFIX(0x7FFFFFFFFFFFFFFF)) + if( x <= UINT64_SUFFIX( 0x7FFFFFFFFFFFFFFF ) ) { n += 1; } @@ -638,4 +645,3 @@ static uint32_t nlz64( return n; } - diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/printf.c b/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/printf.c index 6df0cf4e6..c687a825c 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/printf.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/printf.c @@ -1,42 +1,44 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Implements functions for printing. - - These functions are intended to be used in portable test code, which cannot - assume the standard I/O functions will be available. Similar to their ANSI - C counterparts, these functions allow formatting text strings and (if the - configuration allows it) outputing formatted text. The latter ability - relies on the RedOsOutputString() OS service function. - - Do *not* use these functions in code which can safely assume the standard - I/O functions are available (e.g., in host tools code). - - Do *not* use these functions from within the file system driver. These - functions use variable arguments and thus are not MISRA-C:2012 compliant. -*/ + * @brief Implements functions for printing. + * + * These functions are intended to be used in portable test code, which cannot + * assume the standard I/O functions will be available. Similar to their ANSI + * C counterparts, these functions allow formatting text strings and (if the + * configuration allows it) outputing formatted text. The latter ability + * relies on the RedOsOutputString() OS service function. + * + * Do *not* use these functions in code which can safely assume the standard + * I/O functions are available (e.g., in host tools code). + * + * Do *not* use these functions from within the file system driver. These + * functions use variable arguments and thus are not MISRA-C:2012 compliant. + */ #include #include #include @@ -44,12 +46,12 @@ /** @brief Maximum number of bytes of output supported by RedPrintf(). - - Typically only Datalight code uses these functions, and that could should be - written to respect this limit, so it should not normally be necessary to - adjust this value. -*/ -#define OUTPUT_BUFFER_SIZE 256U + * + * Typically only Datalight code uses these functions, and that could should be + * written to respect this limit, so it should not normally be necessary to + * adjust this value. + */ +#define OUTPUT_BUFFER_SIZE 256U typedef enum @@ -75,320 +77,347 @@ typedef enum typedef struct { - PRINTTYPE type; /* The PRFMT_* type found */ - uint32_t ulSpecifierIdx; /* Returns a pointer to the % sign */ - uint32_t ulFillLen; - char cFillChar; - bool fLeftJustified; - bool fHasIllegalType; /* TRUE if an illegal sequence was skipped over */ - bool fHasVarWidth; + PRINTTYPE type; /* The PRFMT_* type found */ + uint32_t ulSpecifierIdx; /* Returns a pointer to the % sign */ + uint32_t ulFillLen; + char cFillChar; + bool fLeftJustified; + bool fHasIllegalType; /* TRUE if an illegal sequence was skipped over */ + bool fHasVarWidth; } PRINTFORMAT; /* Our output handlers are written for standard fixed width data types. Map - the standard ANSI C data types onto our handlers. Currently this code has - the following requirements: - - 1) shorts must be either 16 or 32 bits - 2) ints must be either 16 or 32 bits - 3) longs must be between 32 or 64 bits - 4) long longs must be 64 bits -*/ -#if (USHRT_MAX == 0xFFFFU) - #define MAPSHORT PRFMT_SIGNED16BIT - #define MAPUSHORT PRFMT_UNSIGNED16BIT - #define MAPHEXUSHORT PRFMT_HEX16BIT -#elif (USHRT_MAX == 0xFFFFFFFFU) - #define MAPSHORT PRFMT_SIGNED32BIT - #define MAPUSHORT PRFMT_UNSIGNED32BIT - #define MAPHEXUSHORT PRFMT_HEX32BIT + * the standard ANSI C data types onto our handlers. Currently this code has + * the following requirements: + * + * 1) shorts must be either 16 or 32 bits + * 2) ints must be either 16 or 32 bits + * 3) longs must be between 32 or 64 bits + * 4) long longs must be 64 bits + */ +#if ( USHRT_MAX == 0xFFFFU ) + #define MAPSHORT PRFMT_SIGNED16BIT + #define MAPUSHORT PRFMT_UNSIGNED16BIT + #define MAPHEXUSHORT PRFMT_HEX16BIT +#elif ( USHRT_MAX == 0xFFFFFFFFU ) + #define MAPSHORT PRFMT_SIGNED32BIT + #define MAPUSHORT PRFMT_UNSIGNED32BIT + #define MAPHEXUSHORT PRFMT_HEX32BIT #else - #error "The 'short' data type does not have a 16 or 32-bit width" + #error "The 'short' data type does not have a 16 or 32-bit width" #endif -#if (UINT_MAX == 0xFFFFU) - #define MAPINT PRFMT_SIGNED16BIT - #define MAPUINT PRFMT_UNSIGNED16BIT - #define MAPHEXUINT PRFMT_HEX16BIT -#elif (UINT_MAX == 0xFFFFFFFFU) - #define MAPINT PRFMT_SIGNED32BIT - #define MAPUINT PRFMT_UNSIGNED32BIT - #define MAPHEXUINT PRFMT_HEX32BIT +#if ( UINT_MAX == 0xFFFFU ) + #define MAPINT PRFMT_SIGNED16BIT + #define MAPUINT PRFMT_UNSIGNED16BIT + #define MAPHEXUINT PRFMT_HEX16BIT +#elif ( UINT_MAX == 0xFFFFFFFFU ) + #define MAPINT PRFMT_SIGNED32BIT + #define MAPUINT PRFMT_UNSIGNED32BIT + #define MAPHEXUINT PRFMT_HEX32BIT #else - #error "The 'int' data type does not have a 16 or 32-bit width" + #error "The 'int' data type does not have a 16 or 32-bit width" #endif -#if (ULONG_MAX == 0xFFFFFFFFU) - #define MAPLONG PRFMT_SIGNED32BIT - #define MAPULONG PRFMT_UNSIGNED32BIT - #define MAPHEXULONG PRFMT_HEX32BIT -#elif (ULONG_MAX <= UINT64_SUFFIX(0xFFFFFFFFFFFFFFFF)) - /* We've run into unusual environments where "longs" are 40-bits wide. - In this event, map them to 64-bit types so no data is lost. - */ - #define MAPLONG PRFMT_SIGNED64BIT - #define MAPULONG PRFMT_UNSIGNED64BIT - #define MAPHEXULONG PRFMT_HEX64BIT -#else - #error "The 'long' data type is not between 32 and 64 bits wide" -#endif +#if ( ULONG_MAX == 0xFFFFFFFFU ) + #define MAPLONG PRFMT_SIGNED32BIT + #define MAPULONG PRFMT_UNSIGNED32BIT + #define MAPHEXULONG PRFMT_HEX32BIT +#elif ( ULONG_MAX <= UINT64_SUFFIX( 0xFFFFFFFFFFFFFFFF ) ) -#if defined(ULLONG_MAX) && (ULLONG_MAX != UINT64_SUFFIX(0xFFFFFFFFFFFFFFFF)) - #error "The 'long long' data type is not 64 bits wide" +/* We've run into unusual environments where "longs" are 40-bits wide. + * In this event, map them to 64-bit types so no data is lost. + */ + #define MAPLONG PRFMT_SIGNED64BIT + #define MAPULONG PRFMT_UNSIGNED64BIT + #define MAPHEXULONG PRFMT_HEX64BIT #else - #define MAPLONGLONG PRFMT_SIGNED64BIT - #define MAPULONGLONG PRFMT_UNSIGNED64BIT - #define MAPHEXULONGLONG PRFMT_HEX64BIT + #error "The 'long' data type is not between 32 and 64 bits wide" +#endif /* if ( ULONG_MAX == 0xFFFFFFFFU ) */ + +#if defined( ULLONG_MAX ) && ( ULLONG_MAX != UINT64_SUFFIX( 0xFFFFFFFFFFFFFFFF ) ) + #error "The 'long long' data type is not 64 bits wide" +#else + #define MAPLONGLONG PRFMT_SIGNED64BIT + #define MAPULONGLONG PRFMT_UNSIGNED64BIT + #define MAPHEXULONGLONG PRFMT_HEX64BIT #endif -static uint32_t ProcessFormatSegment(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, PRINTFORMAT *pFormat, uint32_t *pulSpecifierLen); -static uint32_t ParseFormatSpecifier(char const *pszFormat, PRINTFORMAT *pFormatType); -static PRINTTYPE ParseFormatType(const char *pszFormat, uint32_t *pulTypeLen); -static uint32_t LtoA(char *pcBuffer, uint32_t ulBufferLen, int32_t lNum, uint32_t ulFillLen, char cFill); -static uint32_t LLtoA(char *pcBuffer, uint32_t ulBufferLen, int64_t llNum, uint32_t ulFillLen, char cFill); -static uint32_t ULtoA(char *pcBuffer, uint32_t ulBufferLen, uint32_t ulNum, bool fHex, uint32_t ulFillLen, char cFill); -static uint32_t ULLtoA(char *pcBuffer, uint32_t ulBufferLen, uint64_t ullNum, bool fHex, uint32_t ulFillLen, char cFill); -static uint32_t FinishToA(const char *pcDigits, uint32_t ulDigits, char *pcOutBuffer, uint32_t ulBufferLen, uint32_t ulFillLen, char cFill); +static uint32_t ProcessFormatSegment( char * pcBuffer, + uint32_t ulBufferLen, + const char * pszFormat, + PRINTFORMAT * pFormat, + uint32_t * pulSpecifierLen ); +static uint32_t ParseFormatSpecifier( char const * pszFormat, + PRINTFORMAT * pFormatType ); +static PRINTTYPE ParseFormatType( const char * pszFormat, + uint32_t * pulTypeLen ); +static uint32_t LtoA( char * pcBuffer, + uint32_t ulBufferLen, + int32_t lNum, + uint32_t ulFillLen, + char cFill ); +static uint32_t LLtoA( char * pcBuffer, + uint32_t ulBufferLen, + int64_t llNum, + uint32_t ulFillLen, + char cFill ); +static uint32_t ULtoA( char * pcBuffer, + uint32_t ulBufferLen, + uint32_t ulNum, + bool fHex, + uint32_t ulFillLen, + char cFill ); +static uint32_t ULLtoA( char * pcBuffer, + uint32_t ulBufferLen, + uint64_t ullNum, + bool fHex, + uint32_t ulFillLen, + char cFill ); +static uint32_t FinishToA( const char * pcDigits, + uint32_t ulDigits, + char * pcOutBuffer, + uint32_t ulBufferLen, + uint32_t ulFillLen, + char cFill ); /* Digits for the *LtoA() routines. -*/ + */ static const char gacDigits[] = "0123456789ABCDEF"; #if REDCONF_OUTPUT == 1 + /** @brief Print formatted data with a variable length argument list. + * + * This function provides a subset of the ANSI C printf() functionality with + * several extensions to support fixed size data types. + * + * See RedVSNPrintf() for the list of supported types. + * + * @param pszFormat A pointer to the null-terminated format string. + * @param ... The variable length argument list. + */ + void RedPrintf( const char * pszFormat, + ... ) + { + va_list arglist; - This function provides a subset of the ANSI C printf() functionality with - several extensions to support fixed size data types. + va_start( arglist, pszFormat ); - See RedVSNPrintf() for the list of supported types. + RedVPrintf( pszFormat, arglist ); - @param pszFormat A pointer to the null-terminated format string. - @param ... The variable length argument list. -*/ -void RedPrintf( - const char *pszFormat, - ...) -{ - va_list arglist; - - va_start(arglist, pszFormat); - - RedVPrintf(pszFormat, arglist); - - va_end(arglist); -} + va_end( arglist ); + } /** @brief Print formatted data using a pointer to a variable length argument - list. - - This function provides a subset of the ANSI C vprintf() functionality. - - See RedVSNPrintf() for the list of supported types. - - This function accommodates a maximum output length of #OUTPUT_BUFFER_SIZE. - If this function must truncate the output, and the original string was - \n terminated, the truncated output will be \n terminated as well. - - @param pszFormat A pointer to the null-terminated format string. - @param arglist The variable length argument list. -*/ -void RedVPrintf( - const char *pszFormat, - va_list arglist) -{ - char achBuffer[OUTPUT_BUFFER_SIZE]; - - if(RedVSNPrintf(achBuffer, sizeof(achBuffer), pszFormat, arglist) == -1) + * list. + * + * This function provides a subset of the ANSI C vprintf() functionality. + * + * See RedVSNPrintf() for the list of supported types. + * + * This function accommodates a maximum output length of #OUTPUT_BUFFER_SIZE. + * If this function must truncate the output, and the original string was + * \n terminated, the truncated output will be \n terminated as well. + * + * @param pszFormat A pointer to the null-terminated format string. + * @param arglist The variable length argument list. + */ + void RedVPrintf( const char * pszFormat, + va_list arglist ) { - /* Ensture the buffer is null terminated. - */ - achBuffer[sizeof(achBuffer) - 1U] = '\0'; + char achBuffer[ OUTPUT_BUFFER_SIZE ]; - /* If the original string was \n terminated and the new one is not, due to - truncation, stuff a \n into the new one. - */ - if(pszFormat[RedStrLen(pszFormat) - 1U] == '\n') + if( RedVSNPrintf( achBuffer, sizeof( achBuffer ), pszFormat, arglist ) == -1 ) { - achBuffer[sizeof(achBuffer) - 2U] = '\n'; - } - } + /* Ensure the buffer is null terminated. + */ + achBuffer[ sizeof( achBuffer ) - 1U ] = '\0'; - RedOsOutputString(achBuffer); -} + /* If the original string was \n terminated and the new one is not, due to + * truncation, stuff a \n into the new one. + */ + if( pszFormat[ RedStrLen( pszFormat ) - 1U ] == '\n' ) + { + achBuffer[ sizeof( achBuffer ) - 2U ] = '\n'; + } + } + + RedOsOutputString( achBuffer ); + } #endif /* #if REDCONF_OUTPUT == 1 */ /** @brief Format arguments into a string using a subset of the ANSI C - vsprintf() functionality. - - This function is modeled after the Microsoft _snprint() extension to the - ANSI C sprintf() function, and allows a buffer length to be specified so - that overflow is avoided. - - See RedVSNPrintf() for the list of supported types. - - @param pcBuffer A pointer to the output buffer - @param ulBufferLen The output buffer length - @param pszFormat A pointer to the null terminated format string - @param ... Variable argument list - - @return The length output, or -1 if the buffer filled up. If -1 is - returned, the output buffer may not be null-terminated. -*/ -int32_t RedSNPrintf( - char *pcBuffer, - uint32_t ulBufferLen, - const char *pszFormat, - ...) + * vsprintf() functionality. + * + * This function is modeled after the Microsoft _snprint() extension to the + * ANSI C sprintf() function, and allows a buffer length to be specified so + * that overflow is avoided. + * + * See RedVSNPrintf() for the list of supported types. + * + * @param pcBuffer A pointer to the output buffer + * @param ulBufferLen The output buffer length + * @param pszFormat A pointer to the null terminated format string + * @param ... Variable argument list + * + * @return The length output, or -1 if the buffer filled up. If -1 is + * returned, the output buffer may not be null-terminated. + */ +int32_t RedSNPrintf( char * pcBuffer, + uint32_t ulBufferLen, + const char * pszFormat, + ... ) { - int32_t iLen; - va_list arglist; + int32_t iLen; + va_list arglist; - va_start(arglist, pszFormat); + va_start( arglist, pszFormat ); - iLen = RedVSNPrintf(pcBuffer, ulBufferLen, pszFormat, arglist); + iLen = RedVSNPrintf( pcBuffer, ulBufferLen, pszFormat, arglist ); - va_end(arglist); + va_end( arglist ); return iLen; } /** @brief Format arguments into a string using a subset of the ANSI C - vsprintf() functionality. - - This function is modeled after the Microsoft _vsnprint() extension to the - ANSI C vsprintf() function, and requires a buffer length to be specified so - that overflow is avoided. - - The following ANSI C standard formatting codes are supported: - - | Code | Meaning | - | ---- | ---------------------------------- | - | %c | Format a character | - | %s | Format a null-terminated C string | - | %hd | Format a signed short | - | %hu | Format an unsigned short | - | %d | Format a signed integer | - | %u | Format an unsigned integer | - | %ld | Format a signed long | - | %lu | Format an unsigned long | - | %lld | Format a signed long long | - | %llu | Format an unsigned long long | - | %hx | Format a short in hex | - | %x | Format an integer in hex | - | %lx | Format a long in hex | - | %llx | Format a long long in hex | - | %p | Format a pointer (hex value) | - - @note All formatting codes are case-sensitive. - - Fill characters and field widths are supported per the ANSI standard, as is - left justification with the '-' character. - - The only supported fill characters are '0', ' ', and '_'. - - '*' is supported to specify variable length field widths. - - Hexidecimal numbers are always displayed in upper case. Formatting codes - which specifically request upper case (e.g., "%lX") are not supported. - - Unsupported behaviors: - - Precision is not supported. - - Floating point is not supported. - - Errata: - - There is a subtle difference in the return value for this function versus - the Microsoft implementation. In the Microsoft version, if the buffer - exactly fills up, but there is no room for a null-terminator, the return - value will be the length of the buffer. In this code, -1 will be returned - when this happens. - - When using left justified strings, the only supported fill character is a - space, regardless of what may be specified. It is not clear if this is - ANSI standard or just the way the Microsoft function works, but we emulate - the Microsoft behavior. - - @param pcBuffer A pointer to the output buffer. - @param ulBufferLen The output buffer length. - @param pszFormat A pointer to the null terminated ANSI format string. - @param arglist Variable argument list. - - @return The length output, or -1 if the buffer filled up. If -1 is - returned, the output buffer may not be null-terminated. -*/ -int32_t RedVSNPrintf( - char *pcBuffer, - uint32_t ulBufferLen, - const char *pszFormat, - va_list arglist) + * vsprintf() functionality. + * + * This function is modeled after the Microsoft _vsnprint() extension to the + * ANSI C vsprintf() function, and requires a buffer length to be specified so + * that overflow is avoided. + * + * The following ANSI C standard formatting codes are supported: + * + | Code | Meaning | + | ---- | ---------------------------------- | + | %c | Format a character | + | %s | Format a null-terminated C string | + | %hd | Format a signed short | + | %hu | Format an unsigned short | + | %d | Format a signed integer | + | %u | Format an unsigned integer | + | %ld | Format a signed long | + | %lu | Format an unsigned long | + | %lld | Format a signed long long | + | %llu | Format an unsigned long long | + | %hx | Format a short in hex | + | %x | Format an integer in hex | + | %lx | Format a long in hex | + | %llx | Format a long long in hex | + | %p | Format a pointer (hex value) | + | + | @note All formatting codes are case-sensitive. + | + | Fill characters and field widths are supported per the ANSI standard, as is + | left justification with the '-' character. + | + | The only supported fill characters are '0', ' ', and '_'. + | + | '*' is supported to specify variable length field widths. + | + | Hexidecimal numbers are always displayed in upper case. Formatting codes + | which specifically request upper case (e.g., "%lX") are not supported. + | + | Unsupported behaviors: + | - Precision is not supported. + | - Floating point is not supported. + | + | Errata: + | - There is a subtle difference in the return value for this function versus + | the Microsoft implementation. In the Microsoft version, if the buffer + | exactly fills up, but there is no room for a null-terminator, the return + | value will be the length of the buffer. In this code, -1 will be returned + | when this happens. + | - When using left justified strings, the only supported fill character is a + | space, regardless of what may be specified. It is not clear if this is + | ANSI standard or just the way the Microsoft function works, but we emulate + | the Microsoft behavior. + | + | @param pcBuffer A pointer to the output buffer. + | @param ulBufferLen The output buffer length. + | @param pszFormat A pointer to the null terminated ANSI format string. + | @param arglist Variable argument list. + | + | @return The length output, or -1 if the buffer filled up. If -1 is + | returned, the output buffer may not be null-terminated. + */ +int32_t RedVSNPrintf( char * pcBuffer, + uint32_t ulBufferLen, + const char * pszFormat, + va_list arglist ) { - uint32_t ulBufIdx = 0U; - uint32_t ulFmtIdx = 0U; - int32_t iLen; + uint32_t ulBufIdx = 0U; + uint32_t ulFmtIdx = 0U; + int32_t iLen; - while((pszFormat[ulFmtIdx] != '\0') && (ulBufIdx < ulBufferLen)) + while( ( pszFormat[ ulFmtIdx ] != '\0' ) && ( ulBufIdx < ulBufferLen ) ) { PRINTFORMAT fmt; - uint32_t ulSpecifierLen; - uint32_t ulWidth; + uint32_t ulSpecifierLen; + uint32_t ulWidth; /* Process the next segment of the format string, outputting - any non-format specifiers, as output buffer space allows, - and return information about the next format specifier. - */ - ulWidth = ProcessFormatSegment(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, &pszFormat[ulFmtIdx], &fmt, &ulSpecifierLen); - if(ulWidth) + * any non-format specifiers, as output buffer space allows, + * and return information about the next format specifier. + */ + ulWidth = ProcessFormatSegment( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, &pszFormat[ ulFmtIdx ], &fmt, &ulSpecifierLen ); + + if( ulWidth ) { - REDASSERT(ulWidth <= (ulBufferLen - ulBufIdx)); + REDASSERT( ulWidth <= ( ulBufferLen - ulBufIdx ) ); ulBufIdx += ulWidth; } /* If no specifier was found, or if the output buffer is - full, we're done -- get out. - */ - if((ulSpecifierLen == 0U) || (ulBufIdx == ulBufferLen)) + * full, we're done -- get out. + */ + if( ( ulSpecifierLen == 0U ) || ( ulBufIdx == ulBufferLen ) ) { break; } /* Otherwise, the math should add up for these things... - */ - REDASSERT(&pszFormat[fmt.ulSpecifierIdx] == &pszFormat[ulWidth]); + */ + REDASSERT( &pszFormat[ fmt.ulSpecifierIdx ] == &pszFormat[ ulWidth ] ); /* Point past the specifier, to the next piece of the format string. - */ + */ ulFmtIdx = ulFmtIdx + fmt.ulSpecifierIdx + ulSpecifierLen; - if(fmt.fHasVarWidth) + if( fmt.fHasVarWidth ) { - int iFillLen = va_arg(arglist, int); + int iFillLen = va_arg( arglist, int ); - if(iFillLen >= 0) + if( iFillLen >= 0 ) { - fmt.ulFillLen = (uint32_t)iFillLen; + fmt.ulFillLen = ( uint32_t ) iFillLen; } else { /* Bogus fill length. Ignore. - */ + */ fmt.ulFillLen = 0U; } } - switch(fmt.type) + switch( fmt.type ) { case PRFMT_DOUBLEPERCENT: - { + /* Nothing to do. A single percent has already been output, - and we just finished skipping past the second percent. - */ + * and we just finished skipping past the second percent. + */ break; - } /*-----------------> Small int handling <------------------ * @@ -399,217 +428,230 @@ int32_t RedVSNPrintf( *---------------------------------------------------------*/ case PRFMT_CHAR: - { - pcBuffer[ulBufIdx] = (char)va_arg(arglist, int); + pcBuffer[ ulBufIdx ] = ( char ) va_arg( arglist, int ); ulBufIdx++; break; - } + case PRFMT_SIGNED8BIT: - { - int8_t num = (int8_t)va_arg(arglist, int); + { + int8_t num = ( int8_t ) va_arg( arglist, int ); + + ulBufIdx += LtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, num, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += LtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, num, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_UNSIGNED8BIT: - { - uint8_t bNum = (uint8_t)va_arg(arglist, unsigned); + { + uint8_t bNum = ( uint8_t ) va_arg( arglist, unsigned ); + + ulBufIdx += ULtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, bNum, false, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, bNum, false, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_HEX8BIT: - { - uint8_t bNum = (uint8_t)va_arg(arglist, unsigned); + { + uint8_t bNum = ( uint8_t ) va_arg( arglist, unsigned ); + + ulBufIdx += ULtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, bNum, true, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, bNum, true, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_SIGNED16BIT: - { - int16_t num = (int16_t)va_arg(arglist, int); + { + int16_t num = ( int16_t ) va_arg( arglist, int ); + + ulBufIdx += LtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, num, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += LtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, num, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_UNSIGNED16BIT: - { - uint16_t uNum = (uint16_t)va_arg(arglist, unsigned); + { + uint16_t uNum = ( uint16_t ) va_arg( arglist, unsigned ); + + ulBufIdx += ULtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, uNum, false, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, uNum, false, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_HEX16BIT: - { - uint16_t uNum = (uint16_t)va_arg(arglist, unsigned); + { + uint16_t uNum = ( uint16_t ) va_arg( arglist, unsigned ); + + ulBufIdx += ULtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, uNum, true, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, uNum, true, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_SIGNED32BIT: - { - int32_t lNum = va_arg(arglist, int32_t); + { + int32_t lNum = va_arg( arglist, int32_t ); + + ulBufIdx += LtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, lNum, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += LtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, lNum, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_UNSIGNED32BIT: - { - uint32_t ulNum = va_arg(arglist, uint32_t); + { + uint32_t ulNum = va_arg( arglist, uint32_t ); + + ulBufIdx += ULtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, ulNum, false, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ulNum, false, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_HEX32BIT: - { - uint32_t ulNum = va_arg(arglist, uint32_t); + { + uint32_t ulNum = va_arg( arglist, uint32_t ); + + ulBufIdx += ULtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, ulNum, true, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ulNum, true, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_SIGNED64BIT: - { - int64_t llNum = va_arg(arglist, int64_t); + { + int64_t llNum = va_arg( arglist, int64_t ); + + ulBufIdx += LLtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, llNum, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += LLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, llNum, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_UNSIGNED64BIT: - { - uint64_t ullNum = va_arg(arglist, uint64_t); + { + uint64_t ullNum = va_arg( arglist, uint64_t ); + + ulBufIdx += ULLtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, ullNum, false, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += ULLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ullNum, false, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_HEX64BIT: - { - uint64_t ullNum = va_arg(arglist, uint64_t); + { + uint64_t ullNum = va_arg( arglist, uint64_t ); + + ulBufIdx += ULLtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, ullNum, true, fmt.ulFillLen, fmt.cFillChar ); + break; + } - ulBufIdx += ULLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ullNum, true, fmt.ulFillLen, fmt.cFillChar); - break; - } case PRFMT_POINTER: - { - const void *ptr = va_arg(arglist, const void *); + { + const void * ptr = va_arg( arglist, const void * ); - /* Assert our assumption. - */ - REDASSERT(sizeof(void *) <= 8U); - - /* Format as either a 64-bit or a 32-bit value. - */ - if(sizeof(void *) > 4U) - { - /* Attempt to quiet warnings. + /* Assert our assumption. */ - uintptr_t ptrval = (uintptr_t)ptr; - uint64_t ullPtrVal = (uint64_t)ptrval; + REDASSERT( sizeof( void * ) <= 8U ); - ulBufIdx += ULLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ullPtrVal, true, fmt.ulFillLen, fmt.cFillChar); - } - else - { - /* Attempt to quiet warnings. + /* Format as either a 64-bit or a 32-bit value. */ - uintptr_t ptrval = (uintptr_t)ptr; - uint32_t ulPtrVal = (uint32_t)ptrval; + if( sizeof( void * ) > 4U ) + { + /* Attempt to quiet warnings. + */ + uintptr_t ptrval = ( uintptr_t ) ptr; + uint64_t ullPtrVal = ( uint64_t ) ptrval; - ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ulPtrVal, true, fmt.ulFillLen, fmt.cFillChar); - } + ulBufIdx += ULLtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, ullPtrVal, true, fmt.ulFillLen, fmt.cFillChar ); + } + else + { + /* Attempt to quiet warnings. + */ + uintptr_t ptrval = ( uintptr_t ) ptr; + uint32_t ulPtrVal = ( uint32_t ) ptrval; + + ulBufIdx += ULtoA( &pcBuffer[ ulBufIdx ], ulBufferLen - ulBufIdx, ulPtrVal, true, fmt.ulFillLen, fmt.cFillChar ); + } + + break; + } - break; - } case PRFMT_ANSISTRING: - { - const char *pszArg = va_arg(arglist, const char *); - uint32_t ulArgIdx = 0U; + { + const char * pszArg = va_arg( arglist, const char * ); + uint32_t ulArgIdx = 0U; - if(pszArg == NULL) - { - pszArg = "null"; - } + if( pszArg == NULL ) + { + pszArg = "null"; + } - if(fmt.ulFillLen > 0U) - { - if(!fmt.fLeftJustified) - { - uint32_t ulLen = RedStrLen(pszArg); + if( fmt.ulFillLen > 0U ) + { + if( !fmt.fLeftJustified ) + { + uint32_t ulLen = RedStrLen( pszArg ); - /* So long as we are not left justifying, fill as many - characters as is necessary to make the string right - justified. + /* So long as we are not left justifying, fill as many + * characters as is necessary to make the string right + * justified. + */ + while( ( ( ulBufferLen - ulBufIdx ) > 0U ) && ( fmt.ulFillLen > ulLen ) ) + { + pcBuffer[ ulBufIdx ] = fmt.cFillChar; + ulBufIdx++; + fmt.ulFillLen--; + } + } + + /* Move as many characters as we have space for into the + * output buffer. */ - while(((ulBufferLen - ulBufIdx) > 0U) && (fmt.ulFillLen > ulLen)) - { - pcBuffer[ulBufIdx] = fmt.cFillChar; - ulBufIdx++; - fmt.ulFillLen--; - } - } + while( ( ( ulBufferLen - ulBufIdx ) > 0U ) && ( pszArg[ ulArgIdx ] != '\0' ) ) + { + pcBuffer[ ulBufIdx ] = pszArg[ ulArgIdx ]; + ulBufIdx++; + ulArgIdx++; - /* Move as many characters as we have space for into the - output buffer. - */ - while(((ulBufferLen - ulBufIdx) > 0U) && (pszArg[ulArgIdx] != '\0')) - { - pcBuffer[ulBufIdx] = pszArg[ulArgIdx]; - ulBufIdx++; - ulArgIdx++; - if(fmt.ulFillLen > 0U) - { - fmt.ulFillLen--; - } - } + if( fmt.ulFillLen > 0U ) + { + fmt.ulFillLen--; + } + } - /* If there is any space left to fill, do it (the string - must have been left justified). - */ - while(((ulBufferLen - ulBufIdx) > 0U) && (fmt.ulFillLen > 0U)) - { - /* This is NOT a typo -- when using left justified - strings, spaces are the only allowed fill character. - See the errata. + /* If there is any space left to fill, do it (the string + * must have been left justified). */ - pcBuffer[ulBufIdx] = ' '; - ulBufIdx++; - fmt.ulFillLen--; - } - } - else - { - /* No fill characters, just move up to as many - characters as we have space for in the output - buffer. - */ - while(((ulBufferLen - ulBufIdx) > 0U) && (pszArg[ulArgIdx] != '\0')) - { - pcBuffer[ulBufIdx] = pszArg[ulArgIdx]; - ulBufIdx++; - ulArgIdx++; - } - } - break; - } + while( ( ( ulBufferLen - ulBufIdx ) > 0U ) && ( fmt.ulFillLen > 0U ) ) + { + /* This is NOT a typo -- when using left justified + * strings, spaces are the only allowed fill character. + * See the errata. + */ + pcBuffer[ ulBufIdx ] = ' '; + ulBufIdx++; + fmt.ulFillLen--; + } + } + else + { + /* No fill characters, just move up to as many + * characters as we have space for in the output + * buffer. + */ + while( ( ( ulBufferLen - ulBufIdx ) > 0U ) && ( pszArg[ ulArgIdx ] != '\0' ) ) + { + pcBuffer[ ulBufIdx ] = pszArg[ ulArgIdx ]; + ulBufIdx++; + ulArgIdx++; + } + } + + break; + } + default: - { REDERROR(); break; - } } } /* If there is space, tack on a null and return the output length - processed, not including the null. - */ - if(ulBufIdx < ulBufferLen) + * processed, not including the null. + */ + if( ulBufIdx < ulBufferLen ) { - pcBuffer[ulBufIdx] = '\0'; - iLen = (int32_t)ulBufIdx; + pcBuffer[ ulBufIdx ] = '\0'; + iLen = ( int32_t ) ulBufIdx; } else { /* Not enough space, just return -1, with no null termination - */ + */ iLen = -1; } @@ -618,89 +660,88 @@ int32_t RedVSNPrintf( /** @brief Process the next segment of the format string, outputting any - non-format specifiers, as output buffer space allows, and return - information about the next format specifier. - - @note If the returned value is the same as the supplied @p ulBufferLen, - the output buffer will not be null-terminated. In all other cases, - the result will be null-terminated. The returned length will never - include the null in the count. - - @param pcBuffer The output buffer. - @param ulBufferLen The output buffer length. - @param pszFormat The format string to process. - @param pFormat The PRINTFORMAT structure to fill. - @param pulSpecifierLen Returns the length of any format specifier string, - or zero if no specifier was found. - - @return The count of characters from pszFormatt which were processed and - copied to pcBuffer. - - If zero is returned and *pulSpecifierLen is non-zero, then - a format specifier string was found at the start of pszFmt. - - If non-zero is returned and *pulSpecifierLen is zero, then - no format specifier string was found, and the entire pszFmt - string was copied to pBuffer (or as much as will fit). -*/ -static uint32_t ProcessFormatSegment( - char *pcBuffer, - uint32_t ulBufferLen, - const char *pszFormat, - PRINTFORMAT *pFormat, - uint32_t *pulSpecifierLen) + * non-format specifiers, as output buffer space allows, and return + * information about the next format specifier. + * + * @note If the returned value is the same as the supplied @p ulBufferLen, + * the output buffer will not be null-terminated. In all other cases, + * the result will be null-terminated. The returned length will never + * include the null in the count. + * + * @param pcBuffer The output buffer. + * @param ulBufferLen The output buffer length. + * @param pszFormat The format string to process. + * @param pFormat The PRINTFORMAT structure to fill. + * @param pulSpecifierLen Returns the length of any format specifier string, + * or zero if no specifier was found. + * + * @return The count of characters from pszFormatt which were processed and + * copied to pcBuffer. + * - If zero is returned and *pulSpecifierLen is non-zero, then + * a format specifier string was found at the start of pszFmt. + * - If non-zero is returned and *pulSpecifierLen is zero, then + * no format specifier string was found, and the entire pszFmt + * string was copied to pBuffer (or as much as will fit). + */ +static uint32_t ProcessFormatSegment( char * pcBuffer, + uint32_t ulBufferLen, + const char * pszFormat, + PRINTFORMAT * pFormat, + uint32_t * pulSpecifierLen ) { - uint32_t ulWidth = 0U; + uint32_t ulWidth = 0U; /* Find the next format specifier string, and information about it. - */ - *pulSpecifierLen = ParseFormatSpecifier(pszFormat, pFormat); + */ + *pulSpecifierLen = ParseFormatSpecifier( pszFormat, pFormat ); - if(*pulSpecifierLen == 0U) + if( *pulSpecifierLen == 0U ) { /* If no specifier was found at all, then simply output the full length - of the string, or as much as will fit. + * of the string, or as much as will fit. */ - ulWidth = REDMIN(ulBufferLen, RedStrLen(pszFormat)); + ulWidth = REDMIN( ulBufferLen, RedStrLen( pszFormat ) ); - RedMemCpy(pcBuffer, pszFormat, ulWidth); + RedMemCpy( pcBuffer, pszFormat, ulWidth ); } else { /* If we encountered a double percent, skip past one of them so it is - copied into the output buffer. - */ - if(pFormat->type == PRFMT_DOUBLEPERCENT) + * copied into the output buffer. + */ + if( pFormat->type == PRFMT_DOUBLEPERCENT ) { pFormat->ulSpecifierIdx++; /* A double percent specifier always has a length of two. Since - we're processing one of those percent signs, reduce the length - to one. Assert it so. - */ - REDASSERT(*pulSpecifierLen == 2U); + * we're processing one of those percent signs, reduce the length + * to one. Assert it so. + */ + REDASSERT( *pulSpecifierLen == 2U ); - (*pulSpecifierLen)--; + ( *pulSpecifierLen )--; } /* So long as the specifier is not the very first thing in the format - string... - */ - if(pFormat->ulSpecifierIdx != 0U) + * string... + */ + if( pFormat->ulSpecifierIdx != 0U ) { /* A specifier was found, but there is other data preceding it. - Copy as much as allowed to the output buffer. - */ - ulWidth = REDMIN(ulBufferLen, pFormat->ulSpecifierIdx); + * Copy as much as allowed to the output buffer. + */ + ulWidth = REDMIN( ulBufferLen, pFormat->ulSpecifierIdx ); - RedMemCpy(pcBuffer, pszFormat, ulWidth); + RedMemCpy( pcBuffer, pszFormat, ulWidth ); } } /* If there is room in the output buffer, null-terminate whatever is there. - But note that the returned length never includes the null. - */ - if(ulWidth < ulBufferLen) + * But note that the returned length never includes the null. + */ + if( ulWidth < ulBufferLen ) { - pcBuffer[ulWidth] = 0U; + pcBuffer[ ulWidth ] = 0U; } return ulWidth; @@ -708,52 +749,51 @@ static uint32_t ProcessFormatSegment( /** @brief Parse the specified format string for a valid RedVSNPrintf() format - sequence, and return information about it. - - @param pszFormat The format string to process. - @param pFormatType The PRINTFORMAT structure to fill. The data is only - valid if a non-zero length is returned. - - @return The length of the full format specifier string, starting at - pFormat->ulSpecifierIdx. Returns zero if a valid specifier was - not found. -*/ -static uint32_t ParseFormatSpecifier( - char const *pszFormat, - PRINTFORMAT *pFormatType) + * sequence, and return information about it. + * + * @param pszFormat The format string to process. + * @param pFormatType The PRINTFORMAT structure to fill. The data is only + * valid if a non-zero length is returned. + * + * @return The length of the full format specifier string, starting at + * pFormat->ulSpecifierIdx. Returns zero if a valid specifier was + * not found. + */ +static uint32_t ParseFormatSpecifier( char const * pszFormat, + PRINTFORMAT * pFormatType ) { - bool fContainsIllegalSequence = false; - uint32_t ulLen = 0U; - uint32_t ulIdx = 0U; + bool fContainsIllegalSequence = false; + uint32_t ulLen = 0U; + uint32_t ulIdx = 0U; - while(pszFormat[ulIdx] != '\0') + while( pszFormat[ ulIdx ] != '\0' ) { - uint32_t ulTypeLen; + uint32_t ulTypeLen; /* general output - */ - if(pszFormat[ulIdx] != '%') + */ + if( pszFormat[ ulIdx ] != '%' ) { ulIdx++; } else { - RedMemSet(pFormatType, 0U, sizeof(*pFormatType)); + RedMemSet( pFormatType, 0U, sizeof( *pFormatType ) ); /* Record the location of the start of the format sequence - */ + */ pFormatType->ulSpecifierIdx = ulIdx; ulIdx++; - if(pszFormat[ulIdx] == '-') + if( pszFormat[ ulIdx ] == '-' ) { pFormatType->fLeftJustified = true; ulIdx++; } - if((pszFormat[ulIdx] == '0') || (pszFormat[ulIdx] == '_')) + if( ( pszFormat[ ulIdx ] == '0' ) || ( pszFormat[ ulIdx ] == '_' ) ) { - pFormatType->cFillChar = pszFormat[ulIdx]; + pFormatType->cFillChar = pszFormat[ ulIdx ]; ulIdx++; } else @@ -761,15 +801,16 @@ static uint32_t ParseFormatSpecifier( pFormatType->cFillChar = ' '; } - if(pszFormat[ulIdx] == '*') + if( pszFormat[ ulIdx ] == '*' ) { pFormatType->fHasVarWidth = true; ulIdx++; } - else if(ISDIGIT(pszFormat[ulIdx])) + else if( ISDIGIT( pszFormat[ ulIdx ] ) ) { - pFormatType->ulFillLen = (uint32_t)RedAtoI(&pszFormat[ulIdx]); - while(ISDIGIT(pszFormat[ulIdx])) + pFormatType->ulFillLen = ( uint32_t ) RedAtoI( &pszFormat[ ulIdx ] ); + + while( ISDIGIT( pszFormat[ ulIdx ] ) ) { ulIdx++; } @@ -777,25 +818,26 @@ static uint32_t ParseFormatSpecifier( else { /* No fill length. - */ + */ } - pFormatType->type = ParseFormatType(&pszFormat[ulIdx], &ulTypeLen); - if(pFormatType->type != PRFMT_UNKNOWN) + pFormatType->type = ParseFormatType( &pszFormat[ ulIdx ], &ulTypeLen ); + + if( pFormatType->type != PRFMT_UNKNOWN ) { /* Even though we are returning successfully, keep track of - whether an illegal sequence was encountered and skipped. - */ + * whether an illegal sequence was encountered and skipped. + */ pFormatType->fHasIllegalType = fContainsIllegalSequence; - ulLen = (ulIdx - pFormatType->ulSpecifierIdx) + ulTypeLen; + ulLen = ( ulIdx - pFormatType->ulSpecifierIdx ) + ulTypeLen; break; } /* In the case of an unrecognized type string, simply ignore - it entirely. Reset the pointer to the position following - the percent sign, so it is not found again. - */ + * it entirely. Reset the pointer to the position following + * the percent sign, so it is not found again. + */ fContainsIllegalSequence = false; ulIdx = pFormatType->ulSpecifierIdx + 1U; } @@ -806,110 +848,128 @@ static uint32_t ParseFormatSpecifier( /** @brief Parse a RedPrintf() format type string to determine the proper data - type. - - @param pszFormat The format string to process. This must be a pointer to - the character following any width or justification - characters. - @param pulTypeLen The location in which to store the type length. The - value will be 0 if PRFMT_UNKNOWN is returned. - - @return Rhe PRFMT_* type value, or PRFMT_UNKNOWN if the type is not - recognized. -*/ -static PRINTTYPE ParseFormatType( - const char *pszFormat, - uint32_t *pulTypeLen) + * type. + * + * @param pszFormat The format string to process. This must be a pointer to + * the character following any width or justification + * characters. + * @param pulTypeLen The location in which to store the type length. The + * value will be 0 if PRFMT_UNKNOWN is returned. + * + * @return Rhe PRFMT_* type value, or PRFMT_UNKNOWN if the type is not + * recognized. + */ +static PRINTTYPE ParseFormatType( const char * pszFormat, + uint32_t * pulTypeLen ) { - PRINTTYPE fmtType = PRFMT_UNKNOWN; - uint32_t ulIdx = 0U; + PRINTTYPE fmtType = PRFMT_UNKNOWN; + uint32_t ulIdx = 0U; - switch(pszFormat[ulIdx]) + switch( pszFormat[ ulIdx ] ) { case '%': fmtType = PRFMT_DOUBLEPERCENT; break; + case 'c': fmtType = PRFMT_CHAR; break; + case 's': fmtType = PRFMT_ANSISTRING; break; + case 'p': fmtType = PRFMT_POINTER; break; + case 'd': fmtType = MAPINT; break; + case 'u': fmtType = MAPUINT; break; + case 'x': fmtType = MAPHEXUINT; break; + case 'h': - { ulIdx++; - switch(pszFormat[ulIdx]) + + switch( pszFormat[ ulIdx ] ) { case 'd': fmtType = MAPSHORT; break; + case 'u': fmtType = MAPUSHORT; break; + case 'x': fmtType = MAPHEXUSHORT; break; + default: break; } + break; - } + case 'l': - { ulIdx++; - switch(pszFormat[ulIdx]) + + switch( pszFormat[ ulIdx ] ) { case 'd': fmtType = MAPLONG; break; + case 'u': fmtType = MAPULONG; break; + case 'x': fmtType = MAPHEXULONG; break; + case 'l': - { ulIdx++; - switch(pszFormat[ulIdx]) + + switch( pszFormat[ ulIdx ] ) { case 'd': fmtType = MAPLONGLONG; break; + case 'u': fmtType = MAPULONGLONG; break; + case 'x': case 'X': fmtType = MAPHEXULONGLONG; break; + default: break; } + break; - } + default: break; } + break; - } + default: break; } - if(fmtType != PRFMT_UNKNOWN) + if( fmtType != PRFMT_UNKNOWN ) { *pulTypeLen = ulIdx + 1U; } @@ -923,69 +983,68 @@ static PRINTTYPE ParseFormatType( /** @brief Format a signed 32-bit integer as a base 10 ASCII string. - - @note If the output buffer length is exhausted, the result will *not* be - null-terminated. - - @note If the @p ulFillLen value is greater than or equal to the buffer - length, the result will not be null-terminated, even if the - formatted portion of the data is shorter than the buffer length. - - @param pcBuffer The output buffer - @param ulBufferLen A pointer to the output buffer length - @param lNum The 32-bit signed number to convert - @param ulFillLen The fill length, if any - @param cFill The fill character to use - - @return The length of the string. -*/ -static uint32_t LtoA( - char *pcBuffer, - uint32_t ulBufferLen, - int32_t lNum, - uint32_t ulFillLen, - char cFill) + * + * @note If the output buffer length is exhausted, the result will *not* be + * null-terminated. + * + * @note If the @p ulFillLen value is greater than or equal to the buffer + * length, the result will not be null-terminated, even if the + * formatted portion of the data is shorter than the buffer length. + * + * @param pcBuffer The output buffer + * @param ulBufferLen A pointer to the output buffer length + * @param lNum The 32-bit signed number to convert + * @param ulFillLen The fill length, if any + * @param cFill The fill character to use + * + * @return The length of the string. + */ +static uint32_t LtoA( char * pcBuffer, + uint32_t ulBufferLen, + int32_t lNum, + uint32_t ulFillLen, + char cFill ) { - uint32_t ulLen; + uint32_t ulLen; - if(pcBuffer == NULL) + if( pcBuffer == NULL ) { REDERROR(); ulLen = 0U; } else { - char ach[12U]; /* big enough for a int32_t in base 10 */ - uint32_t ulDigits = 0U; - uint32_t ulNum; - bool fSign; + char ach[ 12U ]; /* big enough for a int32_t in base 10 */ + uint32_t ulDigits = 0U; + uint32_t ulNum; + bool fSign; - if(lNum < 0) + if( lNum < 0 ) { fSign = true; - ulNum = (uint32_t)-lNum; + ulNum = ( uint32_t ) -lNum; } else { fSign = false; - ulNum = (uint32_t)lNum; + ulNum = ( uint32_t ) lNum; } do { - ach[ulDigits] = gacDigits[ulNum % 10U]; + ach[ ulDigits ] = gacDigits[ ulNum % 10U ]; ulNum = ulNum / 10U; ulDigits++; } - while(ulNum); + while( ulNum ); - if(fSign) + if( fSign ) { - ach[ulDigits] = '-'; + ach[ ulDigits ] = '-'; ulDigits++; } - ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill); + ulLen = FinishToA( ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill ); } return ulLen; @@ -993,80 +1052,79 @@ static uint32_t LtoA( /** @brief Format a signed 64-bit integer as a base 10 ASCII string. - - @note If the output buffer length is exhausted, the result will *not* be - null-terminated. - - @note If the @p ulFillLen value is greater than or equal to the buffer - length, the result will not be null-terminated, even if the - formatted portion of the data is shorter than the buffer length. - - @param pcBuffer The output buffer - @param ulBufferLen A pointer to the output buffer length - @param llNum The 64-bit signed number to convert - @param ulFillLen The fill length, if any - @param cFill The fill character to use - - @return The length of the string. -*/ -static uint32_t LLtoA( - char *pcBuffer, - uint32_t ulBufferLen, - int64_t llNum, - uint32_t ulFillLen, - char cFill) + * + * @note If the output buffer length is exhausted, the result will *not* be + * null-terminated. + * + * @note If the @p ulFillLen value is greater than or equal to the buffer + * length, the result will not be null-terminated, even if the + * formatted portion of the data is shorter than the buffer length. + * + * @param pcBuffer The output buffer + * @param ulBufferLen A pointer to the output buffer length + * @param llNum The 64-bit signed number to convert + * @param ulFillLen The fill length, if any + * @param cFill The fill character to use + * + * @return The length of the string. + */ +static uint32_t LLtoA( char * pcBuffer, + uint32_t ulBufferLen, + int64_t llNum, + uint32_t ulFillLen, + char cFill ) { - uint32_t ulLen; + uint32_t ulLen; - if(pcBuffer == NULL) + if( pcBuffer == NULL ) { REDERROR(); ulLen = 0U; } else { - char ach[12U]; /* big enough for a int32_t in base 10 */ - uint32_t ulDigits = 0U; - uint64_t ullNum; - bool fSign; + char ach[ 12U ]; /* big enough for a int32_t in base 10 */ + uint32_t ulDigits = 0U; + uint64_t ullNum; + bool fSign; - if(llNum < 0) + if( llNum < 0 ) { fSign = true; - ullNum = (uint64_t)-llNum; + ullNum = ( uint64_t ) -llNum; } else { fSign = false; - ullNum = (uint64_t)llNum; + ullNum = ( uint64_t ) llNum; } /* Not allowed to assume that 64-bit division is OK, so use a - software division routine. - */ + * software division routine. + */ do { uint64_t ullQuotient; uint32_t ulRemainder; /* Note: RedUint64DivMod32() is smart enough to use normal division - once ullNumericVal <= UINT32_MAX. - */ - ullQuotient = RedUint64DivMod32(ullNum, 10U, &ulRemainder); + * once ullNumericVal <= UINT32_MAX. + */ + ullQuotient = RedUint64DivMod32( ullNum, 10U, &ulRemainder ); - ach[ulDigits] = gacDigits[ulRemainder]; + ach[ ulDigits ] = gacDigits[ ulRemainder ]; ullNum = ullQuotient; ulDigits++; } - while(ullNum > 0U); + while( ullNum > 0U ); - if(fSign) + if( fSign ) { - ach[ulDigits] = '-'; + ach[ ulDigits ] = '-'; ulDigits++; } - ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill); + ulLen = FinishToA( ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill ); } return ulLen; @@ -1074,51 +1132,50 @@ static uint32_t LLtoA( /** @brief Format an unsigned 32-bit integer as an ASCII string as decimal or - hex. - - @note If the output buffer length is exhausted, the result will *not* be - null-terminated. - - @param pcBuffer The output buffer - @param ulBufferLen The output buffer length - @param ulNum The 32-bit unsigned number to convert - @param fHex If true, format as hex; if false, decimal. - @param ulFillLen The fill length, if any - @param cFill The fill character to use - - @return The length of the string. -*/ -static uint32_t ULtoA( - char *pcBuffer, - uint32_t ulBufferLen, - uint32_t ulNum, - bool fHex, - uint32_t ulFillLen, - char cFill) + * hex. + * + * @note If the output buffer length is exhausted, the result will *not* be + * null-terminated. + * + * @param pcBuffer The output buffer + * @param ulBufferLen The output buffer length + * @param ulNum The 32-bit unsigned number to convert + * @param fHex If true, format as hex; if false, decimal. + * @param ulFillLen The fill length, if any + * @param cFill The fill character to use + * + * @return The length of the string. + */ +static uint32_t ULtoA( char * pcBuffer, + uint32_t ulBufferLen, + uint32_t ulNum, + bool fHex, + uint32_t ulFillLen, + char cFill ) { - uint32_t ulLen; + uint32_t ulLen; - if(pcBuffer == NULL) + if( pcBuffer == NULL ) { REDERROR(); ulLen = 0U; } else { - char ach[11U]; /* Big enough for a uint32_t in radix 10 */ - uint32_t ulDigits = 0U; - uint32_t ulNumericVal = ulNum; - uint32_t ulRadix = fHex ? 16U : 10U; + char ach[ 11U ]; /* Big enough for a uint32_t in radix 10 */ + uint32_t ulDigits = 0U; + uint32_t ulNumericVal = ulNum; + uint32_t ulRadix = fHex ? 16U : 10U; do { - ach[ulDigits] = gacDigits[ulNumericVal % ulRadix]; + ach[ ulDigits ] = gacDigits[ ulNumericVal % ulRadix ]; ulNumericVal = ulNumericVal / ulRadix; ulDigits++; } - while(ulNumericVal > 0U); + while( ulNumericVal > 0U ); - ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill); + ulLen = FinishToA( ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill ); } return ulLen; @@ -1126,77 +1183,75 @@ static uint32_t ULtoA( /** @brief Format an unsigned 64-bit integer as an ASCII string as decimal or - hex. - - @note If the output buffer length is exhausted, the result will *not* be - null-terminated. - - @param pcBuffer The output buffer. - @param ulBufferLen The output buffer length. - @param ullNum The unsigned 64-bit number to convert. - @param fHex If true, format as hex; if false, decimal. - @param ulFillLen The fill length, if any. - @param cFill The fill character to use. - - @return The length of the string. -*/ -static uint32_t ULLtoA( - char *pcBuffer, - uint32_t ulBufferLen, - uint64_t ullNum, - bool fHex, - uint32_t ulFillLen, - char cFill) + * hex. + * + * @note If the output buffer length is exhausted, the result will *not* be + * null-terminated. + * + * @param pcBuffer The output buffer. + * @param ulBufferLen The output buffer length. + * @param ullNum The unsigned 64-bit number to convert. + * @param fHex If true, format as hex; if false, decimal. + * @param ulFillLen The fill length, if any. + * @param cFill The fill character to use. + * + * @return The length of the string. + */ +static uint32_t ULLtoA( char * pcBuffer, + uint32_t ulBufferLen, + uint64_t ullNum, + bool fHex, + uint32_t ulFillLen, + char cFill ) { - uint32_t ulLen; + uint32_t ulLen; - if(pcBuffer == NULL) + if( pcBuffer == NULL ) { REDERROR(); ulLen = 0U; } else { + char ach[ 21U ]; /* Big enough for a uint64_t in radix 10 */ + uint32_t ulDigits = 0U; + uint64_t ullNumericVal = ullNum; - char ach[21U]; /* Big enough for a uint64_t in radix 10 */ - uint32_t ulDigits = 0U; - uint64_t ullNumericVal = ullNum; - - if(fHex) + if( fHex ) { /* We can figure out the digits using bit operations. - */ + */ do { - ach[ulDigits] = gacDigits[ullNumericVal & 15U]; + ach[ ulDigits ] = gacDigits[ ullNumericVal & 15U ]; ullNumericVal >>= 4U; ulDigits++; } - while(ullNumericVal > 0U); + while( ullNumericVal > 0U ); } else { /* Not allowed to assume that 64-bit division is OK, so use a - software division routine. - */ + * software division routine. + */ do { uint64_t ullQuotient; uint32_t ulRemainder; /* Note: RedUint64DivMod32() is smart enough to use normal division - once ullNumericVal <= UINT32_MAX. - */ - ullQuotient = RedUint64DivMod32(ullNumericVal, 10U, &ulRemainder); + * once ullNumericVal <= UINT32_MAX. + */ + ullQuotient = RedUint64DivMod32( ullNumericVal, 10U, &ulRemainder ); - ach[ulDigits] = gacDigits[ulRemainder]; + ach[ ulDigits ] = gacDigits[ ulRemainder ]; ullNumericVal = ullQuotient; ulDigits++; } - while(ullNumericVal > 0U); + while( ullNumericVal > 0U ); } - ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill); + ulLen = FinishToA( ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill ); } return ulLen; @@ -1204,62 +1259,60 @@ static uint32_t ULLtoA( /** @brief Finish converting a number into an ASCII string representing that - number. - - This helper function contains common logic that needs to run at the end of - all the "toA" functions. It adds the fill character and reverses the digits - string. - - @param pcDigits The digits (and sign) for the ASCII string, in reverse - order as they were computed. - @param ulDigits The number of digit characters. - @param pcOutBuffer The output buffer. - @param ulBufferLen The length of the output buffer. - @param ulFillLen The fill length. If the number string is shorter than - this, the remaining bytes are filled with @p cFill. - @param cFill The fill character. - - @return The length of @p pcOutBuffer. -*/ -static uint32_t FinishToA( - const char *pcDigits, - uint32_t ulDigits, - char *pcOutBuffer, - uint32_t ulBufferLen, - uint32_t ulFillLen, - char cFill) + * number. + * + * This helper function contains common logic that needs to run at the end of + * all the "toA" functions. It adds the fill character and reverses the digits + * string. + * + * @param pcDigits The digits (and sign) for the ASCII string, in reverse + * order as they were computed. + * @param ulDigits The number of digit characters. + * @param pcOutBuffer The output buffer. + * @param ulBufferLen The length of the output buffer. + * @param ulFillLen The fill length. If the number string is shorter than + * this, the remaining bytes are filled with @p cFill. + * @param cFill The fill character. + * + * @return The length of @p pcOutBuffer. + */ +static uint32_t FinishToA( const char * pcDigits, + uint32_t ulDigits, + char * pcOutBuffer, + uint32_t ulBufferLen, + uint32_t ulFillLen, + char cFill ) { - uint32_t ulIdx = 0U; - uint32_t ulDigitIdx = ulDigits; + uint32_t ulIdx = 0U; + uint32_t ulDigitIdx = ulDigits; /* user may have asked for a fill char - */ - if(ulFillLen > ulDigits) + */ + if( ulFillLen > ulDigits ) { uint32_t ulFillRem = ulFillLen - ulDigits; - while((ulFillRem > 0U) && (ulIdx < ulBufferLen)) + while( ( ulFillRem > 0U ) && ( ulIdx < ulBufferLen ) ) { - pcOutBuffer[ulIdx] = cFill; + pcOutBuffer[ ulIdx ] = cFill; ulIdx++; ulFillRem--; } } /* reverse the string - */ - while((ulDigitIdx > 0) && (ulIdx < ulBufferLen)) + */ + while( ( ulDigitIdx > 0 ) && ( ulIdx < ulBufferLen ) ) { ulDigitIdx--; - pcOutBuffer[ulIdx] = pcDigits[ulDigitIdx]; + pcOutBuffer[ ulIdx ] = pcDigits[ ulDigitIdx ]; ulIdx++; } - if(ulIdx < ulBufferLen) + if( ulIdx < ulBufferLen ) { - pcOutBuffer[ulIdx] = '\0'; + pcOutBuffer[ ulIdx ] = '\0'; } return ulIdx; } - diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/rand.c b/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/rand.c index 6dd443023..8e905d409 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/rand.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/tests/util/rand.c @@ -1,53 +1,54 @@ /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ /* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + /** @file - @brief Implements a random number generator. -*/ + * @brief Implements a random number generator. + */ #include #include /* This is the global seed used by the random number generator when the caller - has not provided a seed to either the RedRand32() or RedRand64() functions. -*/ + * has not provided a seed to either the RedRand32() or RedRand64() functions. + */ static uint64_t ullGlobalRandomNumberSeed; /* Whether the above seed has been initialized. -*/ + */ static bool fGlobalSeedInited; /** @brief Set the global seed used by the random number generator. - - The global seed gets used when RedRand64() or RedRand32() are called with - a NULL seed argument. - - @param ullSeed The value to use as the global RNG seed. -*/ -void RedRandSeed( - uint64_t ullSeed) + * + * The global seed gets used when RedRand64() or RedRand32() are called with + * a NULL seed argument. + * + * @param ullSeed The value to use as the global RNG seed. + */ +void RedRandSeed( uint64_t ullSeed ) { ullGlobalRandomNumberSeed = ullSeed; fGlobalSeedInited = true; @@ -55,105 +56,102 @@ void RedRandSeed( /** @brief Generate a 64-bit pseudo-random number. - - The period of this random number generator is 2^64 (1.8 x 1019). These - parameters are the same as the default one-stream SPRNG lcg64 generator and - it satisfies the requirements for a maximal period. - - The tempering value is used and an AND mask and is specifically selected to - favor the distribution of lower bits. - - @param pullSeed A pointer to the seed to use. Set this value to NULL to - use the internal global seed value. - - @return A pseudo-random number in the range [0, UINT64_MAX]. -*/ -uint64_t RedRand64( - uint64_t *pullSeed) + * + * The period of this random number generator is 2^64 (1.8 x 1019). These + * parameters are the same as the default one-stream SPRNG lcg64 generator and + * it satisfies the requirements for a maximal period. + * + * The tempering value is used and an AND mask and is specifically selected to + * favor the distribution of lower bits. + * + * @param pullSeed A pointer to the seed to use. Set this value to NULL to + * use the internal global seed value. + * + * @return A pseudo-random number in the range [0, UINT64_MAX]. + */ +uint64_t RedRand64( uint64_t * pullSeed ) { - const uint64_t ullA = UINT64_SUFFIX(2862933555777941757); - const uint64_t ullC = UINT64_SUFFIX(3037000493); - const uint64_t ullT = UINT64_SUFFIX(4921441182957829599); - uint64_t ullN; - uint64_t *pullSeedPtr; - uint64_t ullLocalSeed; + const uint64_t ullA = UINT64_SUFFIX( 2862933555777941757 ); + const uint64_t ullC = UINT64_SUFFIX( 3037000493 ); + const uint64_t ullT = UINT64_SUFFIX( 4921441182957829599 ); + uint64_t ullN; + uint64_t * pullSeedPtr; + uint64_t ullLocalSeed; - if(pullSeed != NULL) + if( pullSeed != NULL ) { ullLocalSeed = *pullSeed; pullSeedPtr = pullSeed; } else { - if(!fGlobalSeedInited) + if( !fGlobalSeedInited ) { /* Unfortunately, the Reliance Edge OS services don't give us much - to work with to initialize the global seed. There is no entropy - abstraction, no tick count abstraction, and the timestamp - abstraction uses an opaque type which is not guaranteed to be an - integer. The best we can do is use the RTC. - - Tests using the RNG should be supplying a seed anyway, for - reproducibility. - */ - RedRandSeed((uint64_t)RedOsClockGetTime()); + * to work with to initialize the global seed. There is no entropy + * abstraction, no tick count abstraction, and the timestamp + * abstraction uses an opaque type which is not guaranteed to be an + * integer. The best we can do is use the RTC. + * + * Tests using the RNG should be supplying a seed anyway, for + * reproducibility. + */ + RedRandSeed( ( uint64_t ) RedOsClockGetTime() ); } ullLocalSeed = ullGlobalRandomNumberSeed; pullSeedPtr = &ullGlobalRandomNumberSeed; } - ullN = (ullLocalSeed * ullA) + ullC; + ullN = ( ullLocalSeed * ullA ) + ullC; *pullSeedPtr = ullN; - /* The linear congruential generator used above produces good psuedo-random - 64-bit number sequences, however, as with any LCG, the period of the - lower order bits is much shorter resulting in alternately odd/even pairs - in bit zero. - - The result of the LGC above is tempered below with a series of XOR and - shift operations to produce a more acceptable equidistribution of bits - throughout the 64-bit range. - */ - ullN ^= (ullN >> 21U) & ullT; - ullN ^= (ullN >> 43U) & ullT; - ullN ^= (ullN << 23U) & ~ullT; - ullN ^= (ullN << 31U) & ~ullT; + /* The linear congruential generator used above produces good pseudo-random + * 64-bit number sequences, however, as with any LCG, the period of the + * lower order bits is much shorter resulting in alternately odd/even pairs + * in bit zero. + * + * The result of the LGC above is tempered below with a series of XOR and + * shift operations to produce a more acceptable equidistribution of bits + * throughout the 64-bit range. + */ + ullN ^= ( ullN >> 21U ) & ullT; + ullN ^= ( ullN >> 43U ) & ullT; + ullN ^= ( ullN << 23U ) & ~ullT; + ullN ^= ( ullN << 31U ) & ~ullT; return ullN; } /** @brief Generate a 32-bit pseudo-random number. - - @note The 32-bit random number generator internally uses the 64-bit random - number generator, returning the low 32-bits of the pseudo-random - 64-bit value. - - @param pulSeed A pointer to the seed to use. Set this value to NULL to use - the internal global seed value. - - @return A pseudo-random number in the range [0, UINT32_MAX]. -*/ -uint32_t RedRand32( - uint32_t *pulSeed) + * + * @note The 32-bit random number generator internally uses the 64-bit random + * number generator, returning the low 32-bits of the pseudo-random + * 64-bit value. + * + * @param pulSeed A pointer to the seed to use. Set this value to NULL to use + * the internal global seed value. + * + * @return A pseudo-random number in the range [0, UINT32_MAX]. + */ +uint32_t RedRand32( uint32_t * pulSeed ) { - uint64_t ullN; + uint64_t ullN; - if(pulSeed != NULL) + if( pulSeed != NULL ) { uint64_t ullLocalSeed; ullLocalSeed = *pulSeed; - ullN = RedRand64(&ullLocalSeed); - *pulSeed = (uint32_t)ullLocalSeed; + ullN = RedRand64( &ullLocalSeed ); + *pulSeed = ( uint32_t ) ullLocalSeed; } else { - ullN = RedRand64(NULL); + ullN = RedRand64( NULL ); } - return (uint32_t)ullN; + return ( uint32_t ) ullN; } - diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/getopt.c b/FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/getopt.c index 2a8f001d7..cdee62e82 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/getopt.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/getopt.c @@ -1,559 +1,747 @@ -/* - * Copyright (c) 2002 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dieter Baron and Thomas Klausner. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/** @file - @brief Implementations of getopt() and getopt_long() work-alike functions. - - This code was taken from FreeBSD and slightly modified, mostly to rename - symbols with external linkage to avoid naming conflicts in systems where - there are real getopt()/getopt_long() implementations, and for portability. -*/ -#include -#include -#include - -#include -#include -#include -#include - - -int32_t red_opterr = 1; /* if error message should be printed */ -int32_t red_optind = 1; /* index into parent argv vector */ -int32_t red_optopt = '?'; /* character checked for validity */ -int32_t red_optreset; /* reset RedGetopt */ -const char *red_optarg; /* argument associated with option */ - -#define PRINT_ERROR ((red_opterr) && (*options != ':')) - -#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ -#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ -#define FLAG_LONGONLY 0x04 /* operate as RedGetoptLongOnly */ - -/* return values */ -#define BADCH (int)'?' -#define BADARG ((*options == ':') ? (int)':' : (int)'?') -#define INORDER (int)1 - -#define EMSG "" - -#define NO_PREFIX (-1) -#define D_PREFIX 0 -#define DD_PREFIX 1 -#define W_PREFIX 2 - -static int gcd(int a, int b); -static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char * const *nargv); -static int parse_long_options(char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx, int short_too, int flags); -static int getopt_internal(int nargc, char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx, int flags); - -static const char *place = EMSG; /* option letter processing */ - -/* XXX: set red_optreset to 1 rather than these two */ -static int nonopt_start = -1; /* first non option argument (for permute) */ -static int nonopt_end = -1; /* first option after non options (for permute) */ - -/* Error messages */ -static const char recargchar[] = "option requires an argument -- %c\n"; -static const char illoptchar[] = "illegal option -- %c\n"; /* From P1003.2 */ -static int dash_prefix = NO_PREFIX; -static const char gnuoptchar[] = "invalid option -- %c\n"; - -static const char recargstring[] = "option `%s%s' requires an argument\n"; -static const char ambig[] = "option `%s%s' is ambiguous\n"; -static const char noarg[] = "option `%s%s' doesn't allow an argument\n"; -static const char illoptstring[] = "unrecognized option `%s%s'\n"; - -/* - * Compute the greatest common divisor of a and b. - */ -static int -gcd(int a, int b) -{ - int c; - - c = a % b; - while (c != 0) { - a = b; - b = c; - c = a % b; - } - - return (b); -} - -/* - * Exchange the block from nonopt_start to nonopt_end with the block - * from nonopt_end to opt_end (keeping the same order of arguments - * in each block). - */ -static void -permute_args(int panonopt_start, int panonopt_end, int opt_end, - char * const *nargv) -{ - int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; - char *swap; - - /* - * compute lengths of blocks and number and size of cycles - */ - nnonopts = panonopt_end - panonopt_start; - nopts = opt_end - panonopt_end; - ncycle = gcd(nnonopts, nopts); - cyclelen = (opt_end - panonopt_start) / ncycle; - - for (i = 0; i < ncycle; i++) { - cstart = panonopt_end+i; - pos = cstart; - for (j = 0; j < cyclelen; j++) { - if (pos >= panonopt_end) - pos -= nnonopts; - else - pos += nopts; - swap = nargv[pos]; - ((char **) nargv)[pos] = nargv[cstart]; - ((char **)nargv)[cstart] = swap; - } - } -} - -/* - * parse_long_options -- - * Parse long options in argc/argv argument vector. - * Returns -1 if short_too is set and the option does not match long_options. - */ -static int -parse_long_options(char * const *nargv, const char *options, - const REDOPTION *long_options, int32_t *idx, int short_too, int flags) -{ - const char *current_argv, *has_equal, *current_dash; - size_t current_argv_len; - int i, match, exact_match, second_partial_match; - - current_argv = place; - switch (dash_prefix) { - case D_PREFIX: - current_dash = "-"; - break; - case DD_PREFIX: - current_dash = "--"; - break; - case W_PREFIX: - current_dash = "-W "; - break; - default: - current_dash = ""; - break; - } - match = -1; - exact_match = 0; - second_partial_match = 0; - - red_optind++; - - if ((has_equal = strchr(current_argv, '=')) != NULL) { - /* argument found (--option=arg) */ - current_argv_len = has_equal - current_argv; - has_equal++; - } else - current_argv_len = strlen(current_argv); - - for (i = 0; long_options[i].name; i++) { - /* find matching long option */ - if (strncmp(current_argv, long_options[i].name, - current_argv_len)) - continue; - - if (strlen(long_options[i].name) == current_argv_len) { - /* exact match */ - match = i; - exact_match = 1; - break; - } - /* - * If this is a known short option, don't allow - * a partial match of a single character. - */ - if (short_too && current_argv_len == 1) - continue; - - if (match == -1) /* first partial match */ - match = i; - else if ((flags & FLAG_LONGONLY) || - long_options[i].has_arg != - long_options[match].has_arg || - long_options[i].flag != long_options[match].flag || - long_options[i].val != long_options[match].val) - second_partial_match = 1; - } - if (!exact_match && second_partial_match) { - /* ambiguous abbreviation */ - if (PRINT_ERROR) - fprintf(stderr, - ambig, - current_dash, - current_argv); - red_optopt = 0; - return (BADCH); - } - if (match != -1) { /* option found */ - if (long_options[match].has_arg == red_no_argument - && has_equal) { - if (PRINT_ERROR) - fprintf(stderr, - noarg, - current_dash, - current_argv); - /* - * XXX: GNU sets red_optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - red_optopt = long_options[match].val; - else - red_optopt = 0; - return (BADCH); - } - if (long_options[match].has_arg == red_required_argument || - long_options[match].has_arg == red_optional_argument) { - if (has_equal) - red_optarg = has_equal; - else if (long_options[match].has_arg == - red_required_argument) { - /* - * optional argument doesn't use next nargv - */ - red_optarg = nargv[red_optind++]; - } - } - if ((long_options[match].has_arg == red_required_argument) - && (red_optarg == NULL)) { - /* - * Missing argument; leading ':' indicates no error - * should be generated. - */ - if (PRINT_ERROR) - fprintf(stderr, - recargstring, - current_dash, - current_argv); - /* - * XXX: GNU sets red_optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - red_optopt = long_options[match].val; - else - red_optopt = 0; - --red_optind; - return (BADARG); - } - } else { /* unknown option */ - if (short_too) { - --red_optind; - return (-1); - } - if (PRINT_ERROR) - fprintf(stderr, - illoptstring, - current_dash, - current_argv); - red_optopt = 0; - return (BADCH); - } - if (idx) - *idx = match; - if (long_options[match].flag) { - *long_options[match].flag = long_options[match].val; - return (0); - } else - return (long_options[match].val); -} - -/* - * getopt_internal -- - * Parse argc/argv argument vector. Called by user level routines. - */ -static int -getopt_internal(int nargc, char * const *nargv, const char *options, - const REDOPTION *long_options, int32_t *idx, int flags) -{ - char *oli; /* option letter list index */ - int optchar, short_too; - - if (options == NULL) - return (-1); - - /* - * XXX Some GNU programs (like cvs) set red_optind to 0 instead of - * XXX using red_optreset. Work around this braindamage. - */ - if (red_optind == 0) - red_optind = red_optreset = 1; - - /* - * Disable GNU extensions if options string begins with a '+'. - */ - if (*options == '-') - flags |= FLAG_ALLARGS; - else if (*options == '+') - flags &= ~FLAG_PERMUTE; - if (*options == '+' || *options == '-') - options++; - - red_optarg = NULL; - if (red_optreset) - nonopt_start = nonopt_end = -1; -start: - if (red_optreset || !*place) { /* update scanning pointer */ - red_optreset = 0; - if (red_optind >= nargc) { /* end of argument vector */ - place = EMSG; - if (nonopt_end != -1) { - /* do permutation, if we have to */ - permute_args(nonopt_start, nonopt_end, - red_optind, nargv); - red_optind -= nonopt_end - nonopt_start; - } - else if (nonopt_start != -1) { - /* - * If we skipped non-options, set red_optind - * to the first of them. - */ - red_optind = nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - if (*(place = nargv[red_optind]) != '-' || place[1] == '\0') { - place = EMSG; /* found non-option */ - if (flags & FLAG_ALLARGS) { - /* - * GNU extension: - * return non-option as argument to option 1 - */ - red_optarg = nargv[red_optind++]; - return (INORDER); - } - if (!(flags & FLAG_PERMUTE)) { - /* - * If no permutation wanted, stop parsing - * at first non-option. - */ - return (-1); - } - /* do permutation */ - if (nonopt_start == -1) - nonopt_start = red_optind; - else if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - red_optind, nargv); - nonopt_start = red_optind - - (nonopt_end - nonopt_start); - nonopt_end = -1; - } - red_optind++; - /* process next argument */ - goto start; - } - if (nonopt_start != -1 && nonopt_end == -1) - nonopt_end = red_optind; - - /* - * If we have "-" do nothing, if "--" we are done. - */ - if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { - red_optind++; - place = EMSG; - /* - * We found an option (--), so if we skipped - * non-options, we have to permute. - */ - if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - red_optind, nargv); - red_optind -= nonopt_end - nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - } - - /* - * Check long options if: - * 1) we were passed some - * 2) the arg is not just "-" - * 3) either the arg starts with -- we are RedGetoptLongOnly() - */ - if (long_options != NULL && place != nargv[red_optind] && - (*place == '-' || (flags & FLAG_LONGONLY))) { - short_too = 0; - dash_prefix = D_PREFIX; - if (*place == '-') { - place++; /* --foo long option */ - dash_prefix = DD_PREFIX; - } else if (*place != ':' && strchr(options, *place) != NULL) - short_too = 1; /* could be short option too */ - - optchar = parse_long_options(nargv, options, long_options, - idx, short_too, flags); - if (optchar != -1) { - place = EMSG; - return (optchar); - } - } - - if ((optchar = (int)*place++) == (int)':' || - (optchar == (int)'-' && *place != '\0') || - (oli = strchr(options, optchar)) == NULL) { - /* - * If the user specified "-" and '-' isn't listed in - * options, return -1 (non-option) as per POSIX. - * Otherwise, it is an unknown option character (or ':'). - */ - if (optchar == (int)'-' && *place == '\0') - return (-1); - if (!*place) - ++red_optind; - if (PRINT_ERROR) - fprintf(stderr, gnuoptchar, optchar); - red_optopt = optchar; - return (BADCH); - } - if (long_options != NULL && optchar == 'W' && oli[1] == ';') { - /* -W long-option */ - if (*place) /* no space */ - /* NOTHING */; - else if (++red_optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - fprintf(stderr, recargchar, optchar); - red_optopt = optchar; - return (BADARG); - } else /* white space */ - place = nargv[red_optind]; - dash_prefix = W_PREFIX; - optchar = parse_long_options(nargv, options, long_options, - idx, 0, flags); - place = EMSG; - return (optchar); - } - if (*++oli != ':') { /* doesn't take argument */ - if (!*place) - ++red_optind; - } else { /* takes (optional) argument */ - red_optarg = NULL; - if (*place) /* no white space */ - red_optarg = place; - else if (oli[1] != ':') { /* arg not optional */ - if (++red_optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - fprintf(stderr, recargchar, optchar); - red_optopt = optchar; - return (BADARG); - } else - red_optarg = nargv[red_optind]; - } - place = EMSG; - ++red_optind; - } - /* dump back option letter */ - return (optchar); -} - - -/** @brief Get option character from command line argument list. - - For more details, consult the getopt() man pages, since this function is - generally similar. - - @param nargc Number of arguments (argc passed into main()). - @param nargv Argument vector (argv passed into main()). - @param options String of option characters. - - @return The next known option character in @p options. If a character not - found in @p options is found or if an option is missing an argument, - it returns '?'. Returns -1 when the argument list is exhausted. -*/ -int32_t RedGetopt( - int32_t nargc, - char * const *nargv, - const char *options) -{ - return getopt_internal(nargc, nargv, options, NULL, NULL, FLAG_PERMUTE); -} - - -/** @brief Get long options from command line argument list. - - For more details, consult the getopt_long() man pages, since this function - is generally similar. - - @param nargc Number of arguments (argc passed into main()). - @param nargv Argument vector (argv passed into main()). - @param options String of option characters. - @param long_options The long options; the last element of this array must be - filled with zeroes. - @param idx If non-NULL, then populated with the index of the long - option relative to @p long_options. - - @return If the flag field in REDOPTION is NULL, returns the value specified - in the val field, which is usually just the corresponding short - option. If flag is non-NULL, returns zero and stores val in the - location pointed to by flag. Returns ':' if an option was missing - its argument, '?' for an unknown option, and -1 when the argument - list is exhausted. -*/ -int32_t RedGetoptLong( - int32_t nargc, - char * const *nargv, - const char *options, - const REDOPTION *long_options, - int32_t *idx) -{ - return getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE); -} - +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** @file + * @brief Implementations of getopt() and getopt_long() work-alike functions. + * + * This code was taken from FreeBSD and slightly modified, mostly to rename + * symbols with external linkage to avoid naming conflicts in systems where + * there are real getopt()/getopt_long() implementations, and for portability. + */ +#include +#include +#include + +#include +#include +#include +#include + + +int32_t red_opterr = 1; /* if error message should be printed */ +int32_t red_optind = 1; /* index into parent argv vector */ +int32_t red_optopt = '?'; /* character checked for validity */ +int32_t red_optreset; /* reset RedGetopt */ +const char * red_optarg; /* argument associated with option */ + +#define PRINT_ERROR ( ( red_opterr ) && ( *options != ':' ) ) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as RedGetoptLongOnly */ + +/* return values */ +#define BADCH ( int ) '?' +#define BADARG ( ( *options == ':' ) ? ( int ) ':' : ( int ) '?' ) +#define INORDER ( int ) 1 + +#define EMSG "" + +#define NO_PREFIX ( -1 ) +#define D_PREFIX 0 +#define DD_PREFIX 1 +#define W_PREFIX 2 + +static int gcd( int a, + int b ); +static void permute_args( int panonopt_start, + int panonopt_end, + int opt_end, + char * const * nargv ); +static int parse_long_options( char * const * nargv, + const char * options, + const REDOPTION * long_options, + int32_t * idx, + int short_too, + int flags ); +static int getopt_internal( int nargc, + char * const * nargv, + const char * options, + const REDOPTION * long_options, + int32_t * idx, + int flags ); + +static const char * place = EMSG; /* option letter processing */ + +/* XXX: set red_optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c\n"; +static const char illoptchar[] = "illegal option -- %c\n"; /* From P1003.2 */ +static int dash_prefix = NO_PREFIX; +static const char gnuoptchar[] = "invalid option -- %c\n"; + +static const char recargstring[] = "option `%s%s' requires an argument\n"; +static const char ambig[] = "option `%s%s' is ambiguous\n"; +static const char noarg[] = "option `%s%s' doesn't allow an argument\n"; +static const char illoptstring[] = "unrecognized option `%s%s'\n"; + +/* + * Compute the greatest common divisor of a and b. + */ +static int gcd( int a, + int b ) +{ + int c; + + c = a % b; + + while( c != 0 ) + { + a = b; + b = c; + c = a % b; + } + + return( b ); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void permute_args( int panonopt_start, + int panonopt_end, + int opt_end, + char * const * nargv ) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char * swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd( nnonopts, nopts ); + cyclelen = ( opt_end - panonopt_start ) / ncycle; + + for( i = 0; i < ncycle; i++ ) + { + cstart = panonopt_end + i; + pos = cstart; + + for( j = 0; j < cyclelen; j++ ) + { + if( pos >= panonopt_end ) + { + pos -= nnonopts; + } + else + { + pos += nopts; + } + + swap = nargv[ pos ]; + ( ( char ** ) nargv )[ pos ] = nargv[ cstart ]; + ( ( char ** ) nargv )[ cstart ] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int parse_long_options( char * const * nargv, + const char * options, + const REDOPTION * long_options, + int32_t * idx, + int short_too, + int flags ) +{ + const char * current_argv, * has_equal, * current_dash; + size_t current_argv_len; + int i, match, exact_match, second_partial_match; + + current_argv = place; + + switch( dash_prefix ) + { + case D_PREFIX: + current_dash = "-"; + break; + + case DD_PREFIX: + current_dash = "--"; + break; + + case W_PREFIX: + current_dash = "-W "; + break; + + default: + current_dash = ""; + break; + } + + match = -1; + exact_match = 0; + second_partial_match = 0; + + red_optind++; + + if( ( has_equal = strchr( current_argv, '=' ) ) != NULL ) + { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } + else + { + current_argv_len = strlen( current_argv ); + } + + for( i = 0; long_options[ i ].name; i++ ) + { + /* find matching long option */ + if( strncmp( current_argv, long_options[ i ].name, + current_argv_len ) ) + { + continue; + } + + if( strlen( long_options[ i ].name ) == current_argv_len ) + { + /* exact match */ + match = i; + exact_match = 1; + break; + } + + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if( short_too && ( current_argv_len == 1 ) ) + { + continue; + } + + if( match == -1 ) /* first partial match */ + { + match = i; + } + else if( ( flags & FLAG_LONGONLY ) || + ( long_options[ i ].has_arg != + long_options[ match ].has_arg ) || + ( long_options[ i ].flag != long_options[ match ].flag ) || + ( long_options[ i ].val != long_options[ match ].val ) ) + { + second_partial_match = 1; + } + } + + if( !exact_match && second_partial_match ) + { + /* ambiguous abbreviation */ + if( PRINT_ERROR ) + { + fprintf( stderr, + ambig, + current_dash, + current_argv ); + } + + red_optopt = 0; + return( BADCH ); + } + + if( match != -1 ) /* option found */ + { + if( ( long_options[ match ].has_arg == red_no_argument ) && + has_equal ) + { + if( PRINT_ERROR ) + { + fprintf( stderr, + noarg, + current_dash, + current_argv ); + } + + /* + * XXX: GNU sets red_optopt to val regardless of flag + */ + if( long_options[ match ].flag == NULL ) + { + red_optopt = long_options[ match ].val; + } + else + { + red_optopt = 0; + } + + return( BADCH ); + } + + if( ( long_options[ match ].has_arg == red_required_argument ) || + ( long_options[ match ].has_arg == red_optional_argument ) ) + { + if( has_equal ) + { + red_optarg = has_equal; + } + else if( long_options[ match ].has_arg == + red_required_argument ) + { + /* + * optional argument doesn't use next nargv + */ + red_optarg = nargv[ red_optind++ ]; + } + } + + if( ( long_options[ match ].has_arg == red_required_argument ) && + ( red_optarg == NULL ) ) + { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if( PRINT_ERROR ) + { + fprintf( stderr, + recargstring, + current_dash, + current_argv ); + } + + /* + * XXX: GNU sets red_optopt to val regardless of flag + */ + if( long_options[ match ].flag == NULL ) + { + red_optopt = long_options[ match ].val; + } + else + { + red_optopt = 0; + } + + --red_optind; + return( BADARG ); + } + } + else /* unknown option */ + { + if( short_too ) + { + --red_optind; + return( -1 ); + } + + if( PRINT_ERROR ) + { + fprintf( stderr, + illoptstring, + current_dash, + current_argv ); + } + + red_optopt = 0; + return( BADCH ); + } + + if( idx ) + { + *idx = match; + } + + if( long_options[ match ].flag ) + { + *long_options[ match ].flag = long_options[ match ].val; + return( 0 ); + } + else + { + return( long_options[ match ].val ); + } +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int getopt_internal( int nargc, + char * const * nargv, + const char * options, + const REDOPTION * long_options, + int32_t * idx, + int flags ) +{ + char * oli; /* option letter list index */ + int optchar, short_too; + + if( options == NULL ) + { + return( -1 ); + } + + /* + * XXX Some GNU programs (like cvs) set red_optind to 0 instead of + * XXX using red_optreset. Work around this braindamage. + */ + if( red_optind == 0 ) + { + red_optind = red_optreset = 1; + } + + /* + * Disable GNU extensions if options string begins with a '+'. + */ + if( *options == '-' ) + { + flags |= FLAG_ALLARGS; + } + else if( *options == '+' ) + { + flags &= ~FLAG_PERMUTE; + } + + if( ( *options == '+' ) || ( *options == '-' ) ) + { + options++; + } + + red_optarg = NULL; + + if( red_optreset ) + { + nonopt_start = nonopt_end = -1; + } + +start: + + if( red_optreset || !*place ) /* update scanning pointer */ + { + red_optreset = 0; + + if( red_optind >= nargc ) /* end of argument vector */ + { + place = EMSG; + + if( nonopt_end != -1 ) + { + /* do permutation, if we have to */ + permute_args( nonopt_start, nonopt_end, + red_optind, nargv ); + red_optind -= nonopt_end - nonopt_start; + } + else if( nonopt_start != -1 ) + { + /* + * If we skipped non-options, set red_optind + * to the first of them. + */ + red_optind = nonopt_start; + } + + nonopt_start = nonopt_end = -1; + return( -1 ); + } + + if( ( *( place = nargv[ red_optind ] ) != '-' ) || ( place[ 1 ] == '\0' ) ) + { + place = EMSG; /* found non-option */ + + if( flags & FLAG_ALLARGS ) + { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + red_optarg = nargv[ red_optind++ ]; + return( INORDER ); + } + + if( !( flags & FLAG_PERMUTE ) ) + { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return( -1 ); + } + + /* do permutation */ + if( nonopt_start == -1 ) + { + nonopt_start = red_optind; + } + else if( nonopt_end != -1 ) + { + permute_args( nonopt_start, nonopt_end, + red_optind, nargv ); + nonopt_start = red_optind - + ( nonopt_end - nonopt_start ); + nonopt_end = -1; + } + + red_optind++; + /* process next argument */ + goto start; + } + + if( ( nonopt_start != -1 ) && ( nonopt_end == -1 ) ) + { + nonopt_end = red_optind; + } + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if( ( place[ 1 ] != '\0' ) && ( *++place == '-' ) && ( place[ 1 ] == '\0' ) ) + { + red_optind++; + place = EMSG; + + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if( nonopt_end != -1 ) + { + permute_args( nonopt_start, nonopt_end, + red_optind, nargv ); + red_optind -= nonopt_end - nonopt_start; + } + + nonopt_start = nonopt_end = -1; + return( -1 ); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are RedGetoptLongOnly() + */ + if( ( long_options != NULL ) && ( place != nargv[ red_optind ] ) && + ( ( *place == '-' ) || ( flags & FLAG_LONGONLY ) ) ) + { + short_too = 0; + dash_prefix = D_PREFIX; + + if( *place == '-' ) + { + place++; /* --foo long option */ + dash_prefix = DD_PREFIX; + } + else if( ( *place != ':' ) && ( strchr( options, *place ) != NULL ) ) + { + short_too = 1; /* could be short option too */ + } + + optchar = parse_long_options( nargv, options, long_options, + idx, short_too, flags ); + + if( optchar != -1 ) + { + place = EMSG; + return( optchar ); + } + } + + if( ( ( optchar = ( int ) *place++ ) == ( int ) ':' ) || + ( ( optchar == ( int ) '-' ) && ( *place != '\0' ) ) || + ( ( oli = strchr( options, optchar ) ) == NULL ) ) + { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if( ( optchar == ( int ) '-' ) && ( *place == '\0' ) ) + { + return( -1 ); + } + + if( !*place ) + { + ++red_optind; + } + + if( PRINT_ERROR ) + { + fprintf( stderr, gnuoptchar, optchar ); + } + + red_optopt = optchar; + return( BADCH ); + } + + if( ( long_options != NULL ) && ( optchar == 'W' ) && ( oli[ 1 ] == ';' ) ) + { + /* -W long-option */ + if( *place ) /* no space */ + { /* NOTHING */ + } + else if( ++red_optind >= nargc ) /* no arg */ + { + place = EMSG; + + if( PRINT_ERROR ) + { + fprintf( stderr, recargchar, optchar ); + } + + red_optopt = optchar; + return( BADARG ); + } + else /* white space */ + { + place = nargv[ red_optind ]; + } + + dash_prefix = W_PREFIX; + optchar = parse_long_options( nargv, options, long_options, + idx, 0, flags ); + place = EMSG; + return( optchar ); + } + + if( *++oli != ':' ) /* doesn't take argument */ + { + if( !*place ) + { + ++red_optind; + } + } + else /* takes (optional) argument */ + { + red_optarg = NULL; + + if( *place ) /* no white space */ + { + red_optarg = place; + } + else if( oli[ 1 ] != ':' ) /* arg not optional */ + { + if( ++red_optind >= nargc ) /* no arg */ + { + place = EMSG; + + if( PRINT_ERROR ) + { + fprintf( stderr, recargchar, optchar ); + } + + red_optopt = optchar; + return( BADARG ); + } + else + { + red_optarg = nargv[ red_optind ]; + } + } + + place = EMSG; + ++red_optind; + } + + /* dump back option letter */ + return( optchar ); +} + + +/** @brief Get option character from command line argument list. + * + * For more details, consult the getopt() man pages, since this function is + * generally similar. + * + * @param nargc Number of arguments (argc passed into main()). + * @param nargv Argument vector (argv passed into main()). + * @param options String of option characters. + * + * @return The next known option character in @p options. If a character not + * found in @p options is found or if an option is missing an argument, + * it returns '?'. Returns -1 when the argument list is exhausted. + */ +int32_t RedGetopt( int32_t nargc, + char * const * nargv, + const char * options ) +{ + return getopt_internal( nargc, nargv, options, NULL, NULL, FLAG_PERMUTE ); +} + + +/** @brief Get long options from command line argument list. + * + * For more details, consult the getopt_long() man pages, since this function + * is generally similar. + * + * @param nargc Number of arguments (argc passed into main()). + * @param nargv Argument vector (argv passed into main()). + * @param options String of option characters. + * @param long_options The long options; the last element of this array must be + * filled with zeroes. + * @param idx If non-NULL, then populated with the index of the long + * option relative to @p long_options. + * + * @return If the flag field in REDOPTION is NULL, returns the value specified + * in the val field, which is usually just the corresponding short + * option. If flag is non-NULL, returns zero and stores val in the + * location pointed to by flag. Returns ':' if an option was missing + * its argument, '?' for an unknown option, and -1 when the argument + * list is exhausted. + */ +int32_t RedGetoptLong( int32_t nargc, + char * const * nargv, + const char * options, + const REDOPTION * long_options, + int32_t * idx ) +{ + return getopt_internal( nargc, nargv, options, long_options, idx, FLAG_PERMUTE ); +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/toolcmn.c b/FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/toolcmn.c index 0ad2b64ca..cf51ccbad 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/toolcmn.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/toolcmn.c @@ -1,99 +1,102 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements common-code utilities for tools and tests. -*/ -#include -#include -#include -#include - -#include -#include -#include -#include - - -/** @brief Convert a string into a volume number. - - In a POSIX-like configuration, @p pszVolume can either be a volume number or - a volume path prefix. In case of ambiguity, the volume number of a matching - path prefix takes precedence. - - In an FSE configuration, @p pszVolume can be a volume number. - - @param pszVolume The volume string. - - @return On success, returns the volume number; on failure, returns - #REDCONF_VOLUME_COUNT. -*/ -uint8_t RedFindVolumeNumber( - const char *pszVolume) -{ - unsigned long ulNumber; - const char *pszEndPtr; - uint8_t bVolNum = REDCONF_VOLUME_COUNT; - #if REDCONF_API_POSIX == 1 - uint8_t bIndex; - #endif - - /* Determine if pszVolume can be interpreted as a volume number. - */ - errno = 0; - ulNumber = strtoul(pszVolume, (char **)&pszEndPtr, 10); - if((errno == 0) && (ulNumber != ULONG_MAX) && (pszEndPtr[0U] == '\0') && (ulNumber < REDCONF_VOLUME_COUNT)) - { - bVolNum = (uint8_t)ulNumber; - } - - #if REDCONF_API_POSIX == 1 - /* Determine if pszVolume is a valid path prefix. - */ - for(bIndex = 0U; bIndex < REDCONF_VOLUME_COUNT; bIndex++) - { - if(strcmp(gaRedVolConf[bIndex].pszPathPrefix, pszVolume) == 0) - { - break; - } - } - - if(bIndex < REDCONF_VOLUME_COUNT) - { - /* Edge case: It is technically possible for pszVolume to be both a - valid volume number and a valid volume prefix, for different - volumes. For example, if pszVolume is "2", that would be recognized - as volume number 2 above. But if "2" is the (poorly chosen) path - prefix for volume number 4, that would also be matched. Since the - POSIX-like API is primarily name based, and the ability to use - volume numbers with this tool is just a convenience, the volume - prefix takes precedence. - */ - bVolNum = bIndex; - } - #endif - - return bVolNum; -} - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements common-code utilities for tools and tests. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + + +/** @brief Convert a string into a volume number. + * + * In a POSIX-like configuration, @p pszVolume can either be a volume number or + * a volume path prefix. In case of ambiguity, the volume number of a matching + * path prefix takes precedence. + * + * In an FSE configuration, @p pszVolume can be a volume number. + * + * @param pszVolume The volume string. + * + * @return On success, returns the volume number; on failure, returns + #REDCONF_VOLUME_COUNT. + */ +uint8_t RedFindVolumeNumber( const char * pszVolume ) +{ + unsigned long ulNumber; + const char * pszEndPtr; + uint8_t bVolNum = REDCONF_VOLUME_COUNT; + + #if REDCONF_API_POSIX == 1 + uint8_t bIndex; + #endif + + /* Determine if pszVolume can be interpreted as a volume number. + */ + errno = 0; + ulNumber = strtoul( pszVolume, ( char ** ) &pszEndPtr, 10 ); + + if( ( errno == 0 ) && ( ulNumber != ULONG_MAX ) && ( pszEndPtr[ 0U ] == '\0' ) && ( ulNumber < REDCONF_VOLUME_COUNT ) ) + { + bVolNum = ( uint8_t ) ulNumber; + } + + #if REDCONF_API_POSIX == 1 + + /* Determine if pszVolume is a valid path prefix. + */ + for( bIndex = 0U; bIndex < REDCONF_VOLUME_COUNT; bIndex++ ) + { + if( strcmp( gaRedVolConf[ bIndex ].pszPathPrefix, pszVolume ) == 0 ) + { + break; + } + } + + if( bIndex < REDCONF_VOLUME_COUNT ) + { + /* Edge case: It is technically possible for pszVolume to be both a + * valid volume number and a valid volume prefix, for different + * volumes. For example, if pszVolume is "2", that would be recognized + * as volume number 2 above. But if "2" is the (poorly chosen) path + * prefix for volume number 4, that would also be matched. Since the + * POSIX-like API is primarily name based, and the ability to use + * volume numbers with this tool is just a convenience, the volume + * prefix takes precedence. + */ + bVolNum = bIndex; + } + #endif /* if REDCONF_API_POSIX == 1 */ + + return bVolNum; +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/util/bitmap.c b/FreeRTOS-Plus/Source/Reliance-Edge/util/bitmap.c index c09d3c975..e2f72cb12 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/util/bitmap.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/util/bitmap.c @@ -1,101 +1,99 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements utilities for working with bitmaps. -*/ -#include - - -/** @brief Query the state of a bit in a bitmap. - - Bits are counted from most significant to least significant. Thus, the mask - for bit zero is 0x80 applied to the first byte in the bitmap. - - @param pbBitmap Pointer to the bitmap. - @param ulBit The bit to query. - - @retval Whether the bit is set (true) or clear (false. -*/ -bool RedBitGet( - const uint8_t *pbBitmap, - uint32_t ulBit) -{ - bool fRet; - - if(pbBitmap == NULL) - { - REDERROR(); - fRet = false; - } - else - { - fRet = (pbBitmap[ulBit >> 3U] & (0x80U >> (ulBit & 7U))) != 0U; - } - - return fRet; -} - - -/** @brief Set a bit in a bitmap to one. - - Bits are counted from most significant to least significant. Thus, the mask - for bit zero is 0x80 applied to the first byte in the bitmap. - - @param pbBitmap Pointer to the bitmap. - @param ulBit The bit to set. -*/ -void RedBitSet( - uint8_t *pbBitmap, - uint32_t ulBit) -{ - REDASSERT(pbBitmap != NULL); - - if(pbBitmap != NULL) - { - pbBitmap[ulBit >> 3U] |= (0x80U >> (ulBit & 7U)); - } -} - - -/** @brief Clear a bit in a bitmap to zero. - - Bits are counted from most significant to least significant. Thus, the mask - for bit zero is 0x80 applied to the first byte in the bitmap. - - @param pbBitmap Pointer to the bitmap. - @param ulBit The bit to clear. -*/ -void RedBitClear( - uint8_t *pbBitmap, - uint32_t ulBit) -{ - REDASSERT(pbBitmap != NULL); - - if(pbBitmap != NULL) - { - pbBitmap[ulBit >> 3U] &= ~(0x80U >> (ulBit & 7U)); - } -} - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements utilities for working with bitmaps. + */ +#include + + +/** @brief Query the state of a bit in a bitmap. + * + * Bits are counted from most significant to least significant. Thus, the mask + * for bit zero is 0x80 applied to the first byte in the bitmap. + * + * @param pbBitmap Pointer to the bitmap. + * @param ulBit The bit to query. + * + * @retval Whether the bit is set (true) or clear (false. + */ +bool RedBitGet( const uint8_t * pbBitmap, + uint32_t ulBit ) +{ + bool fRet; + + if( pbBitmap == NULL ) + { + REDERROR(); + fRet = false; + } + else + { + fRet = ( pbBitmap[ ulBit >> 3U ] & ( 0x80U >> ( ulBit & 7U ) ) ) != 0U; + } + + return fRet; +} + + +/** @brief Set a bit in a bitmap to one. + * + * Bits are counted from most significant to least significant. Thus, the mask + * for bit zero is 0x80 applied to the first byte in the bitmap. + * + * @param pbBitmap Pointer to the bitmap. + * @param ulBit The bit to set. + */ +void RedBitSet( uint8_t * pbBitmap, + uint32_t ulBit ) +{ + REDASSERT( pbBitmap != NULL ); + + if( pbBitmap != NULL ) + { + pbBitmap[ ulBit >> 3U ] |= ( 0x80U >> ( ulBit & 7U ) ); + } +} + + +/** @brief Clear a bit in a bitmap to zero. + * + * Bits are counted from most significant to least significant. Thus, the mask + * for bit zero is 0x80 applied to the first byte in the bitmap. + * + * @param pbBitmap Pointer to the bitmap. + * @param ulBit The bit to clear. + */ +void RedBitClear( uint8_t * pbBitmap, + uint32_t ulBit ) +{ + REDASSERT( pbBitmap != NULL ); + + if( pbBitmap != NULL ) + { + pbBitmap[ ulBit >> 3U ] &= ~( 0x80U >> ( ulBit & 7U ) ); + } +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/util/crc.c b/FreeRTOS-Plus/Source/Reliance-Edge/util/crc.c index 7ed15cbb4..3f8079abe 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/util/crc.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/util/crc.c @@ -1,598 +1,595 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements utilities for calculating CRC-32 checksums. -*/ -#include - - -/* The CRC functions do not return errors since the only detectable error - condition is a NULL buffer pointer. If such a condition does arise, the - functions assert and return the below CRC, which, although a legal CRC, - is nonetheless suspicious and could provide a clue that something has - gone wrong. -*/ -#define SUSPICIOUS_CRC_VALUE (0xBAADC0DEU) - -#define CRC_BITWISE (0U) -#define CRC_SARWATE (1U) -#define CRC_SLICEBY8 (2U) - - -#if REDCONF_CRC_ALGORITHM == CRC_BITWISE - -/* The following is representative of the polynomial accepted by CCITT 32-bit - and in IEEE 802.3, Ethernet 2 specification. - - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 - (reverse order) - 1110 1101 1011 1000 1000 0011 0010 0000 1 - (E) (D) (B) (8) (8) (3) (2) (0) -*/ -#define CCITT_32_POLYNOMIAL (0xEDB88320U) - - -/** @brief Compute a CRC32 for the given data buffer. - - For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple - buffers, call this function with the previously returned CRC value. - - @param ulInitCrc32 Starting CRC value. - @param pBuffer Data buffer to calculate the CRC from. - @param ulLength Number of bytes of data in the given buffer. - - @return The updated CRC value. -*/ -uint32_t RedCrc32Update( - uint32_t ulInitCrc32, - const void *pBuffer, - uint32_t ulLength) -{ - uint32_t ulCrc32; - - if(pBuffer == NULL) - { - REDERROR(); - ulCrc32 = SUSPICIOUS_CRC_VALUE; - } - else - { - const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); - uint32_t ulIdx; - - ulCrc32 = ~ulInitCrc32; - - for(ulIdx = 0U; ulIdx < ulLength; ++ulIdx) - { - uint32_t ulBit; - - ulCrc32 ^= pbBuffer[ulIdx]; - - /* Branchless inner loop (greatly improves performance). - */ - for(ulBit = 0U; ulBit < 8U; ulBit++) - { - ulCrc32 = ((ulCrc32 & 1U) * CCITT_32_POLYNOMIAL) ^ (ulCrc32 >> 1U); - } - } - - ulCrc32 = ~ulCrc32; - } - - return ulCrc32; -} - -#elif REDCONF_CRC_ALGORITHM == CRC_SARWATE - -/** @brief Compute a CRC32 for the given data buffer. - - For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple - buffers, call this function with the previously returned CRC value. - - @param ulInitCrc32 Starting CRC value. - @param pBuffer Data buffer to calculate the CRC from. - @param ulLength Number of bytes of data in the given buffer. - - @return The updated CRC value. -*/ -uint32_t RedCrc32Update( - uint32_t ulInitCrc32, - const void *pBuffer, - uint32_t ulLength) -{ - static const uint32_t aulCrc32Table[] = - { - 0x00000000U, 0x77073096U, 0xEE0E612CU, 0x990951BAU, 0x076DC419U, 0x706AF48FU, 0xE963A535U, 0x9E6495A3U, - 0x0EDB8832U, 0x79DCB8A4U, 0xE0D5E91EU, 0x97D2D988U, 0x09B64C2BU, 0x7EB17CBDU, 0xE7B82D07U, 0x90BF1D91U, - 0x1DB71064U, 0x6AB020F2U, 0xF3B97148U, 0x84BE41DEU, 0x1ADAD47DU, 0x6DDDE4EBU, 0xF4D4B551U, 0x83D385C7U, - 0x136C9856U, 0x646BA8C0U, 0xFD62F97AU, 0x8A65C9ECU, 0x14015C4FU, 0x63066CD9U, 0xFA0F3D63U, 0x8D080DF5U, - 0x3B6E20C8U, 0x4C69105EU, 0xD56041E4U, 0xA2677172U, 0x3C03E4D1U, 0x4B04D447U, 0xD20D85FDU, 0xA50AB56BU, - 0x35B5A8FAU, 0x42B2986CU, 0xDBBBC9D6U, 0xACBCF940U, 0x32D86CE3U, 0x45DF5C75U, 0xDCD60DCFU, 0xABD13D59U, - 0x26D930ACU, 0x51DE003AU, 0xC8D75180U, 0xBFD06116U, 0x21B4F4B5U, 0x56B3C423U, 0xCFBA9599U, 0xB8BDA50FU, - 0x2802B89EU, 0x5F058808U, 0xC60CD9B2U, 0xB10BE924U, 0x2F6F7C87U, 0x58684C11U, 0xC1611DABU, 0xB6662D3DU, - 0x76DC4190U, 0x01DB7106U, 0x98D220BCU, 0xEFD5102AU, 0x71B18589U, 0x06B6B51FU, 0x9FBFE4A5U, 0xE8B8D433U, - 0x7807C9A2U, 0x0F00F934U, 0x9609A88EU, 0xE10E9818U, 0x7F6A0DBBU, 0x086D3D2DU, 0x91646C97U, 0xE6635C01U, - 0x6B6B51F4U, 0x1C6C6162U, 0x856530D8U, 0xF262004EU, 0x6C0695EDU, 0x1B01A57BU, 0x8208F4C1U, 0xF50FC457U, - 0x65B0D9C6U, 0x12B7E950U, 0x8BBEB8EAU, 0xFCB9887CU, 0x62DD1DDFU, 0x15DA2D49U, 0x8CD37CF3U, 0xFBD44C65U, - 0x4DB26158U, 0x3AB551CEU, 0xA3BC0074U, 0xD4BB30E2U, 0x4ADFA541U, 0x3DD895D7U, 0xA4D1C46DU, 0xD3D6F4FBU, - 0x4369E96AU, 0x346ED9FCU, 0xAD678846U, 0xDA60B8D0U, 0x44042D73U, 0x33031DE5U, 0xAA0A4C5FU, 0xDD0D7CC9U, - 0x5005713CU, 0x270241AAU, 0xBE0B1010U, 0xC90C2086U, 0x5768B525U, 0x206F85B3U, 0xB966D409U, 0xCE61E49FU, - 0x5EDEF90EU, 0x29D9C998U, 0xB0D09822U, 0xC7D7A8B4U, 0x59B33D17U, 0x2EB40D81U, 0xB7BD5C3BU, 0xC0BA6CADU, - 0xEDB88320U, 0x9ABFB3B6U, 0x03B6E20CU, 0x74B1D29AU, 0xEAD54739U, 0x9DD277AFU, 0x04DB2615U, 0x73DC1683U, - 0xE3630B12U, 0x94643B84U, 0x0D6D6A3EU, 0x7A6A5AA8U, 0xE40ECF0BU, 0x9309FF9DU, 0x0A00AE27U, 0x7D079EB1U, - 0xF00F9344U, 0x8708A3D2U, 0x1E01F268U, 0x6906C2FEU, 0xF762575DU, 0x806567CBU, 0x196C3671U, 0x6E6B06E7U, - 0xFED41B76U, 0x89D32BE0U, 0x10DA7A5AU, 0x67DD4ACCU, 0xF9B9DF6FU, 0x8EBEEFF9U, 0x17B7BE43U, 0x60B08ED5U, - 0xD6D6A3E8U, 0xA1D1937EU, 0x38D8C2C4U, 0x4FDFF252U, 0xD1BB67F1U, 0xA6BC5767U, 0x3FB506DDU, 0x48B2364BU, - 0xD80D2BDAU, 0xAF0A1B4CU, 0x36034AF6U, 0x41047A60U, 0xDF60EFC3U, 0xA867DF55U, 0x316E8EEFU, 0x4669BE79U, - 0xCB61B38CU, 0xBC66831AU, 0x256FD2A0U, 0x5268E236U, 0xCC0C7795U, 0xBB0B4703U, 0x220216B9U, 0x5505262FU, - 0xC5BA3BBEU, 0xB2BD0B28U, 0x2BB45A92U, 0x5CB36A04U, 0xC2D7FFA7U, 0xB5D0CF31U, 0x2CD99E8BU, 0x5BDEAE1DU, - 0x9B64C2B0U, 0xEC63F226U, 0x756AA39CU, 0x026D930AU, 0x9C0906A9U, 0xEB0E363FU, 0x72076785U, 0x05005713U, - 0x95BF4A82U, 0xE2B87A14U, 0x7BB12BAEU, 0x0CB61B38U, 0x92D28E9BU, 0xE5D5BE0DU, 0x7CDCEFB7U, 0x0BDBDF21U, - 0x86D3D2D4U, 0xF1D4E242U, 0x68DDB3F8U, 0x1FDA836EU, 0x81BE16CDU, 0xF6B9265BU, 0x6FB077E1U, 0x18B74777U, - 0x88085AE6U, 0xFF0F6A70U, 0x66063BCAU, 0x11010B5CU, 0x8F659EFFU, 0xF862AE69U, 0x616BFFD3U, 0x166CCF45U, - 0xA00AE278U, 0xD70DD2EEU, 0x4E048354U, 0x3903B3C2U, 0xA7672661U, 0xD06016F7U, 0x4969474DU, 0x3E6E77DBU, - 0xAED16A4AU, 0xD9D65ADCU, 0x40DF0B66U, 0x37D83BF0U, 0xA9BCAE53U, 0xDEBB9EC5U, 0x47B2CF7FU, 0x30B5FFE9U, - 0xBDBDF21CU, 0xCABAC28AU, 0x53B39330U, 0x24B4A3A6U, 0xBAD03605U, 0xCDD70693U, 0x54DE5729U, 0x23D967BFU, - 0xB3667A2EU, 0xC4614AB8U, 0x5D681B02U, 0x2A6F2B94U, 0xB40BBE37U, 0xC30C8EA1U, 0x5A05DF1BU, 0x2D02EF8DU, - }; - - uint32_t ulCrc32; - - if(pBuffer == NULL) - { - REDERROR(); - ulCrc32 = SUSPICIOUS_CRC_VALUE; - } - else - { - const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); - uint32_t ulIdx; - - ulCrc32 = ~ulInitCrc32; - - for(ulIdx = 0U; ulIdx < ulLength; ++ulIdx) - { - ulCrc32 = (ulCrc32 >> 8U) ^ aulCrc32Table[(ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU]; - } - - ulCrc32 = ~ulCrc32; - } - - return ulCrc32; -} - -#elif REDCONF_CRC_ALGORITHM == CRC_SLICEBY8 - - -/** @brief Compute a CRC32 for the given data buffer. - - For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple - buffers, call this function with the previously returned CRC value. - - @param ulInitCrc32 Starting CRC value. - @param pBuffer Data buffer to calculate the CRC from. - @param ulLength Number of bytes of data in the given buffer. - - @return The updated CRC value. -*/ -uint32_t RedCrc32Update( - uint32_t ulInitCrc32, - const void *pBuffer, - uint32_t ulLength) -{ - /* CRC32 XOR table, with slicing-by-8 extensions. - - This first column of the table contains the same XOR values as used in - the classic byte-at-a-time Sarwate algorithm. The other seven columns - are derived from the first, and are used in Intel's slicing-by-eight CRC - algorithm. - - The layout of this array in memory is novel and deserves explanation. - In other implementations, including Intel's example, each of the below - columns is an array. The first column is a 256-entry array, followed by - another 256-entry array for the second column, etc. Testing on both ARM - and x86 has shown the below mixed arrangement to be about 5-9% faster. - One possible explanation: With the array-per-table approach, each of the - eight table lookups is guaranteed to be in a separate 1 KB chunk of - memory. With the below array, sometimes multiple table lookups will, by - coincidence, be close together, making better use of the cache. - */ - static const uint32_t aulCrc32Table[] = - { - 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, - 0x77073096U, 0x191B3141U, 0x01C26A37U, 0xB8BC6765U, 0x3D6029B0U, 0xCB5CD3A5U, 0xA6770BB4U, 0xCCAA009EU, - 0xEE0E612CU, 0x32366282U, 0x0384D46EU, 0xAA09C88BU, 0x7AC05360U, 0x4DC8A10BU, 0x979F1129U, 0x4225077DU, - 0x990951BAU, 0x2B2D53C3U, 0x0246BE59U, 0x12B5AFEEU, 0x47A07AD0U, 0x869472AEU, 0x31E81A9DU, 0x8E8F07E3U, - 0x076DC419U, 0x646CC504U, 0x0709A8DCU, 0x8F629757U, 0xF580A6C0U, 0x9B914216U, 0xF44F2413U, 0x844A0EFAU, - 0x706AF48FU, 0x7D77F445U, 0x06CBC2EBU, 0x37DEF032U, 0xC8E08F70U, 0x50CD91B3U, 0x52382FA7U, 0x48E00E64U, - 0xE963A535U, 0x565AA786U, 0x048D7CB2U, 0x256B5FDCU, 0x8F40F5A0U, 0xD659E31DU, 0x63D0353AU, 0xC66F0987U, - 0x9E6495A3U, 0x4F4196C7U, 0x054F1685U, 0x9DD738B9U, 0xB220DC10U, 0x1D0530B8U, 0xC5A73E8EU, 0x0AC50919U, - 0x0EDB8832U, 0xC8D98A08U, 0x0E1351B8U, 0xC5B428EFU, 0x30704BC1U, 0xEC53826DU, 0x33EF4E67U, 0xD3E51BB5U, - 0x79DCB8A4U, 0xD1C2BB49U, 0x0FD13B8FU, 0x7D084F8AU, 0x0D106271U, 0x270F51C8U, 0x959845D3U, 0x1F4F1B2BU, - 0xE0D5E91EU, 0xFAEFE88AU, 0x0D9785D6U, 0x6FBDE064U, 0x4AB018A1U, 0xA19B2366U, 0xA4705F4EU, 0x91C01CC8U, - 0x97D2D988U, 0xE3F4D9CBU, 0x0C55EFE1U, 0xD7018701U, 0x77D03111U, 0x6AC7F0C3U, 0x020754FAU, 0x5D6A1C56U, - 0x09B64C2BU, 0xACB54F0CU, 0x091AF964U, 0x4AD6BFB8U, 0xC5F0ED01U, 0x77C2C07BU, 0xC7A06A74U, 0x57AF154FU, - 0x7EB17CBDU, 0xB5AE7E4DU, 0x08D89353U, 0xF26AD8DDU, 0xF890C4B1U, 0xBC9E13DEU, 0x61D761C0U, 0x9B0515D1U, - 0xE7B82D07U, 0x9E832D8EU, 0x0A9E2D0AU, 0xE0DF7733U, 0xBF30BE61U, 0x3A0A6170U, 0x503F7B5DU, 0x158A1232U, - 0x90BF1D91U, 0x87981CCFU, 0x0B5C473DU, 0x58631056U, 0x825097D1U, 0xF156B2D5U, 0xF64870E9U, 0xD92012ACU, - 0x1DB71064U, 0x4AC21251U, 0x1C26A370U, 0x5019579FU, 0x60E09782U, 0x03D6029BU, 0x67DE9CCEU, 0x7CBB312BU, - 0x6AB020F2U, 0x53D92310U, 0x1DE4C947U, 0xE8A530FAU, 0x5D80BE32U, 0xC88AD13EU, 0xC1A9977AU, 0xB01131B5U, - 0xF3B97148U, 0x78F470D3U, 0x1FA2771EU, 0xFA109F14U, 0x1A20C4E2U, 0x4E1EA390U, 0xF0418DE7U, 0x3E9E3656U, - 0x84BE41DEU, 0x61EF4192U, 0x1E601D29U, 0x42ACF871U, 0x2740ED52U, 0x85427035U, 0x56368653U, 0xF23436C8U, - 0x1ADAD47DU, 0x2EAED755U, 0x1B2F0BACU, 0xDF7BC0C8U, 0x95603142U, 0x9847408DU, 0x9391B8DDU, 0xF8F13FD1U, - 0x6DDDE4EBU, 0x37B5E614U, 0x1AED619BU, 0x67C7A7ADU, 0xA80018F2U, 0x531B9328U, 0x35E6B369U, 0x345B3F4FU, - 0xF4D4B551U, 0x1C98B5D7U, 0x18ABDFC2U, 0x75720843U, 0xEFA06222U, 0xD58FE186U, 0x040EA9F4U, 0xBAD438ACU, - 0x83D385C7U, 0x05838496U, 0x1969B5F5U, 0xCDCE6F26U, 0xD2C04B92U, 0x1ED33223U, 0xA279A240U, 0x767E3832U, - 0x136C9856U, 0x821B9859U, 0x1235F2C8U, 0x95AD7F70U, 0x5090DC43U, 0xEF8580F6U, 0x5431D2A9U, 0xAF5E2A9EU, - 0x646BA8C0U, 0x9B00A918U, 0x13F798FFU, 0x2D111815U, 0x6DF0F5F3U, 0x24D95353U, 0xF246D91DU, 0x63F42A00U, - 0xFD62F97AU, 0xB02DFADBU, 0x11B126A6U, 0x3FA4B7FBU, 0x2A508F23U, 0xA24D21FDU, 0xC3AEC380U, 0xED7B2DE3U, - 0x8A65C9ECU, 0xA936CB9AU, 0x10734C91U, 0x8718D09EU, 0x1730A693U, 0x6911F258U, 0x65D9C834U, 0x21D12D7DU, - 0x14015C4FU, 0xE6775D5DU, 0x153C5A14U, 0x1ACFE827U, 0xA5107A83U, 0x7414C2E0U, 0xA07EF6BAU, 0x2B142464U, - 0x63066CD9U, 0xFF6C6C1CU, 0x14FE3023U, 0xA2738F42U, 0x98705333U, 0xBF481145U, 0x0609FD0EU, 0xE7BE24FAU, - 0xFA0F3D63U, 0xD4413FDFU, 0x16B88E7AU, 0xB0C620ACU, 0xDFD029E3U, 0x39DC63EBU, 0x37E1E793U, 0x69312319U, - 0x8D080DF5U, 0xCD5A0E9EU, 0x177AE44DU, 0x087A47C9U, 0xE2B00053U, 0xF280B04EU, 0x9196EC27U, 0xA59B2387U, - 0x3B6E20C8U, 0x958424A2U, 0x384D46E0U, 0xA032AF3EU, 0xC1C12F04U, 0x07AC0536U, 0xCFBD399CU, 0xF9766256U, - 0x4C69105EU, 0x8C9F15E3U, 0x398F2CD7U, 0x188EC85BU, 0xFCA106B4U, 0xCCF0D693U, 0x69CA3228U, 0x35DC62C8U, - 0xD56041E4U, 0xA7B24620U, 0x3BC9928EU, 0x0A3B67B5U, 0xBB017C64U, 0x4A64A43DU, 0x582228B5U, 0xBB53652BU, - 0xA2677172U, 0xBEA97761U, 0x3A0BF8B9U, 0xB28700D0U, 0x866155D4U, 0x81387798U, 0xFE552301U, 0x77F965B5U, - 0x3C03E4D1U, 0xF1E8E1A6U, 0x3F44EE3CU, 0x2F503869U, 0x344189C4U, 0x9C3D4720U, 0x3BF21D8FU, 0x7D3C6CACU, - 0x4B04D447U, 0xE8F3D0E7U, 0x3E86840BU, 0x97EC5F0CU, 0x0921A074U, 0x57619485U, 0x9D85163BU, 0xB1966C32U, - 0xD20D85FDU, 0xC3DE8324U, 0x3CC03A52U, 0x8559F0E2U, 0x4E81DAA4U, 0xD1F5E62BU, 0xAC6D0CA6U, 0x3F196BD1U, - 0xA50AB56BU, 0xDAC5B265U, 0x3D025065U, 0x3DE59787U, 0x73E1F314U, 0x1AA9358EU, 0x0A1A0712U, 0xF3B36B4FU, - 0x35B5A8FAU, 0x5D5DAEAAU, 0x365E1758U, 0x658687D1U, 0xF1B164C5U, 0xEBFF875BU, 0xFC5277FBU, 0x2A9379E3U, - 0x42B2986CU, 0x44469FEBU, 0x379C7D6FU, 0xDD3AE0B4U, 0xCCD14D75U, 0x20A354FEU, 0x5A257C4FU, 0xE639797DU, - 0xDBBBC9D6U, 0x6F6BCC28U, 0x35DAC336U, 0xCF8F4F5AU, 0x8B7137A5U, 0xA6372650U, 0x6BCD66D2U, 0x68B67E9EU, - 0xACBCF940U, 0x7670FD69U, 0x3418A901U, 0x7733283FU, 0xB6111E15U, 0x6D6BF5F5U, 0xCDBA6D66U, 0xA41C7E00U, - 0x32D86CE3U, 0x39316BAEU, 0x3157BF84U, 0xEAE41086U, 0x0431C205U, 0x706EC54DU, 0x081D53E8U, 0xAED97719U, - 0x45DF5C75U, 0x202A5AEFU, 0x3095D5B3U, 0x525877E3U, 0x3951EBB5U, 0xBB3216E8U, 0xAE6A585CU, 0x62737787U, - 0xDCD60DCFU, 0x0B07092CU, 0x32D36BEAU, 0x40EDD80DU, 0x7EF19165U, 0x3DA66446U, 0x9F8242C1U, 0xECFC7064U, - 0xABD13D59U, 0x121C386DU, 0x331101DDU, 0xF851BF68U, 0x4391B8D5U, 0xF6FAB7E3U, 0x39F54975U, 0x205670FAU, - 0x26D930ACU, 0xDF4636F3U, 0x246BE590U, 0xF02BF8A1U, 0xA121B886U, 0x047A07ADU, 0xA863A552U, 0x85CD537DU, - 0x51DE003AU, 0xC65D07B2U, 0x25A98FA7U, 0x48979FC4U, 0x9C419136U, 0xCF26D408U, 0x0E14AEE6U, 0x496753E3U, - 0xC8D75180U, 0xED705471U, 0x27EF31FEU, 0x5A22302AU, 0xDBE1EBE6U, 0x49B2A6A6U, 0x3FFCB47BU, 0xC7E85400U, - 0xBFD06116U, 0xF46B6530U, 0x262D5BC9U, 0xE29E574FU, 0xE681C256U, 0x82EE7503U, 0x998BBFCFU, 0x0B42549EU, - 0x21B4F4B5U, 0xBB2AF3F7U, 0x23624D4CU, 0x7F496FF6U, 0x54A11E46U, 0x9FEB45BBU, 0x5C2C8141U, 0x01875D87U, - 0x56B3C423U, 0xA231C2B6U, 0x22A0277BU, 0xC7F50893U, 0x69C137F6U, 0x54B7961EU, 0xFA5B8AF5U, 0xCD2D5D19U, - 0xCFBA9599U, 0x891C9175U, 0x20E69922U, 0xD540A77DU, 0x2E614D26U, 0xD223E4B0U, 0xCBB39068U, 0x43A25AFAU, - 0xB8BDA50FU, 0x9007A034U, 0x2124F315U, 0x6DFCC018U, 0x13016496U, 0x197F3715U, 0x6DC49BDCU, 0x8F085A64U, - 0x2802B89EU, 0x179FBCFBU, 0x2A78B428U, 0x359FD04EU, 0x9151F347U, 0xE82985C0U, 0x9B8CEB35U, 0x562848C8U, - 0x5F058808U, 0x0E848DBAU, 0x2BBADE1FU, 0x8D23B72BU, 0xAC31DAF7U, 0x23755665U, 0x3DFBE081U, 0x9A824856U, - 0xC60CD9B2U, 0x25A9DE79U, 0x29FC6046U, 0x9F9618C5U, 0xEB91A027U, 0xA5E124CBU, 0x0C13FA1CU, 0x140D4FB5U, - 0xB10BE924U, 0x3CB2EF38U, 0x283E0A71U, 0x272A7FA0U, 0xD6F18997U, 0x6EBDF76EU, 0xAA64F1A8U, 0xD8A74F2BU, - 0x2F6F7C87U, 0x73F379FFU, 0x2D711CF4U, 0xBAFD4719U, 0x64D15587U, 0x73B8C7D6U, 0x6FC3CF26U, 0xD2624632U, - 0x58684C11U, 0x6AE848BEU, 0x2CB376C3U, 0x0241207CU, 0x59B17C37U, 0xB8E41473U, 0xC9B4C492U, 0x1EC846ACU, - 0xC1611DABU, 0x41C51B7DU, 0x2EF5C89AU, 0x10F48F92U, 0x1E1106E7U, 0x3E7066DDU, 0xF85CDE0FU, 0x9047414FU, - 0xB6662D3DU, 0x58DE2A3CU, 0x2F37A2ADU, 0xA848E8F7U, 0x23712F57U, 0xF52CB578U, 0x5E2BD5BBU, 0x5CED41D1U, - 0x76DC4190U, 0xF0794F05U, 0x709A8DC0U, 0x9B14583DU, 0x58F35849U, 0x0F580A6CU, 0x440B7579U, 0x299DC2EDU, - 0x01DB7106U, 0xE9627E44U, 0x7158E7F7U, 0x23A83F58U, 0x659371F9U, 0xC404D9C9U, 0xE27C7ECDU, 0xE537C273U, - 0x98D220BCU, 0xC24F2D87U, 0x731E59AEU, 0x311D90B6U, 0x22330B29U, 0x4290AB67U, 0xD3946450U, 0x6BB8C590U, - 0xEFD5102AU, 0xDB541CC6U, 0x72DC3399U, 0x89A1F7D3U, 0x1F532299U, 0x89CC78C2U, 0x75E36FE4U, 0xA712C50EU, - 0x71B18589U, 0x94158A01U, 0x7793251CU, 0x1476CF6AU, 0xAD73FE89U, 0x94C9487AU, 0xB044516AU, 0xADD7CC17U, - 0x06B6B51FU, 0x8D0EBB40U, 0x76514F2BU, 0xACCAA80FU, 0x9013D739U, 0x5F959BDFU, 0x16335ADEU, 0x617DCC89U, - 0x9FBFE4A5U, 0xA623E883U, 0x7417F172U, 0xBE7F07E1U, 0xD7B3ADE9U, 0xD901E971U, 0x27DB4043U, 0xEFF2CB6AU, - 0xE8B8D433U, 0xBF38D9C2U, 0x75D59B45U, 0x06C36084U, 0xEAD38459U, 0x125D3AD4U, 0x81AC4BF7U, 0x2358CBF4U, - 0x7807C9A2U, 0x38A0C50DU, 0x7E89DC78U, 0x5EA070D2U, 0x68831388U, 0xE30B8801U, 0x77E43B1EU, 0xFA78D958U, - 0x0F00F934U, 0x21BBF44CU, 0x7F4BB64FU, 0xE61C17B7U, 0x55E33A38U, 0x28575BA4U, 0xD19330AAU, 0x36D2D9C6U, - 0x9609A88EU, 0x0A96A78FU, 0x7D0D0816U, 0xF4A9B859U, 0x124340E8U, 0xAEC3290AU, 0xE07B2A37U, 0xB85DDE25U, - 0xE10E9818U, 0x138D96CEU, 0x7CCF6221U, 0x4C15DF3CU, 0x2F236958U, 0x659FFAAFU, 0x460C2183U, 0x74F7DEBBU, - 0x7F6A0DBBU, 0x5CCC0009U, 0x798074A4U, 0xD1C2E785U, 0x9D03B548U, 0x789ACA17U, 0x83AB1F0DU, 0x7E32D7A2U, - 0x086D3D2DU, 0x45D73148U, 0x78421E93U, 0x697E80E0U, 0xA0639CF8U, 0xB3C619B2U, 0x25DC14B9U, 0xB298D73CU, - 0x91646C97U, 0x6EFA628BU, 0x7A04A0CAU, 0x7BCB2F0EU, 0xE7C3E628U, 0x35526B1CU, 0x14340E24U, 0x3C17D0DFU, - 0xE6635C01U, 0x77E153CAU, 0x7BC6CAFDU, 0xC377486BU, 0xDAA3CF98U, 0xFE0EB8B9U, 0xB2430590U, 0xF0BDD041U, - 0x6B6B51F4U, 0xBABB5D54U, 0x6CBC2EB0U, 0xCB0D0FA2U, 0x3813CFCBU, 0x0C8E08F7U, 0x23D5E9B7U, 0x5526F3C6U, - 0x1C6C6162U, 0xA3A06C15U, 0x6D7E4487U, 0x73B168C7U, 0x0573E67BU, 0xC7D2DB52U, 0x85A2E203U, 0x998CF358U, - 0x856530D8U, 0x888D3FD6U, 0x6F38FADEU, 0x6104C729U, 0x42D39CABU, 0x4146A9FCU, 0xB44AF89EU, 0x1703F4BBU, - 0xF262004EU, 0x91960E97U, 0x6EFA90E9U, 0xD9B8A04CU, 0x7FB3B51BU, 0x8A1A7A59U, 0x123DF32AU, 0xDBA9F425U, - 0x6C0695EDU, 0xDED79850U, 0x6BB5866CU, 0x446F98F5U, 0xCD93690BU, 0x971F4AE1U, 0xD79ACDA4U, 0xD16CFD3CU, - 0x1B01A57BU, 0xC7CCA911U, 0x6A77EC5BU, 0xFCD3FF90U, 0xF0F340BBU, 0x5C439944U, 0x71EDC610U, 0x1DC6FDA2U, - 0x8208F4C1U, 0xECE1FAD2U, 0x68315202U, 0xEE66507EU, 0xB7533A6BU, 0xDAD7EBEAU, 0x4005DC8DU, 0x9349FA41U, - 0xF50FC457U, 0xF5FACB93U, 0x69F33835U, 0x56DA371BU, 0x8A3313DBU, 0x118B384FU, 0xE672D739U, 0x5FE3FADFU, - 0x65B0D9C6U, 0x7262D75CU, 0x62AF7F08U, 0x0EB9274DU, 0x0863840AU, 0xE0DD8A9AU, 0x103AA7D0U, 0x86C3E873U, - 0x12B7E950U, 0x6B79E61DU, 0x636D153FU, 0xB6054028U, 0x3503ADBAU, 0x2B81593FU, 0xB64DAC64U, 0x4A69E8EDU, - 0x8BBEB8EAU, 0x4054B5DEU, 0x612BAB66U, 0xA4B0EFC6U, 0x72A3D76AU, 0xAD152B91U, 0x87A5B6F9U, 0xC4E6EF0EU, - 0xFCB9887CU, 0x594F849FU, 0x60E9C151U, 0x1C0C88A3U, 0x4FC3FEDAU, 0x6649F834U, 0x21D2BD4DU, 0x084CEF90U, - 0x62DD1DDFU, 0x160E1258U, 0x65A6D7D4U, 0x81DBB01AU, 0xFDE322CAU, 0x7B4CC88CU, 0xE47583C3U, 0x0289E689U, - 0x15DA2D49U, 0x0F152319U, 0x6464BDE3U, 0x3967D77FU, 0xC0830B7AU, 0xB0101B29U, 0x42028877U, 0xCE23E617U, - 0x8CD37CF3U, 0x243870DAU, 0x662203BAU, 0x2BD27891U, 0x872371AAU, 0x36846987U, 0x73EA92EAU, 0x40ACE1F4U, - 0xFBD44C65U, 0x3D23419BU, 0x67E0698DU, 0x936E1FF4U, 0xBA43581AU, 0xFDD8BA22U, 0xD59D995EU, 0x8C06E16AU, - 0x4DB26158U, 0x65FD6BA7U, 0x48D7CB20U, 0x3B26F703U, 0x9932774DU, 0x08F40F5AU, 0x8BB64CE5U, 0xD0EBA0BBU, - 0x3AB551CEU, 0x7CE65AE6U, 0x4915A117U, 0x839A9066U, 0xA4525EFDU, 0xC3A8DCFFU, 0x2DC14751U, 0x1C41A025U, - 0xA3BC0074U, 0x57CB0925U, 0x4B531F4EU, 0x912F3F88U, 0xE3F2242DU, 0x453CAE51U, 0x1C295DCCU, 0x92CEA7C6U, - 0xD4BB30E2U, 0x4ED03864U, 0x4A917579U, 0x299358EDU, 0xDE920D9DU, 0x8E607DF4U, 0xBA5E5678U, 0x5E64A758U, - 0x4ADFA541U, 0x0191AEA3U, 0x4FDE63FCU, 0xB4446054U, 0x6CB2D18DU, 0x93654D4CU, 0x7FF968F6U, 0x54A1AE41U, - 0x3DD895D7U, 0x188A9FE2U, 0x4E1C09CBU, 0x0CF80731U, 0x51D2F83DU, 0x58399EE9U, 0xD98E6342U, 0x980BAEDFU, - 0xA4D1C46DU, 0x33A7CC21U, 0x4C5AB792U, 0x1E4DA8DFU, 0x167282EDU, 0xDEADEC47U, 0xE86679DFU, 0x1684A93CU, - 0xD3D6F4FBU, 0x2ABCFD60U, 0x4D98DDA5U, 0xA6F1CFBAU, 0x2B12AB5DU, 0x15F13FE2U, 0x4E11726BU, 0xDA2EA9A2U, - 0x4369E96AU, 0xAD24E1AFU, 0x46C49A98U, 0xFE92DFECU, 0xA9423C8CU, 0xE4A78D37U, 0xB8590282U, 0x030EBB0EU, - 0x346ED9FCU, 0xB43FD0EEU, 0x4706F0AFU, 0x462EB889U, 0x9422153CU, 0x2FFB5E92U, 0x1E2E0936U, 0xCFA4BB90U, - 0xAD678846U, 0x9F12832DU, 0x45404EF6U, 0x549B1767U, 0xD3826FECU, 0xA96F2C3CU, 0x2FC613ABU, 0x412BBC73U, - 0xDA60B8D0U, 0x8609B26CU, 0x448224C1U, 0xEC277002U, 0xEEE2465CU, 0x6233FF99U, 0x89B1181FU, 0x8D81BCEDU, - 0x44042D73U, 0xC94824ABU, 0x41CD3244U, 0x71F048BBU, 0x5CC29A4CU, 0x7F36CF21U, 0x4C162691U, 0x8744B5F4U, - 0x33031DE5U, 0xD05315EAU, 0x400F5873U, 0xC94C2FDEU, 0x61A2B3FCU, 0xB46A1C84U, 0xEA612D25U, 0x4BEEB56AU, - 0xAA0A4C5FU, 0xFB7E4629U, 0x4249E62AU, 0xDBF98030U, 0x2602C92CU, 0x32FE6E2AU, 0xDB8937B8U, 0xC561B289U, - 0xDD0D7CC9U, 0xE2657768U, 0x438B8C1DU, 0x6345E755U, 0x1B62E09CU, 0xF9A2BD8FU, 0x7DFE3C0CU, 0x09CBB217U, - 0x5005713CU, 0x2F3F79F6U, 0x54F16850U, 0x6B3FA09CU, 0xF9D2E0CFU, 0x0B220DC1U, 0xEC68D02BU, 0xAC509190U, - 0x270241AAU, 0x362448B7U, 0x55330267U, 0xD383C7F9U, 0xC4B2C97FU, 0xC07EDE64U, 0x4A1FDB9FU, 0x60FA910EU, - 0xBE0B1010U, 0x1D091B74U, 0x5775BC3EU, 0xC1366817U, 0x8312B3AFU, 0x46EAACCAU, 0x7BF7C102U, 0xEE7596EDU, - 0xC90C2086U, 0x04122A35U, 0x56B7D609U, 0x798A0F72U, 0xBE729A1FU, 0x8DB67F6FU, 0xDD80CAB6U, 0x22DF9673U, - 0x5768B525U, 0x4B53BCF2U, 0x53F8C08CU, 0xE45D37CBU, 0x0C52460FU, 0x90B34FD7U, 0x1827F438U, 0x281A9F6AU, - 0x206F85B3U, 0x52488DB3U, 0x523AAABBU, 0x5CE150AEU, 0x31326FBFU, 0x5BEF9C72U, 0xBE50FF8CU, 0xE4B09FF4U, - 0xB966D409U, 0x7965DE70U, 0x507C14E2U, 0x4E54FF40U, 0x7692156FU, 0xDD7BEEDCU, 0x8FB8E511U, 0x6A3F9817U, - 0xCE61E49FU, 0x607EEF31U, 0x51BE7ED5U, 0xF6E89825U, 0x4BF23CDFU, 0x16273D79U, 0x29CFEEA5U, 0xA6959889U, - 0x5EDEF90EU, 0xE7E6F3FEU, 0x5AE239E8U, 0xAE8B8873U, 0xC9A2AB0EU, 0xE7718FACU, 0xDF879E4CU, 0x7FB58A25U, - 0x29D9C998U, 0xFEFDC2BFU, 0x5B2053DFU, 0x1637EF16U, 0xF4C282BEU, 0x2C2D5C09U, 0x79F095F8U, 0xB31F8ABBU, - 0xB0D09822U, 0xD5D0917CU, 0x5966ED86U, 0x048240F8U, 0xB362F86EU, 0xAAB92EA7U, 0x48188F65U, 0x3D908D58U, - 0xC7D7A8B4U, 0xCCCBA03DU, 0x58A487B1U, 0xBC3E279DU, 0x8E02D1DEU, 0x61E5FD02U, 0xEE6F84D1U, 0xF13A8DC6U, - 0x59B33D17U, 0x838A36FAU, 0x5DEB9134U, 0x21E91F24U, 0x3C220DCEU, 0x7CE0CDBAU, 0x2BC8BA5FU, 0xFBFF84DFU, - 0x2EB40D81U, 0x9A9107BBU, 0x5C29FB03U, 0x99557841U, 0x0142247EU, 0xB7BC1E1FU, 0x8DBFB1EBU, 0x37558441U, - 0xB7BD5C3BU, 0xB1BC5478U, 0x5E6F455AU, 0x8BE0D7AFU, 0x46E25EAEU, 0x31286CB1U, 0xBC57AB76U, 0xB9DA83A2U, - 0xC0BA6CADU, 0xA8A76539U, 0x5FAD2F6DU, 0x335CB0CAU, 0x7B82771EU, 0xFA74BF14U, 0x1A20A0C2U, 0x7570833CU, - 0xEDB88320U, 0x3B83984BU, 0xE1351B80U, 0xED59B63BU, 0xB1E6B092U, 0x1EB014D8U, 0x8816EAF2U, 0x533B85DAU, - 0x9ABFB3B6U, 0x2298A90AU, 0xE0F771B7U, 0x55E5D15EU, 0x8C869922U, 0xD5ECC77DU, 0x2E61E146U, 0x9F918544U, - 0x03B6E20CU, 0x09B5FAC9U, 0xE2B1CFEEU, 0x47507EB0U, 0xCB26E3F2U, 0x5378B5D3U, 0x1F89FBDBU, 0x111E82A7U, - 0x74B1D29AU, 0x10AECB88U, 0xE373A5D9U, 0xFFEC19D5U, 0xF646CA42U, 0x98246676U, 0xB9FEF06FU, 0xDDB48239U, - 0xEAD54739U, 0x5FEF5D4FU, 0xE63CB35CU, 0x623B216CU, 0x44661652U, 0x852156CEU, 0x7C59CEE1U, 0xD7718B20U, - 0x9DD277AFU, 0x46F46C0EU, 0xE7FED96BU, 0xDA874609U, 0x79063FE2U, 0x4E7D856BU, 0xDA2EC555U, 0x1BDB8BBEU, - 0x04DB2615U, 0x6DD93FCDU, 0xE5B86732U, 0xC832E9E7U, 0x3EA64532U, 0xC8E9F7C5U, 0xEBC6DFC8U, 0x95548C5DU, - 0x73DC1683U, 0x74C20E8CU, 0xE47A0D05U, 0x708E8E82U, 0x03C66C82U, 0x03B52460U, 0x4DB1D47CU, 0x59FE8CC3U, - 0xE3630B12U, 0xF35A1243U, 0xEF264A38U, 0x28ED9ED4U, 0x8196FB53U, 0xF2E396B5U, 0xBBF9A495U, 0x80DE9E6FU, - 0x94643B84U, 0xEA412302U, 0xEEE4200FU, 0x9051F9B1U, 0xBCF6D2E3U, 0x39BF4510U, 0x1D8EAF21U, 0x4C749EF1U, - 0x0D6D6A3EU, 0xC16C70C1U, 0xECA29E56U, 0x82E4565FU, 0xFB56A833U, 0xBF2B37BEU, 0x2C66B5BCU, 0xC2FB9912U, - 0x7A6A5AA8U, 0xD8774180U, 0xED60F461U, 0x3A58313AU, 0xC6368183U, 0x7477E41BU, 0x8A11BE08U, 0x0E51998CU, - 0xE40ECF0BU, 0x9736D747U, 0xE82FE2E4U, 0xA78F0983U, 0x74165D93U, 0x6972D4A3U, 0x4FB68086U, 0x04949095U, - 0x9309FF9DU, 0x8E2DE606U, 0xE9ED88D3U, 0x1F336EE6U, 0x49767423U, 0xA22E0706U, 0xE9C18B32U, 0xC83E900BU, - 0x0A00AE27U, 0xA500B5C5U, 0xEBAB368AU, 0x0D86C108U, 0x0ED60EF3U, 0x24BA75A8U, 0xD82991AFU, 0x46B197E8U, - 0x7D079EB1U, 0xBC1B8484U, 0xEA695CBDU, 0xB53AA66DU, 0x33B62743U, 0xEFE6A60DU, 0x7E5E9A1BU, 0x8A1B9776U, - 0xF00F9344U, 0x71418A1AU, 0xFD13B8F0U, 0xBD40E1A4U, 0xD1062710U, 0x1D661643U, 0xEFC8763CU, 0x2F80B4F1U, - 0x8708A3D2U, 0x685ABB5BU, 0xFCD1D2C7U, 0x05FC86C1U, 0xEC660EA0U, 0xD63AC5E6U, 0x49BF7D88U, 0xE32AB46FU, - 0x1E01F268U, 0x4377E898U, 0xFE976C9EU, 0x1749292FU, 0xABC67470U, 0x50AEB748U, 0x78576715U, 0x6DA5B38CU, - 0x6906C2FEU, 0x5A6CD9D9U, 0xFF5506A9U, 0xAFF54E4AU, 0x96A65DC0U, 0x9BF264EDU, 0xDE206CA1U, 0xA10FB312U, - 0xF762575DU, 0x152D4F1EU, 0xFA1A102CU, 0x322276F3U, 0x248681D0U, 0x86F75455U, 0x1B87522FU, 0xABCABA0BU, - 0x806567CBU, 0x0C367E5FU, 0xFBD87A1BU, 0x8A9E1196U, 0x19E6A860U, 0x4DAB87F0U, 0xBDF0599BU, 0x6760BA95U, - 0x196C3671U, 0x271B2D9CU, 0xF99EC442U, 0x982BBE78U, 0x5E46D2B0U, 0xCB3FF55EU, 0x8C184306U, 0xE9EFBD76U, - 0x6E6B06E7U, 0x3E001CDDU, 0xF85CAE75U, 0x2097D91DU, 0x6326FB00U, 0x006326FBU, 0x2A6F48B2U, 0x2545BDE8U, - 0xFED41B76U, 0xB9980012U, 0xF300E948U, 0x78F4C94BU, 0xE1766CD1U, 0xF135942EU, 0xDC27385BU, 0xFC65AF44U, - 0x89D32BE0U, 0xA0833153U, 0xF2C2837FU, 0xC048AE2EU, 0xDC164561U, 0x3A69478BU, 0x7A5033EFU, 0x30CFAFDAU, - 0x10DA7A5AU, 0x8BAE6290U, 0xF0843D26U, 0xD2FD01C0U, 0x9BB63FB1U, 0xBCFD3525U, 0x4BB82972U, 0xBE40A839U, - 0x67DD4ACCU, 0x92B553D1U, 0xF1465711U, 0x6A4166A5U, 0xA6D61601U, 0x77A1E680U, 0xEDCF22C6U, 0x72EAA8A7U, - 0xF9B9DF6FU, 0xDDF4C516U, 0xF4094194U, 0xF7965E1CU, 0x14F6CA11U, 0x6AA4D638U, 0x28681C48U, 0x782FA1BEU, - 0x8EBEEFF9U, 0xC4EFF457U, 0xF5CB2BA3U, 0x4F2A3979U, 0x2996E3A1U, 0xA1F8059DU, 0x8E1F17FCU, 0xB485A120U, - 0x17B7BE43U, 0xEFC2A794U, 0xF78D95FAU, 0x5D9F9697U, 0x6E369971U, 0x276C7733U, 0xBFF70D61U, 0x3A0AA6C3U, - 0x60B08ED5U, 0xF6D996D5U, 0xF64FFFCDU, 0xE523F1F2U, 0x5356B0C1U, 0xEC30A496U, 0x198006D5U, 0xF6A0A65DU, - 0xD6D6A3E8U, 0xAE07BCE9U, 0xD9785D60U, 0x4D6B1905U, 0x70279F96U, 0x191C11EEU, 0x47ABD36EU, 0xAA4DE78CU, - 0xA1D1937EU, 0xB71C8DA8U, 0xD8BA3757U, 0xF5D77E60U, 0x4D47B626U, 0xD240C24BU, 0xE1DCD8DAU, 0x66E7E712U, - 0x38D8C2C4U, 0x9C31DE6BU, 0xDAFC890EU, 0xE762D18EU, 0x0AE7CCF6U, 0x54D4B0E5U, 0xD034C247U, 0xE868E0F1U, - 0x4FDFF252U, 0x852AEF2AU, 0xDB3EE339U, 0x5FDEB6EBU, 0x3787E546U, 0x9F886340U, 0x7643C9F3U, 0x24C2E06FU, - 0xD1BB67F1U, 0xCA6B79EDU, 0xDE71F5BCU, 0xC2098E52U, 0x85A73956U, 0x828D53F8U, 0xB3E4F77DU, 0x2E07E976U, - 0xA6BC5767U, 0xD37048ACU, 0xDFB39F8BU, 0x7AB5E937U, 0xB8C710E6U, 0x49D1805DU, 0x1593FCC9U, 0xE2ADE9E8U, - 0x3FB506DDU, 0xF85D1B6FU, 0xDDF521D2U, 0x680046D9U, 0xFF676A36U, 0xCF45F2F3U, 0x247BE654U, 0x6C22EE0BU, - 0x48B2364BU, 0xE1462A2EU, 0xDC374BE5U, 0xD0BC21BCU, 0xC2074386U, 0x04192156U, 0x820CEDE0U, 0xA088EE95U, - 0xD80D2BDAU, 0x66DE36E1U, 0xD76B0CD8U, 0x88DF31EAU, 0x4057D457U, 0xF54F9383U, 0x74449D09U, 0x79A8FC39U, - 0xAF0A1B4CU, 0x7FC507A0U, 0xD6A966EFU, 0x3063568FU, 0x7D37FDE7U, 0x3E134026U, 0xD23396BDU, 0xB502FCA7U, - 0x36034AF6U, 0x54E85463U, 0xD4EFD8B6U, 0x22D6F961U, 0x3A978737U, 0xB8873288U, 0xE3DB8C20U, 0x3B8DFB44U, - 0x41047A60U, 0x4DF36522U, 0xD52DB281U, 0x9A6A9E04U, 0x07F7AE87U, 0x73DBE12DU, 0x45AC8794U, 0xF727FBDAU, - 0xDF60EFC3U, 0x02B2F3E5U, 0xD062A404U, 0x07BDA6BDU, 0xB5D77297U, 0x6EDED195U, 0x800BB91AU, 0xFDE2F2C3U, - 0xA867DF55U, 0x1BA9C2A4U, 0xD1A0CE33U, 0xBF01C1D8U, 0x88B75B27U, 0xA5820230U, 0x267CB2AEU, 0x3148F25DU, - 0x316E8EEFU, 0x30849167U, 0xD3E6706AU, 0xADB46E36U, 0xCF1721F7U, 0x2316709EU, 0x1794A833U, 0xBFC7F5BEU, - 0x4669BE79U, 0x299FA026U, 0xD2241A5DU, 0x15080953U, 0xF2770847U, 0xE84AA33BU, 0xB1E3A387U, 0x736DF520U, - 0xCB61B38CU, 0xE4C5AEB8U, 0xC55EFE10U, 0x1D724E9AU, 0x10C70814U, 0x1ACA1375U, 0x20754FA0U, 0xD6F6D6A7U, - 0xBC66831AU, 0xFDDE9FF9U, 0xC49C9427U, 0xA5CE29FFU, 0x2DA721A4U, 0xD196C0D0U, 0x86024414U, 0x1A5CD639U, - 0x256FD2A0U, 0xD6F3CC3AU, 0xC6DA2A7EU, 0xB77B8611U, 0x6A075B74U, 0x5702B27EU, 0xB7EA5E89U, 0x94D3D1DAU, - 0x5268E236U, 0xCFE8FD7BU, 0xC7184049U, 0x0FC7E174U, 0x576772C4U, 0x9C5E61DBU, 0x119D553DU, 0x5879D144U, - 0xCC0C7795U, 0x80A96BBCU, 0xC25756CCU, 0x9210D9CDU, 0xE547AED4U, 0x815B5163U, 0xD43A6BB3U, 0x52BCD85DU, - 0xBB0B4703U, 0x99B25AFDU, 0xC3953CFBU, 0x2AACBEA8U, 0xD8278764U, 0x4A0782C6U, 0x724D6007U, 0x9E16D8C3U, - 0x220216B9U, 0xB29F093EU, 0xC1D382A2U, 0x38191146U, 0x9F87FDB4U, 0xCC93F068U, 0x43A57A9AU, 0x1099DF20U, - 0x5505262FU, 0xAB84387FU, 0xC011E895U, 0x80A57623U, 0xA2E7D404U, 0x07CF23CDU, 0xE5D2712EU, 0xDC33DFBEU, - 0xC5BA3BBEU, 0x2C1C24B0U, 0xCB4DAFA8U, 0xD8C66675U, 0x20B743D5U, 0xF6999118U, 0x139A01C7U, 0x0513CD12U, - 0xB2BD0B28U, 0x350715F1U, 0xCA8FC59FU, 0x607A0110U, 0x1DD76A65U, 0x3DC542BDU, 0xB5ED0A73U, 0xC9B9CD8CU, - 0x2BB45A92U, 0x1E2A4632U, 0xC8C97BC6U, 0x72CFAEFEU, 0x5A7710B5U, 0xBB513013U, 0x840510EEU, 0x4736CA6FU, - 0x5CB36A04U, 0x07317773U, 0xC90B11F1U, 0xCA73C99BU, 0x67173905U, 0x700DE3B6U, 0x22721B5AU, 0x8B9CCAF1U, - 0xC2D7FFA7U, 0x4870E1B4U, 0xCC440774U, 0x57A4F122U, 0xD537E515U, 0x6D08D30EU, 0xE7D525D4U, 0x8159C3E8U, - 0xB5D0CF31U, 0x516BD0F5U, 0xCD866D43U, 0xEF189647U, 0xE857CCA5U, 0xA65400ABU, 0x41A22E60U, 0x4DF3C376U, - 0x2CD99E8BU, 0x7A468336U, 0xCFC0D31AU, 0xFDAD39A9U, 0xAFF7B675U, 0x20C07205U, 0x704A34FDU, 0xC37CC495U, - 0x5BDEAE1DU, 0x635DB277U, 0xCE02B92DU, 0x45115ECCU, 0x92979FC5U, 0xEB9CA1A0U, 0xD63D3F49U, 0x0FD6C40BU, - 0x9B64C2B0U, 0xCBFAD74EU, 0x91AF9640U, 0x764DEE06U, 0xE915E8DBU, 0x11E81EB4U, 0xCC1D9F8BU, 0x7AA64737U, - 0xEC63F226U, 0xD2E1E60FU, 0x906DFC77U, 0xCEF18963U, 0xD475C16BU, 0xDAB4CD11U, 0x6A6A943FU, 0xB60C47A9U, - 0x756AA39CU, 0xF9CCB5CCU, 0x922B422EU, 0xDC44268DU, 0x93D5BBBBU, 0x5C20BFBFU, 0x5B828EA2U, 0x3883404AU, - 0x026D930AU, 0xE0D7848DU, 0x93E92819U, 0x64F841E8U, 0xAEB5920BU, 0x977C6C1AU, 0xFDF58516U, 0xF42940D4U, - 0x9C0906A9U, 0xAF96124AU, 0x96A63E9CU, 0xF92F7951U, 0x1C954E1BU, 0x8A795CA2U, 0x3852BB98U, 0xFEEC49CDU, - 0xEB0E363FU, 0xB68D230BU, 0x976454ABU, 0x41931E34U, 0x21F567ABU, 0x41258F07U, 0x9E25B02CU, 0x32464953U, - 0x72076785U, 0x9DA070C8U, 0x9522EAF2U, 0x5326B1DAU, 0x66551D7BU, 0xC7B1FDA9U, 0xAFCDAAB1U, 0xBCC94EB0U, - 0x05005713U, 0x84BB4189U, 0x94E080C5U, 0xEB9AD6BFU, 0x5B3534CBU, 0x0CED2E0CU, 0x09BAA105U, 0x70634E2EU, - 0x95BF4A82U, 0x03235D46U, 0x9FBCC7F8U, 0xB3F9C6E9U, 0xD965A31AU, 0xFDBB9CD9U, 0xFFF2D1ECU, 0xA9435C82U, - 0xE2B87A14U, 0x1A386C07U, 0x9E7EADCFU, 0x0B45A18CU, 0xE4058AAAU, 0x36E74F7CU, 0x5985DA58U, 0x65E95C1CU, - 0x7BB12BAEU, 0x31153FC4U, 0x9C381396U, 0x19F00E62U, 0xA3A5F07AU, 0xB0733DD2U, 0x686DC0C5U, 0xEB665BFFU, - 0x0CB61B38U, 0x280E0E85U, 0x9DFA79A1U, 0xA14C6907U, 0x9EC5D9CAU, 0x7B2FEE77U, 0xCE1ACB71U, 0x27CC5B61U, - 0x92D28E9BU, 0x674F9842U, 0x98B56F24U, 0x3C9B51BEU, 0x2CE505DAU, 0x662ADECFU, 0x0BBDF5FFU, 0x2D095278U, - 0xE5D5BE0DU, 0x7E54A903U, 0x99770513U, 0x842736DBU, 0x11852C6AU, 0xAD760D6AU, 0xADCAFE4BU, 0xE1A352E6U, - 0x7CDCEFB7U, 0x5579FAC0U, 0x9B31BB4AU, 0x96929935U, 0x562556BAU, 0x2BE27FC4U, 0x9C22E4D6U, 0x6F2C5505U, - 0x0BDBDF21U, 0x4C62CB81U, 0x9AF3D17DU, 0x2E2EFE50U, 0x6B457F0AU, 0xE0BEAC61U, 0x3A55EF62U, 0xA386559BU, - 0x86D3D2D4U, 0x8138C51FU, 0x8D893530U, 0x2654B999U, 0x89F57F59U, 0x123E1C2FU, 0xABC30345U, 0x061D761CU, - 0xF1D4E242U, 0x9823F45EU, 0x8C4B5F07U, 0x9EE8DEFCU, 0xB49556E9U, 0xD962CF8AU, 0x0DB408F1U, 0xCAB77682U, - 0x68DDB3F8U, 0xB30EA79DU, 0x8E0DE15EU, 0x8C5D7112U, 0xF3352C39U, 0x5FF6BD24U, 0x3C5C126CU, 0x44387161U, - 0x1FDA836EU, 0xAA1596DCU, 0x8FCF8B69U, 0x34E11677U, 0xCE550589U, 0x94AA6E81U, 0x9A2B19D8U, 0x889271FFU, - 0x81BE16CDU, 0xE554001BU, 0x8A809DECU, 0xA9362ECEU, 0x7C75D999U, 0x89AF5E39U, 0x5F8C2756U, 0x825778E6U, - 0xF6B9265BU, 0xFC4F315AU, 0x8B42F7DBU, 0x118A49ABU, 0x4115F029U, 0x42F38D9CU, 0xF9FB2CE2U, 0x4EFD7878U, - 0x6FB077E1U, 0xD7626299U, 0x89044982U, 0x033FE645U, 0x06B58AF9U, 0xC467FF32U, 0xC813367FU, 0xC0727F9BU, - 0x18B74777U, 0xCE7953D8U, 0x88C623B5U, 0xBB838120U, 0x3BD5A349U, 0x0F3B2C97U, 0x6E643DCBU, 0x0CD87F05U, - 0x88085AE6U, 0x49E14F17U, 0x839A6488U, 0xE3E09176U, 0xB9853498U, 0xFE6D9E42U, 0x982C4D22U, 0xD5F86DA9U, - 0xFF0F6A70U, 0x50FA7E56U, 0x82580EBFU, 0x5B5CF613U, 0x84E51D28U, 0x35314DE7U, 0x3E5B4696U, 0x19526D37U, - 0x66063BCAU, 0x7BD72D95U, 0x801EB0E6U, 0x49E959FDU, 0xC34567F8U, 0xB3A53F49U, 0x0FB35C0BU, 0x97DD6AD4U, - 0x11010B5CU, 0x62CC1CD4U, 0x81DCDAD1U, 0xF1553E98U, 0xFE254E48U, 0x78F9ECECU, 0xA9C457BFU, 0x5B776A4AU, - 0x8F659EFFU, 0x2D8D8A13U, 0x8493CC54U, 0x6C820621U, 0x4C059258U, 0x65FCDC54U, 0x6C636931U, 0x51B26353U, - 0xF862AE69U, 0x3496BB52U, 0x8551A663U, 0xD43E6144U, 0x7165BBE8U, 0xAEA00FF1U, 0xCA146285U, 0x9D1863CDU, - 0x616BFFD3U, 0x1FBBE891U, 0x8717183AU, 0xC68BCEAAU, 0x36C5C138U, 0x28347D5FU, 0xFBFC7818U, 0x1397642EU, - 0x166CCF45U, 0x06A0D9D0U, 0x86D5720DU, 0x7E37A9CFU, 0x0BA5E888U, 0xE368AEFAU, 0x5D8B73ACU, 0xDF3D64B0U, - 0xA00AE278U, 0x5E7EF3ECU, 0xA9E2D0A0U, 0xD67F4138U, 0x28D4C7DFU, 0x16441B82U, 0x03A0A617U, 0x83D02561U, - 0xD70DD2EEU, 0x4765C2ADU, 0xA820BA97U, 0x6EC3265DU, 0x15B4EE6FU, 0xDD18C827U, 0xA5D7ADA3U, 0x4F7A25FFU, - 0x4E048354U, 0x6C48916EU, 0xAA6604CEU, 0x7C7689B3U, 0x521494BFU, 0x5B8CBA89U, 0x943FB73EU, 0xC1F5221CU, - 0x3903B3C2U, 0x7553A02FU, 0xABA46EF9U, 0xC4CAEED6U, 0x6F74BD0FU, 0x90D0692CU, 0x3248BC8AU, 0x0D5F2282U, - 0xA7672661U, 0x3A1236E8U, 0xAEEB787CU, 0x591DD66FU, 0xDD54611FU, 0x8DD55994U, 0xF7EF8204U, 0x079A2B9BU, - 0xD06016F7U, 0x230907A9U, 0xAF29124BU, 0xE1A1B10AU, 0xE03448AFU, 0x46898A31U, 0x519889B0U, 0xCB302B05U, - 0x4969474DU, 0x0824546AU, 0xAD6FAC12U, 0xF3141EE4U, 0xA794327FU, 0xC01DF89FU, 0x6070932DU, 0x45BF2CE6U, - 0x3E6E77DBU, 0x113F652BU, 0xACADC625U, 0x4BA87981U, 0x9AF41BCFU, 0x0B412B3AU, 0xC6079899U, 0x89152C78U, - 0xAED16A4AU, 0x96A779E4U, 0xA7F18118U, 0x13CB69D7U, 0x18A48C1EU, 0xFA1799EFU, 0x304FE870U, 0x50353ED4U, - 0xD9D65ADCU, 0x8FBC48A5U, 0xA633EB2FU, 0xAB770EB2U, 0x25C4A5AEU, 0x314B4A4AU, 0x9638E3C4U, 0x9C9F3E4AU, - 0x40DF0B66U, 0xA4911B66U, 0xA4755576U, 0xB9C2A15CU, 0x6264DF7EU, 0xB7DF38E4U, 0xA7D0F959U, 0x121039A9U, - 0x37D83BF0U, 0xBD8A2A27U, 0xA5B73F41U, 0x017EC639U, 0x5F04F6CEU, 0x7C83EB41U, 0x01A7F2EDU, 0xDEBA3937U, - 0xA9BCAE53U, 0xF2CBBCE0U, 0xA0F829C4U, 0x9CA9FE80U, 0xED242ADEU, 0x6186DBF9U, 0xC400CC63U, 0xD47F302EU, - 0xDEBB9EC5U, 0xEBD08DA1U, 0xA13A43F3U, 0x241599E5U, 0xD044036EU, 0xAADA085CU, 0x6277C7D7U, 0x18D530B0U, - 0x47B2CF7FU, 0xC0FDDE62U, 0xA37CFDAAU, 0x36A0360BU, 0x97E479BEU, 0x2C4E7AF2U, 0x539FDD4AU, 0x965A3753U, - 0x30B5FFE9U, 0xD9E6EF23U, 0xA2BE979DU, 0x8E1C516EU, 0xAA84500EU, 0xE712A957U, 0xF5E8D6FEU, 0x5AF037CDU, - 0xBDBDF21CU, 0x14BCE1BDU, 0xB5C473D0U, 0x866616A7U, 0x4834505DU, 0x15921919U, 0x647E3AD9U, 0xFF6B144AU, - 0xCABAC28AU, 0x0DA7D0FCU, 0xB40619E7U, 0x3EDA71C2U, 0x755479EDU, 0xDECECABCU, 0xC209316DU, 0x33C114D4U, - 0x53B39330U, 0x268A833FU, 0xB640A7BEU, 0x2C6FDE2CU, 0x32F4033DU, 0x585AB812U, 0xF3E12BF0U, 0xBD4E1337U, - 0x24B4A3A6U, 0x3F91B27EU, 0xB782CD89U, 0x94D3B949U, 0x0F942A8DU, 0x93066BB7U, 0x55962044U, 0x71E413A9U, - 0xBAD03605U, 0x70D024B9U, 0xB2CDDB0CU, 0x090481F0U, 0xBDB4F69DU, 0x8E035B0FU, 0x90311ECAU, 0x7B211AB0U, - 0xCDD70693U, 0x69CB15F8U, 0xB30FB13BU, 0xB1B8E695U, 0x80D4DF2DU, 0x455F88AAU, 0x3646157EU, 0xB78B1A2EU, - 0x54DE5729U, 0x42E6463BU, 0xB1490F62U, 0xA30D497BU, 0xC774A5FDU, 0xC3CBFA04U, 0x07AE0FE3U, 0x39041DCDU, - 0x23D967BFU, 0x5BFD777AU, 0xB08B6555U, 0x1BB12E1EU, 0xFA148C4DU, 0x089729A1U, 0xA1D90457U, 0xF5AE1D53U, - 0xB3667A2EU, 0xDC656BB5U, 0xBBD72268U, 0x43D23E48U, 0x78441B9CU, 0xF9C19B74U, 0x579174BEU, 0x2C8E0FFFU, - 0xC4614AB8U, 0xC57E5AF4U, 0xBA15485FU, 0xFB6E592DU, 0x4524322CU, 0x329D48D1U, 0xF1E67F0AU, 0xE0240F61U, - 0x5D681B02U, 0xEE530937U, 0xB853F606U, 0xE9DBF6C3U, 0x028448FCU, 0xB4093A7FU, 0xC00E6597U, 0x6EAB0882U, - 0x2A6F2B94U, 0xF7483876U, 0xB9919C31U, 0x516791A6U, 0x3FE4614CU, 0x7F55E9DAU, 0x66796E23U, 0xA201081CU, - 0xB40BBE37U, 0xB809AEB1U, 0xBCDE8AB4U, 0xCCB0A91FU, 0x8DC4BD5CU, 0x6250D962U, 0xA3DE50ADU, 0xA8C40105U, - 0xC30C8EA1U, 0xA1129FF0U, 0xBD1CE083U, 0x740CCE7AU, 0xB0A494ECU, 0xA90C0AC7U, 0x05A95B19U, 0x646E019BU, - 0x5A05DF1BU, 0x8A3FCC33U, 0xBF5A5EDAU, 0x66B96194U, 0xF704EE3CU, 0x2F987869U, 0x34414184U, 0xEAE10678U, - 0x2D02EF8DU, 0x9324FD72U, 0xBE9834EDU, 0xDE0506F1U, 0xCA64C78CU, 0xE4C4ABCCU, 0x92364A30U, 0x264B06E6U, - }; - - uint32_t ulCrc32; - - if(pBuffer == NULL) - { - REDERROR(); - ulCrc32 = SUSPICIOUS_CRC_VALUE; - } - else - { - const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); - uint32_t ulIdx = 0U; - const uint32_t *pulXorCrc0 = &aulCrc32Table[7U]; - const uint32_t *pulXorCrc1 = &aulCrc32Table[6U]; - const uint32_t *pulXorCrc2 = &aulCrc32Table[5U]; - const uint32_t *pulXorCrc3 = &aulCrc32Table[4U]; - const uint32_t *pulXorData4 = &aulCrc32Table[3U]; - const uint32_t *pulXorData5 = &aulCrc32Table[2U]; - const uint32_t *pulXorData6 = &aulCrc32Table[1U]; - const uint32_t *pulXorData7 = &aulCrc32Table[0U]; - uint32_t ulSliceLen; - - ulCrc32 = ~ulInitCrc32; - - /* Aligned memory access is used below. To avoid suboptimal - performance and faults (depending on platform), handle the - unaligned initial bytes (if any) using the Sarwate algorithm. - */ - while((ulIdx < ulLength) && !IS_ALIGNED_PTR(&pbBuffer[ulIdx])) - { - ulCrc32 = (ulCrc32 >> 8U) ^ aulCrc32Table[((ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU) << 3U]; - - ulIdx++; - } - - /* Round down the length to the nearest multiple of eight. - */ - ulSliceLen = (((ulLength - ulIdx) >> 3U) << 3U) + ulIdx; - - /* Compute the CRC in eight byte "slices". Takes advantage of - modern processors which can load in parallel from multiple - memory locations. - */ - while(ulIdx < ulSliceLen) - { - #if REDCONF_ENDIAN_BIG == 1 - ulCrc32 ^= pbBuffer[ulIdx] | ((uint32_t)pbBuffer[ulIdx+1U] << 8U) | - ((uint32_t)pbBuffer[ulIdx+2U] << 16U) | ((uint32_t)pbBuffer[ulIdx+3U] << 24U); - #else - ulCrc32 ^= *CAST_CONST_UINT32_PTR(&pbBuffer[ulIdx]); - #endif - - ulCrc32 = - pulXorCrc3[((ulCrc32 >> 24U) & 0xFFU) << 3U] ^ - pulXorCrc2[((ulCrc32 >> 16U) & 0xFFU) << 3U] ^ - pulXorCrc1[((ulCrc32 >> 8U) & 0xFFU) << 3U] ^ - pulXorCrc0[ (ulCrc32 & 0xFFU) << 3U] ^ - pulXorData7[pbBuffer[ulIdx+7U] << 3U] ^ - pulXorData6[pbBuffer[ulIdx+6U] << 3U] ^ - pulXorData5[pbBuffer[ulIdx+5U] << 3U] ^ - pulXorData4[pbBuffer[ulIdx+4U] << 3U]; - - ulIdx += 8U; - } - - /* Compute the remaining bytes with the Sarwate algorithm. - */ - while(ulIdx < ulLength) - { - ulCrc32 = (ulCrc32 >> 8U) ^ aulCrc32Table[((ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU) << 3U]; - - ulIdx++; - } - - ulCrc32 = ~ulCrc32; - } - - return ulCrc32; -} - -#else - -#error "REDCONF_CRC_ALGORITHM must be set to CRC_BITWISE, CRC_SARWATE, or CRC_SLICEBY8" - -#endif - - -/** @brief Compute a CRC32 for a metadata node buffer. - - @param pBuffer The metadata node buffer for which to compute a CRC. Must - be a block sized buffer. - - @return The CRC of the buffer. -*/ -uint32_t RedCrcNode( - const void *pBuffer) -{ - uint32_t ulCrc; - - if(pBuffer == NULL) - { - REDERROR(); - ulCrc = SUSPICIOUS_CRC_VALUE; - } - else - { - const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); - - /* The first eight bytes of a metadata node contain the signature and - the CRC. There is little value in CRCing the signature, and the - CRC cannot be CRC'd, so skip over that part of the buffer. - */ - ulCrc = RedCrc32Update(0U, &pbBuffer[8U], REDCONF_BLOCK_SIZE - 8U); - } - - return ulCrc; -} - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements utilities for calculating CRC-32 checksums. + */ +#include + + +/* The CRC functions do not return errors since the only detectable error + * condition is a NULL buffer pointer. If such a condition does arise, the + * functions assert and return the below CRC, which, although a legal CRC, + * is nonetheless suspicious and could provide a clue that something has + * gone wrong. + */ +#define SUSPICIOUS_CRC_VALUE ( 0xBAADC0DEU ) + +#define CRC_BITWISE ( 0U ) +#define CRC_SARWATE ( 1U ) +#define CRC_SLICEBY8 ( 2U ) + + +#if REDCONF_CRC_ALGORITHM == CRC_BITWISE + +/* The following is representative of the polynomial accepted by CCITT 32-bit + * and in IEEE 802.3, Ethernet 2 specification. + * + * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 + * (reverse order) + * 1110 1101 1011 1000 1000 0011 0010 0000 1 + * (E) (D) (B) (8) (8) (3) (2) (0) + */ + #define CCITT_32_POLYNOMIAL ( 0xEDB88320U ) + + +/** @brief Compute a CRC32 for the given data buffer. + * + * For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple + * buffers, call this function with the previously returned CRC value. + * + * @param ulInitCrc32 Starting CRC value. + * @param pBuffer Data buffer to calculate the CRC from. + * @param ulLength Number of bytes of data in the given buffer. + * + * @return The updated CRC value. + */ + uint32_t RedCrc32Update( uint32_t ulInitCrc32, + const void * pBuffer, + uint32_t ulLength ) + { + uint32_t ulCrc32; + + if( pBuffer == NULL ) + { + REDERROR(); + ulCrc32 = SUSPICIOUS_CRC_VALUE; + } + else + { + const uint8_t * pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pBuffer ); + uint32_t ulIdx; + + ulCrc32 = ~ulInitCrc32; + + for( ulIdx = 0U; ulIdx < ulLength; ++ulIdx ) + { + uint32_t ulBit; + + ulCrc32 ^= pbBuffer[ ulIdx ]; + + /* Branchless inner loop (greatly improves performance). + */ + for( ulBit = 0U; ulBit < 8U; ulBit++ ) + { + ulCrc32 = ( ( ulCrc32 & 1U ) * CCITT_32_POLYNOMIAL ) ^ ( ulCrc32 >> 1U ); + } + } + + ulCrc32 = ~ulCrc32; + } + + return ulCrc32; + } + +#elif REDCONF_CRC_ALGORITHM == CRC_SARWATE + +/** @brief Compute a CRC32 for the given data buffer. + * + * For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple + * buffers, call this function with the previously returned CRC value. + * + * @param ulInitCrc32 Starting CRC value. + * @param pBuffer Data buffer to calculate the CRC from. + * @param ulLength Number of bytes of data in the given buffer. + * + * @return The updated CRC value. + */ + uint32_t RedCrc32Update( uint32_t ulInitCrc32, + const void * pBuffer, + uint32_t ulLength ) + { + static const uint32_t aulCrc32Table[] = + { + 0x00000000U, 0x77073096U, 0xEE0E612CU, 0x990951BAU, 0x076DC419U, 0x706AF48FU, 0xE963A535U, 0x9E6495A3U, + 0x0EDB8832U, 0x79DCB8A4U, 0xE0D5E91EU, 0x97D2D988U, 0x09B64C2BU, 0x7EB17CBDU, 0xE7B82D07U, 0x90BF1D91U, + 0x1DB71064U, 0x6AB020F2U, 0xF3B97148U, 0x84BE41DEU, 0x1ADAD47DU, 0x6DDDE4EBU, 0xF4D4B551U, 0x83D385C7U, + 0x136C9856U, 0x646BA8C0U, 0xFD62F97AU, 0x8A65C9ECU, 0x14015C4FU, 0x63066CD9U, 0xFA0F3D63U, 0x8D080DF5U, + 0x3B6E20C8U, 0x4C69105EU, 0xD56041E4U, 0xA2677172U, 0x3C03E4D1U, 0x4B04D447U, 0xD20D85FDU, 0xA50AB56BU, + 0x35B5A8FAU, 0x42B2986CU, 0xDBBBC9D6U, 0xACBCF940U, 0x32D86CE3U, 0x45DF5C75U, 0xDCD60DCFU, 0xABD13D59U, + 0x26D930ACU, 0x51DE003AU, 0xC8D75180U, 0xBFD06116U, 0x21B4F4B5U, 0x56B3C423U, 0xCFBA9599U, 0xB8BDA50FU, + 0x2802B89EU, 0x5F058808U, 0xC60CD9B2U, 0xB10BE924U, 0x2F6F7C87U, 0x58684C11U, 0xC1611DABU, 0xB6662D3DU, + 0x76DC4190U, 0x01DB7106U, 0x98D220BCU, 0xEFD5102AU, 0x71B18589U, 0x06B6B51FU, 0x9FBFE4A5U, 0xE8B8D433U, + 0x7807C9A2U, 0x0F00F934U, 0x9609A88EU, 0xE10E9818U, 0x7F6A0DBBU, 0x086D3D2DU, 0x91646C97U, 0xE6635C01U, + 0x6B6B51F4U, 0x1C6C6162U, 0x856530D8U, 0xF262004EU, 0x6C0695EDU, 0x1B01A57BU, 0x8208F4C1U, 0xF50FC457U, + 0x65B0D9C6U, 0x12B7E950U, 0x8BBEB8EAU, 0xFCB9887CU, 0x62DD1DDFU, 0x15DA2D49U, 0x8CD37CF3U, 0xFBD44C65U, + 0x4DB26158U, 0x3AB551CEU, 0xA3BC0074U, 0xD4BB30E2U, 0x4ADFA541U, 0x3DD895D7U, 0xA4D1C46DU, 0xD3D6F4FBU, + 0x4369E96AU, 0x346ED9FCU, 0xAD678846U, 0xDA60B8D0U, 0x44042D73U, 0x33031DE5U, 0xAA0A4C5FU, 0xDD0D7CC9U, + 0x5005713CU, 0x270241AAU, 0xBE0B1010U, 0xC90C2086U, 0x5768B525U, 0x206F85B3U, 0xB966D409U, 0xCE61E49FU, + 0x5EDEF90EU, 0x29D9C998U, 0xB0D09822U, 0xC7D7A8B4U, 0x59B33D17U, 0x2EB40D81U, 0xB7BD5C3BU, 0xC0BA6CADU, + 0xEDB88320U, 0x9ABFB3B6U, 0x03B6E20CU, 0x74B1D29AU, 0xEAD54739U, 0x9DD277AFU, 0x04DB2615U, 0x73DC1683U, + 0xE3630B12U, 0x94643B84U, 0x0D6D6A3EU, 0x7A6A5AA8U, 0xE40ECF0BU, 0x9309FF9DU, 0x0A00AE27U, 0x7D079EB1U, + 0xF00F9344U, 0x8708A3D2U, 0x1E01F268U, 0x6906C2FEU, 0xF762575DU, 0x806567CBU, 0x196C3671U, 0x6E6B06E7U, + 0xFED41B76U, 0x89D32BE0U, 0x10DA7A5AU, 0x67DD4ACCU, 0xF9B9DF6FU, 0x8EBEEFF9U, 0x17B7BE43U, 0x60B08ED5U, + 0xD6D6A3E8U, 0xA1D1937EU, 0x38D8C2C4U, 0x4FDFF252U, 0xD1BB67F1U, 0xA6BC5767U, 0x3FB506DDU, 0x48B2364BU, + 0xD80D2BDAU, 0xAF0A1B4CU, 0x36034AF6U, 0x41047A60U, 0xDF60EFC3U, 0xA867DF55U, 0x316E8EEFU, 0x4669BE79U, + 0xCB61B38CU, 0xBC66831AU, 0x256FD2A0U, 0x5268E236U, 0xCC0C7795U, 0xBB0B4703U, 0x220216B9U, 0x5505262FU, + 0xC5BA3BBEU, 0xB2BD0B28U, 0x2BB45A92U, 0x5CB36A04U, 0xC2D7FFA7U, 0xB5D0CF31U, 0x2CD99E8BU, 0x5BDEAE1DU, + 0x9B64C2B0U, 0xEC63F226U, 0x756AA39CU, 0x026D930AU, 0x9C0906A9U, 0xEB0E363FU, 0x72076785U, 0x05005713U, + 0x95BF4A82U, 0xE2B87A14U, 0x7BB12BAEU, 0x0CB61B38U, 0x92D28E9BU, 0xE5D5BE0DU, 0x7CDCEFB7U, 0x0BDBDF21U, + 0x86D3D2D4U, 0xF1D4E242U, 0x68DDB3F8U, 0x1FDA836EU, 0x81BE16CDU, 0xF6B9265BU, 0x6FB077E1U, 0x18B74777U, + 0x88085AE6U, 0xFF0F6A70U, 0x66063BCAU, 0x11010B5CU, 0x8F659EFFU, 0xF862AE69U, 0x616BFFD3U, 0x166CCF45U, + 0xA00AE278U, 0xD70DD2EEU, 0x4E048354U, 0x3903B3C2U, 0xA7672661U, 0xD06016F7U, 0x4969474DU, 0x3E6E77DBU, + 0xAED16A4AU, 0xD9D65ADCU, 0x40DF0B66U, 0x37D83BF0U, 0xA9BCAE53U, 0xDEBB9EC5U, 0x47B2CF7FU, 0x30B5FFE9U, + 0xBDBDF21CU, 0xCABAC28AU, 0x53B39330U, 0x24B4A3A6U, 0xBAD03605U, 0xCDD70693U, 0x54DE5729U, 0x23D967BFU, + 0xB3667A2EU, 0xC4614AB8U, 0x5D681B02U, 0x2A6F2B94U, 0xB40BBE37U, 0xC30C8EA1U, 0x5A05DF1BU, 0x2D02EF8DU, + }; + + uint32_t ulCrc32; + + if( pBuffer == NULL ) + { + REDERROR(); + ulCrc32 = SUSPICIOUS_CRC_VALUE; + } + else + { + const uint8_t * pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pBuffer ); + uint32_t ulIdx; + + ulCrc32 = ~ulInitCrc32; + + for( ulIdx = 0U; ulIdx < ulLength; ++ulIdx ) + { + ulCrc32 = ( ulCrc32 >> 8U ) ^ aulCrc32Table[ ( ulCrc32 ^ pbBuffer[ ulIdx ] ) & 0xFFU ]; + } + + ulCrc32 = ~ulCrc32; + } + + return ulCrc32; + } + +#elif REDCONF_CRC_ALGORITHM == CRC_SLICEBY8 + + +/** @brief Compute a CRC32 for the given data buffer. + * + * For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple + * buffers, call this function with the previously returned CRC value. + * + * @param ulInitCrc32 Starting CRC value. + * @param pBuffer Data buffer to calculate the CRC from. + * @param ulLength Number of bytes of data in the given buffer. + * + * @return The updated CRC value. + */ + uint32_t RedCrc32Update( uint32_t ulInitCrc32, + const void * pBuffer, + uint32_t ulLength ) + { + /* CRC32 XOR table, with slicing-by-8 extensions. + * + * This first column of the table contains the same XOR values as used in + * the classic byte-at-a-time Sarwate algorithm. The other seven columns + * are derived from the first, and are used in Intel's slicing-by-eight CRC + * algorithm. + * + * The layout of this array in memory is novel and deserves explanation. + * In other implementations, including Intel's example, each of the below + * columns is an array. The first column is a 256-entry array, followed by + * another 256-entry array for the second column, etc. Testing on both ARM + * and x86 has shown the below mixed arrangement to be about 5-9% faster. + * One possible explanation: With the array-per-table approach, each of the + * eight table lookups is guaranteed to be in a separate 1 KB chunk of + * memory. With the below array, sometimes multiple table lookups will, by + * coincidence, be close together, making better use of the cache. + */ + static const uint32_t aulCrc32Table[] = + { + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x77073096U, 0x191B3141U, 0x01C26A37U, 0xB8BC6765U, 0x3D6029B0U, 0xCB5CD3A5U, 0xA6770BB4U, 0xCCAA009EU, + 0xEE0E612CU, 0x32366282U, 0x0384D46EU, 0xAA09C88BU, 0x7AC05360U, 0x4DC8A10BU, 0x979F1129U, 0x4225077DU, + 0x990951BAU, 0x2B2D53C3U, 0x0246BE59U, 0x12B5AFEEU, 0x47A07AD0U, 0x869472AEU, 0x31E81A9DU, 0x8E8F07E3U, + 0x076DC419U, 0x646CC504U, 0x0709A8DCU, 0x8F629757U, 0xF580A6C0U, 0x9B914216U, 0xF44F2413U, 0x844A0EFAU, + 0x706AF48FU, 0x7D77F445U, 0x06CBC2EBU, 0x37DEF032U, 0xC8E08F70U, 0x50CD91B3U, 0x52382FA7U, 0x48E00E64U, + 0xE963A535U, 0x565AA786U, 0x048D7CB2U, 0x256B5FDCU, 0x8F40F5A0U, 0xD659E31DU, 0x63D0353AU, 0xC66F0987U, + 0x9E6495A3U, 0x4F4196C7U, 0x054F1685U, 0x9DD738B9U, 0xB220DC10U, 0x1D0530B8U, 0xC5A73E8EU, 0x0AC50919U, + 0x0EDB8832U, 0xC8D98A08U, 0x0E1351B8U, 0xC5B428EFU, 0x30704BC1U, 0xEC53826DU, 0x33EF4E67U, 0xD3E51BB5U, + 0x79DCB8A4U, 0xD1C2BB49U, 0x0FD13B8FU, 0x7D084F8AU, 0x0D106271U, 0x270F51C8U, 0x959845D3U, 0x1F4F1B2BU, + 0xE0D5E91EU, 0xFAEFE88AU, 0x0D9785D6U, 0x6FBDE064U, 0x4AB018A1U, 0xA19B2366U, 0xA4705F4EU, 0x91C01CC8U, + 0x97D2D988U, 0xE3F4D9CBU, 0x0C55EFE1U, 0xD7018701U, 0x77D03111U, 0x6AC7F0C3U, 0x020754FAU, 0x5D6A1C56U, + 0x09B64C2BU, 0xACB54F0CU, 0x091AF964U, 0x4AD6BFB8U, 0xC5F0ED01U, 0x77C2C07BU, 0xC7A06A74U, 0x57AF154FU, + 0x7EB17CBDU, 0xB5AE7E4DU, 0x08D89353U, 0xF26AD8DDU, 0xF890C4B1U, 0xBC9E13DEU, 0x61D761C0U, 0x9B0515D1U, + 0xE7B82D07U, 0x9E832D8EU, 0x0A9E2D0AU, 0xE0DF7733U, 0xBF30BE61U, 0x3A0A6170U, 0x503F7B5DU, 0x158A1232U, + 0x90BF1D91U, 0x87981CCFU, 0x0B5C473DU, 0x58631056U, 0x825097D1U, 0xF156B2D5U, 0xF64870E9U, 0xD92012ACU, + 0x1DB71064U, 0x4AC21251U, 0x1C26A370U, 0x5019579FU, 0x60E09782U, 0x03D6029BU, 0x67DE9CCEU, 0x7CBB312BU, + 0x6AB020F2U, 0x53D92310U, 0x1DE4C947U, 0xE8A530FAU, 0x5D80BE32U, 0xC88AD13EU, 0xC1A9977AU, 0xB01131B5U, + 0xF3B97148U, 0x78F470D3U, 0x1FA2771EU, 0xFA109F14U, 0x1A20C4E2U, 0x4E1EA390U, 0xF0418DE7U, 0x3E9E3656U, + 0x84BE41DEU, 0x61EF4192U, 0x1E601D29U, 0x42ACF871U, 0x2740ED52U, 0x85427035U, 0x56368653U, 0xF23436C8U, + 0x1ADAD47DU, 0x2EAED755U, 0x1B2F0BACU, 0xDF7BC0C8U, 0x95603142U, 0x9847408DU, 0x9391B8DDU, 0xF8F13FD1U, + 0x6DDDE4EBU, 0x37B5E614U, 0x1AED619BU, 0x67C7A7ADU, 0xA80018F2U, 0x531B9328U, 0x35E6B369U, 0x345B3F4FU, + 0xF4D4B551U, 0x1C98B5D7U, 0x18ABDFC2U, 0x75720843U, 0xEFA06222U, 0xD58FE186U, 0x040EA9F4U, 0xBAD438ACU, + 0x83D385C7U, 0x05838496U, 0x1969B5F5U, 0xCDCE6F26U, 0xD2C04B92U, 0x1ED33223U, 0xA279A240U, 0x767E3832U, + 0x136C9856U, 0x821B9859U, 0x1235F2C8U, 0x95AD7F70U, 0x5090DC43U, 0xEF8580F6U, 0x5431D2A9U, 0xAF5E2A9EU, + 0x646BA8C0U, 0x9B00A918U, 0x13F798FFU, 0x2D111815U, 0x6DF0F5F3U, 0x24D95353U, 0xF246D91DU, 0x63F42A00U, + 0xFD62F97AU, 0xB02DFADBU, 0x11B126A6U, 0x3FA4B7FBU, 0x2A508F23U, 0xA24D21FDU, 0xC3AEC380U, 0xED7B2DE3U, + 0x8A65C9ECU, 0xA936CB9AU, 0x10734C91U, 0x8718D09EU, 0x1730A693U, 0x6911F258U, 0x65D9C834U, 0x21D12D7DU, + 0x14015C4FU, 0xE6775D5DU, 0x153C5A14U, 0x1ACFE827U, 0xA5107A83U, 0x7414C2E0U, 0xA07EF6BAU, 0x2B142464U, + 0x63066CD9U, 0xFF6C6C1CU, 0x14FE3023U, 0xA2738F42U, 0x98705333U, 0xBF481145U, 0x0609FD0EU, 0xE7BE24FAU, + 0xFA0F3D63U, 0xD4413FDFU, 0x16B88E7AU, 0xB0C620ACU, 0xDFD029E3U, 0x39DC63EBU, 0x37E1E793U, 0x69312319U, + 0x8D080DF5U, 0xCD5A0E9EU, 0x177AE44DU, 0x087A47C9U, 0xE2B00053U, 0xF280B04EU, 0x9196EC27U, 0xA59B2387U, + 0x3B6E20C8U, 0x958424A2U, 0x384D46E0U, 0xA032AF3EU, 0xC1C12F04U, 0x07AC0536U, 0xCFBD399CU, 0xF9766256U, + 0x4C69105EU, 0x8C9F15E3U, 0x398F2CD7U, 0x188EC85BU, 0xFCA106B4U, 0xCCF0D693U, 0x69CA3228U, 0x35DC62C8U, + 0xD56041E4U, 0xA7B24620U, 0x3BC9928EU, 0x0A3B67B5U, 0xBB017C64U, 0x4A64A43DU, 0x582228B5U, 0xBB53652BU, + 0xA2677172U, 0xBEA97761U, 0x3A0BF8B9U, 0xB28700D0U, 0x866155D4U, 0x81387798U, 0xFE552301U, 0x77F965B5U, + 0x3C03E4D1U, 0xF1E8E1A6U, 0x3F44EE3CU, 0x2F503869U, 0x344189C4U, 0x9C3D4720U, 0x3BF21D8FU, 0x7D3C6CACU, + 0x4B04D447U, 0xE8F3D0E7U, 0x3E86840BU, 0x97EC5F0CU, 0x0921A074U, 0x57619485U, 0x9D85163BU, 0xB1966C32U, + 0xD20D85FDU, 0xC3DE8324U, 0x3CC03A52U, 0x8559F0E2U, 0x4E81DAA4U, 0xD1F5E62BU, 0xAC6D0CA6U, 0x3F196BD1U, + 0xA50AB56BU, 0xDAC5B265U, 0x3D025065U, 0x3DE59787U, 0x73E1F314U, 0x1AA9358EU, 0x0A1A0712U, 0xF3B36B4FU, + 0x35B5A8FAU, 0x5D5DAEAAU, 0x365E1758U, 0x658687D1U, 0xF1B164C5U, 0xEBFF875BU, 0xFC5277FBU, 0x2A9379E3U, + 0x42B2986CU, 0x44469FEBU, 0x379C7D6FU, 0xDD3AE0B4U, 0xCCD14D75U, 0x20A354FEU, 0x5A257C4FU, 0xE639797DU, + 0xDBBBC9D6U, 0x6F6BCC28U, 0x35DAC336U, 0xCF8F4F5AU, 0x8B7137A5U, 0xA6372650U, 0x6BCD66D2U, 0x68B67E9EU, + 0xACBCF940U, 0x7670FD69U, 0x3418A901U, 0x7733283FU, 0xB6111E15U, 0x6D6BF5F5U, 0xCDBA6D66U, 0xA41C7E00U, + 0x32D86CE3U, 0x39316BAEU, 0x3157BF84U, 0xEAE41086U, 0x0431C205U, 0x706EC54DU, 0x081D53E8U, 0xAED97719U, + 0x45DF5C75U, 0x202A5AEFU, 0x3095D5B3U, 0x525877E3U, 0x3951EBB5U, 0xBB3216E8U, 0xAE6A585CU, 0x62737787U, + 0xDCD60DCFU, 0x0B07092CU, 0x32D36BEAU, 0x40EDD80DU, 0x7EF19165U, 0x3DA66446U, 0x9F8242C1U, 0xECFC7064U, + 0xABD13D59U, 0x121C386DU, 0x331101DDU, 0xF851BF68U, 0x4391B8D5U, 0xF6FAB7E3U, 0x39F54975U, 0x205670FAU, + 0x26D930ACU, 0xDF4636F3U, 0x246BE590U, 0xF02BF8A1U, 0xA121B886U, 0x047A07ADU, 0xA863A552U, 0x85CD537DU, + 0x51DE003AU, 0xC65D07B2U, 0x25A98FA7U, 0x48979FC4U, 0x9C419136U, 0xCF26D408U, 0x0E14AEE6U, 0x496753E3U, + 0xC8D75180U, 0xED705471U, 0x27EF31FEU, 0x5A22302AU, 0xDBE1EBE6U, 0x49B2A6A6U, 0x3FFCB47BU, 0xC7E85400U, + 0xBFD06116U, 0xF46B6530U, 0x262D5BC9U, 0xE29E574FU, 0xE681C256U, 0x82EE7503U, 0x998BBFCFU, 0x0B42549EU, + 0x21B4F4B5U, 0xBB2AF3F7U, 0x23624D4CU, 0x7F496FF6U, 0x54A11E46U, 0x9FEB45BBU, 0x5C2C8141U, 0x01875D87U, + 0x56B3C423U, 0xA231C2B6U, 0x22A0277BU, 0xC7F50893U, 0x69C137F6U, 0x54B7961EU, 0xFA5B8AF5U, 0xCD2D5D19U, + 0xCFBA9599U, 0x891C9175U, 0x20E69922U, 0xD540A77DU, 0x2E614D26U, 0xD223E4B0U, 0xCBB39068U, 0x43A25AFAU, + 0xB8BDA50FU, 0x9007A034U, 0x2124F315U, 0x6DFCC018U, 0x13016496U, 0x197F3715U, 0x6DC49BDCU, 0x8F085A64U, + 0x2802B89EU, 0x179FBCFBU, 0x2A78B428U, 0x359FD04EU, 0x9151F347U, 0xE82985C0U, 0x9B8CEB35U, 0x562848C8U, + 0x5F058808U, 0x0E848DBAU, 0x2BBADE1FU, 0x8D23B72BU, 0xAC31DAF7U, 0x23755665U, 0x3DFBE081U, 0x9A824856U, + 0xC60CD9B2U, 0x25A9DE79U, 0x29FC6046U, 0x9F9618C5U, 0xEB91A027U, 0xA5E124CBU, 0x0C13FA1CU, 0x140D4FB5U, + 0xB10BE924U, 0x3CB2EF38U, 0x283E0A71U, 0x272A7FA0U, 0xD6F18997U, 0x6EBDF76EU, 0xAA64F1A8U, 0xD8A74F2BU, + 0x2F6F7C87U, 0x73F379FFU, 0x2D711CF4U, 0xBAFD4719U, 0x64D15587U, 0x73B8C7D6U, 0x6FC3CF26U, 0xD2624632U, + 0x58684C11U, 0x6AE848BEU, 0x2CB376C3U, 0x0241207CU, 0x59B17C37U, 0xB8E41473U, 0xC9B4C492U, 0x1EC846ACU, + 0xC1611DABU, 0x41C51B7DU, 0x2EF5C89AU, 0x10F48F92U, 0x1E1106E7U, 0x3E7066DDU, 0xF85CDE0FU, 0x9047414FU, + 0xB6662D3DU, 0x58DE2A3CU, 0x2F37A2ADU, 0xA848E8F7U, 0x23712F57U, 0xF52CB578U, 0x5E2BD5BBU, 0x5CED41D1U, + 0x76DC4190U, 0xF0794F05U, 0x709A8DC0U, 0x9B14583DU, 0x58F35849U, 0x0F580A6CU, 0x440B7579U, 0x299DC2EDU, + 0x01DB7106U, 0xE9627E44U, 0x7158E7F7U, 0x23A83F58U, 0x659371F9U, 0xC404D9C9U, 0xE27C7ECDU, 0xE537C273U, + 0x98D220BCU, 0xC24F2D87U, 0x731E59AEU, 0x311D90B6U, 0x22330B29U, 0x4290AB67U, 0xD3946450U, 0x6BB8C590U, + 0xEFD5102AU, 0xDB541CC6U, 0x72DC3399U, 0x89A1F7D3U, 0x1F532299U, 0x89CC78C2U, 0x75E36FE4U, 0xA712C50EU, + 0x71B18589U, 0x94158A01U, 0x7793251CU, 0x1476CF6AU, 0xAD73FE89U, 0x94C9487AU, 0xB044516AU, 0xADD7CC17U, + 0x06B6B51FU, 0x8D0EBB40U, 0x76514F2BU, 0xACCAA80FU, 0x9013D739U, 0x5F959BDFU, 0x16335ADEU, 0x617DCC89U, + 0x9FBFE4A5U, 0xA623E883U, 0x7417F172U, 0xBE7F07E1U, 0xD7B3ADE9U, 0xD901E971U, 0x27DB4043U, 0xEFF2CB6AU, + 0xE8B8D433U, 0xBF38D9C2U, 0x75D59B45U, 0x06C36084U, 0xEAD38459U, 0x125D3AD4U, 0x81AC4BF7U, 0x2358CBF4U, + 0x7807C9A2U, 0x38A0C50DU, 0x7E89DC78U, 0x5EA070D2U, 0x68831388U, 0xE30B8801U, 0x77E43B1EU, 0xFA78D958U, + 0x0F00F934U, 0x21BBF44CU, 0x7F4BB64FU, 0xE61C17B7U, 0x55E33A38U, 0x28575BA4U, 0xD19330AAU, 0x36D2D9C6U, + 0x9609A88EU, 0x0A96A78FU, 0x7D0D0816U, 0xF4A9B859U, 0x124340E8U, 0xAEC3290AU, 0xE07B2A37U, 0xB85DDE25U, + 0xE10E9818U, 0x138D96CEU, 0x7CCF6221U, 0x4C15DF3CU, 0x2F236958U, 0x659FFAAFU, 0x460C2183U, 0x74F7DEBBU, + 0x7F6A0DBBU, 0x5CCC0009U, 0x798074A4U, 0xD1C2E785U, 0x9D03B548U, 0x789ACA17U, 0x83AB1F0DU, 0x7E32D7A2U, + 0x086D3D2DU, 0x45D73148U, 0x78421E93U, 0x697E80E0U, 0xA0639CF8U, 0xB3C619B2U, 0x25DC14B9U, 0xB298D73CU, + 0x91646C97U, 0x6EFA628BU, 0x7A04A0CAU, 0x7BCB2F0EU, 0xE7C3E628U, 0x35526B1CU, 0x14340E24U, 0x3C17D0DFU, + 0xE6635C01U, 0x77E153CAU, 0x7BC6CAFDU, 0xC377486BU, 0xDAA3CF98U, 0xFE0EB8B9U, 0xB2430590U, 0xF0BDD041U, + 0x6B6B51F4U, 0xBABB5D54U, 0x6CBC2EB0U, 0xCB0D0FA2U, 0x3813CFCBU, 0x0C8E08F7U, 0x23D5E9B7U, 0x5526F3C6U, + 0x1C6C6162U, 0xA3A06C15U, 0x6D7E4487U, 0x73B168C7U, 0x0573E67BU, 0xC7D2DB52U, 0x85A2E203U, 0x998CF358U, + 0x856530D8U, 0x888D3FD6U, 0x6F38FADEU, 0x6104C729U, 0x42D39CABU, 0x4146A9FCU, 0xB44AF89EU, 0x1703F4BBU, + 0xF262004EU, 0x91960E97U, 0x6EFA90E9U, 0xD9B8A04CU, 0x7FB3B51BU, 0x8A1A7A59U, 0x123DF32AU, 0xDBA9F425U, + 0x6C0695EDU, 0xDED79850U, 0x6BB5866CU, 0x446F98F5U, 0xCD93690BU, 0x971F4AE1U, 0xD79ACDA4U, 0xD16CFD3CU, + 0x1B01A57BU, 0xC7CCA911U, 0x6A77EC5BU, 0xFCD3FF90U, 0xF0F340BBU, 0x5C439944U, 0x71EDC610U, 0x1DC6FDA2U, + 0x8208F4C1U, 0xECE1FAD2U, 0x68315202U, 0xEE66507EU, 0xB7533A6BU, 0xDAD7EBEAU, 0x4005DC8DU, 0x9349FA41U, + 0xF50FC457U, 0xF5FACB93U, 0x69F33835U, 0x56DA371BU, 0x8A3313DBU, 0x118B384FU, 0xE672D739U, 0x5FE3FADFU, + 0x65B0D9C6U, 0x7262D75CU, 0x62AF7F08U, 0x0EB9274DU, 0x0863840AU, 0xE0DD8A9AU, 0x103AA7D0U, 0x86C3E873U, + 0x12B7E950U, 0x6B79E61DU, 0x636D153FU, 0xB6054028U, 0x3503ADBAU, 0x2B81593FU, 0xB64DAC64U, 0x4A69E8EDU, + 0x8BBEB8EAU, 0x4054B5DEU, 0x612BAB66U, 0xA4B0EFC6U, 0x72A3D76AU, 0xAD152B91U, 0x87A5B6F9U, 0xC4E6EF0EU, + 0xFCB9887CU, 0x594F849FU, 0x60E9C151U, 0x1C0C88A3U, 0x4FC3FEDAU, 0x6649F834U, 0x21D2BD4DU, 0x084CEF90U, + 0x62DD1DDFU, 0x160E1258U, 0x65A6D7D4U, 0x81DBB01AU, 0xFDE322CAU, 0x7B4CC88CU, 0xE47583C3U, 0x0289E689U, + 0x15DA2D49U, 0x0F152319U, 0x6464BDE3U, 0x3967D77FU, 0xC0830B7AU, 0xB0101B29U, 0x42028877U, 0xCE23E617U, + 0x8CD37CF3U, 0x243870DAU, 0x662203BAU, 0x2BD27891U, 0x872371AAU, 0x36846987U, 0x73EA92EAU, 0x40ACE1F4U, + 0xFBD44C65U, 0x3D23419BU, 0x67E0698DU, 0x936E1FF4U, 0xBA43581AU, 0xFDD8BA22U, 0xD59D995EU, 0x8C06E16AU, + 0x4DB26158U, 0x65FD6BA7U, 0x48D7CB20U, 0x3B26F703U, 0x9932774DU, 0x08F40F5AU, 0x8BB64CE5U, 0xD0EBA0BBU, + 0x3AB551CEU, 0x7CE65AE6U, 0x4915A117U, 0x839A9066U, 0xA4525EFDU, 0xC3A8DCFFU, 0x2DC14751U, 0x1C41A025U, + 0xA3BC0074U, 0x57CB0925U, 0x4B531F4EU, 0x912F3F88U, 0xE3F2242DU, 0x453CAE51U, 0x1C295DCCU, 0x92CEA7C6U, + 0xD4BB30E2U, 0x4ED03864U, 0x4A917579U, 0x299358EDU, 0xDE920D9DU, 0x8E607DF4U, 0xBA5E5678U, 0x5E64A758U, + 0x4ADFA541U, 0x0191AEA3U, 0x4FDE63FCU, 0xB4446054U, 0x6CB2D18DU, 0x93654D4CU, 0x7FF968F6U, 0x54A1AE41U, + 0x3DD895D7U, 0x188A9FE2U, 0x4E1C09CBU, 0x0CF80731U, 0x51D2F83DU, 0x58399EE9U, 0xD98E6342U, 0x980BAEDFU, + 0xA4D1C46DU, 0x33A7CC21U, 0x4C5AB792U, 0x1E4DA8DFU, 0x167282EDU, 0xDEADEC47U, 0xE86679DFU, 0x1684A93CU, + 0xD3D6F4FBU, 0x2ABCFD60U, 0x4D98DDA5U, 0xA6F1CFBAU, 0x2B12AB5DU, 0x15F13FE2U, 0x4E11726BU, 0xDA2EA9A2U, + 0x4369E96AU, 0xAD24E1AFU, 0x46C49A98U, 0xFE92DFECU, 0xA9423C8CU, 0xE4A78D37U, 0xB8590282U, 0x030EBB0EU, + 0x346ED9FCU, 0xB43FD0EEU, 0x4706F0AFU, 0x462EB889U, 0x9422153CU, 0x2FFB5E92U, 0x1E2E0936U, 0xCFA4BB90U, + 0xAD678846U, 0x9F12832DU, 0x45404EF6U, 0x549B1767U, 0xD3826FECU, 0xA96F2C3CU, 0x2FC613ABU, 0x412BBC73U, + 0xDA60B8D0U, 0x8609B26CU, 0x448224C1U, 0xEC277002U, 0xEEE2465CU, 0x6233FF99U, 0x89B1181FU, 0x8D81BCEDU, + 0x44042D73U, 0xC94824ABU, 0x41CD3244U, 0x71F048BBU, 0x5CC29A4CU, 0x7F36CF21U, 0x4C162691U, 0x8744B5F4U, + 0x33031DE5U, 0xD05315EAU, 0x400F5873U, 0xC94C2FDEU, 0x61A2B3FCU, 0xB46A1C84U, 0xEA612D25U, 0x4BEEB56AU, + 0xAA0A4C5FU, 0xFB7E4629U, 0x4249E62AU, 0xDBF98030U, 0x2602C92CU, 0x32FE6E2AU, 0xDB8937B8U, 0xC561B289U, + 0xDD0D7CC9U, 0xE2657768U, 0x438B8C1DU, 0x6345E755U, 0x1B62E09CU, 0xF9A2BD8FU, 0x7DFE3C0CU, 0x09CBB217U, + 0x5005713CU, 0x2F3F79F6U, 0x54F16850U, 0x6B3FA09CU, 0xF9D2E0CFU, 0x0B220DC1U, 0xEC68D02BU, 0xAC509190U, + 0x270241AAU, 0x362448B7U, 0x55330267U, 0xD383C7F9U, 0xC4B2C97FU, 0xC07EDE64U, 0x4A1FDB9FU, 0x60FA910EU, + 0xBE0B1010U, 0x1D091B74U, 0x5775BC3EU, 0xC1366817U, 0x8312B3AFU, 0x46EAACCAU, 0x7BF7C102U, 0xEE7596EDU, + 0xC90C2086U, 0x04122A35U, 0x56B7D609U, 0x798A0F72U, 0xBE729A1FU, 0x8DB67F6FU, 0xDD80CAB6U, 0x22DF9673U, + 0x5768B525U, 0x4B53BCF2U, 0x53F8C08CU, 0xE45D37CBU, 0x0C52460FU, 0x90B34FD7U, 0x1827F438U, 0x281A9F6AU, + 0x206F85B3U, 0x52488DB3U, 0x523AAABBU, 0x5CE150AEU, 0x31326FBFU, 0x5BEF9C72U, 0xBE50FF8CU, 0xE4B09FF4U, + 0xB966D409U, 0x7965DE70U, 0x507C14E2U, 0x4E54FF40U, 0x7692156FU, 0xDD7BEEDCU, 0x8FB8E511U, 0x6A3F9817U, + 0xCE61E49FU, 0x607EEF31U, 0x51BE7ED5U, 0xF6E89825U, 0x4BF23CDFU, 0x16273D79U, 0x29CFEEA5U, 0xA6959889U, + 0x5EDEF90EU, 0xE7E6F3FEU, 0x5AE239E8U, 0xAE8B8873U, 0xC9A2AB0EU, 0xE7718FACU, 0xDF879E4CU, 0x7FB58A25U, + 0x29D9C998U, 0xFEFDC2BFU, 0x5B2053DFU, 0x1637EF16U, 0xF4C282BEU, 0x2C2D5C09U, 0x79F095F8U, 0xB31F8ABBU, + 0xB0D09822U, 0xD5D0917CU, 0x5966ED86U, 0x048240F8U, 0xB362F86EU, 0xAAB92EA7U, 0x48188F65U, 0x3D908D58U, + 0xC7D7A8B4U, 0xCCCBA03DU, 0x58A487B1U, 0xBC3E279DU, 0x8E02D1DEU, 0x61E5FD02U, 0xEE6F84D1U, 0xF13A8DC6U, + 0x59B33D17U, 0x838A36FAU, 0x5DEB9134U, 0x21E91F24U, 0x3C220DCEU, 0x7CE0CDBAU, 0x2BC8BA5FU, 0xFBFF84DFU, + 0x2EB40D81U, 0x9A9107BBU, 0x5C29FB03U, 0x99557841U, 0x0142247EU, 0xB7BC1E1FU, 0x8DBFB1EBU, 0x37558441U, + 0xB7BD5C3BU, 0xB1BC5478U, 0x5E6F455AU, 0x8BE0D7AFU, 0x46E25EAEU, 0x31286CB1U, 0xBC57AB76U, 0xB9DA83A2U, + 0xC0BA6CADU, 0xA8A76539U, 0x5FAD2F6DU, 0x335CB0CAU, 0x7B82771EU, 0xFA74BF14U, 0x1A20A0C2U, 0x7570833CU, + 0xEDB88320U, 0x3B83984BU, 0xE1351B80U, 0xED59B63BU, 0xB1E6B092U, 0x1EB014D8U, 0x8816EAF2U, 0x533B85DAU, + 0x9ABFB3B6U, 0x2298A90AU, 0xE0F771B7U, 0x55E5D15EU, 0x8C869922U, 0xD5ECC77DU, 0x2E61E146U, 0x9F918544U, + 0x03B6E20CU, 0x09B5FAC9U, 0xE2B1CFEEU, 0x47507EB0U, 0xCB26E3F2U, 0x5378B5D3U, 0x1F89FBDBU, 0x111E82A7U, + 0x74B1D29AU, 0x10AECB88U, 0xE373A5D9U, 0xFFEC19D5U, 0xF646CA42U, 0x98246676U, 0xB9FEF06FU, 0xDDB48239U, + 0xEAD54739U, 0x5FEF5D4FU, 0xE63CB35CU, 0x623B216CU, 0x44661652U, 0x852156CEU, 0x7C59CEE1U, 0xD7718B20U, + 0x9DD277AFU, 0x46F46C0EU, 0xE7FED96BU, 0xDA874609U, 0x79063FE2U, 0x4E7D856BU, 0xDA2EC555U, 0x1BDB8BBEU, + 0x04DB2615U, 0x6DD93FCDU, 0xE5B86732U, 0xC832E9E7U, 0x3EA64532U, 0xC8E9F7C5U, 0xEBC6DFC8U, 0x95548C5DU, + 0x73DC1683U, 0x74C20E8CU, 0xE47A0D05U, 0x708E8E82U, 0x03C66C82U, 0x03B52460U, 0x4DB1D47CU, 0x59FE8CC3U, + 0xE3630B12U, 0xF35A1243U, 0xEF264A38U, 0x28ED9ED4U, 0x8196FB53U, 0xF2E396B5U, 0xBBF9A495U, 0x80DE9E6FU, + 0x94643B84U, 0xEA412302U, 0xEEE4200FU, 0x9051F9B1U, 0xBCF6D2E3U, 0x39BF4510U, 0x1D8EAF21U, 0x4C749EF1U, + 0x0D6D6A3EU, 0xC16C70C1U, 0xECA29E56U, 0x82E4565FU, 0xFB56A833U, 0xBF2B37BEU, 0x2C66B5BCU, 0xC2FB9912U, + 0x7A6A5AA8U, 0xD8774180U, 0xED60F461U, 0x3A58313AU, 0xC6368183U, 0x7477E41BU, 0x8A11BE08U, 0x0E51998CU, + 0xE40ECF0BU, 0x9736D747U, 0xE82FE2E4U, 0xA78F0983U, 0x74165D93U, 0x6972D4A3U, 0x4FB68086U, 0x04949095U, + 0x9309FF9DU, 0x8E2DE606U, 0xE9ED88D3U, 0x1F336EE6U, 0x49767423U, 0xA22E0706U, 0xE9C18B32U, 0xC83E900BU, + 0x0A00AE27U, 0xA500B5C5U, 0xEBAB368AU, 0x0D86C108U, 0x0ED60EF3U, 0x24BA75A8U, 0xD82991AFU, 0x46B197E8U, + 0x7D079EB1U, 0xBC1B8484U, 0xEA695CBDU, 0xB53AA66DU, 0x33B62743U, 0xEFE6A60DU, 0x7E5E9A1BU, 0x8A1B9776U, + 0xF00F9344U, 0x71418A1AU, 0xFD13B8F0U, 0xBD40E1A4U, 0xD1062710U, 0x1D661643U, 0xEFC8763CU, 0x2F80B4F1U, + 0x8708A3D2U, 0x685ABB5BU, 0xFCD1D2C7U, 0x05FC86C1U, 0xEC660EA0U, 0xD63AC5E6U, 0x49BF7D88U, 0xE32AB46FU, + 0x1E01F268U, 0x4377E898U, 0xFE976C9EU, 0x1749292FU, 0xABC67470U, 0x50AEB748U, 0x78576715U, 0x6DA5B38CU, + 0x6906C2FEU, 0x5A6CD9D9U, 0xFF5506A9U, 0xAFF54E4AU, 0x96A65DC0U, 0x9BF264EDU, 0xDE206CA1U, 0xA10FB312U, + 0xF762575DU, 0x152D4F1EU, 0xFA1A102CU, 0x322276F3U, 0x248681D0U, 0x86F75455U, 0x1B87522FU, 0xABCABA0BU, + 0x806567CBU, 0x0C367E5FU, 0xFBD87A1BU, 0x8A9E1196U, 0x19E6A860U, 0x4DAB87F0U, 0xBDF0599BU, 0x6760BA95U, + 0x196C3671U, 0x271B2D9CU, 0xF99EC442U, 0x982BBE78U, 0x5E46D2B0U, 0xCB3FF55EU, 0x8C184306U, 0xE9EFBD76U, + 0x6E6B06E7U, 0x3E001CDDU, 0xF85CAE75U, 0x2097D91DU, 0x6326FB00U, 0x006326FBU, 0x2A6F48B2U, 0x2545BDE8U, + 0xFED41B76U, 0xB9980012U, 0xF300E948U, 0x78F4C94BU, 0xE1766CD1U, 0xF135942EU, 0xDC27385BU, 0xFC65AF44U, + 0x89D32BE0U, 0xA0833153U, 0xF2C2837FU, 0xC048AE2EU, 0xDC164561U, 0x3A69478BU, 0x7A5033EFU, 0x30CFAFDAU, + 0x10DA7A5AU, 0x8BAE6290U, 0xF0843D26U, 0xD2FD01C0U, 0x9BB63FB1U, 0xBCFD3525U, 0x4BB82972U, 0xBE40A839U, + 0x67DD4ACCU, 0x92B553D1U, 0xF1465711U, 0x6A4166A5U, 0xA6D61601U, 0x77A1E680U, 0xEDCF22C6U, 0x72EAA8A7U, + 0xF9B9DF6FU, 0xDDF4C516U, 0xF4094194U, 0xF7965E1CU, 0x14F6CA11U, 0x6AA4D638U, 0x28681C48U, 0x782FA1BEU, + 0x8EBEEFF9U, 0xC4EFF457U, 0xF5CB2BA3U, 0x4F2A3979U, 0x2996E3A1U, 0xA1F8059DU, 0x8E1F17FCU, 0xB485A120U, + 0x17B7BE43U, 0xEFC2A794U, 0xF78D95FAU, 0x5D9F9697U, 0x6E369971U, 0x276C7733U, 0xBFF70D61U, 0x3A0AA6C3U, + 0x60B08ED5U, 0xF6D996D5U, 0xF64FFFCDU, 0xE523F1F2U, 0x5356B0C1U, 0xEC30A496U, 0x198006D5U, 0xF6A0A65DU, + 0xD6D6A3E8U, 0xAE07BCE9U, 0xD9785D60U, 0x4D6B1905U, 0x70279F96U, 0x191C11EEU, 0x47ABD36EU, 0xAA4DE78CU, + 0xA1D1937EU, 0xB71C8DA8U, 0xD8BA3757U, 0xF5D77E60U, 0x4D47B626U, 0xD240C24BU, 0xE1DCD8DAU, 0x66E7E712U, + 0x38D8C2C4U, 0x9C31DE6BU, 0xDAFC890EU, 0xE762D18EU, 0x0AE7CCF6U, 0x54D4B0E5U, 0xD034C247U, 0xE868E0F1U, + 0x4FDFF252U, 0x852AEF2AU, 0xDB3EE339U, 0x5FDEB6EBU, 0x3787E546U, 0x9F886340U, 0x7643C9F3U, 0x24C2E06FU, + 0xD1BB67F1U, 0xCA6B79EDU, 0xDE71F5BCU, 0xC2098E52U, 0x85A73956U, 0x828D53F8U, 0xB3E4F77DU, 0x2E07E976U, + 0xA6BC5767U, 0xD37048ACU, 0xDFB39F8BU, 0x7AB5E937U, 0xB8C710E6U, 0x49D1805DU, 0x1593FCC9U, 0xE2ADE9E8U, + 0x3FB506DDU, 0xF85D1B6FU, 0xDDF521D2U, 0x680046D9U, 0xFF676A36U, 0xCF45F2F3U, 0x247BE654U, 0x6C22EE0BU, + 0x48B2364BU, 0xE1462A2EU, 0xDC374BE5U, 0xD0BC21BCU, 0xC2074386U, 0x04192156U, 0x820CEDE0U, 0xA088EE95U, + 0xD80D2BDAU, 0x66DE36E1U, 0xD76B0CD8U, 0x88DF31EAU, 0x4057D457U, 0xF54F9383U, 0x74449D09U, 0x79A8FC39U, + 0xAF0A1B4CU, 0x7FC507A0U, 0xD6A966EFU, 0x3063568FU, 0x7D37FDE7U, 0x3E134026U, 0xD23396BDU, 0xB502FCA7U, + 0x36034AF6U, 0x54E85463U, 0xD4EFD8B6U, 0x22D6F961U, 0x3A978737U, 0xB8873288U, 0xE3DB8C20U, 0x3B8DFB44U, + 0x41047A60U, 0x4DF36522U, 0xD52DB281U, 0x9A6A9E04U, 0x07F7AE87U, 0x73DBE12DU, 0x45AC8794U, 0xF727FBDAU, + 0xDF60EFC3U, 0x02B2F3E5U, 0xD062A404U, 0x07BDA6BDU, 0xB5D77297U, 0x6EDED195U, 0x800BB91AU, 0xFDE2F2C3U, + 0xA867DF55U, 0x1BA9C2A4U, 0xD1A0CE33U, 0xBF01C1D8U, 0x88B75B27U, 0xA5820230U, 0x267CB2AEU, 0x3148F25DU, + 0x316E8EEFU, 0x30849167U, 0xD3E6706AU, 0xADB46E36U, 0xCF1721F7U, 0x2316709EU, 0x1794A833U, 0xBFC7F5BEU, + 0x4669BE79U, 0x299FA026U, 0xD2241A5DU, 0x15080953U, 0xF2770847U, 0xE84AA33BU, 0xB1E3A387U, 0x736DF520U, + 0xCB61B38CU, 0xE4C5AEB8U, 0xC55EFE10U, 0x1D724E9AU, 0x10C70814U, 0x1ACA1375U, 0x20754FA0U, 0xD6F6D6A7U, + 0xBC66831AU, 0xFDDE9FF9U, 0xC49C9427U, 0xA5CE29FFU, 0x2DA721A4U, 0xD196C0D0U, 0x86024414U, 0x1A5CD639U, + 0x256FD2A0U, 0xD6F3CC3AU, 0xC6DA2A7EU, 0xB77B8611U, 0x6A075B74U, 0x5702B27EU, 0xB7EA5E89U, 0x94D3D1DAU, + 0x5268E236U, 0xCFE8FD7BU, 0xC7184049U, 0x0FC7E174U, 0x576772C4U, 0x9C5E61DBU, 0x119D553DU, 0x5879D144U, + 0xCC0C7795U, 0x80A96BBCU, 0xC25756CCU, 0x9210D9CDU, 0xE547AED4U, 0x815B5163U, 0xD43A6BB3U, 0x52BCD85DU, + 0xBB0B4703U, 0x99B25AFDU, 0xC3953CFBU, 0x2AACBEA8U, 0xD8278764U, 0x4A0782C6U, 0x724D6007U, 0x9E16D8C3U, + 0x220216B9U, 0xB29F093EU, 0xC1D382A2U, 0x38191146U, 0x9F87FDB4U, 0xCC93F068U, 0x43A57A9AU, 0x1099DF20U, + 0x5505262FU, 0xAB84387FU, 0xC011E895U, 0x80A57623U, 0xA2E7D404U, 0x07CF23CDU, 0xE5D2712EU, 0xDC33DFBEU, + 0xC5BA3BBEU, 0x2C1C24B0U, 0xCB4DAFA8U, 0xD8C66675U, 0x20B743D5U, 0xF6999118U, 0x139A01C7U, 0x0513CD12U, + 0xB2BD0B28U, 0x350715F1U, 0xCA8FC59FU, 0x607A0110U, 0x1DD76A65U, 0x3DC542BDU, 0xB5ED0A73U, 0xC9B9CD8CU, + 0x2BB45A92U, 0x1E2A4632U, 0xC8C97BC6U, 0x72CFAEFEU, 0x5A7710B5U, 0xBB513013U, 0x840510EEU, 0x4736CA6FU, + 0x5CB36A04U, 0x07317773U, 0xC90B11F1U, 0xCA73C99BU, 0x67173905U, 0x700DE3B6U, 0x22721B5AU, 0x8B9CCAF1U, + 0xC2D7FFA7U, 0x4870E1B4U, 0xCC440774U, 0x57A4F122U, 0xD537E515U, 0x6D08D30EU, 0xE7D525D4U, 0x8159C3E8U, + 0xB5D0CF31U, 0x516BD0F5U, 0xCD866D43U, 0xEF189647U, 0xE857CCA5U, 0xA65400ABU, 0x41A22E60U, 0x4DF3C376U, + 0x2CD99E8BU, 0x7A468336U, 0xCFC0D31AU, 0xFDAD39A9U, 0xAFF7B675U, 0x20C07205U, 0x704A34FDU, 0xC37CC495U, + 0x5BDEAE1DU, 0x635DB277U, 0xCE02B92DU, 0x45115ECCU, 0x92979FC5U, 0xEB9CA1A0U, 0xD63D3F49U, 0x0FD6C40BU, + 0x9B64C2B0U, 0xCBFAD74EU, 0x91AF9640U, 0x764DEE06U, 0xE915E8DBU, 0x11E81EB4U, 0xCC1D9F8BU, 0x7AA64737U, + 0xEC63F226U, 0xD2E1E60FU, 0x906DFC77U, 0xCEF18963U, 0xD475C16BU, 0xDAB4CD11U, 0x6A6A943FU, 0xB60C47A9U, + 0x756AA39CU, 0xF9CCB5CCU, 0x922B422EU, 0xDC44268DU, 0x93D5BBBBU, 0x5C20BFBFU, 0x5B828EA2U, 0x3883404AU, + 0x026D930AU, 0xE0D7848DU, 0x93E92819U, 0x64F841E8U, 0xAEB5920BU, 0x977C6C1AU, 0xFDF58516U, 0xF42940D4U, + 0x9C0906A9U, 0xAF96124AU, 0x96A63E9CU, 0xF92F7951U, 0x1C954E1BU, 0x8A795CA2U, 0x3852BB98U, 0xFEEC49CDU, + 0xEB0E363FU, 0xB68D230BU, 0x976454ABU, 0x41931E34U, 0x21F567ABU, 0x41258F07U, 0x9E25B02CU, 0x32464953U, + 0x72076785U, 0x9DA070C8U, 0x9522EAF2U, 0x5326B1DAU, 0x66551D7BU, 0xC7B1FDA9U, 0xAFCDAAB1U, 0xBCC94EB0U, + 0x05005713U, 0x84BB4189U, 0x94E080C5U, 0xEB9AD6BFU, 0x5B3534CBU, 0x0CED2E0CU, 0x09BAA105U, 0x70634E2EU, + 0x95BF4A82U, 0x03235D46U, 0x9FBCC7F8U, 0xB3F9C6E9U, 0xD965A31AU, 0xFDBB9CD9U, 0xFFF2D1ECU, 0xA9435C82U, + 0xE2B87A14U, 0x1A386C07U, 0x9E7EADCFU, 0x0B45A18CU, 0xE4058AAAU, 0x36E74F7CU, 0x5985DA58U, 0x65E95C1CU, + 0x7BB12BAEU, 0x31153FC4U, 0x9C381396U, 0x19F00E62U, 0xA3A5F07AU, 0xB0733DD2U, 0x686DC0C5U, 0xEB665BFFU, + 0x0CB61B38U, 0x280E0E85U, 0x9DFA79A1U, 0xA14C6907U, 0x9EC5D9CAU, 0x7B2FEE77U, 0xCE1ACB71U, 0x27CC5B61U, + 0x92D28E9BU, 0x674F9842U, 0x98B56F24U, 0x3C9B51BEU, 0x2CE505DAU, 0x662ADECFU, 0x0BBDF5FFU, 0x2D095278U, + 0xE5D5BE0DU, 0x7E54A903U, 0x99770513U, 0x842736DBU, 0x11852C6AU, 0xAD760D6AU, 0xADCAFE4BU, 0xE1A352E6U, + 0x7CDCEFB7U, 0x5579FAC0U, 0x9B31BB4AU, 0x96929935U, 0x562556BAU, 0x2BE27FC4U, 0x9C22E4D6U, 0x6F2C5505U, + 0x0BDBDF21U, 0x4C62CB81U, 0x9AF3D17DU, 0x2E2EFE50U, 0x6B457F0AU, 0xE0BEAC61U, 0x3A55EF62U, 0xA386559BU, + 0x86D3D2D4U, 0x8138C51FU, 0x8D893530U, 0x2654B999U, 0x89F57F59U, 0x123E1C2FU, 0xABC30345U, 0x061D761CU, + 0xF1D4E242U, 0x9823F45EU, 0x8C4B5F07U, 0x9EE8DEFCU, 0xB49556E9U, 0xD962CF8AU, 0x0DB408F1U, 0xCAB77682U, + 0x68DDB3F8U, 0xB30EA79DU, 0x8E0DE15EU, 0x8C5D7112U, 0xF3352C39U, 0x5FF6BD24U, 0x3C5C126CU, 0x44387161U, + 0x1FDA836EU, 0xAA1596DCU, 0x8FCF8B69U, 0x34E11677U, 0xCE550589U, 0x94AA6E81U, 0x9A2B19D8U, 0x889271FFU, + 0x81BE16CDU, 0xE554001BU, 0x8A809DECU, 0xA9362ECEU, 0x7C75D999U, 0x89AF5E39U, 0x5F8C2756U, 0x825778E6U, + 0xF6B9265BU, 0xFC4F315AU, 0x8B42F7DBU, 0x118A49ABU, 0x4115F029U, 0x42F38D9CU, 0xF9FB2CE2U, 0x4EFD7878U, + 0x6FB077E1U, 0xD7626299U, 0x89044982U, 0x033FE645U, 0x06B58AF9U, 0xC467FF32U, 0xC813367FU, 0xC0727F9BU, + 0x18B74777U, 0xCE7953D8U, 0x88C623B5U, 0xBB838120U, 0x3BD5A349U, 0x0F3B2C97U, 0x6E643DCBU, 0x0CD87F05U, + 0x88085AE6U, 0x49E14F17U, 0x839A6488U, 0xE3E09176U, 0xB9853498U, 0xFE6D9E42U, 0x982C4D22U, 0xD5F86DA9U, + 0xFF0F6A70U, 0x50FA7E56U, 0x82580EBFU, 0x5B5CF613U, 0x84E51D28U, 0x35314DE7U, 0x3E5B4696U, 0x19526D37U, + 0x66063BCAU, 0x7BD72D95U, 0x801EB0E6U, 0x49E959FDU, 0xC34567F8U, 0xB3A53F49U, 0x0FB35C0BU, 0x97DD6AD4U, + 0x11010B5CU, 0x62CC1CD4U, 0x81DCDAD1U, 0xF1553E98U, 0xFE254E48U, 0x78F9ECECU, 0xA9C457BFU, 0x5B776A4AU, + 0x8F659EFFU, 0x2D8D8A13U, 0x8493CC54U, 0x6C820621U, 0x4C059258U, 0x65FCDC54U, 0x6C636931U, 0x51B26353U, + 0xF862AE69U, 0x3496BB52U, 0x8551A663U, 0xD43E6144U, 0x7165BBE8U, 0xAEA00FF1U, 0xCA146285U, 0x9D1863CDU, + 0x616BFFD3U, 0x1FBBE891U, 0x8717183AU, 0xC68BCEAAU, 0x36C5C138U, 0x28347D5FU, 0xFBFC7818U, 0x1397642EU, + 0x166CCF45U, 0x06A0D9D0U, 0x86D5720DU, 0x7E37A9CFU, 0x0BA5E888U, 0xE368AEFAU, 0x5D8B73ACU, 0xDF3D64B0U, + 0xA00AE278U, 0x5E7EF3ECU, 0xA9E2D0A0U, 0xD67F4138U, 0x28D4C7DFU, 0x16441B82U, 0x03A0A617U, 0x83D02561U, + 0xD70DD2EEU, 0x4765C2ADU, 0xA820BA97U, 0x6EC3265DU, 0x15B4EE6FU, 0xDD18C827U, 0xA5D7ADA3U, 0x4F7A25FFU, + 0x4E048354U, 0x6C48916EU, 0xAA6604CEU, 0x7C7689B3U, 0x521494BFU, 0x5B8CBA89U, 0x943FB73EU, 0xC1F5221CU, + 0x3903B3C2U, 0x7553A02FU, 0xABA46EF9U, 0xC4CAEED6U, 0x6F74BD0FU, 0x90D0692CU, 0x3248BC8AU, 0x0D5F2282U, + 0xA7672661U, 0x3A1236E8U, 0xAEEB787CU, 0x591DD66FU, 0xDD54611FU, 0x8DD55994U, 0xF7EF8204U, 0x079A2B9BU, + 0xD06016F7U, 0x230907A9U, 0xAF29124BU, 0xE1A1B10AU, 0xE03448AFU, 0x46898A31U, 0x519889B0U, 0xCB302B05U, + 0x4969474DU, 0x0824546AU, 0xAD6FAC12U, 0xF3141EE4U, 0xA794327FU, 0xC01DF89FU, 0x6070932DU, 0x45BF2CE6U, + 0x3E6E77DBU, 0x113F652BU, 0xACADC625U, 0x4BA87981U, 0x9AF41BCFU, 0x0B412B3AU, 0xC6079899U, 0x89152C78U, + 0xAED16A4AU, 0x96A779E4U, 0xA7F18118U, 0x13CB69D7U, 0x18A48C1EU, 0xFA1799EFU, 0x304FE870U, 0x50353ED4U, + 0xD9D65ADCU, 0x8FBC48A5U, 0xA633EB2FU, 0xAB770EB2U, 0x25C4A5AEU, 0x314B4A4AU, 0x9638E3C4U, 0x9C9F3E4AU, + 0x40DF0B66U, 0xA4911B66U, 0xA4755576U, 0xB9C2A15CU, 0x6264DF7EU, 0xB7DF38E4U, 0xA7D0F959U, 0x121039A9U, + 0x37D83BF0U, 0xBD8A2A27U, 0xA5B73F41U, 0x017EC639U, 0x5F04F6CEU, 0x7C83EB41U, 0x01A7F2EDU, 0xDEBA3937U, + 0xA9BCAE53U, 0xF2CBBCE0U, 0xA0F829C4U, 0x9CA9FE80U, 0xED242ADEU, 0x6186DBF9U, 0xC400CC63U, 0xD47F302EU, + 0xDEBB9EC5U, 0xEBD08DA1U, 0xA13A43F3U, 0x241599E5U, 0xD044036EU, 0xAADA085CU, 0x6277C7D7U, 0x18D530B0U, + 0x47B2CF7FU, 0xC0FDDE62U, 0xA37CFDAAU, 0x36A0360BU, 0x97E479BEU, 0x2C4E7AF2U, 0x539FDD4AU, 0x965A3753U, + 0x30B5FFE9U, 0xD9E6EF23U, 0xA2BE979DU, 0x8E1C516EU, 0xAA84500EU, 0xE712A957U, 0xF5E8D6FEU, 0x5AF037CDU, + 0xBDBDF21CU, 0x14BCE1BDU, 0xB5C473D0U, 0x866616A7U, 0x4834505DU, 0x15921919U, 0x647E3AD9U, 0xFF6B144AU, + 0xCABAC28AU, 0x0DA7D0FCU, 0xB40619E7U, 0x3EDA71C2U, 0x755479EDU, 0xDECECABCU, 0xC209316DU, 0x33C114D4U, + 0x53B39330U, 0x268A833FU, 0xB640A7BEU, 0x2C6FDE2CU, 0x32F4033DU, 0x585AB812U, 0xF3E12BF0U, 0xBD4E1337U, + 0x24B4A3A6U, 0x3F91B27EU, 0xB782CD89U, 0x94D3B949U, 0x0F942A8DU, 0x93066BB7U, 0x55962044U, 0x71E413A9U, + 0xBAD03605U, 0x70D024B9U, 0xB2CDDB0CU, 0x090481F0U, 0xBDB4F69DU, 0x8E035B0FU, 0x90311ECAU, 0x7B211AB0U, + 0xCDD70693U, 0x69CB15F8U, 0xB30FB13BU, 0xB1B8E695U, 0x80D4DF2DU, 0x455F88AAU, 0x3646157EU, 0xB78B1A2EU, + 0x54DE5729U, 0x42E6463BU, 0xB1490F62U, 0xA30D497BU, 0xC774A5FDU, 0xC3CBFA04U, 0x07AE0FE3U, 0x39041DCDU, + 0x23D967BFU, 0x5BFD777AU, 0xB08B6555U, 0x1BB12E1EU, 0xFA148C4DU, 0x089729A1U, 0xA1D90457U, 0xF5AE1D53U, + 0xB3667A2EU, 0xDC656BB5U, 0xBBD72268U, 0x43D23E48U, 0x78441B9CU, 0xF9C19B74U, 0x579174BEU, 0x2C8E0FFFU, + 0xC4614AB8U, 0xC57E5AF4U, 0xBA15485FU, 0xFB6E592DU, 0x4524322CU, 0x329D48D1U, 0xF1E67F0AU, 0xE0240F61U, + 0x5D681B02U, 0xEE530937U, 0xB853F606U, 0xE9DBF6C3U, 0x028448FCU, 0xB4093A7FU, 0xC00E6597U, 0x6EAB0882U, + 0x2A6F2B94U, 0xF7483876U, 0xB9919C31U, 0x516791A6U, 0x3FE4614CU, 0x7F55E9DAU, 0x66796E23U, 0xA201081CU, + 0xB40BBE37U, 0xB809AEB1U, 0xBCDE8AB4U, 0xCCB0A91FU, 0x8DC4BD5CU, 0x6250D962U, 0xA3DE50ADU, 0xA8C40105U, + 0xC30C8EA1U, 0xA1129FF0U, 0xBD1CE083U, 0x740CCE7AU, 0xB0A494ECU, 0xA90C0AC7U, 0x05A95B19U, 0x646E019BU, + 0x5A05DF1BU, 0x8A3FCC33U, 0xBF5A5EDAU, 0x66B96194U, 0xF704EE3CU, 0x2F987869U, 0x34414184U, 0xEAE10678U, + 0x2D02EF8DU, 0x9324FD72U, 0xBE9834EDU, 0xDE0506F1U, 0xCA64C78CU, 0xE4C4ABCCU, 0x92364A30U, 0x264B06E6U, + }; + + uint32_t ulCrc32; + + if( pBuffer == NULL ) + { + REDERROR(); + ulCrc32 = SUSPICIOUS_CRC_VALUE; + } + else + { + const uint8_t * pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pBuffer ); + uint32_t ulIdx = 0U; + const uint32_t * pulXorCrc0 = &aulCrc32Table[ 7U ]; + const uint32_t * pulXorCrc1 = &aulCrc32Table[ 6U ]; + const uint32_t * pulXorCrc2 = &aulCrc32Table[ 5U ]; + const uint32_t * pulXorCrc3 = &aulCrc32Table[ 4U ]; + const uint32_t * pulXorData4 = &aulCrc32Table[ 3U ]; + const uint32_t * pulXorData5 = &aulCrc32Table[ 2U ]; + const uint32_t * pulXorData6 = &aulCrc32Table[ 1U ]; + const uint32_t * pulXorData7 = &aulCrc32Table[ 0U ]; + uint32_t ulSliceLen; + + ulCrc32 = ~ulInitCrc32; + + /* Aligned memory access is used below. To avoid suboptimal + * performance and faults (depending on platform), handle the + * unaligned initial bytes (if any) using the Sarwate algorithm. + */ + while( ( ulIdx < ulLength ) && !IS_ALIGNED_PTR( &pbBuffer[ ulIdx ] ) ) + { + ulCrc32 = ( ulCrc32 >> 8U ) ^ aulCrc32Table[ ( ( ulCrc32 ^ pbBuffer[ ulIdx ] ) & 0xFFU ) << 3U ]; + + ulIdx++; + } + + /* Round down the length to the nearest multiple of eight. + */ + ulSliceLen = ( ( ( ulLength - ulIdx ) >> 3U ) << 3U ) + ulIdx; + + /* Compute the CRC in eight byte "slices". Takes advantage of + * modern processors which can load in parallel from multiple + * memory locations. + */ + while( ulIdx < ulSliceLen ) + { + #if REDCONF_ENDIAN_BIG == 1 + ulCrc32 ^= pbBuffer[ ulIdx ] | ( ( uint32_t ) pbBuffer[ ulIdx + 1U ] << 8U ) | + ( ( uint32_t ) pbBuffer[ ulIdx + 2U ] << 16U ) | ( ( uint32_t ) pbBuffer[ ulIdx + 3U ] << 24U ); + #else + ulCrc32 ^= *CAST_CONST_UINT32_PTR( &pbBuffer[ ulIdx ] ); + #endif + + ulCrc32 = + pulXorCrc3[ ( ( ulCrc32 >> 24U ) & 0xFFU ) << 3U ] ^ + pulXorCrc2[ ( ( ulCrc32 >> 16U ) & 0xFFU ) << 3U ] ^ + pulXorCrc1[ ( ( ulCrc32 >> 8U ) & 0xFFU ) << 3U ] ^ + pulXorCrc0[ ( ulCrc32 & 0xFFU ) << 3U ] ^ + pulXorData7[ pbBuffer[ ulIdx + 7U ] << 3U ] ^ + pulXorData6[ pbBuffer[ ulIdx + 6U ] << 3U ] ^ + pulXorData5[ pbBuffer[ ulIdx + 5U ] << 3U ] ^ + pulXorData4[ pbBuffer[ ulIdx + 4U ] << 3U ]; + + ulIdx += 8U; + } + + /* Compute the remaining bytes with the Sarwate algorithm. + */ + while( ulIdx < ulLength ) + { + ulCrc32 = ( ulCrc32 >> 8U ) ^ aulCrc32Table[ ( ( ulCrc32 ^ pbBuffer[ ulIdx ] ) & 0xFFU ) << 3U ]; + + ulIdx++; + } + + ulCrc32 = ~ulCrc32; + } + + return ulCrc32; + } + +#else /* if REDCONF_CRC_ALGORITHM == CRC_BITWISE */ + + #error "REDCONF_CRC_ALGORITHM must be set to CRC_BITWISE, CRC_SARWATE, or CRC_SLICEBY8" + +#endif /* if REDCONF_CRC_ALGORITHM == CRC_BITWISE */ + + +/** @brief Compute a CRC32 for a metadata node buffer. + * + * @param pBuffer The metadata node buffer for which to compute a CRC. Must + * be a block sized buffer. + * + * @return The CRC of the buffer. + */ +uint32_t RedCrcNode( const void * pBuffer ) +{ + uint32_t ulCrc; + + if( pBuffer == NULL ) + { + REDERROR(); + ulCrc = SUSPICIOUS_CRC_VALUE; + } + else + { + const uint8_t * pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pBuffer ); + + /* The first eight bytes of a metadata node contain the signature and + * the CRC. There is little value in CRCing the signature, and the + * CRC cannot be CRC'd, so skip over that part of the buffer. + */ + ulCrc = RedCrc32Update( 0U, &pbBuffer[ 8U ], REDCONF_BLOCK_SIZE - 8U ); + } + + return ulCrc; +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/util/endian.c b/FreeRTOS-Plus/Source/Reliance-Edge/util/endian.c index 3cc5452a1..c195191be 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/util/endian.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/util/endian.c @@ -1,82 +1,80 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements utilities for performing endian swaps. -*/ -#include - - -#ifdef REDCONF_ENDIAN_SWAP - -/** @brief Reverse the byte order of a 64-bit number. - - @param ullToRev Number whose bytes will be reversed - - @retval @p ullToRev with its bytes reversed. -*/ -uint64_t RedRev64( - uint64_t ullToRev) -{ - uint64_t ullRet = ullToRev; - - ullRet = ((ullRet & UINT64_SUFFIX(0x00000000FFFFFFFF)) << 32U) | ((ullRet & UINT64_SUFFIX(0xFFFFFFFF00000000)) >> 32U); - ullRet = ((ullRet & UINT64_SUFFIX(0x0000FFFF0000FFFF)) << 16U) | ((ullRet & UINT64_SUFFIX(0xFFFF0000FFFF0000)) >> 16U); - ullRet = ((ullRet & UINT64_SUFFIX(0x00FF00FF00FF00FF)) << 8U) | ((ullRet & UINT64_SUFFIX(0xFF00FF00FF00FF00)) >> 8U); - - return ullRet; -} - - -/** @brief Reverse the byte order of a 32-bit number. - - @param ulToRev Number whose bytes will be reversed - - @retval @p ulToRev with its bytes reversed. -*/ -uint32_t RedRev32( - uint32_t ulToRev) -{ - return ((ulToRev & 0x000000FFU) << 24U) - | ((ulToRev & 0x0000FF00U) << 8U) - | ((ulToRev & 0x00FF0000U) >> 8U) - | ((ulToRev & 0xFF000000U) >> 24U); -} - - -/** @brief Reverse the byte order of a 16-bit number. - - @param uToRev Number whose bytes will be reversed - - @retval @p uToRev with its bytes reversed. -*/ -uint16_t RedRev16( - uint16_t uToRev) -{ - return ((uToRev & 0xFF00U) >> 8U) - | ((uToRev & 0x00FFU) << 8U); -} - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements utilities for performing endian swaps. + */ +#include + + +#ifdef REDCONF_ENDIAN_SWAP + +/** @brief Reverse the byte order of a 64-bit number. + * + * @param ullToRev Number whose bytes will be reversed + * + * @retval @p ullToRev with its bytes reversed. + */ + uint64_t RedRev64( uint64_t ullToRev ) + { + uint64_t ullRet = ullToRev; + + ullRet = ( ( ullRet & UINT64_SUFFIX( 0x00000000FFFFFFFF ) ) << 32U ) | ( ( ullRet & UINT64_SUFFIX( 0xFFFFFFFF00000000 ) ) >> 32U ); + ullRet = ( ( ullRet & UINT64_SUFFIX( 0x0000FFFF0000FFFF ) ) << 16U ) | ( ( ullRet & UINT64_SUFFIX( 0xFFFF0000FFFF0000 ) ) >> 16U ); + ullRet = ( ( ullRet & UINT64_SUFFIX( 0x00FF00FF00FF00FF ) ) << 8U ) | ( ( ullRet & UINT64_SUFFIX( 0xFF00FF00FF00FF00 ) ) >> 8U ); + + return ullRet; + } + + +/** @brief Reverse the byte order of a 32-bit number. + * + * @param ulToRev Number whose bytes will be reversed + * + * @retval @p ulToRev with its bytes reversed. + */ + uint32_t RedRev32( uint32_t ulToRev ) + { + return ( ( ulToRev & 0x000000FFU ) << 24U ) + | ( ( ulToRev & 0x0000FF00U ) << 8U ) + | ( ( ulToRev & 0x00FF0000U ) >> 8U ) + | ( ( ulToRev & 0xFF000000U ) >> 24U ); + } + + +/** @brief Reverse the byte order of a 16-bit number. + * + * @param uToRev Number whose bytes will be reversed + * + * @retval @p uToRev with its bytes reversed. + */ + uint16_t RedRev16( uint16_t uToRev ) + { + return ( ( uToRev & 0xFF00U ) >> 8U ) + | ( ( uToRev & 0x00FFU ) << 8U ); + } + +#endif /* ifdef REDCONF_ENDIAN_SWAP */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/util/memory.c b/FreeRTOS-Plus/Source/Reliance-Edge/util/memory.c index 3c30bae78..ce1cf1396 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/util/memory.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/util/memory.c @@ -1,301 +1,306 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Default implementations of memory manipulation functions. - - These implementations are intended to be small and simple, and thus forego - all optimizations. If the C library is available, or if there are better - third-party implementations available in the system, those can be used - instead by defining the appropriate macros in redconf.h. - - These functions are not intended to be completely 100% ANSI C compatible - implementations, but rather are designed to meet the needs of Reliance Edge. - The compatibility is close enough that ANSI C compatible implementations - can be "dropped in" as replacements without difficulty. -*/ -#include - - -#ifndef RedMemCpyUnchecked -static void RedMemCpyUnchecked(void *pDest, const void *pSrc, uint32_t ulLen); -#endif -#ifndef RedMemMoveUnchecked -static void RedMemMoveUnchecked(void *pDest, const void *pSrc, uint32_t ulLen); -#endif -#ifndef RedMemSetUnchecked -static void RedMemSetUnchecked(void *pDest, uint8_t bVal, uint32_t ulLen); -#endif -#ifndef RedMemCmpUnchecked -static int32_t RedMemCmpUnchecked(const void *pMem1, const void *pMem2, uint32_t ulLen); -#endif - - -/** @brief Copy memory from one address to another. - - The source and destination memory buffers should not overlap. If the - buffers overlap, use RedMemMove() instead. - - @param pDest The destination buffer. - @param pSrc The source buffer. - @param ulLen The number of bytes to copy. -*/ -void RedMemCpy( - void *pDest, - const void *pSrc, - uint32_t ulLen) -{ - if((pDest == NULL) || (pSrc == NULL)) - { - REDERROR(); - } - else - { - RedMemCpyUnchecked(pDest, pSrc, ulLen); - } -} - - -#ifndef RedMemCpyUnchecked -/** @brief Copy memory from one address to another. - - This function should only be called from RedMemCpy(). - - @param pDest The destination buffer. - @param pSrc The source buffer. - @param ulLen The number of bytes to copy. -*/ -static void RedMemCpyUnchecked( - void *pDest, - const void *pSrc, - uint32_t ulLen) -{ - uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest); - const uint8_t *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc); - uint32_t ulIdx; - - for(ulIdx = 0U; ulIdx < ulLen; ulIdx++) - { - pbDest[ulIdx] = pbSrc[ulIdx]; - } -} -#endif - - -/** @brief Move memory from one address to another. - - Supports overlapping memory regions. If memory regions do not overlap, it - is generally better to use RedMemCpy() instead. - - @param pDest The destination buffer. - @param pSrc The source buffer. - @param ulLen The number of bytes to copy. -*/ -void RedMemMove( - void *pDest, - const void *pSrc, - uint32_t ulLen) -{ - if((pDest == NULL) || (pSrc == NULL)) - { - REDERROR(); - } - else - { - RedMemMoveUnchecked(pDest, pSrc, ulLen); - } -} - - -#ifndef RedMemMoveUnchecked -/** @brief Move memory from one address to another. - - This function should only be called from RedMemMove(). - - @param pDest The destination buffer. - @param pSrc The source buffer. - @param ulLen The number of bytes to copy. -*/ -static void RedMemMoveUnchecked( - void *pDest, - const void *pSrc, - uint32_t ulLen) -{ - uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest); - const uint8_t *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc); - uint32_t ulIdx; - - if(MEMMOVE_MUST_COPY_FORWARD(pbDest, pbSrc)) - { - /* If the destination is lower than the source with overlapping memory - regions, we must copy from start to end in order to copy the memory - correctly. - - Don't use RedMemCpy() to do this. It is possible that RedMemCpy() - has been replaced (even though this function has not been replaced) - with an implementation that cannot handle any kind of buffer - overlap. - */ - for(ulIdx = 0U; ulIdx < ulLen; ulIdx++) - { - pbDest[ulIdx] = pbSrc[ulIdx]; - } - } - else - { - ulIdx = ulLen; - - while(ulIdx > 0U) - { - ulIdx--; - pbDest[ulIdx] = pbSrc[ulIdx]; - } - } -} -#endif /* RedMemMoveUnchecked */ - - -/** @brief Initialize a buffer with the specified byte value. - - @param pDest The buffer to initialize. - @param bVal The byte value with which to initialize @p pDest. - @param ulLen The number of bytes to initialize. -*/ -void RedMemSet( - void *pDest, - uint8_t bVal, - uint32_t ulLen) -{ - if(pDest == NULL) - { - REDERROR(); - } - else - { - RedMemSetUnchecked(pDest, bVal, ulLen); - } -} - - -#ifndef RedMemSetUnchecked -/** @brief Initialize a buffer with the specified byte value. - - This function should only be called from RedMemSet(). - - @param pDest The buffer to initialize. - @param bVal The byte value with which to initialize @p pDest. - @param ulLen The number of bytes to initialize. -*/ -static void RedMemSetUnchecked( - void *pDest, - uint8_t bVal, - uint32_t ulLen) -{ - uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest); - uint32_t ulIdx; - - for(ulIdx = 0U; ulIdx < ulLen; ulIdx++) - { - pbDest[ulIdx] = bVal; - } -} -#endif - - -/** @brief Compare the contents of two buffers. - - @param pMem1 The first buffer to compare. - @param pMem2 The second buffer to compare. - @param ulLen The length to compare. - - @return Zero if the two buffers are the same, otherwise nonzero. - - @retval 0 @p pMem1 and @p pMem2 are the same. - @retval 1 @p pMem1 is greater than @p pMem2, as determined by the - values of the first differing bytes. - @retval -1 @p pMem2 is greater than @p pMem1, as determined by the - values of the first differing bytes. -*/ -int32_t RedMemCmp( - const void *pMem1, - const void *pMem2, - uint32_t ulLen) -{ - int32_t lResult; - - if((pMem1 == NULL) || (pMem2 == NULL)) - { - REDERROR(); - lResult = 0; - } - else - { - lResult = RedMemCmpUnchecked(pMem1, pMem2, ulLen); - } - - return lResult; -} - - -#ifndef RedMemCmpUnchecked -/** @brief Compare the contents of two buffers. - - @param pMem1 The first buffer to compare. - @param pMem2 The second buffer to compare. - @param ulLen The length to compare. - - @return Zero if the two buffers are the same, otherwise nonzero. -*/ -static int32_t RedMemCmpUnchecked( - const void *pMem1, - const void *pMem2, - uint32_t ulLen) -{ - const uint8_t *pbMem1 = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMem1); - const uint8_t *pbMem2 = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMem2); - uint32_t ulIdx = 0U; - int32_t lResult; - - while((ulIdx < ulLen) && (pbMem1[ulIdx] == pbMem2[ulIdx])) - { - ulIdx++; - } - - if(ulIdx == ulLen) - { - lResult = 0; - } - else if(pbMem1[ulIdx] > pbMem2[ulIdx]) - { - lResult = 1; - } - else - { - lResult = -1; - } - - return lResult; -} -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Default implementations of memory manipulation functions. + * + * These implementations are intended to be small and simple, and thus forego + * all optimizations. If the C library is available, or if there are better + * third-party implementations available in the system, those can be used + * instead by defining the appropriate macros in redconf.h. + * + * These functions are not intended to be completely 100% ANSI C compatible + * implementations, but rather are designed to meet the needs of Reliance Edge. + * The compatibility is close enough that ANSI C compatible implementations + * can be "dropped in" as replacements without difficulty. + */ +#include + + +#ifndef RedMemCpyUnchecked + static void RedMemCpyUnchecked( void * pDest, + const void * pSrc, + uint32_t ulLen ); +#endif +#ifndef RedMemMoveUnchecked + static void RedMemMoveUnchecked( void * pDest, + const void * pSrc, + uint32_t ulLen ); +#endif +#ifndef RedMemSetUnchecked + static void RedMemSetUnchecked( void * pDest, + uint8_t bVal, + uint32_t ulLen ); +#endif +#ifndef RedMemCmpUnchecked + static int32_t RedMemCmpUnchecked( const void * pMem1, + const void * pMem2, + uint32_t ulLen ); +#endif + + +/** @brief Copy memory from one address to another. + * + * The source and destination memory buffers should not overlap. If the + * buffers overlap, use RedMemMove() instead. + * + * @param pDest The destination buffer. + * @param pSrc The source buffer. + * @param ulLen The number of bytes to copy. + */ +void RedMemCpy( void * pDest, + const void * pSrc, + uint32_t ulLen ) +{ + if( ( pDest == NULL ) || ( pSrc == NULL ) ) + { + REDERROR(); + } + else + { + RedMemCpyUnchecked( pDest, pSrc, ulLen ); + } +} + + +#ifndef RedMemCpyUnchecked + +/** @brief Copy memory from one address to another. + * + * This function should only be called from RedMemCpy(). + * + * @param pDest The destination buffer. + * @param pSrc The source buffer. + * @param ulLen The number of bytes to copy. + */ + static void RedMemCpyUnchecked( void * pDest, + const void * pSrc, + uint32_t ulLen ) + { + uint8_t * pbDest = CAST_VOID_PTR_TO_UINT8_PTR( pDest ); + const uint8_t * pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pSrc ); + uint32_t ulIdx; + + for( ulIdx = 0U; ulIdx < ulLen; ulIdx++ ) + { + pbDest[ ulIdx ] = pbSrc[ ulIdx ]; + } + } +#endif /* ifndef RedMemCpyUnchecked */ + + +/** @brief Move memory from one address to another. + * + * Supports overlapping memory regions. If memory regions do not overlap, it + * is generally better to use RedMemCpy() instead. + * + * @param pDest The destination buffer. + * @param pSrc The source buffer. + * @param ulLen The number of bytes to copy. + */ +void RedMemMove( void * pDest, + const void * pSrc, + uint32_t ulLen ) +{ + if( ( pDest == NULL ) || ( pSrc == NULL ) ) + { + REDERROR(); + } + else + { + RedMemMoveUnchecked( pDest, pSrc, ulLen ); + } +} + + +#ifndef RedMemMoveUnchecked + +/** @brief Move memory from one address to another. + * + * This function should only be called from RedMemMove(). + * + * @param pDest The destination buffer. + * @param pSrc The source buffer. + * @param ulLen The number of bytes to copy. + */ + static void RedMemMoveUnchecked( void * pDest, + const void * pSrc, + uint32_t ulLen ) + { + uint8_t * pbDest = CAST_VOID_PTR_TO_UINT8_PTR( pDest ); + const uint8_t * pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pSrc ); + uint32_t ulIdx; + + if( MEMMOVE_MUST_COPY_FORWARD( pbDest, pbSrc ) ) + { + /* If the destination is lower than the source with overlapping memory + * regions, we must copy from start to end in order to copy the memory + * correctly. + * + * Don't use RedMemCpy() to do this. It is possible that RedMemCpy() + * has been replaced (even though this function has not been replaced) + * with an implementation that cannot handle any kind of buffer + * overlap. + */ + for( ulIdx = 0U; ulIdx < ulLen; ulIdx++ ) + { + pbDest[ ulIdx ] = pbSrc[ ulIdx ]; + } + } + else + { + ulIdx = ulLen; + + while( ulIdx > 0U ) + { + ulIdx--; + pbDest[ ulIdx ] = pbSrc[ ulIdx ]; + } + } + } +#endif /* RedMemMoveUnchecked */ + + +/** @brief Initialize a buffer with the specified byte value. + * + * @param pDest The buffer to initialize. + * @param bVal The byte value with which to initialize @p pDest. + * @param ulLen The number of bytes to initialize. + */ +void RedMemSet( void * pDest, + uint8_t bVal, + uint32_t ulLen ) +{ + if( pDest == NULL ) + { + REDERROR(); + } + else + { + RedMemSetUnchecked( pDest, bVal, ulLen ); + } +} + + +#ifndef RedMemSetUnchecked + +/** @brief Initialize a buffer with the specified byte value. + * + * This function should only be called from RedMemSet(). + * + * @param pDest The buffer to initialize. + * @param bVal The byte value with which to initialize @p pDest. + * @param ulLen The number of bytes to initialize. + */ + static void RedMemSetUnchecked( void * pDest, + uint8_t bVal, + uint32_t ulLen ) + { + uint8_t * pbDest = CAST_VOID_PTR_TO_UINT8_PTR( pDest ); + uint32_t ulIdx; + + for( ulIdx = 0U; ulIdx < ulLen; ulIdx++ ) + { + pbDest[ ulIdx ] = bVal; + } + } +#endif /* ifndef RedMemSetUnchecked */ + + +/** @brief Compare the contents of two buffers. + * + * @param pMem1 The first buffer to compare. + * @param pMem2 The second buffer to compare. + * @param ulLen The length to compare. + * + * @return Zero if the two buffers are the same, otherwise nonzero. + * + * @retval 0 @p pMem1 and @p pMem2 are the same. + * @retval 1 @p pMem1 is greater than @p pMem2, as determined by the + * values of the first differing bytes. + * @retval -1 @p pMem2 is greater than @p pMem1, as determined by the + * values of the first differing bytes. + */ +int32_t RedMemCmp( const void * pMem1, + const void * pMem2, + uint32_t ulLen ) +{ + int32_t lResult; + + if( ( pMem1 == NULL ) || ( pMem2 == NULL ) ) + { + REDERROR(); + lResult = 0; + } + else + { + lResult = RedMemCmpUnchecked( pMem1, pMem2, ulLen ); + } + + return lResult; +} + + +#ifndef RedMemCmpUnchecked + +/** @brief Compare the contents of two buffers. + * + * @param pMem1 The first buffer to compare. + * @param pMem2 The second buffer to compare. + * @param ulLen The length to compare. + * + * @return Zero if the two buffers are the same, otherwise nonzero. + */ + static int32_t RedMemCmpUnchecked( const void * pMem1, + const void * pMem2, + uint32_t ulLen ) + { + const uint8_t * pbMem1 = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pMem1 ); + const uint8_t * pbMem2 = CAST_VOID_PTR_TO_CONST_UINT8_PTR( pMem2 ); + uint32_t ulIdx = 0U; + int32_t lResult; + + while( ( ulIdx < ulLen ) && ( pbMem1[ ulIdx ] == pbMem2[ ulIdx ] ) ) + { + ulIdx++; + } + + if( ulIdx == ulLen ) + { + lResult = 0; + } + else if( pbMem1[ ulIdx ] > pbMem2[ ulIdx ] ) + { + lResult = 1; + } + else + { + lResult = -1; + } + + return lResult; + } +#endif /* ifndef RedMemCmpUnchecked */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/util/namelen.c b/FreeRTOS-Plus/Source/Reliance-Edge/util/namelen.c index abf2c733c..00b4d6ca5 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/util/namelen.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/util/namelen.c @@ -1,61 +1,61 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements a utility to find the length of a name. -*/ -#include - -#if REDCONF_API_POSIX == 1 - - -/** @brief Determine the length of a name, terminated either by a null or a path - separator character. - - @param pszName The name whose length is to be determined. - - @return The length of the name. -*/ -uint32_t RedNameLen( - const char *pszName) -{ - uint32_t ulIdx = 0U; - - if(pszName == NULL) - { - REDERROR(); - } - else - { - while((pszName[ulIdx] != '\0') && (pszName[ulIdx] != REDCONF_PATH_SEPARATOR)) - { - ulIdx++; - } - } - - return ulIdx; -} - -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements a utility to find the length of a name. + */ +#include + +#if REDCONF_API_POSIX == 1 + + +/** @brief Determine the length of a name, terminated either by a null or a path + * separator character. + * + * @param pszName The name whose length is to be determined. + * + * @return The length of the name. + */ + uint32_t RedNameLen( const char * pszName ) + { + uint32_t ulIdx = 0U; + + if( pszName == NULL ) + { + REDERROR(); + } + else + { + while( ( pszName[ ulIdx ] != '\0' ) && ( pszName[ ulIdx ] != REDCONF_PATH_SEPARATOR ) ) + { + ulIdx++; + } + } + + return ulIdx; + } + +#endif /* if REDCONF_API_POSIX == 1 */ diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/util/sign.c b/FreeRTOS-Plus/Source/Reliance-Edge/util/sign.c index d182ab1c7..599bfb732 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/util/sign.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/util/sign.c @@ -1,63 +1,62 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Implements a sign on message. -*/ -#include - - -/** @brief Display the Reliance Edge signon message. -*/ -void RedSignOn(void) -{ - #if REDCONF_OUTPUT == 1 - - /* Use RedOsOutputString() instead of RedPrintf() to avoid using variadic - arguments, since this function is called from the driver and cannot use - functions that violate MISRA-C:2012. - */ - RedOsOutputString(RED_PRODUCT_NAME "\n"); - RedOsOutputString(RED_PRODUCT_EDITION "\n"); - RedOsOutputString(RED_PRODUCT_LEGAL "\n"); - RedOsOutputString(RED_PRODUCT_PATENT "\n"); - - #else - - /* Always embed the copyright into the program data. Use "volatile" to try - to avoid the compiler removing the variables. - */ - static volatile const char szVersion[] = RED_PRODUCT_NAME; - static volatile const char szEdition[] = RED_PRODUCT_EDITION; - static volatile const char szCopyright[] = RED_PRODUCT_LEGAL; - static volatile const char szPatent[] = RED_PRODUCT_PATENT; - - (void)szVersion; - (void)szEdition; - (void)szCopyright; - (void)szPatent; - - #endif -} - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Implements a sign on message. + */ +#include + + +/** @brief Display the Reliance Edge signon message. + */ +void RedSignOn( void ) +{ + #if REDCONF_OUTPUT == 1 + + /* Use RedOsOutputString() instead of RedPrintf() to avoid using variadic + * arguments, since this function is called from the driver and cannot use + * functions that violate MISRA-C:2012. + */ + RedOsOutputString( RED_PRODUCT_NAME "\n" ); + RedOsOutputString( RED_PRODUCT_EDITION "\n" ); + RedOsOutputString( RED_PRODUCT_LEGAL "\n" ); + RedOsOutputString( RED_PRODUCT_PATENT "\n" ); + #else + + /* Always embed the copyright into the program data. Use "volatile" to try + * to avoid the compiler removing the variables. + */ + static volatile const char szVersion[] = RED_PRODUCT_NAME; + static volatile const char szEdition[] = RED_PRODUCT_EDITION; + static volatile const char szCopyright[] = RED_PRODUCT_LEGAL; + static volatile const char szPatent[] = RED_PRODUCT_PATENT; + + ( void ) szVersion; + ( void ) szEdition; + ( void ) szCopyright; + ( void ) szPatent; + #endif /* if REDCONF_OUTPUT == 1 */ +} diff --git a/FreeRTOS-Plus/Source/Reliance-Edge/util/string.c b/FreeRTOS-Plus/Source/Reliance-Edge/util/string.c index 46119d948..11b7da826 100644 --- a/FreeRTOS-Plus/Source/Reliance-Edge/util/string.c +++ b/FreeRTOS-Plus/Source/Reliance-Edge/util/string.c @@ -1,329 +1,331 @@ -/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- - - Copyright (c) 2014-2015 Datalight, Inc. - All Rights Reserved Worldwide. - - 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; use version 2 of the License. - - This program is distributed in the hope that it will be useful, - but "AS-IS," 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -/* Businesses and individuals that for commercial or other reasons cannot - comply with the terms of the GPLv2 license may obtain a commercial license - before incorporating Reliance Edge into proprietary software for - distribution in any form. Visit http://www.datalight.com/reliance-edge for - more information. -*/ -/** @file - @brief Default implementations of string manipulation functions. - - These implementations are intended to be small and simple, and thus forego - all optimizations. If the C library is available, or if there are better - third-party implementations available in the system, those can be used - instead by defining the appropriate macros in redconf.h. - - These functions are not intended to be completely 100% ANSI C compatible - implementations, but rather are designed to meet the needs of Reliance Edge. - The compatibility is close enough that ANSI C compatible implementations - can be "dropped in" as replacements without difficulty. -*/ -#include - - -#ifndef RedStrLenUnchecked -static uint32_t RedStrLenUnchecked(const char *pszStr); -#endif -#ifndef RedStrCmpUnchecked -static int32_t RedStrCmpUnchecked(const char *pszStr1, const char *pszStr2); -#endif -#ifndef RedStrNCmpUnchecked -static int32_t RedStrNCmpUnchecked(const char *pszStr1, const char *pszStr2, uint32_t ulLen); -#endif -#ifndef RedStrNCpyUnchecked -static void RedStrNCpyUnchecked(char *pszDst, const char *pszSrc, uint32_t ulLen); -#endif - - -/** @brief Determine the length (in bytes) of a null terminated string. - - The length does not include the null terminator byte. - - @param pszStr The null terminated string whose length is to be determined. - - @return The length of the @p pszStr string. -*/ -uint32_t RedStrLen( - const char *pszStr) -{ - uint32_t ulLen; - - if(pszStr == NULL) - { - REDERROR(); - ulLen = 0U; - } - else - { - /* Cast the result to uint32_t, since RedStrLenUnchecked() might be - strlen(), which returns size_t, which is possibly a 64-bit value. - */ - ulLen = (uint32_t)RedStrLenUnchecked(pszStr); - } - - return ulLen; -} - - -#ifndef RedStrLenUnchecked -/** @brief Determine the length (in bytes) of a null terminated string. - - @param pszStr The null terminated string whose length is to be determined. - - @return The length of the @p pszStr string. -*/ -static uint32_t RedStrLenUnchecked( - const char *pszStr) -{ - uint32_t ulLen = 0U; - - while(pszStr[ulLen] != '\0') - { - ulLen++; - } - - return ulLen; -} -#endif - - -/** @brief Compare two null terminated strings. - - @param pszStr1 The first string to compare. - @param pszStr2 The second string to compare. - - @return Zero if the two strings are the same, otherwise nonzero. - - @retval 0 @p pszStr1 and @p pszStr2 are the same. - @retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the - values of the first differing bytes. - @retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the - values of the first differing bytes. -*/ -int32_t RedStrCmp( - const char *pszStr1, - const char *pszStr2) -{ - int32_t lResult; - - if((pszStr1 == NULL) || (pszStr2 == NULL)) - { - REDERROR(); - lResult = 0; - } - else - { - lResult = RedStrCmpUnchecked(pszStr1, pszStr2); - } - - return lResult; -} - - -#ifndef RedStrCmpUnchecked -/** @brief Compare two null terminated strings. - - @param pszStr1 The first string to compare. - @param pszStr2 The second string to compare. - - @return Zero if the two strings are the same, otherwise nonzero. -*/ -static int32_t RedStrCmpUnchecked( - const char *pszStr1, - const char *pszStr2) -{ - int32_t lResult; - uint32_t ulIdx = 0U; - - while((pszStr1[ulIdx] == pszStr2[ulIdx]) && (pszStr1[ulIdx] != '\0')) - { - ulIdx++; - } - - /* "The sign of a non-zero return value is determined by the sign of the - difference between the values of the first pair of bytes (both - interpreted as type unsigned char) that differ in the strings being - compared." Use uint8_t instead of unsigned char to avoid MISRA C - deviations. - */ - if((uint8_t)pszStr1[ulIdx] > (uint8_t)pszStr2[ulIdx]) - { - lResult = 1; - } - else if((uint8_t)pszStr1[ulIdx] < (uint8_t)pszStr2[ulIdx]) - { - lResult = -1; - } - else - { - lResult = 0; - } - - return lResult; -} -#endif - - -/** @brief Compare the first @p ulLen characters of two null terminated strings. - - @param pszStr1 The first string to compare. - @param pszStr2 The second string to compare. - @param ulLen The maximum length to compare. The comparison stops when - either of the strings end or when @p ulLen bytes have been - compared. - - @return Zero if the two strings are the same, otherwise nonzero. - - @retval 0 @p pszStr1 and @p pszStr2 are the same. - @retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the - values of the first differing bytes. - @retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the - values of the first differing bytes. -*/ -int32_t RedStrNCmp( - const char *pszStr1, - const char *pszStr2, - uint32_t ulLen) -{ - int32_t lResult; - - if((pszStr1 == NULL) || (pszStr2 == NULL)) - { - REDERROR(); - lResult = 0; - } - else - { - lResult = RedStrNCmpUnchecked(pszStr1, pszStr2, ulLen); - } - - return lResult; -} - - -#ifndef RedStrNCmpUnchecked -/** @brief Compare the first @p ulLen characters of two null terminated strings. - - @param pszStr1 The first string to compare. - @param pszStr2 The second string to compare. - @param ulLen The maximum length to compare. The comparison stops when - either of the strings end or when @p ulLen bytes have been - compared. - - @return Zero if the two strings are the same, otherwise nonzero. -*/ -static int32_t RedStrNCmpUnchecked( - const char *pszStr1, - const char *pszStr2, - uint32_t ulLen) -{ - int32_t lResult = 0; - uint32_t ulIdx; - - for(ulIdx = 0U; ulIdx < ulLen; ulIdx++) - { - if(pszStr1[ulIdx] != pszStr2[ulIdx]) - { - /* "The sign of a non-zero return value is determined by the sign - of the difference between the values of the first pair of bytes - (both interpreted as type unsigned char) that differ in the - strings being compared." Use uint8_t instead of unsigned char - to avoid MISRA C deviations. - */ - if((uint8_t)pszStr1[ulIdx] > (uint8_t)pszStr2[ulIdx]) - { - lResult = 1; - } - else - { - lResult = -1; - } - } - - if((lResult != 0) || (pszStr1[ulIdx] == '\0')) - { - break; - } - } - - return lResult; -} -#endif - - -/** @brief Copy a string. - - Copy up to @p ulLen bytes of a null-terminated string (@p pszSrc) to a - destination buffer (@p pszDst). The result will not be null-terminated if - @p pszSrc is longer than @p ulLen - 1 bytes. - - If @p pszSrc is shorter than @p ulLen - 1 bytes, the remainder of @p pszDst - will be filled with null bytes. - - @param pszDst The destination buffer, which is at least @p ulLen bytes - in size. - @param pszSrc The null-terminated string to copy. - @param ulLen The maximum number of characters to copy. -*/ -void RedStrNCpy( - char *pszDst, - const char *pszSrc, - uint32_t ulLen) -{ - if((pszDst == NULL) || (pszSrc == NULL)) - { - REDERROR(); - } - else - { - RedStrNCpyUnchecked(pszDst, pszSrc, ulLen); - } -} - - -#ifndef RedStrNCpyUnchecked -/** @brief Copy a string. - - @param pszDst The destination buffer, which is at least @p ulLen bytes - in size. - @param pszSrc The null-terminated string to copy. - @param ulLen The maximum number of characters to copy. -*/ -static void RedStrNCpyUnchecked( - char *pszDst, - const char *pszSrc, - uint32_t ulLen) -{ - uint32_t ulIdx = 0U; - - while((ulIdx < ulLen) && (pszSrc[ulIdx] != '\0')) - { - pszDst[ulIdx] = pszSrc[ulIdx]; - ulIdx++; - } - - while(ulIdx < ulLen) - { - pszDst[ulIdx] = '\0'; - ulIdx++; - } -} -#endif - +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + * + * Copyright (c) 2014-2015 Datalight, Inc. + * All Rights Reserved Worldwide. + * + * 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; use version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but "AS-IS," 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* Businesses and individuals that for commercial or other reasons cannot + * comply with the terms of the GPLv2 license may obtain a commercial license + * before incorporating Reliance Edge into proprietary software for + * distribution in any form. Visit http://www.datalight.com/reliance-edge for + * more information. + */ + +/** @file + * @brief Default implementations of string manipulation functions. + * + * These implementations are intended to be small and simple, and thus forego + * all optimizations. If the C library is available, or if there are better + * third-party implementations available in the system, those can be used + * instead by defining the appropriate macros in redconf.h. + * + * These functions are not intended to be completely 100% ANSI C compatible + * implementations, but rather are designed to meet the needs of Reliance Edge. + * The compatibility is close enough that ANSI C compatible implementations + * can be "dropped in" as replacements without difficulty. + */ +#include + + +#ifndef RedStrLenUnchecked + static uint32_t RedStrLenUnchecked( const char * pszStr ); +#endif +#ifndef RedStrCmpUnchecked + static int32_t RedStrCmpUnchecked( const char * pszStr1, + const char * pszStr2 ); +#endif +#ifndef RedStrNCmpUnchecked + static int32_t RedStrNCmpUnchecked( const char * pszStr1, + const char * pszStr2, + uint32_t ulLen ); +#endif +#ifndef RedStrNCpyUnchecked + static void RedStrNCpyUnchecked( char * pszDst, + const char * pszSrc, + uint32_t ulLen ); +#endif + + +/** @brief Determine the length (in bytes) of a null terminated string. + * + * The length does not include the null terminator byte. + * + * @param pszStr The null terminated string whose length is to be determined. + * + * @return The length of the @p pszStr string. + */ +uint32_t RedStrLen( const char * pszStr ) +{ + uint32_t ulLen; + + if( pszStr == NULL ) + { + REDERROR(); + ulLen = 0U; + } + else + { + /* Cast the result to uint32_t, since RedStrLenUnchecked() might be + * strlen(), which returns size_t, which is possibly a 64-bit value. + */ + ulLen = ( uint32_t ) RedStrLenUnchecked( pszStr ); + } + + return ulLen; +} + + +#ifndef RedStrLenUnchecked + +/** @brief Determine the length (in bytes) of a null terminated string. + * + * @param pszStr The null terminated string whose length is to be determined. + * + * @return The length of the @p pszStr string. + */ + static uint32_t RedStrLenUnchecked( const char * pszStr ) + { + uint32_t ulLen = 0U; + + while( pszStr[ ulLen ] != '\0' ) + { + ulLen++; + } + + return ulLen; + } +#endif /* ifndef RedStrLenUnchecked */ + + +/** @brief Compare two null terminated strings. + * + * @param pszStr1 The first string to compare. + * @param pszStr2 The second string to compare. + * + * @return Zero if the two strings are the same, otherwise nonzero. + * + * @retval 0 @p pszStr1 and @p pszStr2 are the same. + * @retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the + * values of the first differing bytes. + * @retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the + * values of the first differing bytes. + */ +int32_t RedStrCmp( const char * pszStr1, + const char * pszStr2 ) +{ + int32_t lResult; + + if( ( pszStr1 == NULL ) || ( pszStr2 == NULL ) ) + { + REDERROR(); + lResult = 0; + } + else + { + lResult = RedStrCmpUnchecked( pszStr1, pszStr2 ); + } + + return lResult; +} + + +#ifndef RedStrCmpUnchecked + +/** @brief Compare two null terminated strings. + * + * @param pszStr1 The first string to compare. + * @param pszStr2 The second string to compare. + * + * @return Zero if the two strings are the same, otherwise nonzero. + */ + static int32_t RedStrCmpUnchecked( const char * pszStr1, + const char * pszStr2 ) + { + int32_t lResult; + uint32_t ulIdx = 0U; + + while( ( pszStr1[ ulIdx ] == pszStr2[ ulIdx ] ) && ( pszStr1[ ulIdx ] != '\0' ) ) + { + ulIdx++; + } + + /* "The sign of a non-zero return value is determined by the sign of the + * difference between the values of the first pair of bytes (both + * interpreted as type unsigned char) that differ in the strings being + * compared." Use uint8_t instead of unsigned char to avoid MISRA C + * deviations. + */ + if( ( uint8_t ) pszStr1[ ulIdx ] > ( uint8_t ) pszStr2[ ulIdx ] ) + { + lResult = 1; + } + else if( ( uint8_t ) pszStr1[ ulIdx ] < ( uint8_t ) pszStr2[ ulIdx ] ) + { + lResult = -1; + } + else + { + lResult = 0; + } + + return lResult; + } +#endif /* ifndef RedStrCmpUnchecked */ + + +/** @brief Compare the first @p ulLen characters of two null terminated strings. + * + * @param pszStr1 The first string to compare. + * @param pszStr2 The second string to compare. + * @param ulLen The maximum length to compare. The comparison stops when + * either of the strings end or when @p ulLen bytes have been + * compared. + * + * @return Zero if the two strings are the same, otherwise nonzero. + * + * @retval 0 @p pszStr1 and @p pszStr2 are the same. + * @retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the + * values of the first differing bytes. + * @retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the + * values of the first differing bytes. + */ +int32_t RedStrNCmp( const char * pszStr1, + const char * pszStr2, + uint32_t ulLen ) +{ + int32_t lResult; + + if( ( pszStr1 == NULL ) || ( pszStr2 == NULL ) ) + { + REDERROR(); + lResult = 0; + } + else + { + lResult = RedStrNCmpUnchecked( pszStr1, pszStr2, ulLen ); + } + + return lResult; +} + + +#ifndef RedStrNCmpUnchecked + +/** @brief Compare the first @p ulLen characters of two null terminated strings. + * + * @param pszStr1 The first string to compare. + * @param pszStr2 The second string to compare. + * @param ulLen The maximum length to compare. The comparison stops when + * either of the strings end or when @p ulLen bytes have been + * compared. + * + * @return Zero if the two strings are the same, otherwise nonzero. + */ + static int32_t RedStrNCmpUnchecked( const char * pszStr1, + const char * pszStr2, + uint32_t ulLen ) + { + int32_t lResult = 0; + uint32_t ulIdx; + + for( ulIdx = 0U; ulIdx < ulLen; ulIdx++ ) + { + if( pszStr1[ ulIdx ] != pszStr2[ ulIdx ] ) + { + /* "The sign of a non-zero return value is determined by the sign + * of the difference between the values of the first pair of bytes + * (both interpreted as type unsigned char) that differ in the + * strings being compared." Use uint8_t instead of unsigned char + * to avoid MISRA C deviations. + */ + if( ( uint8_t ) pszStr1[ ulIdx ] > ( uint8_t ) pszStr2[ ulIdx ] ) + { + lResult = 1; + } + else + { + lResult = -1; + } + } + + if( ( lResult != 0 ) || ( pszStr1[ ulIdx ] == '\0' ) ) + { + break; + } + } + + return lResult; + } +#endif /* ifndef RedStrNCmpUnchecked */ + + +/** @brief Copy a string. + * + * Copy up to @p ulLen bytes of a null-terminated string (@p pszSrc) to a + * destination buffer (@p pszDst). The result will not be null-terminated if + * @p pszSrc is longer than @p ulLen - 1 bytes. + * + * If @p pszSrc is shorter than @p ulLen - 1 bytes, the remainder of @p pszDst + * will be filled with null bytes. + * + * @param pszDst The destination buffer, which is at least @p ulLen bytes + * in size. + * @param pszSrc The null-terminated string to copy. + * @param ulLen The maximum number of characters to copy. + */ +void RedStrNCpy( char * pszDst, + const char * pszSrc, + uint32_t ulLen ) +{ + if( ( pszDst == NULL ) || ( pszSrc == NULL ) ) + { + REDERROR(); + } + else + { + RedStrNCpyUnchecked( pszDst, pszSrc, ulLen ); + } +} + + +#ifndef RedStrNCpyUnchecked + +/** @brief Copy a string. + * + * @param pszDst The destination buffer, which is at least @p ulLen bytes + * in size. + * @param pszSrc The null-terminated string to copy. + * @param ulLen The maximum number of characters to copy. + */ + static void RedStrNCpyUnchecked( char * pszDst, + const char * pszSrc, + uint32_t ulLen ) + { + uint32_t ulIdx = 0U; + + while( ( ulIdx < ulLen ) && ( pszSrc[ ulIdx ] != '\0' ) ) + { + pszDst[ ulIdx ] = pszSrc[ ulIdx ]; + ulIdx++; + } + + while( ulIdx < ulLen ) + { + pszDst[ ulIdx ] = '\0'; + ulIdx++; + } + } +#endif /* ifndef RedStrNCpyUnchecked */ diff --git a/FreeRTOS-Plus/Source/Utilities/logging/logging.h b/FreeRTOS-Plus/Source/Utilities/logging/logging.h index 875095edf..e6ced52ea 100644 --- a/FreeRTOS-Plus/Source/Utilities/logging/logging.h +++ b/FreeRTOS-Plus/Source/Utilities/logging/logging.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -45,8 +45,9 @@ void vLoggingInit( BaseType_t xLogToStdout, uint32_t ulRemoteIPAddress, uint16_t usRemotePort ); -void vPlatformInitLogging(void); +void vPlatformInitLogging( void ); -void vLoggingPrintf(const char* pcFormat, ...); +void vLoggingPrintf( const char * pcFormat, + ... ); #endif /* DEMO_LOGGING_H */ diff --git a/FreeRTOS-Plus/Source/Utilities/logging/logging_levels.h b/FreeRTOS-Plus/Source/Utilities/logging/logging_levels.h index 4e9c873b7..ccc3cbcdb 100644 --- a/FreeRTOS-Plus/Source/Utilities/logging/logging_levels.h +++ b/FreeRTOS-Plus/Source/Utilities/logging/logging_levels.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,7 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ diff --git a/FreeRTOS-Plus/Source/Utilities/logging/logging_stack.h b/FreeRTOS-Plus/Source/Utilities/logging/logging_stack.h index 64d9f123d..2473a4e28 100644 --- a/FreeRTOS-Plus/Source/Utilities/logging/logging_stack.h +++ b/FreeRTOS-Plus/Source/Utilities/logging/logging_stack.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -94,31 +94,31 @@ #if LIBRARY_LOG_LEVEL == LOG_DEBUG /* All log level messages will logged. */ #define LogAlways( message ) SdkLog( ( "[ALWAYS] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogWarn( message ) SdkLog( ( "[WARN] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogInfo( message ) SdkLog( ( "[INFO] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogDebug( message ) SdkLog( ( "[DEBUG] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogWarn( message ) SdkLog( ( "[WARN] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogInfo( message ) SdkLog( ( "[INFO] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogDebug( message ) SdkLog( ( "[DEBUG] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) #elif LIBRARY_LOG_LEVEL == LOG_INFO /* Only INFO, WARNING, ERROR, and ALWAYS messages will be logged. */ #define LogAlways( message ) SdkLog( ( "[ALWAYS] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogWarn( message ) SdkLog( ( "[WARN] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogInfo( message ) SdkLog( ( "[INFO] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogWarn( message ) SdkLog( ( "[WARN] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogInfo( message ) SdkLog( ( "[INFO] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) #define LogDebug( message ) #elif LIBRARY_LOG_LEVEL == LOG_WARN /* Only WARNING, ERROR, and ALWAYS messages will be logged. */ #define LogAlways( message ) SdkLog( ( "[ALWAYS] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogWarn( message ) SdkLog( ( "[WARN] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogWarn( message ) SdkLog( ( "[WARN] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) #define LogInfo( message ) #define LogDebug( message ) #elif LIBRARY_LOG_LEVEL == LOG_ERROR /* Only ERROR and ALWAYS messages will be logged. */ #define LogAlways( message ) SdkLog( ( "[ALWAYS] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) - #define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) + #define LogError( message ) SdkLog( ( "[ERROR] [%s] "LOG_METADATA_FORMAT, LIBRARY_LOG_NAME, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) #define LogWarn( message ) #define LogInfo( message ) #define LogDebug( message ) diff --git a/FreeRTOS-Plus/Source/WebDocs.url b/FreeRTOS-Plus/Source/WebDocs.url index be5966fe2..9ce0b5c5c 100644 --- a/FreeRTOS-Plus/Source/WebDocs.url +++ b/FreeRTOS-Plus/Source/WebDocs.url @@ -1,5 +1,5 @@ -[InternetShortcut] -URL=http://www.freertos.org/plus -IDList= -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/plus +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Config/FreeRTOSConfig.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Config/FreeRTOSConfig.h index e11a6d0fc..7aaf3874a 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Config/FreeRTOSConfig.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Config/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Config/FreeRTOSIPConfig.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Config/FreeRTOSIPConfig.h index 966831802..86573f18e 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Config/FreeRTOSIPConfig.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Config/FreeRTOSIPConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/FreeRTOS-Cellular-Interface-Integration.sln b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/FreeRTOS-Cellular-Interface-Integration.sln index f907d968a..ae4add02d 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/FreeRTOS-Cellular-Interface-Integration.sln +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/FreeRTOS-Cellular-Interface-Integration.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}" diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_declare.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_declare.h index 7e24efacc..7c574a110 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_declare.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_declare.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_dns_define.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_dns_define.h index 7600adb84..4cc2995c3 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_dns_define.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_dns_define.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_tcp_define.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_tcp_define.h index e062035a8..74b5657b0 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_tcp_define.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/freertos_tcp_test_access_tcp_define.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/test_freertos_tcp.c b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/test_freertos_tcp.c index cb9a3a2a9..05a459697 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/test_freertos_tcp.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Cases/test_freertos_tcp.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner.c b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner.c index ea8b2ea01..e7c2b605d 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner.h index b798b2105..ed3c1cef9 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner_config.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner_config.h index 8acd51b56..69a483ca6 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner_config.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/Test_Runner/test_runner_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/test_cellular_api.c b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/test_cellular_api.c index 346d1fd59..76e80b007 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/test_cellular_api.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/test_cellular_api.c @@ -1,2820 +1,2820 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* stdlib includes. */ -#include "string.h" -#include "stdio.h" - -/* Cellular include. */ -#include "cellular_config.h" -#include "cellular_config_defaults.h" -#include "cellular_platform.h" -#include "cellular_api.h" -#include "cellular_types.h" -#include "cellular_comm_interface.h" - -/* Testing variable includes. */ -#include "test_config.h" - -/* Unity framework includes. */ -#include "unity_fixture.h" - -/*-----------------------------------------------------------*/ - -/* Testing configurations definitions. */ - -/* Retry until SIM is ready. */ -#ifndef CELLULAR_MAX_SIM_RETRY - #define CELLULAR_MAX_SIM_RETRY ( 5U ) -#endif - -/* - * 2 GSM - * 3 UTRAN - * 4 LTE Cat M1 - * 5 LTE Cat NB1 - */ -#ifndef testCELLULAR_EDRX_RAT - #define testCELLULAR_EDRX_RAT ( 4 ) -#endif - -#ifndef testCELLULAR_SOCKET_CONNECTION_TIMEOUT_MS - #define testCELLULAR_SOCKET_CONNECTION_TIMEOUT_MS ( 150000U ) -#endif - -#ifndef testCELLULAR_SOCKET_SEND_TIMEOUT_MS - #define testCELLULAR_SOCKET_SEND_TIMEOUT_MS ( 60000U ) -#endif - -#ifndef testCELLULAR_SOCKET_CLOSE_TIMEOUT_MS - #define testCELLULAR_SOCKET_CLOSE_TIMEOUT_MS ( 60000U ) -#endif - -#ifndef testCELLULAR_SOCKET_RECEIVE_TIMEOUT_MS - #define testCELLULAR_SOCKET_RECEIVE_TIMEOUT_MS ( 5000U ) -#endif - -#ifndef testCELLULAR_MAX_NETWORK_REGISTER_RETRY - #define testCELLULAR_MAX_NETWORK_REGISTER_RETRY ( 40U ) -#endif - -#ifndef testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS - #define testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ( 500U ) -#endif - -/* Retry until SIM is ready. */ -#ifndef testCELLULAR_MAX_SIM_RETRY - #define testCELLULAR_MAX_SIM_RETRY ( 5U ) -#endif - -#ifndef testCELLULAR_SIM_RETRY_INTERVAL_MS - #define testCELLULAR_SIM_RETRY_INTERVAL_MS ( 500U ) -#endif - -#ifndef testCELLULAR_MAX_GET_PSM_RETRY - #define testCELLULAR_MAX_GET_PSM_RETRY ( 5U ) -#endif - -#ifndef testCELLULAR_GET_PSM_RETRY_INTERVAL_MS - #define testCELLULAR_GET_PSM_RETRY_INTERVAL_MS ( 500U ) -#endif - -#ifndef testCELLULAR_SOCKET_WAIT_INTERVAL_MS - #define testCELLULAR_SOCKET_WAIT_INTERVAL_MS ( 2000UL ) -#endif - -#ifndef testCELLULAR_GET_RAT_RETRY - #define testCELLULAR_GET_RAT_RETRY ( 5UL ) -#endif - -#ifndef testCELLULAR_GET_RAT_RETRY_INTERVAL_MS - #define testCELLULAR_GET_RAT_RETRY_INTERVAL_MS ( 200U ) -#endif - -#ifndef testCELLULAR_WAIT_PSM_ENTER_EVENT_RETRY - #define testCELLULAR_WAIT_PSM_ENTER_EVENT_RETRY ( 2U ) -#endif - -#ifndef testCELLULAR_MAX_PDN_STATSU_NUM - #define testCELLULAR_MAX_PDN_STATSU_NUM ( CELLULAR_PDN_CONTEXT_ID_MAX - CELLULAR_PDN_CONTEXT_ID_MIN + 1U ) -#endif - -/* Custom CELLULAR Test asserts. */ -#define TEST_CELLULAR_ASSERT_REQUIRED_API( condition, result ) \ - if( result == CELLULAR_UNSUPPORTED ) \ - { \ - TEST_FAIL_MESSAGE( "Required CELLULAR API is not implemented." ); \ - } \ - else \ - { \ - TEST_ASSERT( condition ); \ - } - -#define TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( condition, result, message ) \ - if( result == CELLULAR_UNSUPPORTED ) \ - { \ - TEST_FAIL_MESSAGE( "Required CELLULAR API is not implemented." ); \ - } \ - else \ - { \ - TEST_ASSERT_MESSAGE( condition, message ); \ - } - -#define TEST_CELLULAR_ASSERT_OPTIONAL_API( condition, result ) \ - if( result == CELLULAR_UNSUPPORTED ) \ - { \ - TEST_ASSERT( 1 ); \ - } \ - else \ - { \ - TEST_ASSERT( condition ); \ - } - -#define TEST_CELLULAR_ASSERT_OPTIONAL_API_MSG( condition, result, message ) \ - if( result == CELLULAR_UNSUPPORTED ) \ - { \ - TEST_ASSERT( 1 ); \ - } \ - else \ - { \ - TEST_ASSERT_MESSAGE( condition, message ); \ - } - -#define TEST_INVALID_CELLULAR_APN "VZWINTERNETVZWINTERNETVZWINTERNETVZWINTERNETVZWINTERNETVZWINTERN" - -#define SOCKET_DATA_RECEIVED_CALLBACK_BIT ( 0x00000001U ) -#define SOCKET_OPEN_CALLBACK_BIT ( 0x00000002U ) -#define SOCKET_OPEN_FAILED_CALLBACK_BIT ( 0x00000004U ) -#define SOCKET_CLOSED_CALLBACK_BIT ( 0x00000008U ) - -#define ECHO_SERVER_DATA_SEND_INTERVAL_MS ( 30000UL ) - -#define MODEM_EVENT_BOOTUP_OR_REBOOT_BIT ( 0x00000001U ) -#define MODEM_EVENT_POWERED_DOWN_BIT ( 0x00000002U ) -#define MODEM_EVENT_PSM_ENTER_BIT ( 0x00000004U ) - -#define SOCKET_OPEN_STATUS_UNKNOWN ( 0U ) -#define SOCKET_OPEN_STATUS_OPENED ( 1U ) -#define SOCKET_OPEN_STATUS_FAILED ( 2U ) - -#define SOCKET_OPERATION_POLLING_TIMES ( 4U ) - -#define MESSAGE_BUFFER_LENGTH ( 256U ) - -/* APN for the test network. */ -#define testCELLULAR_APN CELLULAR_APN - -/* PDN context id for cellular network. */ -#define testCELLULAR_PDN_CONTEXT_ID ( CELLULAR_PDN_CONTEXT_ID ) - -/* The number of times to loop in the CELLULARConnectionLoop test. */ -#define testCELLULARCONNECTION_LOOP_TIMES ( CELLULAR_NUM_SOCKET_MAX + 3U ) - -#define testCELLULARDATA_TRANSFER_LOOP_TIMES ( 10U ) - -/* RAT priority count for testing. This value should larger or equal to - * CELLULAR_MAX_RAT_PRIORITY_COUNT. */ -#define TEST_MAX_RAT_PRIORITY_COUNT ( 3U ) -#if CELLULAR_MAX_RAT_PRIORITY_COUNT > TEST_MAX_RAT_PRIORITY_COUNT - #error "TEST_MAX_RAT_PRIORITY_COUNT should not larger or equal to CELLULAR_MAX_RAT_PRIORITY_COUNT" -#endif - -#ifndef testCELLULAR_DNS_SERVER_ADDRESS - #error "testCELLULAR_DNS_SERVER_ADDRESS is not defined" -#endif - -#ifndef testCELLULAR_HOST_NAME - #error "testCELLULAR_HOST_NAME is not defined" -#endif - -#ifndef testCELLULAR_HOST_NAME_ADDRESS - #error "testCELLULAR_HOST_NAME_ADDRESS is not defined" -#endif - -#ifndef testCELLULAR_ECHO_SERVER_ADDRESS - #error "testCELLULAR_ECHO_SERVER_ADDRESS is not defined" -#endif - -#ifndef testCELLULAR_ECHO_SERVER_PORT - #error "testCELLULAR_ECHO_SERVER_PORT is not defined" -#endif - -#ifndef testCELLULAR_EDRX_ECHO_SERVER_ADDRESS - #error "testCELLULAR_EDRX_ECHO_SERVER_ADDRESS is not defined" -#endif - -#ifndef testCELLULAR_EDRX_ECHO_SERVER_PORT - #error "testCELLULAR_EDRX_ECHO_SERVER_PORT is not defined" -#endif - -#ifndef testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS - #error "testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS is not defined" -#endif - -/*-----------------------------------------------------------*/ - -/** - * @brief the default Cellular comm interface in system. - */ -extern CellularCommInterface_t CellularCommInterface; - -/*-----------------------------------------------------------*/ - -/* Test state variables. */ -static uint8_t _dataReady = 0; -static CellularHandle_t _cellularHandle = NULL; -static bool _genericUrcCalled = false; -static PlatformEventGroupHandle_t _socketEventGroup = NULL; -static PlatformEventGroupHandle_t _modemEventGroup = NULL; - -/* The callback context to check. */ -static void * _socketDataReadyContext = NULL; -static void * _socketOpenContext = NULL; -static void * _socketClosedContext = NULL; - -/* Socket data send pattern. */ -static const char _socketDataSend[] = "hello from SJC31"; - -/*-----------------------------------------------------------*/ - -/* Network registration callback function. */ -static void prvNetworkRegistrationCallback( CellularUrcEvent_t urcEvent, - const CellularServiceStatus_t * pServiceStatus, - void * pCallbackContext ) -{ - TEST_ASSERT( pCallbackContext == _cellularHandle ); - - if( pServiceStatus != NULL ) - { - if( ( urcEvent == CELLULAR_URC_EVENT_NETWORK_CS_REGISTRATION ) || - ( urcEvent == CELLULAR_URC_EVENT_NETWORK_PS_REGISTRATION ) ) - { - configPRINTF( ( "Network CS registration status received: %d. \r\n", pServiceStatus->csRegistrationStatus ) ); - configPRINTF( ( "Network PS registration status received: %d. \r\n", pServiceStatus->psRegistrationStatus ) ); - } - } -} - -/*-----------------------------------------------------------*/ - -/* Signal strength changed callback function. */ -static void prvSignalStrengthChangedCallback( CellularUrcEvent_t urcEvent, - const CellularSignalInfo_t * pSignalInfo, - void * pCallbackContext ) -{ - TEST_ASSERT( pCallbackContext == _cellularHandle ); - - if( ( pSignalInfo != NULL ) && ( urcEvent == CELLULAR_URC_EVENT_SIGNAL_CHANGED ) ) - { - if( pSignalInfo->rssi != CELLULAR_INVALID_SIGNAL_VALUE ) - { - configPRINTF( ( "RSSI received: %d. \r\n", pSignalInfo->rssi ) ); - } - else - { - configPRINTF( ( "RSSI received: UNKNOWN. \r\n" ) ); - } - - if( pSignalInfo->rsrp != CELLULAR_INVALID_SIGNAL_VALUE ) - { - configPRINTF( ( "RSRP received: %d. \r\n", pSignalInfo->rsrp ) ); - } - else - { - configPRINTF( ( "RSRP received: UNKNOWN. \r\n" ) ); - } - - if( pSignalInfo->rsrq != CELLULAR_INVALID_SIGNAL_VALUE ) - { - configPRINTF( ( "RSRQ received: %d. \r\n", pSignalInfo->rsrq ) ); - } - else - { - configPRINTF( ( "RSRQ received: UNKNOWN. \r\n" ) ); - } - - if( pSignalInfo->ber != CELLULAR_INVALID_SIGNAL_VALUE ) - { - configPRINTF( ( "BER received: %d. \r\n", pSignalInfo->ber ) ); - } - else - { - configPRINTF( ( "BER received: UNKNOWN. \r\n" ) ); - } - - if( pSignalInfo->bars != CELLULAR_INVALID_SIGNAL_BAR_VALUE ) - { - configPRINTF( ( "BARS received: %u. \r\n", pSignalInfo->bars ) ); - } - else - { - configPRINTF( ( "BARS received: UNKNOWN. \r\n" ) ); - } - } -} - -/*-----------------------------------------------------------*/ - -/* Generic callback function to test Cellular_RegisterUrcGenericCallback API. */ -static void prvGenericCallback( const char * pRawData, - void * pCallbackContext ) -{ - TEST_ASSERT( pCallbackContext == _cellularHandle ); - - configPRINTF( ( "prvGenericCallback : %s \r\n", pRawData ) ); - _genericUrcCalled = true; -} - -/*-----------------------------------------------------------*/ - -/* PDN event callback function. */ -static void prvPdnEventCallback( CellularUrcEvent_t urcEvent, - uint8_t contextId, - void * pCallbackContext ) -{ - TEST_ASSERT( pCallbackContext == _cellularHandle ); - - if( contextId == testCELLULAR_PDN_CONTEXT_ID ) - { - if( ( urcEvent == CELLULAR_URC_EVENT_PDN_ACTIVATED ) || ( urcEvent == CELLULAR_URC_EVENT_PDN_DEACTIVATED ) ) - { - configPRINTF( ( "PDP Status changed. context ID %u event %d\r\n", contextId, urcEvent ) ); - } - } -} - -/*-----------------------------------------------------------*/ - -/* Callback functions for testing. */ -static void prvCellularSocketDataReadyCallback( CellularSocketHandle_t socketHandle, - void * pCallbackContext ) -{ - PlatformEventGroupHandle_t eventGroupHandle = ( PlatformEventGroupHandle_t ) pCallbackContext; - - TEST_ASSERT( socketHandle != NULL ); - - configPRINTF( ( "Data Ready on Socket \r\n" ) ); - _dataReady = 1; - - if( eventGroupHandle != NULL ) - { - ( void ) PlatformEventGroup_SetBits( eventGroupHandle, SOCKET_DATA_RECEIVED_CALLBACK_BIT ); - } - - _socketDataReadyContext = pCallbackContext; -} - -/*-----------------------------------------------------------*/ - -/* Socket close event callback function. */ -static void prvSocketClosedCallback( CellularSocketHandle_t socketHandle, - void * pCallbackContext ) -{ - PlatformEventGroupHandle_t eventGroupHandle = ( PlatformEventGroupHandle_t ) pCallbackContext; - - TEST_ASSERT( socketHandle != NULL ); - - configPRINTF( ( "Socket is closed. \r\n" ) ); - - if( eventGroupHandle != NULL ) - { - ( void ) PlatformEventGroup_SetBits( eventGroupHandle, SOCKET_CLOSED_CALLBACK_BIT ); - } - - _socketClosedContext = pCallbackContext; -} - -/*-----------------------------------------------------------*/ - -/* Socket open event callback function. */ -static void prvCellularSocketOpenCallback( CellularUrcEvent_t urcEvent, - CellularSocketHandle_t socketHandle, - void * pCallbackContext ) -{ - PlatformEventGroupHandle_t eventGroupHandle = ( PlatformEventGroupHandle_t ) pCallbackContext; - - TEST_ASSERT( socketHandle != NULL ); - - if( eventGroupHandle != NULL ) - { - if( urcEvent == CELLULAR_URC_SOCKET_OPENED ) - { - configPRINTF( ( "Socket open callback, Success\r\n" ) ); - ( void ) PlatformEventGroup_SetBits( eventGroupHandle, SOCKET_OPEN_CALLBACK_BIT ); - } - else - { - configPRINTF( ( "Socket open callback, Failure\r\n" ) ); - ( void ) PlatformEventGroup_SetBits( eventGroupHandle, SOCKET_OPEN_FAILED_CALLBACK_BIT ); - } - } - - _socketOpenContext = pCallbackContext; -} - -/*-----------------------------------------------------------*/ - -/* Modem event callback function. */ -static void prvCellularModemEventCallback( CellularModemEvent_t modemEvent, - void * pCallbackContext ) -{ - ( void ) pCallbackContext; - - if( _modemEventGroup != NULL ) - { - switch( modemEvent ) - { - case CELLULAR_MODEM_EVENT_BOOTUP_OR_REBOOT: - ( void ) PlatformEventGroup_SetBits( _modemEventGroup, MODEM_EVENT_BOOTUP_OR_REBOOT_BIT ); - break; - - case CELLULAR_MODEM_EVENT_POWERED_DOWN: - ( void ) PlatformEventGroup_SetBits( _modemEventGroup, MODEM_EVENT_POWERED_DOWN_BIT ); - break; - - case CELLULAR_MODEM_EVENT_PSM_ENTER: - ( void ) PlatformEventGroup_SetBits( _modemEventGroup, MODEM_EVENT_PSM_ENTER_BIT ); - break; - - default: - break; - } - } -} - -/*-----------------------------------------------------------*/ - -/* Helper function to check sim card ready. */ -static bool prvWaitSimCardReady( void ) -{ - bool simReady = false; - uint32_t tries = 0; - CellularSimCardStatus_t simStatus = { 0 }; - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - for( tries = 0; tries < testCELLULAR_MAX_SIM_RETRY; tries++ ) - { - xCellularStatus = Cellular_GetSimCardStatus( _cellularHandle, &simStatus ); - - if( ( CELLULAR_SUCCESS == xCellularStatus ) && - ( simStatus.simCardState == CELLULAR_SIM_CARD_INSERTED ) && - ( simStatus.simCardLockState == CELLULAR_SIM_CARD_READY ) ) - { - simReady = true; - break; - } - - Platform_Delay( testCELLULAR_SIM_RETRY_INTERVAL_MS ); - } - - return simReady; -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Connect to the CELLULAR and verify success. - */ -static BaseType_t prvConnectCellular( void ) -{ - BaseType_t xResult = pdPASS; - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularServiceStatus_t serviceStatus = { 0 }; - CellularCommInterface_t * pCommIntf = &CellularCommInterface; - CellularPdnConfig_t pdnConfig = { CELLULAR_PDN_CONTEXT_IPV4, CELLULAR_PDN_AUTH_NONE, testCELLULAR_APN, "", "" }; - CellularPdnStatus_t PdnStatusBuffers[ testCELLULAR_MAX_PDN_STATSU_NUM ] = { 0 }; - char localIP[ CELLULAR_IP_ADDRESS_MAX_SIZE ] = { '\0' }; - uint32_t timeoutCount = 0; - uint8_t NumStatus = 0; - bool simReady = false; - CellularPsmSettings_t psmSettings = { 0 }; - CellularEidrxSettings_t eidrxSettings = { 0 }; - uint32_t i = 0; - - /* Clean up the cellular handle before init. */ - if( _cellularHandle != NULL ) - { - ( void ) Cellular_Cleanup( _cellularHandle ); - _cellularHandle = NULL; - } - - /* Initialize Cellular Comm Interface. */ - xCellularStatus = Cellular_Init( &_cellularHandle, pCommIntf ); - - if( xCellularStatus != CELLULAR_SUCCESS ) - { - configPRINTF( ( ">>> Cellular module can't initialized <<<\r\n" ) ); - xResult = pdFAIL; - } - else - { - xResult = pdPASS; - } - - if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) - { - /* Wait until SIM is ready. */ - simReady = prvWaitSimCardReady(); - - if( simReady == false ) - { - xResult = pdFAIL; - } - } - - if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) - { - /* Setup PDN for EPS Network Registration. */ - xCellularStatus = Cellular_SetPdnConfig( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, &pdnConfig ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - xResult = pdPASS; - } - else - { - xResult = pdFAIL; - } - } - - /* Rescan network. */ - if( xCellularStatus == CELLULAR_SUCCESS ) - { - ( void ) Cellular_RfOff( _cellularHandle ); - xCellularStatus = Cellular_RfOn( _cellularHandle ); - } - - if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) - { - /* Check network register status. */ - xResult = pdFAIL; - - for( timeoutCount = 0; timeoutCount < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; timeoutCount++ ) - { - xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); - - if( ( xCellularStatus == CELLULAR_SUCCESS ) && - ( ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_REGISTERED_HOME ) || - ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_ROAMING_REGISTERED ) ) ) - { - xResult = pdPASS; - break; - } - - Platform_Delay( testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ); - } - - if( xResult == pdFAIL ) - { - configPRINTF( ( ">>> Cellular module can't be registered <<<\r\n" ) ); - } - } - - /* Disable PSM and EIDRX. */ - if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) - { - psmSettings.mode = 0; - psmSettings.periodicTauValue = 0; - psmSettings.periodicRauValue = 0; - psmSettings.gprsReadyTimer = 0; - psmSettings.activeTimeValue = 0; - - xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); - } - - /* Disable the EDRX mode. */ - if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) - { - eidrxSettings.mode = 0; - eidrxSettings.rat = testCELLULAR_EDRX_RAT; - eidrxSettings.requestedEdrxVaue = 0; - - xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); - } - - if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) - { - xCellularStatus = Cellular_RegisterUrcNetworkRegistrationEventCallback( _cellularHandle, &prvNetworkRegistrationCallback, _cellularHandle ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - xCellularStatus = Cellular_RegisterUrcPdnEventCallback( _cellularHandle, &prvPdnEventCallback, _cellularHandle ); - } - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - xCellularStatus = Cellular_SetPdnConfig( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, &pdnConfig ); - } - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - xCellularStatus = Cellular_ActivatePdn( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID ); - } - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - xCellularStatus = Cellular_GetIPAddress( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, localIP, sizeof( localIP ) ); - } - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, PdnStatusBuffers, testCELLULAR_MAX_PDN_STATSU_NUM, &NumStatus ); - } - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - xCellularStatus = Cellular_SetDns( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, testCELLULAR_DNS_SERVER_ADDRESS ); - - /* Modem use dynamic DNS. */ - if( xCellularStatus == CELLULAR_UNSUPPORTED ) - { - xCellularStatus = CELLULAR_SUCCESS; - } - } - } - - if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) - { - for( i = 0; i < NumStatus; i++ ) - { - if( ( PdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) && ( PdnStatusBuffers[ i ].state == 1 ) ) - { - break; - } - } - - if( i != NumStatus ) - { - xResult = pdPASS; - } - } - else - { - xResult = pdFAIL; - } - - return xResult; -} - -/*-----------------------------------------------------------*/ - -/* Helper function to check if cellular network connected. */ -static BaseType_t prvIsConnectedCellular( void ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularPdnStatus_t PdnStatusBuffers[ testCELLULAR_MAX_PDN_STATSU_NUM ] = { 0 }; - uint8_t NumStatus = 0; - BaseType_t xResult = pdFAIL; - uint32_t i = 0; - - if( _cellularHandle != NULL ) - { - xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, - PdnStatusBuffers, - testCELLULAR_MAX_PDN_STATSU_NUM, - &NumStatus ); - - /* State 0 = Deactivated, 1 = Activated. */ - if( xCellularStatus == CELLULAR_SUCCESS ) - { - for( i = 0; i < NumStatus; i++ ) - { - if( ( PdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) && ( PdnStatusBuffers[ i ].state == 1 ) ) - { - xResult = pdPASS; - break; - } - } - } - } - else - { - xResult = pdFAIL; - } - - return xResult; -} - -/*-----------------------------------------------------------*/ - -/* Finish test help function. */ -static BaseType_t prvFinishCellularTesting( void ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - BaseType_t xResult = pdPASS; - - if( _cellularHandle != NULL ) - { - xCellularStatus = Cellular_Cleanup( _cellularHandle ); - } - - if( xCellularStatus != CELLULAR_SUCCESS ) - { - configPRINTF( ( ">>> Cellular module cleanup failed <<<\r\n" ) ); - xResult = pdFAIL; - } - else - { - _cellularHandle = NULL; - xResult = pdPASS; - } - - return xResult; -} - -/*-----------------------------------------------------------*/ - -/* Setup socket connection. */ -static CellularSocketHandle_t prvSocketConnectionSetup( uint16_t serverPort, - char * pServerAddress, - PlatformEventGroupHandle_t * pSocketEventGroup ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularSocketAddress_t remoteSocketAddress = { 0 }; - CellularSocketHandle_t socketHandle = NULL; - uint32_t sendTimeout = testCELLULAR_SOCKET_SEND_TIMEOUT_MS; - EventBits_t waitEventBits = 0; - PlatformEventGroupHandle_t socketEventGroup = NULL; - - /* Setup the event group. */ - socketEventGroup = xEventGroupCreate(); - TEST_ASSERT_MESSAGE( socketEventGroup != NULL, "event group create failed" ); - *pSocketEventGroup = socketEventGroup; - xEventGroupClearBits( socketEventGroup, - SOCKET_OPEN_CALLBACK_BIT | SOCKET_OPEN_FAILED_CALLBACK_BIT | SOCKET_DATA_RECEIVED_CALLBACK_BIT ); - - /* Setup the tcp connection. */ - /* Create Socket. */ - xCellularStatus = Cellular_CreateSocket( _cellularHandle, - testCELLULAR_PDN_CONTEXT_ID, - CELLULAR_SOCKET_DOMAIN_AF_INET, - CELLULAR_SOCKET_TYPE_DGRAM, - CELLULAR_SOCKET_PROTOCOL_TCP, - &socketHandle ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Modify Socket. */ - xCellularStatus = Cellular_SocketSetSockOpt( _cellularHandle, - socketHandle, - CELLULAR_SOCKET_OPTION_LEVEL_TRANSPORT, - CELLULAR_SOCKET_OPTION_SEND_TIMEOUT, - ( uint8_t * ) &sendTimeout, - sizeof( sendTimeout ) ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Data and Socket Event call back enabled. */ - xCellularStatus = Cellular_SocketRegisterDataReadyCallback( _cellularHandle, - socketHandle, - &prvCellularSocketDataReadyCallback, - socketEventGroup ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - xCellularStatus = Cellular_SocketRegisterSocketOpenCallback( _cellularHandle, - socketHandle, - &prvCellularSocketOpenCallback, - socketEventGroup ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - xCellularStatus = Cellular_SocketRegisterClosedCallback( _cellularHandle, - socketHandle, - &prvSocketClosedCallback, - socketEventGroup ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Connect Socket. */ - remoteSocketAddress.port = serverPort; - remoteSocketAddress.ipAddress.ipAddressType = CELLULAR_IP_ADDRESS_V4; - strncpy( remoteSocketAddress.ipAddress.ipAddress, pServerAddress, CELLULAR_IP_ADDRESS_MAX_SIZE ); - xCellularStatus = Cellular_SocketConnect( _cellularHandle, - socketHandle, - CELLULAR_ACCESSMODE_BUFFER, - &remoteSocketAddress ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - waitEventBits = xEventGroupWaitBits( socketEventGroup, - SOCKET_OPEN_CALLBACK_BIT | SOCKET_OPEN_FAILED_CALLBACK_BIT, - pdTRUE, - pdFALSE, - pdMS_TO_TICKS( testCELLULAR_SOCKET_CONNECTION_TIMEOUT_MS ) ); - TEST_ASSERT_MESSAGE( ( waitEventBits & SOCKET_OPEN_CALLBACK_BIT ) != 0, "Socket connection timeout or failed" ); - - return socketHandle; -} - - -/*-----------------------------------------------------------*/ - -/* Close socket connection. */ -static void prvSocketConnectionClose( CellularSocketHandle_t socketHandle, - PlatformEventGroupHandle_t socketEventGroup, - bool waitCallback ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - PlatformEventGroup_EventBits waitEventBits = 0; - - /* Close the socket. */ - xCellularStatus = Cellular_SocketRegisterDataReadyCallback( _cellularHandle, - socketHandle, - NULL, - NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - xCellularStatus = Cellular_SocketRegisterSocketOpenCallback( _cellularHandle, - socketHandle, - NULL, - NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - if( waitCallback == false ) - { - xCellularStatus = Cellular_SocketRegisterClosedCallback( _cellularHandle, - socketHandle, - NULL, - NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - } - - xCellularStatus = Cellular_SocketClose( _cellularHandle, socketHandle ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - if( ( waitCallback == true ) && ( socketEventGroup != NULL ) ) - { - waitEventBits = PlatformEventGroup_WaitBits( socketEventGroup, - SOCKET_CLOSED_CALLBACK_BIT, - pdTRUE, - pdFALSE, - pdMS_TO_TICKS( testCELLULAR_SOCKET_CLOSE_TIMEOUT_MS ) ); - TEST_ASSERT_MESSAGE( ( waitEventBits & SOCKET_CLOSED_CALLBACK_BIT ) != 0, "Socket close timeout or failed" ); - } - - if( socketEventGroup != NULL ) - { - vEventGroupDelete( socketEventGroup ); - } -} - -/*-----------------------------------------------------------*/ - -/* EDRX receive count test function. */ -static uint32_t prvTestSocketReceiveCount( const uint32_t testTimeMs, - const uint32_t dataReceiveIntervalMs ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularSocketHandle_t socketHandle = NULL; - uint32_t dataReceivedCount = 0; - uint32_t sentDataLen = 0; - uint8_t receiveBuff[ 100 ] = { 0 }; - uint32_t receivedDataLen = 0; - uint32_t totalReceivedDataLen = 0; - TickType_t recvStartTime = 0; - PlatformEventGroupHandle_t socketEventGroup = NULL; - - /* Setup the socket connection. */ - socketHandle = prvSocketConnectionSetup( testCELLULAR_EDRX_ECHO_SERVER_PORT, - testCELLULAR_EDRX_ECHO_SERVER_ADDRESS, - &socketEventGroup ); - - /* Send a byte to the server to start echo in time interval. */ - xCellularStatus = Cellular_SocketSend( _cellularHandle, - socketHandle, - ( const uint8_t * ) _socketDataSend, - strlen( _socketDataSend ), - &sentDataLen ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - recvStartTime = xTaskGetTickCount(); - /* Echo server will send data after received data. Wait 5 seconds for the first data. */ - configPRINTF( ( "start receive time %d, test time ms %d\r\n", recvStartTime, testTimeMs ) ); - Platform_Delay( 5000UL ); - - while( 1 ) - { - totalReceivedDataLen = 0; - - while( 1 ) - { - xCellularStatus = Cellular_SocketRecv( _cellularHandle, - socketHandle, - receiveBuff, - sizeof( receiveBuff ), - &receivedDataLen ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - if( receivedDataLen == 0 ) - { - break; - } - - totalReceivedDataLen = totalReceivedDataLen + receivedDataLen; - } - - if( totalReceivedDataLen != 0 ) - { - configPRINTF( ( "Bytes received %d\r\n", totalReceivedDataLen ) ); - dataReceivedCount = dataReceivedCount + 1; - } - - if( ( xTaskGetTickCount() - recvStartTime ) > pdMS_TO_TICKS( testTimeMs ) ) - { - break; - } - - Platform_Delay( dataReceiveIntervalMs ); - } - - prvSocketConnectionClose( socketHandle, socketEventGroup, false ); - - return dataReceivedCount; -} - -/*-----------------------------------------------------------*/ - -/* Unity TEST initializations. */ -TEST_GROUP( Full_CELLULAR_API ); - -/*-----------------------------------------------------------*/ - -TEST_SETUP( Full_CELLULAR_API ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularModemInfo_t modemInfo = { 0 }; - CellularSimCardInfo_t simCardInfo = { 0 }; - CellularSimCardStatus_t simStatus = { 0 }; - CellularSignalInfo_t signalInfo = { 0 }; - char localIP[ CELLULAR_IP_ADDRESS_MAX_SIZE ] = { '\0' }; - CellularPlmnInfo_t networkInfo = { 0 }; - CellularServiceStatus_t serviceStatus = { 0 }; - CellularTime_t networkTime = { 0 }; - CellularPsmSettings_t psmSettings = { 0 }; - CellularEidrxSettingsList_t eidrxSettingsList = { 0 }; - CellularRat_t pRatPriorities[ CELLULAR_MAX_RAT_PRIORITY_COUNT ] = { CELLULAR_RAT_INVALID }; - uint8_t receivedRatPrioritiesLength = 0; - uint32_t ratIndex = 0; - - configPRINTF( ( "\r\n==================================================================================\r\n" ) ); - - xCellularStatus = Cellular_GetModemInfo( _cellularHandle, &modemInfo ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( - ( " FW: %s \r\n IMEI: %s \r\n MfrID/ModId: %s/%s \r\n", modemInfo.firmwareVersion, modemInfo.imei, modemInfo.manufactureId, modemInfo.modelId ) ); - } - else - { - configPRINTF( ( " FW: \r\n IMEI: \r\n MfrID/ModId: \r\n" ) ); - } - - xCellularStatus = Cellular_GetSimCardInfo( _cellularHandle, &simCardInfo ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( - ( " ICCID: %s \r\n IMSI: %s \r\n HPLMN: %s-%s \r\n", simCardInfo.iccid, simCardInfo.imsi, simCardInfo.plmn.mcc, simCardInfo.plmn.mnc ) ); - } - else - { - configPRINTF( ( " ICCID: \r\n IMSI: \r\n HPLMN: \r\n" ) ); - } - - xCellularStatus = Cellular_GetSimCardStatus( _cellularHandle, &simStatus ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( ( " SIM Status: %d \r\n SIM Lock: %d \r\n", simStatus.simCardState, simStatus.simCardLockState ) ); - } - else - { - configPRINTF( ( " SIM Status: \r\n SIM Lock: \r\n" ) ); - } - - xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( - ( " rat: %d \r\n cs: %d \r\n ps: %d \r\n mode: %d \r\n csRej: %d \r\n psRej: %d \r\n plmn: %s%s \r\n", serviceStatus.rat, serviceStatus.csRegistrationStatus, serviceStatus.psRegistrationStatus, serviceStatus.networkRegistrationMode, serviceStatus.csRejectionCause, serviceStatus.psRejectionCause, serviceStatus.plmnInfo.mcc, serviceStatus.plmnInfo.mnc ) ); - } - else - { - configPRINTF( ( " rat: \r\n cs: \r\n ps: \r\n mode: \r\n csRej: \r\n psRej: \r\n plmn: \r\n" ) ); - } - - xCellularStatus = Cellular_GetRegisteredNetwork( _cellularHandle, &networkInfo ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( ( " Network: %s-%s \r\n", networkInfo.mcc, networkInfo.mnc ) ); - } - else - { - configPRINTF( ( " Network: \r\n" ) ); - } - - /* Cellular_GetSignalInfo should be called after Cellular_GetServiceStatus to set libAtData.rat to get correct bar level. */ - xCellularStatus = Cellular_GetSignalInfo( _cellularHandle, &signalInfo ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( - ( " Signal Bars: %d \r\n Signal RSSI: %d \r\n Signal RSRP: %d \r\n Signal RSRQ: %d \r\n", signalInfo.bars, signalInfo.rssi, signalInfo.rsrp, signalInfo.rsrq ) ); - } - else - { - configPRINTF( - ( " Signal Bars: N/A\r\n Signal RSSI: N/A\r\n Signal RSRP: N/A\r\n Signal RSRQ: N/A\r\n" ) ); - } - - xCellularStatus = Cellular_GetNetworkTime( _cellularHandle, &networkTime ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( - ( " Network time: %d/%d/%d %d:%d:%d \r\n", networkTime.month, networkTime.day, networkTime.year, networkTime.hour, networkTime.minute, networkTime.second ) ); - } - else - { - configPRINTF( ( " Network time: \r\n" ) ); - } - - xCellularStatus = Cellular_GetRatPriority( _cellularHandle, - pRatPriorities, CELLULAR_MAX_RAT_PRIORITY_COUNT, &receivedRatPrioritiesLength ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - for( ratIndex = 0; ratIndex < receivedRatPrioritiesLength; ratIndex++ ) - { - configPRINTF( ( " RAT Priority: %u %u\r\n", ratIndex, pRatPriorities[ ratIndex ] ) ); - } - } - - xCellularStatus = Cellular_GetIPAddress( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, localIP, sizeof( localIP ) ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( ( " IP address: %s \r\n", localIP ) ); - } - else - { - configPRINTF( ( " IP address: \r\n" ) ); - } - - xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( ( " PSM mode: %d \r\n PSM TAU Value: %d \r\n PSM RAU Value: %d \r\n PSM GPRS Timer: %d \r\n PSM Active Value: %d \r\n", - psmSettings.mode, - psmSettings.periodicTauValue, - psmSettings.periodicRauValue, - psmSettings.gprsReadyTimer, - psmSettings.activeTimeValue ) ); - } - else - { - configPRINTF( - ( " PSM mode: \r\n PSM TAU Value: \r\n PSM RAU Value: \r\n PSM GPRS Timer: \r\n PSM Active Value: \r\n" ) ); - } - - xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - for( int i = 0; i < eidrxSettingsList.count; i++ ) - { - configPRINTF( ( " eDRX index: %d eDRX mode: %d eDRX rat:%d eDRX UE Value:%d eDRX NW value:%d \r\n", - i, - eidrxSettingsList.eidrxList[ i ].mode, - eidrxSettingsList.eidrxList[ i ].rat, - eidrxSettingsList.eidrxList[ i ].requestedEdrxVaue, - eidrxSettingsList.eidrxList[ i ].nwProvidedEdrxVaue ) ); - } - } - else - { - configPRINTF( ( " eDRX index: eDRX mode: eDRX rat: eDRX UE Value: eDRX NW value: \r\n" ) ); - } - - configPRINTF( ( "\r\n==================================================================================\r\n" ) ); -} - -/*-----------------------------------------------------------*/ - -TEST_TEAR_DOWN( Full_CELLULAR_API ) -{ - configPRINTF( ( "\r\n==================================================================================\r\n" ) ); -} - -/*-----------------------------------------------------------*/ - -TEST_GROUP_RUNNER( Full_CELLULAR_API ) -{ - /* List of all tests under this group */ - /* In sequence tests. */ - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Configure ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Activate ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetNetworkTime ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetHostByName ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_TCPDataTransfer ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_EidrxSettings ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_PsmSettings ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_RatPriority ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_AtCommandRawAndGenericUrc ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_AirplaneMode ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Deactivate ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_UnConfigure ); - - /* Null parameter tests. */ - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetModemInfo_NullParameters ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetSimCardInfo_NullParameters ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetSimCardStatus_NullParameters ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetServiceStatus_NullParameters ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetSignalInfo_NullParameters ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetRegisteredNetwork_NullParameters ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetPsmSettings_NullParameters ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetEidrxSettings_NullParameters ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetPdnStatus_NullParameters ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetIPAddress_NullParameters ); - - /* Invalid parameters tests. */ - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetRatPriority_InvalidMode ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetPsmSettings_InvalidMode ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetEidrxSettings_InvalidMode ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetPdnConfig_InvalidMode ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetDns_InvalidMode ); - - /* Stability tests. */ - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Data_Loop ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_MultipleSocketConnection ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_AirplaneMode_Loop ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Power_Loop ); - - /* PSM and eDRX tests. */ - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_EidrxEchoTimes ); - RUN_TEST_CASE( Full_CELLULAR_API, Cellular_PsmStatus ); - - prvFinishCellularTesting(); -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Configure CELLULAR. - */ -TEST( Full_CELLULAR_API, Cellular_Configure ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularSimCardStatus_t simStatus = { 0 }; - CellularCommInterface_t * pCommIntf = &CellularCommInterface; - uint8_t tries = 0; - uint8_t simReady = 0; - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_Init( &_cellularHandle, pCommIntf ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> Cellular module can't be initialized <<<" ); - - /* Wait until SIM is ready. */ - for( tries = 0; tries < testCELLULAR_MAX_SIM_RETRY; tries++ ) - { - xCellularStatus = Cellular_GetSimCardStatus( _cellularHandle, &simStatus ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> Cellular SIM failure <<<" ); - - if( ( simStatus.simCardState == CELLULAR_SIM_CARD_INSERTED ) && - ( simStatus.simCardLockState == CELLULAR_SIM_CARD_READY ) ) - { - simReady = 1; - break; - } - - Platform_Delay( testCELLULAR_SIM_RETRY_INTERVAL_MS ); - } - - TEST_ASSERT( simReady != 0 ); - - /* Enable Callbacks. */ - xCellularStatus = Cellular_RegisterUrcSignalStrengthChangedCallback( _cellularHandle, &prvSignalStrengthChangedCallback, _cellularHandle ); - TEST_CELLULAR_ASSERT_OPTIONAL_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - xCellularStatus = Cellular_RegisterUrcNetworkRegistrationEventCallback( _cellularHandle, &prvNetworkRegistrationCallback, _cellularHandle ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - xCellularStatus = Cellular_RegisterUrcPdnEventCallback( _cellularHandle, &prvPdnEventCallback, _cellularHandle ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief CELLULAR Activate. - */ -TEST( Full_CELLULAR_API, Cellular_Activate ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularServiceStatus_t serviceStatus = { 0 }; - CellularPdnConfig_t pdnConfig = - { CELLULAR_PDN_CONTEXT_IPV4, CELLULAR_PDN_AUTH_NONE, testCELLULAR_APN, "", "" }; - CellularPdnStatus_t PdnStatusBuffers[ testCELLULAR_MAX_PDN_STATSU_NUM ] = { 0 }; - char localIP[ CELLULAR_IP_ADDRESS_MAX_SIZE ] = { '\0' }; - uint32_t timeoutCount = 0; - uint8_t numStatus = 0; - CellularPsmSettings_t psmSettings = { 0 }; - CellularEidrxSettings_t eidrxSettings = { 0 }; - uint32_t i = 0; - - if( TEST_PROTECT() ) - { - /* Setup PDN for EPS Network Registration. */ - xCellularStatus = Cellular_SetPdnConfig( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, &pdnConfig ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> PDN configuration failed <<<" ); - - /* Rescan network. */ - if( xCellularStatus == CELLULAR_SUCCESS ) - { - xCellularStatus = Cellular_RfOff( _cellularHandle ); - } - - Platform_Delay( 5000 ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - for( timeoutCount = 0; timeoutCount < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; timeoutCount++ ) - { - xCellularStatus = Cellular_RfOn( _cellularHandle ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - break; - } - } - } - - TEST_ASSERT( xCellularStatus == CELLULAR_SUCCESS ); - - /* Verify registration. */ - for( timeoutCount = 0; timeoutCount < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; timeoutCount++ ) - { - xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> Cellular module can't be registered <<<" ); - - if( ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_REGISTERED_HOME ) || - ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_ROAMING_REGISTERED ) ) - { - break; - } - - Platform_Delay( testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ); - } - - if( timeoutCount >= testCELLULAR_MAX_NETWORK_REGISTER_RETRY ) - { - TEST_FAIL_MESSAGE( ">>> Cellular module can't be registered <<<" ); - } - - /* Configure and Activate PDN, set DNS and verify IP. */ - xCellularStatus = Cellular_ActivatePdn( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> Cellular module can't be activated <<<" ); - - /* Get PDN & IP and verify. */ - xCellularStatus = Cellular_GetIPAddress( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, localIP, sizeof( localIP ) ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, - PdnStatusBuffers, - testCELLULAR_MAX_PDN_STATSU_NUM, - &numStatus ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - for( i = 0; i < numStatus; i++ ) - { - if( PdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) - { - TEST_ASSERT_EQUAL_INT32_MESSAGE( 1, PdnStatusBuffers[ i ].state, - ">>> Cellular module failed to be activated <<<" ); - break; - } - } - - TEST_ASSERT_MESSAGE( i != numStatus, ">>> Cellular module failed to be activated, no activate PDN found <<<" ); - - /* Set DNS. */ - xCellularStatus = Cellular_SetDns( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, testCELLULAR_DNS_SERVER_ADDRESS ); - TEST_CELLULAR_ASSERT_OPTIONAL_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> DNS configuration failed <<<" ); - - /* Disable PSM and eDRX for the following tests. */ - psmSettings.mode = 0; - psmSettings.periodicTauValue = 0; - psmSettings.periodicRauValue = 0; - psmSettings.gprsReadyTimer = 0; - psmSettings.activeTimeValue = 0; - xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> Disable PSM failed <<<" ); - - eidrxSettings.mode = 0; - eidrxSettings.rat = testCELLULAR_EDRX_RAT; - eidrxSettings.requestedEdrxVaue = 0; - xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> Disable EDRX failed <<<" ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Get network time. - */ -TEST( Full_CELLULAR_API, Cellular_GetNetworkTime ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularTime_t networkTime = { 0 }; - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetNetworkTime( _cellularHandle, &networkTime ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> Get network time failed <<<" ); - - /* Verify the value range. */ - TEST_ASSERT_MESSAGE( ( ( networkTime.month >= 1 ) && ( networkTime.month <= 12 ) ), - ">>> Get network time month value error <<<" ); - TEST_ASSERT_MESSAGE( ( ( networkTime.day >= 1 ) && ( networkTime.day <= 31 ) ), - ">>> Get network time day value error <<<" ); - TEST_ASSERT_MESSAGE( ( ( networkTime.hour >= 0 ) && ( networkTime.hour <= 24 ) ), - ">>> Get network time hour value error <<<" ); - TEST_ASSERT_MESSAGE( ( ( networkTime.minute >= 0 ) && ( networkTime.minute <= 59 ) ), - ">>> Get network time minute value error <<<" ); - TEST_ASSERT_MESSAGE( ( ( networkTime.second >= 0 ) && ( networkTime.second <= 59 ) ), - ">>> Get network time second value error <<<" ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Host name resolve test. - */ -TEST( Full_CELLULAR_API, Cellular_GetHostByName ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - char pIpAddress[ CELLULAR_IP_ADDRESS_MAX_SIZE ] = { '\0' }; - - if( TEST_PROTECT() ) - { - /* DNS query IP. */ - xCellularStatus = Cellular_GetHostByName( - _cellularHandle, - testCELLULAR_PDN_CONTEXT_ID, - testCELLULAR_HOST_NAME, - pIpAddress ); - TEST_CELLULAR_ASSERT_OPTIONAL_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> DNS query IP failed <<<" ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - TEST_ASSERT_MESSAGE( strncmp( pIpAddress, testCELLULAR_HOST_NAME_ADDRESS, CELLULAR_IP_ADDRESS_MAX_SIZE ) == 0, - ">>> DNS query IP incorrect <<<" ); - } - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief TCP Data Transfer. - */ -TEST( Full_CELLULAR_API, Cellular_TCPDataTransfer ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularSocketHandle_t socketHandle = NULL; - uint8_t tries = 0; - uint32_t sentDataLen = 0; - char receiveBuff[ 100 ] = { 0 }; - uint32_t receivedDataLen = 0; - - if( TEST_PROTECT() ) - { - /* Setup the test variable. */ - _dataReady = 0; - _socketOpenContext = NULL; - _socketDataReadyContext = NULL; - _socketClosedContext = NULL; - - /* Setup server connection. */ - socketHandle = prvSocketConnectionSetup( testCELLULAR_ECHO_SERVER_PORT, - testCELLULAR_ECHO_SERVER_ADDRESS, - &_socketEventGroup ); - TEST_ASSERT_MESSAGE( _socketOpenContext == _socketEventGroup, "Socket open context check failed" ); - - /* Send Data on Socket. */ - for( tries = 0; tries < SOCKET_OPERATION_POLLING_TIMES; tries++ ) - { - xCellularStatus = Cellular_SocketSend( _cellularHandle, - socketHandle, - ( const uint8_t * ) _socketDataSend, - strlen( _socketDataSend ), - &sentDataLen ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - break; - } - } - - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Receive Data on Socket in polling method. */ - for( tries = 0; tries < SOCKET_OPERATION_POLLING_TIMES; tries++ ) - { - Platform_Delay( testCELLULAR_SOCKET_WAIT_INTERVAL_MS ); - - if( _dataReady == 1 ) - { - xCellularStatus = Cellular_SocketRecv( _cellularHandle, - socketHandle, - ( uint8_t * ) receiveBuff, - sizeof( receiveBuff ), - &receivedDataLen ); - TEST_ASSERT_MESSAGE( _socketDataReadyContext == _socketEventGroup, "Socket data ready context check failed" ); - break; - } - } - - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Compare Data on Socket. */ - TEST_ASSERT_MESSAGE( strncmp( _socketDataSend, receiveBuff, strlen( _socketDataSend ) ) == 0, - "Cellular_TCPDataTransfer received data compare failed" ); - - /* Close Socket. */ - #ifdef CELLULAR_ASYNC_SOCKET_CLOSE - prvSocketConnectionClose( socketHandle, _socketEventGroup, true ); - TEST_ASSERT_MESSAGE( _socketClosedContext == _socketEventGroup, "Socket close context check failed" ); - #else - prvSocketConnectionClose( socketHandle, _socketEventGroup, false ); - #endif - _socketEventGroup = NULL; - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Enable CELLULAR Idle Discontinuous Reception. - */ -TEST( Full_CELLULAR_API, Cellular_EidrxSettings ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularEidrxSettings_t eidrxSettings = { 0 }; - CellularEidrxSettingsList_t eidrxSettingsList = { 0 }; - uint8_t drxValue = 5; /* 5 = ( 0 1 0 1 ) 81.92 seconds. */ - int i = 0; - - if( TEST_PROTECT() ) - { - /* Disable the EDRX mode. */ - eidrxSettings.mode = 0; - eidrxSettings.rat = testCELLULAR_EDRX_RAT; - eidrxSettings.requestedEdrxVaue = 0; - - xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Enabling the EDRX mode and verify. */ - eidrxSettings.mode = 1; /* Enable the use of e-I-DRX. */ - eidrxSettings.rat = testCELLULAR_EDRX_RAT; - eidrxSettings.requestedEdrxVaue = drxValue; - - xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - TEST_ASSERT_MESSAGE( eidrxSettingsList.count > 0, "eidrxSettingsList count is 0" ); - - for( i = 0; i < eidrxSettingsList.count; i++ ) - { - if( eidrxSettingsList.eidrxList[ i ].rat == testCELLULAR_EDRX_RAT ) - { - TEST_ASSERT_EQUAL_INT32( eidrxSettingsList.eidrxList[ i ].requestedEdrxVaue, drxValue ); - } - } - - /* Disabling the EDRX mode and verify. */ - eidrxSettings.mode = 3; /* Disable the use of e-I-DRX and discard all parameters for e-I-DRX or, - * if available, reset to the manufacturer specific default values. */ - eidrxSettings.rat = testCELLULAR_EDRX_RAT; - eidrxSettings.requestedEdrxVaue = 0; - - xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Enable CELLULAR Power Saving Mode attributes. - */ -TEST( Full_CELLULAR_API, Cellular_PsmSettings ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularPsmSettings_t psmSettings = { 0 }; - uint32_t psmTau = 4; /* 4 * 10 minutes = 40 minutes. */ - uint32_t psmTimer = 14; /* 14 * 2 seconds = 28 Seconds. */ - uint32_t tries = 0; - - if( TEST_PROTECT() ) - { - /* Disabling the PSM mode if ON. */ - xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - if( psmSettings.mode == 1 ) - { - psmSettings.mode = 0; - psmSettings.periodicTauValue = 0; - psmSettings.periodicRauValue = 0; - psmSettings.gprsReadyTimer = 0; - psmSettings.activeTimeValue = 0; - - xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - } - - /* Enabling the PSM mode and verify. */ - psmSettings.mode = 1; - psmSettings.periodicTauValue = psmTau; - psmSettings.periodicRauValue = 0; - psmSettings.gprsReadyTimer = 0; - psmSettings.activeTimeValue = psmTimer; - - xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - for( tries = 0; tries < testCELLULAR_MAX_GET_PSM_RETRY; tries++ ) - { - xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); - - if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( psmSettings.mode == 1 ) ) - { - break; - } - - Platform_Delay( testCELLULAR_GET_PSM_RETRY_INTERVAL_MS ); - } - - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - TEST_ASSERT_EQUAL_INT32( psmSettings.mode, 1 ); - - /* Disabling the PSM mode and verify. */ - psmSettings.mode = 0; - psmSettings.periodicTauValue = 0; - psmSettings.periodicRauValue = 0; - psmSettings.gprsReadyTimer = 0; - psmSettings.activeTimeValue = 0; - - xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - for( tries = 0; tries < testCELLULAR_MAX_GET_PSM_RETRY; tries++ ) - { - xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); - - if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( psmSettings.mode == 0 ) ) - { - break; - } - - Platform_Delay( testCELLULAR_GET_PSM_RETRY_INTERVAL_MS ); - } - - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - TEST_ASSERT_EQUAL_INT32( psmSettings.mode, 0 ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Setting and checking CELLULAR RAT priority. - */ -TEST( Full_CELLULAR_API, Cellular_RatPriority ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - const CellularRat_t pRatPriorities1[ TEST_MAX_RAT_PRIORITY_COUNT ] = - { CELLULAR_RAT_NBIOT, CELLULAR_RAT_CATM1, CELLULAR_RAT_GSM }; - const CellularRat_t pRatPriorities2[ TEST_MAX_RAT_PRIORITY_COUNT ] = - { CELLULAR_RAT_CATM1, CELLULAR_RAT_NBIOT, CELLULAR_RAT_GSM }; - CellularRat_t pRatPriorities[ TEST_MAX_RAT_PRIORITY_COUNT ] = { CELLULAR_RAT_INVALID }; - uint8_t receivedRatPrioritiesLength = 0; - int i = 0; - uint32_t tries = 0; - bool ratFlag = true; - - if( TEST_PROTECT() ) - { - /* Set the first priority and verify. */ - xCellularStatus = Cellular_SetRatPriority( _cellularHandle, - ( const CellularRat_t * ) pRatPriorities1, - CELLULAR_MAX_RAT_PRIORITY_COUNT ); - TEST_CELLULAR_ASSERT_OPTIONAL_API_MSG( ( CELLULAR_SUCCESS == xCellularStatus ) || ( CELLULAR_NOT_ALLOWED == xCellularStatus ), - xCellularStatus, - "Set RAT priority failed" ); - - /* Set RAT priority may not be supported in the cellular module. */ - if( xCellularStatus == CELLULAR_SUCCESS ) - { - for( tries = 0; tries < testCELLULAR_GET_RAT_RETRY; tries++ ) - { - xCellularStatus = Cellular_GetRatPriority( _cellularHandle, - pRatPriorities, - CELLULAR_MAX_RAT_PRIORITY_COUNT, - &receivedRatPrioritiesLength ); - TEST_ASSERT_MESSAGE( CELLULAR_SUCCESS == xCellularStatus, "Get RAT priority failed" ); - - /* Check the return priority length if RAT priority is supported. */ - if( xCellularStatus == CELLULAR_SUCCESS ) - { - TEST_ASSERT_MESSAGE( receivedRatPrioritiesLength > 0, "Get RAT priority failed" ); - ratFlag = true; - - for( i = 0; i < receivedRatPrioritiesLength; i++ ) - { - if( pRatPriorities1[ i ] != pRatPriorities[ i ] ) - { - configPRINTF( ( "%d : Set RAT [%d] != Get RAT [ %d ]\r\n", - i, pRatPriorities1[ i ], pRatPriorities[ i ] ) ); - ratFlag = false; - break; - } - } - - if( ratFlag == true ) - { - break; - } - } - else - { - break; - } - - Platform_Delay( testCELLULAR_GET_RAT_RETRY_INTERVAL_MS ); - } - - TEST_ASSERT_MESSAGE( ratFlag == true, "RATs priority compare failed" ); - - /* Restore the second priority. */ - xCellularStatus = Cellular_SetRatPriority( _cellularHandle, - ( const CellularRat_t * ) pRatPriorities2, - CELLULAR_MAX_RAT_PRIORITY_COUNT ); - TEST_ASSERT_MESSAGE( CELLULAR_SUCCESS == xCellularStatus, "Set RAT priority failed" ); - } - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Send AT command with receive the generic URC. - */ -TEST( Full_CELLULAR_API, Cellular_AtCommandRawAndGenericUrc ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( TEST_PROTECT() ) - { - _genericUrcCalled = false; - xCellularStatus = Cellular_RegisterUrcGenericCallback( _cellularHandle, - prvGenericCallback, _cellularHandle ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( xCellularStatus == CELLULAR_SUCCESS, xCellularStatus, - "Register URC generic callback failed" ); - - /* Send the 3GPP get network time AT command. - * The returned network time string is handled in generic URC handler. */ - xCellularStatus = Cellular_ATCommandRaw( _cellularHandle, - NULL, - "AT+CCLK?", - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - 0U ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( xCellularStatus == CELLULAR_SUCCESS, xCellularStatus, - "Send AT command raw failed" ); - - /* The maximum response time is 300ms. */ - Platform_Delay( 300U ); - TEST_ASSERT_MESSAGE( _genericUrcCalled == true, "Generic URC is not called" ); - - xCellularStatus = Cellular_RegisterUrcGenericCallback( _cellularHandle, - NULL, - NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( xCellularStatus == CELLULAR_SUCCESS, xCellularStatus, - "Register URC generic callback failed" ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Setting CELLULAR Airplane Mode On and off. - */ -TEST( Full_CELLULAR_API, Cellular_AirplaneMode ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularServiceStatus_t serviceStatus = { 0 }; - bool simReady = false; - uint32_t tries = 0; - - if( TEST_PROTECT() ) - { - /* RF Off. */ - xCellularStatus = Cellular_RfOff( _cellularHandle ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Wait until SIM is ready. */ - simReady = prvWaitSimCardReady(); - TEST_ASSERT( simReady == true ); - - /* Check network registration status. Airplane mode the register status should be - * CELLULAR_NETWORK_REGISTRATION_STATUS_NOT_REGISTERED_NOT_SEARCHING */ - for( tries = 0; tries < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; tries++ ) - { - xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - if( ( serviceStatus.psRegistrationStatus != REGISTRATION_STATUS_REGISTERED_HOME ) && - ( serviceStatus.psRegistrationStatus != REGISTRATION_STATUS_ROAMING_REGISTERED ) ) - { - break; - } - - Platform_Delay( testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ); - } - - configPRINTF( ( "serviceStatus.psRegistrationStatus %d\r\n", serviceStatus.psRegistrationStatus ) ); - - /* Add also psRegistrationStatus=4 if +CGREG: 2,0 and +CEREG: 2,4. */ - TEST_ASSERT_MESSAGE( ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_NO_REGISTERED_SEARCHING ) || - ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_UNKNOWN ), - "Airplane mode network registration check failed" ); - - /* RF On. */ - xCellularStatus = Cellular_RfOn( _cellularHandle ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Wait until SIM is ready. */ - simReady = prvWaitSimCardReady(); - TEST_ASSERT( simReady == true ); - - /* Check network registration status. Airplane mode the register status should be - * CELLULAR_NETWORK_REGISTRATION_STATUS_REGISTERED_HOME or - * CELLULAR_NETWORK_REGISTRATION_STATUS_REGISTERED_ROAMING */ - for( tries = 0; tries < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; tries++ ) - { - xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - if( ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_REGISTERED_HOME ) || - ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_ROAMING_REGISTERED ) ) - { - break; - } - - Platform_Delay( testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ); - } - - configPRINTF( ( "serviceStatus.psRegistrationStatus %d\r\n", serviceStatus.psRegistrationStatus ) ); - TEST_ASSERT_MESSAGE( - ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_REGISTERED_HOME ) || - ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_ROAMING_REGISTERED ), - "Airplane mode network registration check failed\r\n" ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Deactivate CELLULAR. - */ -TEST( Full_CELLULAR_API, Cellular_Deactivate ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularPdnStatus_t pdnStatusBuffers[ testCELLULAR_MAX_PDN_STATSU_NUM ] = { 0 }; - uint8_t numStatus = 0; - uint32_t i = 0; - - if( TEST_PROTECT() ) - { - /* Activate PDN for deactivate test. */ - xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, - pdnStatusBuffers, - testCELLULAR_MAX_PDN_STATSU_NUM, - &numStatus ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - for( i = 0; i < numStatus; i++ ) - { - if( pdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) - { - if( pdnStatusBuffers[ testCELLULAR_PDN_CONTEXT_ID ].state == 1 ) - { - break; - } - } - } - - if( i == numStatus ) - { - xCellularStatus = Cellular_ActivatePdn( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - } - - /* Deactivate PDN and verify. */ - xCellularStatus = Cellular_DeactivatePdn( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID ); - - /* Check also if in LTE network, modem allows default bearer context to be deactivated. */ - TEST_CELLULAR_ASSERT_REQUIRED_API( ( CELLULAR_SUCCESS == xCellularStatus ) || - ( CELLULAR_NOT_ALLOWED == xCellularStatus ), xCellularStatus ); - - if( xCellularStatus != CELLULAR_NOT_ALLOWED ) - { - xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, - pdnStatusBuffers, - testCELLULAR_MAX_PDN_STATSU_NUM, - &numStatus ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - if( numStatus != 0 ) - { - for( i = 0; i < numStatus; i++ ) - { - if( pdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) - { - TEST_ASSERT_MESSAGE( ( pdnStatusBuffers[ i ].state == 0 ), "Deactive PDN should return 0" ); - break; - } - } - - TEST_ASSERT_MESSAGE( i != numStatus, "No deactivated PDN context found" ); - } - } - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief CELLULAR unconfigure. - */ -TEST( Full_CELLULAR_API, Cellular_UnConfigure ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( TEST_PROTECT() ) - { - /* Remove call backs. */ - xCellularStatus = Cellular_RegisterUrcSignalStrengthChangedCallback( _cellularHandle, NULL, NULL ); - TEST_CELLULAR_ASSERT_OPTIONAL_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - xCellularStatus = Cellular_RegisterUrcNetworkRegistrationEventCallback( _cellularHandle, NULL, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - xCellularStatus = Cellular_RegisterUrcPdnEventCallback( _cellularHandle, NULL, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - xCellularStatus = Cellular_RegisterModemEventCallback( _cellularHandle, NULL, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Clean up. */ - xCellularStatus = Cellular_Cleanup( _cellularHandle ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - _cellularHandle = NULL; - } - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_GetModemInfo( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetModemInfo_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetModemInfo( _cellularHandle, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_Cellular_GetSimCardInfo( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetSimCardInfo_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetSimCardInfo( _cellularHandle, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_GetSimCardStatus( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetSimCardStatus_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetSimCardStatus( _cellularHandle, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_GetServiceStatus( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetServiceStatus_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_GetSignalInfo( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetSignalInfo_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetSignalInfo( _cellularHandle, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_GetRegisteredNetwork( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetRegisteredNetwork_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetRegisteredNetwork( _cellularHandle, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_GetPsmSettings( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetPsmSettings_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_GetEidrxSettings( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetEidrxSettings_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_GetPdnStatus( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetPdnStatus_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - uint8_t numStatus = 0; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, NULL, testCELLULAR_PDN_CONTEXT_ID, &numStatus ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_GetIPAddress( _cellularHandle ) with Null parameters and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_GetIPAddress_NullParameters ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_GetIPAddress( _cellularHandle, - testCELLULAR_PDN_CONTEXT_ID, - NULL, - CELLULAR_IP_ADDRESS_MAX_SIZE ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_SetRatPriority( _cellularHandle ) with an invalid mode and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_SetRatPriority_InvalidMode ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - const CellularRat_t ratPriorities[ TEST_MAX_RAT_PRIORITY_COUNT ] = { 9, 8, 1 }; /* Invalid value 1. */ - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_SetRatPriority( _cellularHandle, - ( const CellularRat_t * ) &ratPriorities, - 5 /* Invalid value. */ ); - TEST_CELLULAR_ASSERT_OPTIONAL_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_SetPsmSettings( _cellularHandle ) with an invalid mode and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_SetPsmSettings_InvalidMode ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularPsmSettings_t psmSettings = { 0 }; - - psmSettings.activeTimeValue = 28; - psmSettings.gprsReadyTimer = 0; - psmSettings.mode = 2; /* Invalid value. */ - psmSettings.periodicRauValue = 0; - psmSettings.periodicTauValue = 4; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_SetEidrxSettings( _cellularHandle ) with an invalid mode and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_SetEidrxSettings_InvalidMode ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularEidrxSettings_t eidrxSettings = { 0 }; - - eidrxSettings.mode = 1; - eidrxSettings.rat = 6; /* invalid value. */ - eidrxSettings.requestedEdrxVaue = 1; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_SetPdnConfig( _cellularHandle ) with an invalid mode and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_SetPdnConfig_InvalidMode ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - /* Set the invalid PDN context type. */ - CellularPdnConfig_t pdnConfig = - { CELLULAR_PDN_CONTEXT_TYPE_MAX, CELLULAR_PDN_AUTH_NONE, TEST_INVALID_CELLULAR_APN, "", "" }; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_SetPdnConfig( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, &pdnConfig ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Call Cellular_SetDns( _cellularHandle ) with an invalid mode and verify failure. - */ -TEST( Full_CELLULAR_API, Cellular_SetDns_InvalidMode ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - xCellularStatus = Cellular_SetDns( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, "123" ); - TEST_CELLULAR_ASSERT_OPTIONAL_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief CELLULAR data transfer loop. - */ -TEST( Full_CELLULAR_API, Cellular_Data_Loop ) -{ - uint8_t index = 0; - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularSocketHandle_t socketHandle = NULL; - uint32_t sentDataLen = 0; - char receiveBuff[ 100 ] = { 0 }; - uint32_t receivedDataLen = 0; - char cBuffer[ MESSAGE_BUFFER_LENGTH ] = { '\0' }; - PlatformEventGroupHandle_t socketEventGroup = NULL; - PlatformEventGroup_EventBits eventBits = 0; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - for( index = 0; index < testCELLULARCONNECTION_LOOP_TIMES; ++index ) - { - socketHandle = prvSocketConnectionSetup( testCELLULAR_ECHO_SERVER_PORT, - testCELLULAR_ECHO_SERVER_ADDRESS, - &socketEventGroup ); - - /* Send Data on Socket. */ - xCellularStatus = Cellular_SocketSend( _cellularHandle, socketHandle, ( const uint8_t * ) _socketDataSend, strlen( _socketDataSend ), - &sentDataLen ); - snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_SocketSend( _cellularHandle ) in iteration %d", index ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); - - /* Receive Data on Socket. */ - eventBits = PlatformEventGroup_WaitBits( socketEventGroup, - SOCKET_DATA_RECEIVED_CALLBACK_BIT, - true, - false, - pdMS_TO_TICKS( testCELLULAR_SOCKET_RECEIVE_TIMEOUT_MS ) ); - TEST_ASSERT( ( eventBits & SOCKET_DATA_RECEIVED_CALLBACK_BIT ) != 0 ); - xCellularStatus = Cellular_SocketRecv( _cellularHandle, - socketHandle, - ( uint8_t * ) receiveBuff, - sizeof( receiveBuff ), - &receivedDataLen ); - - snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_SocketRecv( _cellularHandle ) in iteration %d", index ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); - - /* Compare Data on Socket. */ - TEST_ASSERT_MESSAGE( strncmp( _socketDataSend, receiveBuff, strlen( _socketDataSend ) ) == 0, - "Cellular_Data_Loop received data compare failed" ); - - /* Close Socket. */ - #ifdef CELLULAR_ASYNC_SOCKET_CLOSE - if( index < ( CELLULAR_NUM_SOCKET_MAX - 1 ) ) - { - prvSocketConnectionClose( socketHandle, socketEventGroup, false ); - } - else - { - prvSocketConnectionClose( socketHandle, socketEventGroup, true ); - } - #else - prvSocketConnectionClose( socketHandle, socketEventGroup, false ); - #endif - } - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief CELLULAR data transfer multiple connection. - */ -TEST( Full_CELLULAR_API, Cellular_MultipleSocketConnection ) -{ - uint8_t index = 0; - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularSocketHandle_t socketHandles[ CELLULAR_NUM_SOCKET_MAX ] = { 0 }; - uint32_t sentDataLen = 0; - char receiveBuff[ 100 ] = { 0 }; - uint32_t receivedDataLen = 0; - char cBuffer[ MESSAGE_BUFFER_LENGTH ] = { '\0' }; - PlatformEventGroupHandle_t socketEventGroups[ CELLULAR_NUM_SOCKET_MAX ] = { 0 }; - PlatformEventGroup_EventBits eventBits = 0; - uint32_t loopCount = 0; - - /* This test needs all the available socket. Reinitialize the cellular modem. */ - TEST_ASSERT( prvConnectCellular() == pdPASS ); - - if( TEST_PROTECT() ) - { - /* Open sockets. */ - for( index = 0; index < CELLULAR_NUM_SOCKET_MAX; ++index ) - { - socketHandles[ index ] = prvSocketConnectionSetup( testCELLULAR_ECHO_SERVER_PORT, - testCELLULAR_ECHO_SERVER_ADDRESS, - &socketEventGroups[ index ] ); - } - - /* Do more data transfer. */ - for( loopCount = 0; loopCount < testCELLULARDATA_TRANSFER_LOOP_TIMES; loopCount++ ) - { - for( index = 0; index < CELLULAR_NUM_SOCKET_MAX; ++index ) - { - /* Send Data on Socket. */ - xCellularStatus = Cellular_SocketSend( _cellularHandle, - socketHandles[ index ], - ( const uint8_t * ) _socketDataSend, - strlen( _socketDataSend ), - &sentDataLen ); - snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_SocketSend( _cellularHandle ) in iteration %d", index ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); - - /* Receive Data on Socket. */ - eventBits = PlatformEventGroup_WaitBits( socketEventGroups[ index ], - SOCKET_DATA_RECEIVED_CALLBACK_BIT, - true, - false, - pdMS_TO_TICKS( testCELLULAR_SOCKET_RECEIVE_TIMEOUT_MS ) ); - TEST_ASSERT( ( eventBits & SOCKET_DATA_RECEIVED_CALLBACK_BIT ) != 0 ); - xCellularStatus = Cellular_SocketRecv( _cellularHandle, - socketHandles[ index ], - ( uint8_t * ) receiveBuff, - sizeof( receiveBuff ), - &receivedDataLen ); - - snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_SocketRecv( _cellularHandle ) in iteration %d", index ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); - - /* Compare Data on Socket. */ - TEST_ASSERT_MESSAGE( strncmp( _socketDataSend, receiveBuff, strlen( _socketDataSend ) ) == 0, - "Cellular_Data_Loop received data compare failed" ); - } - } - - /* Close Socket. */ - for( index = 0; index < CELLULAR_NUM_SOCKET_MAX; ++index ) - { - prvSocketConnectionClose( socketHandles[ index ], socketEventGroups[ index ], false ); - } - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief CELLULAR airplane mode loop. - */ -TEST( Full_CELLULAR_API, Cellular_AirplaneMode_Loop ) -{ - char cBuffer[ MESSAGE_BUFFER_LENGTH ] = { '\0' }; - uint8_t index = 0; - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - bool simReady = false; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - for( index = 0; index < testCELLULARCONNECTION_LOOP_TIMES; ++index ) - { - /* RF Off. */ - xCellularStatus = Cellular_RfOff( _cellularHandle ); - snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_RfOff( _cellularHandle ) in iteration %d", index ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); - - /* Wait until SIM is ready. */ - simReady = prvWaitSimCardReady(); - TEST_ASSERT( simReady == true ); - - /* RF On. */ - xCellularStatus = Cellular_RfOn( _cellularHandle ); - snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_RfOn( _cellularHandle ) in iteration %d", index ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); - - /* Wait until SIM is ready. */ - simReady = prvWaitSimCardReady(); - TEST_ASSERT( simReady == true ); - } - - ( void ) Cellular_Cleanup( _cellularHandle ); - _cellularHandle = NULL; - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief CELLULAR power cycle loop. - */ -TEST( Full_CELLULAR_API, Cellular_Power_Loop ) -{ - uint8_t index = 0; - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularCommInterface_t * pCommIntf = &CellularCommInterface; - - if( TEST_PROTECT() ) - { - /* Clean previous setting. */ - ( void ) Cellular_Cleanup( _cellularHandle ); - _cellularHandle = NULL; - - for( index = 0; index < testCELLULARCONNECTION_LOOP_TIMES; ++index ) - { - xCellularStatus = Cellular_Init( &_cellularHandle, pCommIntf ); - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> Cellular module can't be initialized <<<" ); - - /* Clean up. */ - xCellularStatus = Cellular_Cleanup( _cellularHandle ); - _cellularHandle = NULL; - TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, - ">>> Cellular module can't be cleanup <<<" ); - } - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/** - * @brief Test eDRX settings on echo server received times. - * - * ------------------------------|-------------------------------- - * t1 | t2 - * EDRX = 0 | EDRX = 1 - * ( RX is on ) | ( RX is off periodically ) - * ( Data reception is normal ) | ( Data reception is delayed ) - * ------------------------------|-------------------------------- - */ -TEST( Full_CELLULAR_API, Cellular_EidrxEchoTimes ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularEidrxSettings_t eidrxSettings = { 0 }; - CellularEidrxSettingsList_t eidrxSettingsList = { 0 }; - uint8_t drxValue = 5; /* 5 = ( 0 1 0 1 ) 81.92 seconds. */ - const uint32_t testTimoutMs = 80000U; /* Test waiting socket receive time. */ - uint32_t normalReceiveTimes = 0; - uint32_t edrxReceiveTimes = 0; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - /* Disable the EDRX mode. */ - eidrxSettings.mode = 0; - eidrxSettings.rat = testCELLULAR_EDRX_RAT; - eidrxSettings.requestedEdrxVaue = 0; - - xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Send the data to the server and wait for response. */ - normalReceiveTimes = prvTestSocketReceiveCount( testTimoutMs, testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS ); - configPRINTF( ( "Normal echo test receive times %d\r\n", normalReceiveTimes ) ); - Platform_Delay( testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS ); - - /* Enabling the EDRX mode and verify. */ - eidrxSettings.mode = 1; - eidrxSettings.rat = testCELLULAR_EDRX_RAT; - eidrxSettings.requestedEdrxVaue = drxValue; - - xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Send the data to the server and wait for response. - * Data receive times is less in eDRX mode. */ - edrxReceiveTimes = prvTestSocketReceiveCount( testTimoutMs, testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS ); - configPRINTF( ( "EDRX echo test receive times %d\r\n", edrxReceiveTimes ) ); - TEST_ASSERT_MESSAGE( ( edrxReceiveTimes < normalReceiveTimes ), - "EDRX receive more times than normal" ); - - /* Disabling the EDRX mode. */ - eidrxSettings.mode = 3; - eidrxSettings.rat = testCELLULAR_EDRX_RAT; - eidrxSettings.requestedEdrxVaue = 0; - - configPRINTF( ( "Disable and reset EDRX settings\r\n" ) ); - xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - } - else - { - TEST_FAIL(); - } -} - -/*-----------------------------------------------------------*/ - -/* - * @brief Check cellular power saving mode status. - * - * --------------------|--------------------- - * t1 | t2 - * PSM = 0 | PSM = 1 - * (at cmd works) | (at cmd fails) - * --------------------|--------------------- - */ -TEST( Full_CELLULAR_API, Cellular_PsmStatus ) -{ - CellularError_t xCellularStatus = CELLULAR_SUCCESS; - CellularPsmSettings_t psmSettings = { 0 }; - uint32_t psmTau = 4; /* 4 * 10 minutes = 40 minutes. */ - uint32_t psmTimer = 14; /* 14 * 2 seconds = 28 Seconds. */ - uint32_t tries = 0; - EventBits_t waitEventBits = 0; - - if( prvIsConnectedCellular() == pdFAIL ) - { - TEST_ASSERT( prvConnectCellular() == pdPASS ); - } - - if( TEST_PROTECT() ) - { - /* Setup the modem event. */ - _modemEventGroup = xEventGroupCreate(); - TEST_ASSERT_MESSAGE( _modemEventGroup != NULL, "Create event group fail" ); - xEventGroupClearBits( _modemEventGroup, - MODEM_EVENT_BOOTUP_OR_REBOOT_BIT | MODEM_EVENT_POWERED_DOWN_BIT | MODEM_EVENT_PSM_ENTER_BIT ); - - xCellularStatus = Cellular_RegisterModemEventCallback( _cellularHandle, prvCellularModemEventCallback, NULL ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - /* Disabling the PSM mode if ON. */ - xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - if( psmSettings.mode == 1 ) - { - psmSettings.mode = 0; - psmSettings.periodicTauValue = 0; - psmSettings.periodicRauValue = 0; - psmSettings.gprsReadyTimer = 0; - psmSettings.activeTimeValue = 0; - - xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - } - - /* Enabling the PSM mode and verify. */ - psmSettings.mode = 1; - psmSettings.periodicTauValue = psmTau; - psmSettings.periodicRauValue = 0; - psmSettings.gprsReadyTimer = 0; - psmSettings.activeTimeValue = psmTimer; - - xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); - TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); - - for( tries = 0; tries < testCELLULAR_MAX_GET_PSM_RETRY; tries++ ) - { - xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - configPRINTF( ( "PSM mode polling %u\r\n", psmSettings.mode ) ); - - if( psmSettings.mode == 1 ) - { - break; - } - } - - Platform_Delay( testCELLULAR_GET_PSM_RETRY_INTERVAL_MS ); - } - - if( xCellularStatus == CELLULAR_SUCCESS ) - { - TEST_ASSERT_EQUAL_INT32( psmSettings.mode, 1 ); - configPRINTF( ( "PSM active time %u\r\n", psmSettings.activeTimeValue ) ); - } - - /* Wait until active timer expired. */ - for( tries = 0; tries < testCELLULAR_WAIT_PSM_ENTER_EVENT_RETRY; tries++ ) - { - configPRINTF( ( "Waiting PSM enter event %u\r\n", tries ) ); - waitEventBits = xEventGroupWaitBits( _modemEventGroup, - MODEM_EVENT_PSM_ENTER_BIT, - pdTRUE, - pdFALSE, - pdMS_TO_TICKS( psmSettings.activeTimeValue * 1000UL ) ); - - if( ( waitEventBits & MODEM_EVENT_PSM_ENTER_BIT ) != 0 ) - { - break; - } - } - - /* Wait 5 seconds after PSM mode entered. */ - Platform_Delay( 5000 ); - - /* Send the AT command to cellular module should return error. */ - xCellularStatus = Cellular_ATCommandRaw( _cellularHandle, - NULL, - "AT", - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - 0U ); - - if( CELLULAR_SUCCESS == xCellularStatus ) - { - configPRINTF( ( "Cellular modem still reply to AT. Ignore this test. \r\n" ) ); - TEST_IGNORE(); - } - } - else - { - TEST_FAIL(); - } - - if( _modemEventGroup != NULL ) - { - vEventGroupDelete( _modemEventGroup ); - _modemEventGroup = NULL; - } -} - -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* stdlib includes. */ +#include "string.h" +#include "stdio.h" + +/* Cellular include. */ +#include "cellular_config.h" +#include "cellular_config_defaults.h" +#include "cellular_platform.h" +#include "cellular_api.h" +#include "cellular_types.h" +#include "cellular_comm_interface.h" + +/* Testing variable includes. */ +#include "test_config.h" + +/* Unity framework includes. */ +#include "unity_fixture.h" + +/*-----------------------------------------------------------*/ + +/* Testing configurations definitions. */ + +/* Retry until SIM is ready. */ +#ifndef CELLULAR_MAX_SIM_RETRY + #define CELLULAR_MAX_SIM_RETRY ( 5U ) +#endif + +/* + * 2 GSM + * 3 UTRAN + * 4 LTE Cat M1 + * 5 LTE Cat NB1 + */ +#ifndef testCELLULAR_EDRX_RAT + #define testCELLULAR_EDRX_RAT ( 4 ) +#endif + +#ifndef testCELLULAR_SOCKET_CONNECTION_TIMEOUT_MS + #define testCELLULAR_SOCKET_CONNECTION_TIMEOUT_MS ( 150000U ) +#endif + +#ifndef testCELLULAR_SOCKET_SEND_TIMEOUT_MS + #define testCELLULAR_SOCKET_SEND_TIMEOUT_MS ( 60000U ) +#endif + +#ifndef testCELLULAR_SOCKET_CLOSE_TIMEOUT_MS + #define testCELLULAR_SOCKET_CLOSE_TIMEOUT_MS ( 60000U ) +#endif + +#ifndef testCELLULAR_SOCKET_RECEIVE_TIMEOUT_MS + #define testCELLULAR_SOCKET_RECEIVE_TIMEOUT_MS ( 5000U ) +#endif + +#ifndef testCELLULAR_MAX_NETWORK_REGISTER_RETRY + #define testCELLULAR_MAX_NETWORK_REGISTER_RETRY ( 40U ) +#endif + +#ifndef testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS + #define testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ( 500U ) +#endif + +/* Retry until SIM is ready. */ +#ifndef testCELLULAR_MAX_SIM_RETRY + #define testCELLULAR_MAX_SIM_RETRY ( 5U ) +#endif + +#ifndef testCELLULAR_SIM_RETRY_INTERVAL_MS + #define testCELLULAR_SIM_RETRY_INTERVAL_MS ( 500U ) +#endif + +#ifndef testCELLULAR_MAX_GET_PSM_RETRY + #define testCELLULAR_MAX_GET_PSM_RETRY ( 5U ) +#endif + +#ifndef testCELLULAR_GET_PSM_RETRY_INTERVAL_MS + #define testCELLULAR_GET_PSM_RETRY_INTERVAL_MS ( 500U ) +#endif + +#ifndef testCELLULAR_SOCKET_WAIT_INTERVAL_MS + #define testCELLULAR_SOCKET_WAIT_INTERVAL_MS ( 2000UL ) +#endif + +#ifndef testCELLULAR_GET_RAT_RETRY + #define testCELLULAR_GET_RAT_RETRY ( 5UL ) +#endif + +#ifndef testCELLULAR_GET_RAT_RETRY_INTERVAL_MS + #define testCELLULAR_GET_RAT_RETRY_INTERVAL_MS ( 200U ) +#endif + +#ifndef testCELLULAR_WAIT_PSM_ENTER_EVENT_RETRY + #define testCELLULAR_WAIT_PSM_ENTER_EVENT_RETRY ( 2U ) +#endif + +#ifndef testCELLULAR_MAX_PDN_STATUS_NUM + #define testCELLULAR_MAX_PDN_STATUS_NUM ( CELLULAR_PDN_CONTEXT_ID_MAX - CELLULAR_PDN_CONTEXT_ID_MIN + 1U ) +#endif + +/* Custom CELLULAR Test asserts. */ +#define TEST_CELLULAR_ASSERT_REQUIRED_API( condition, result ) \ + if( result == CELLULAR_UNSUPPORTED ) \ + { \ + TEST_FAIL_MESSAGE( "Required CELLULAR API is not implemented." ); \ + } \ + else \ + { \ + TEST_ASSERT( condition ); \ + } + +#define TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( condition, result, message ) \ + if( result == CELLULAR_UNSUPPORTED ) \ + { \ + TEST_FAIL_MESSAGE( "Required CELLULAR API is not implemented." ); \ + } \ + else \ + { \ + TEST_ASSERT_MESSAGE( condition, message ); \ + } + +#define TEST_CELLULAR_ASSERT_OPTIONAL_API( condition, result ) \ + if( result == CELLULAR_UNSUPPORTED ) \ + { \ + TEST_ASSERT( 1 ); \ + } \ + else \ + { \ + TEST_ASSERT( condition ); \ + } + +#define TEST_CELLULAR_ASSERT_OPTIONAL_API_MSG( condition, result, message ) \ + if( result == CELLULAR_UNSUPPORTED ) \ + { \ + TEST_ASSERT( 1 ); \ + } \ + else \ + { \ + TEST_ASSERT_MESSAGE( condition, message ); \ + } + +#define TEST_INVALID_CELLULAR_APN "VZWINTERNETVZWINTERNETVZWINTERNETVZWINTERNETVZWINTERNETVZWINTERN" + +#define SOCKET_DATA_RECEIVED_CALLBACK_BIT ( 0x00000001U ) +#define SOCKET_OPEN_CALLBACK_BIT ( 0x00000002U ) +#define SOCKET_OPEN_FAILED_CALLBACK_BIT ( 0x00000004U ) +#define SOCKET_CLOSED_CALLBACK_BIT ( 0x00000008U ) + +#define ECHO_SERVER_DATA_SEND_INTERVAL_MS ( 30000UL ) + +#define MODEM_EVENT_BOOTUP_OR_REBOOT_BIT ( 0x00000001U ) +#define MODEM_EVENT_POWERED_DOWN_BIT ( 0x00000002U ) +#define MODEM_EVENT_PSM_ENTER_BIT ( 0x00000004U ) + +#define SOCKET_OPEN_STATUS_UNKNOWN ( 0U ) +#define SOCKET_OPEN_STATUS_OPENED ( 1U ) +#define SOCKET_OPEN_STATUS_FAILED ( 2U ) + +#define SOCKET_OPERATION_POLLING_TIMES ( 4U ) + +#define MESSAGE_BUFFER_LENGTH ( 256U ) + +/* APN for the test network. */ +#define testCELLULAR_APN CELLULAR_APN + +/* PDN context id for cellular network. */ +#define testCELLULAR_PDN_CONTEXT_ID ( CELLULAR_PDN_CONTEXT_ID ) + +/* The number of times to loop in the CELLULARConnectionLoop test. */ +#define testCELLULARCONNECTION_LOOP_TIMES ( CELLULAR_NUM_SOCKET_MAX + 3U ) + +#define testCELLULARDATA_TRANSFER_LOOP_TIMES ( 10U ) + +/* RAT priority count for testing. This value should larger or equal to + * CELLULAR_MAX_RAT_PRIORITY_COUNT. */ +#define TEST_MAX_RAT_PRIORITY_COUNT ( 3U ) +#if CELLULAR_MAX_RAT_PRIORITY_COUNT > TEST_MAX_RAT_PRIORITY_COUNT + #error "TEST_MAX_RAT_PRIORITY_COUNT should not larger or equal to CELLULAR_MAX_RAT_PRIORITY_COUNT" +#endif + +#ifndef testCELLULAR_DNS_SERVER_ADDRESS + #error "testCELLULAR_DNS_SERVER_ADDRESS is not defined" +#endif + +#ifndef testCELLULAR_HOST_NAME + #error "testCELLULAR_HOST_NAME is not defined" +#endif + +#ifndef testCELLULAR_HOST_NAME_ADDRESS + #error "testCELLULAR_HOST_NAME_ADDRESS is not defined" +#endif + +#ifndef testCELLULAR_ECHO_SERVER_ADDRESS + #error "testCELLULAR_ECHO_SERVER_ADDRESS is not defined" +#endif + +#ifndef testCELLULAR_ECHO_SERVER_PORT + #error "testCELLULAR_ECHO_SERVER_PORT is not defined" +#endif + +#ifndef testCELLULAR_EDRX_ECHO_SERVER_ADDRESS + #error "testCELLULAR_EDRX_ECHO_SERVER_ADDRESS is not defined" +#endif + +#ifndef testCELLULAR_EDRX_ECHO_SERVER_PORT + #error "testCELLULAR_EDRX_ECHO_SERVER_PORT is not defined" +#endif + +#ifndef testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS + #error "testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS is not defined" +#endif + +/*-----------------------------------------------------------*/ + +/** + * @brief the default Cellular comm interface in system. + */ +extern CellularCommInterface_t CellularCommInterface; + +/*-----------------------------------------------------------*/ + +/* Test state variables. */ +static uint8_t _dataReady = 0; +static CellularHandle_t _cellularHandle = NULL; +static bool _genericUrcCalled = false; +static PlatformEventGroupHandle_t _socketEventGroup = NULL; +static PlatformEventGroupHandle_t _modemEventGroup = NULL; + +/* The callback context to check. */ +static void * _socketDataReadyContext = NULL; +static void * _socketOpenContext = NULL; +static void * _socketClosedContext = NULL; + +/* Socket data send pattern. */ +static const char _socketDataSend[] = "hello from SJC31"; + +/*-----------------------------------------------------------*/ + +/* Network registration callback function. */ +static void prvNetworkRegistrationCallback( CellularUrcEvent_t urcEvent, + const CellularServiceStatus_t * pServiceStatus, + void * pCallbackContext ) +{ + TEST_ASSERT( pCallbackContext == _cellularHandle ); + + if( pServiceStatus != NULL ) + { + if( ( urcEvent == CELLULAR_URC_EVENT_NETWORK_CS_REGISTRATION ) || + ( urcEvent == CELLULAR_URC_EVENT_NETWORK_PS_REGISTRATION ) ) + { + configPRINTF( ( "Network CS registration status received: %d. \r\n", pServiceStatus->csRegistrationStatus ) ); + configPRINTF( ( "Network PS registration status received: %d. \r\n", pServiceStatus->psRegistrationStatus ) ); + } + } +} + +/*-----------------------------------------------------------*/ + +/* Signal strength changed callback function. */ +static void prvSignalStrengthChangedCallback( CellularUrcEvent_t urcEvent, + const CellularSignalInfo_t * pSignalInfo, + void * pCallbackContext ) +{ + TEST_ASSERT( pCallbackContext == _cellularHandle ); + + if( ( pSignalInfo != NULL ) && ( urcEvent == CELLULAR_URC_EVENT_SIGNAL_CHANGED ) ) + { + if( pSignalInfo->rssi != CELLULAR_INVALID_SIGNAL_VALUE ) + { + configPRINTF( ( "RSSI received: %d. \r\n", pSignalInfo->rssi ) ); + } + else + { + configPRINTF( ( "RSSI received: UNKNOWN. \r\n" ) ); + } + + if( pSignalInfo->rsrp != CELLULAR_INVALID_SIGNAL_VALUE ) + { + configPRINTF( ( "RSRP received: %d. \r\n", pSignalInfo->rsrp ) ); + } + else + { + configPRINTF( ( "RSRP received: UNKNOWN. \r\n" ) ); + } + + if( pSignalInfo->rsrq != CELLULAR_INVALID_SIGNAL_VALUE ) + { + configPRINTF( ( "RSRQ received: %d. \r\n", pSignalInfo->rsrq ) ); + } + else + { + configPRINTF( ( "RSRQ received: UNKNOWN. \r\n" ) ); + } + + if( pSignalInfo->ber != CELLULAR_INVALID_SIGNAL_VALUE ) + { + configPRINTF( ( "BER received: %d. \r\n", pSignalInfo->ber ) ); + } + else + { + configPRINTF( ( "BER received: UNKNOWN. \r\n" ) ); + } + + if( pSignalInfo->bars != CELLULAR_INVALID_SIGNAL_BAR_VALUE ) + { + configPRINTF( ( "BARS received: %u. \r\n", pSignalInfo->bars ) ); + } + else + { + configPRINTF( ( "BARS received: UNKNOWN. \r\n" ) ); + } + } +} + +/*-----------------------------------------------------------*/ + +/* Generic callback function to test Cellular_RegisterUrcGenericCallback API. */ +static void prvGenericCallback( const char * pRawData, + void * pCallbackContext ) +{ + TEST_ASSERT( pCallbackContext == _cellularHandle ); + + configPRINTF( ( "prvGenericCallback : %s \r\n", pRawData ) ); + _genericUrcCalled = true; +} + +/*-----------------------------------------------------------*/ + +/* PDN event callback function. */ +static void prvPdnEventCallback( CellularUrcEvent_t urcEvent, + uint8_t contextId, + void * pCallbackContext ) +{ + TEST_ASSERT( pCallbackContext == _cellularHandle ); + + if( contextId == testCELLULAR_PDN_CONTEXT_ID ) + { + if( ( urcEvent == CELLULAR_URC_EVENT_PDN_ACTIVATED ) || ( urcEvent == CELLULAR_URC_EVENT_PDN_DEACTIVATED ) ) + { + configPRINTF( ( "PDP Status changed. context ID %u event %d\r\n", contextId, urcEvent ) ); + } + } +} + +/*-----------------------------------------------------------*/ + +/* Callback functions for testing. */ +static void prvCellularSocketDataReadyCallback( CellularSocketHandle_t socketHandle, + void * pCallbackContext ) +{ + PlatformEventGroupHandle_t eventGroupHandle = ( PlatformEventGroupHandle_t ) pCallbackContext; + + TEST_ASSERT( socketHandle != NULL ); + + configPRINTF( ( "Data Ready on Socket \r\n" ) ); + _dataReady = 1; + + if( eventGroupHandle != NULL ) + { + ( void ) PlatformEventGroup_SetBits( eventGroupHandle, SOCKET_DATA_RECEIVED_CALLBACK_BIT ); + } + + _socketDataReadyContext = pCallbackContext; +} + +/*-----------------------------------------------------------*/ + +/* Socket close event callback function. */ +static void prvSocketClosedCallback( CellularSocketHandle_t socketHandle, + void * pCallbackContext ) +{ + PlatformEventGroupHandle_t eventGroupHandle = ( PlatformEventGroupHandle_t ) pCallbackContext; + + TEST_ASSERT( socketHandle != NULL ); + + configPRINTF( ( "Socket is closed. \r\n" ) ); + + if( eventGroupHandle != NULL ) + { + ( void ) PlatformEventGroup_SetBits( eventGroupHandle, SOCKET_CLOSED_CALLBACK_BIT ); + } + + _socketClosedContext = pCallbackContext; +} + +/*-----------------------------------------------------------*/ + +/* Socket open event callback function. */ +static void prvCellularSocketOpenCallback( CellularUrcEvent_t urcEvent, + CellularSocketHandle_t socketHandle, + void * pCallbackContext ) +{ + PlatformEventGroupHandle_t eventGroupHandle = ( PlatformEventGroupHandle_t ) pCallbackContext; + + TEST_ASSERT( socketHandle != NULL ); + + if( eventGroupHandle != NULL ) + { + if( urcEvent == CELLULAR_URC_SOCKET_OPENED ) + { + configPRINTF( ( "Socket open callback, Success\r\n" ) ); + ( void ) PlatformEventGroup_SetBits( eventGroupHandle, SOCKET_OPEN_CALLBACK_BIT ); + } + else + { + configPRINTF( ( "Socket open callback, Failure\r\n" ) ); + ( void ) PlatformEventGroup_SetBits( eventGroupHandle, SOCKET_OPEN_FAILED_CALLBACK_BIT ); + } + } + + _socketOpenContext = pCallbackContext; +} + +/*-----------------------------------------------------------*/ + +/* Modem event callback function. */ +static void prvCellularModemEventCallback( CellularModemEvent_t modemEvent, + void * pCallbackContext ) +{ + ( void ) pCallbackContext; + + if( _modemEventGroup != NULL ) + { + switch( modemEvent ) + { + case CELLULAR_MODEM_EVENT_BOOTUP_OR_REBOOT: + ( void ) PlatformEventGroup_SetBits( _modemEventGroup, MODEM_EVENT_BOOTUP_OR_REBOOT_BIT ); + break; + + case CELLULAR_MODEM_EVENT_POWERED_DOWN: + ( void ) PlatformEventGroup_SetBits( _modemEventGroup, MODEM_EVENT_POWERED_DOWN_BIT ); + break; + + case CELLULAR_MODEM_EVENT_PSM_ENTER: + ( void ) PlatformEventGroup_SetBits( _modemEventGroup, MODEM_EVENT_PSM_ENTER_BIT ); + break; + + default: + break; + } + } +} + +/*-----------------------------------------------------------*/ + +/* Helper function to check sim card ready. */ +static bool prvWaitSimCardReady( void ) +{ + bool simReady = false; + uint32_t tries = 0; + CellularSimCardStatus_t simStatus = { 0 }; + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + for( tries = 0; tries < testCELLULAR_MAX_SIM_RETRY; tries++ ) + { + xCellularStatus = Cellular_GetSimCardStatus( _cellularHandle, &simStatus ); + + if( ( CELLULAR_SUCCESS == xCellularStatus ) && + ( simStatus.simCardState == CELLULAR_SIM_CARD_INSERTED ) && + ( simStatus.simCardLockState == CELLULAR_SIM_CARD_READY ) ) + { + simReady = true; + break; + } + + Platform_Delay( testCELLULAR_SIM_RETRY_INTERVAL_MS ); + } + + return simReady; +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Connect to the CELLULAR and verify success. + */ +static BaseType_t prvConnectCellular( void ) +{ + BaseType_t xResult = pdPASS; + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularServiceStatus_t serviceStatus = { 0 }; + CellularCommInterface_t * pCommIntf = &CellularCommInterface; + CellularPdnConfig_t pdnConfig = { CELLULAR_PDN_CONTEXT_IPV4, CELLULAR_PDN_AUTH_NONE, testCELLULAR_APN, "", "" }; + CellularPdnStatus_t PdnStatusBuffers[ testCELLULAR_MAX_PDN_STATUS_NUM ] = { 0 }; + char localIP[ CELLULAR_IP_ADDRESS_MAX_SIZE ] = { '\0' }; + uint32_t timeoutCount = 0; + uint8_t NumStatus = 0; + bool simReady = false; + CellularPsmSettings_t psmSettings = { 0 }; + CellularEidrxSettings_t eidrxSettings = { 0 }; + uint32_t i = 0; + + /* Clean up the cellular handle before init. */ + if( _cellularHandle != NULL ) + { + ( void ) Cellular_Cleanup( _cellularHandle ); + _cellularHandle = NULL; + } + + /* Initialize Cellular Comm Interface. */ + xCellularStatus = Cellular_Init( &_cellularHandle, pCommIntf ); + + if( xCellularStatus != CELLULAR_SUCCESS ) + { + configPRINTF( ( ">>> Cellular module can't initialized <<<\r\n" ) ); + xResult = pdFAIL; + } + else + { + xResult = pdPASS; + } + + if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) + { + /* Wait until SIM is ready. */ + simReady = prvWaitSimCardReady(); + + if( simReady == false ) + { + xResult = pdFAIL; + } + } + + if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) + { + /* Setup PDN for EPS Network Registration. */ + xCellularStatus = Cellular_SetPdnConfig( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, &pdnConfig ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + xResult = pdPASS; + } + else + { + xResult = pdFAIL; + } + } + + /* Rescan network. */ + if( xCellularStatus == CELLULAR_SUCCESS ) + { + ( void ) Cellular_RfOff( _cellularHandle ); + xCellularStatus = Cellular_RfOn( _cellularHandle ); + } + + if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) + { + /* Check network register status. */ + xResult = pdFAIL; + + for( timeoutCount = 0; timeoutCount < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; timeoutCount++ ) + { + xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); + + if( ( xCellularStatus == CELLULAR_SUCCESS ) && + ( ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_REGISTERED_HOME ) || + ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_ROAMING_REGISTERED ) ) ) + { + xResult = pdPASS; + break; + } + + Platform_Delay( testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ); + } + + if( xResult == pdFAIL ) + { + configPRINTF( ( ">>> Cellular module can't be registered <<<\r\n" ) ); + } + } + + /* Disable PSM and EIDRX. */ + if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) + { + psmSettings.mode = 0; + psmSettings.periodicTauValue = 0; + psmSettings.periodicRauValue = 0; + psmSettings.gprsReadyTimer = 0; + psmSettings.activeTimeValue = 0; + + xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); + } + + /* Disable the EDRX mode. */ + if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) + { + eidrxSettings.mode = 0; + eidrxSettings.rat = testCELLULAR_EDRX_RAT; + eidrxSettings.requestedEdrxValue = 0; + + xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); + } + + if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) + { + xCellularStatus = Cellular_RegisterUrcNetworkRegistrationEventCallback( _cellularHandle, &prvNetworkRegistrationCallback, _cellularHandle ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + xCellularStatus = Cellular_RegisterUrcPdnEventCallback( _cellularHandle, &prvPdnEventCallback, _cellularHandle ); + } + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + xCellularStatus = Cellular_SetPdnConfig( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, &pdnConfig ); + } + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + xCellularStatus = Cellular_ActivatePdn( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID ); + } + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + xCellularStatus = Cellular_GetIPAddress( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, localIP, sizeof( localIP ) ); + } + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, PdnStatusBuffers, testCELLULAR_MAX_PDN_STATUS_NUM, &NumStatus ); + } + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + xCellularStatus = Cellular_SetDns( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, testCELLULAR_DNS_SERVER_ADDRESS ); + + /* Modem use dynamic DNS. */ + if( xCellularStatus == CELLULAR_UNSUPPORTED ) + { + xCellularStatus = CELLULAR_SUCCESS; + } + } + } + + if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( xResult == pdPASS ) ) + { + for( i = 0; i < NumStatus; i++ ) + { + if( ( PdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) && ( PdnStatusBuffers[ i ].state == 1 ) ) + { + break; + } + } + + if( i != NumStatus ) + { + xResult = pdPASS; + } + } + else + { + xResult = pdFAIL; + } + + return xResult; +} + +/*-----------------------------------------------------------*/ + +/* Helper function to check if cellular network connected. */ +static BaseType_t prvIsConnectedCellular( void ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularPdnStatus_t PdnStatusBuffers[ testCELLULAR_MAX_PDN_STATUS_NUM ] = { 0 }; + uint8_t NumStatus = 0; + BaseType_t xResult = pdFAIL; + uint32_t i = 0; + + if( _cellularHandle != NULL ) + { + xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, + PdnStatusBuffers, + testCELLULAR_MAX_PDN_STATUS_NUM, + &NumStatus ); + + /* State 0 = Deactivated, 1 = Activated. */ + if( xCellularStatus == CELLULAR_SUCCESS ) + { + for( i = 0; i < NumStatus; i++ ) + { + if( ( PdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) && ( PdnStatusBuffers[ i ].state == 1 ) ) + { + xResult = pdPASS; + break; + } + } + } + } + else + { + xResult = pdFAIL; + } + + return xResult; +} + +/*-----------------------------------------------------------*/ + +/* Finish test help function. */ +static BaseType_t prvFinishCellularTesting( void ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + BaseType_t xResult = pdPASS; + + if( _cellularHandle != NULL ) + { + xCellularStatus = Cellular_Cleanup( _cellularHandle ); + } + + if( xCellularStatus != CELLULAR_SUCCESS ) + { + configPRINTF( ( ">>> Cellular module cleanup failed <<<\r\n" ) ); + xResult = pdFAIL; + } + else + { + _cellularHandle = NULL; + xResult = pdPASS; + } + + return xResult; +} + +/*-----------------------------------------------------------*/ + +/* Setup socket connection. */ +static CellularSocketHandle_t prvSocketConnectionSetup( uint16_t serverPort, + char * pServerAddress, + PlatformEventGroupHandle_t * pSocketEventGroup ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularSocketAddress_t remoteSocketAddress = { 0 }; + CellularSocketHandle_t socketHandle = NULL; + uint32_t sendTimeout = testCELLULAR_SOCKET_SEND_TIMEOUT_MS; + EventBits_t waitEventBits = 0; + PlatformEventGroupHandle_t socketEventGroup = NULL; + + /* Setup the event group. */ + socketEventGroup = xEventGroupCreate(); + TEST_ASSERT_MESSAGE( socketEventGroup != NULL, "event group create failed" ); + *pSocketEventGroup = socketEventGroup; + xEventGroupClearBits( socketEventGroup, + SOCKET_OPEN_CALLBACK_BIT | SOCKET_OPEN_FAILED_CALLBACK_BIT | SOCKET_DATA_RECEIVED_CALLBACK_BIT ); + + /* Setup the tcp connection. */ + /* Create Socket. */ + xCellularStatus = Cellular_CreateSocket( _cellularHandle, + testCELLULAR_PDN_CONTEXT_ID, + CELLULAR_SOCKET_DOMAIN_AF_INET, + CELLULAR_SOCKET_TYPE_DGRAM, + CELLULAR_SOCKET_PROTOCOL_TCP, + &socketHandle ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Modify Socket. */ + xCellularStatus = Cellular_SocketSetSockOpt( _cellularHandle, + socketHandle, + CELLULAR_SOCKET_OPTION_LEVEL_TRANSPORT, + CELLULAR_SOCKET_OPTION_SEND_TIMEOUT, + ( uint8_t * ) &sendTimeout, + sizeof( sendTimeout ) ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Data and Socket Event call back enabled. */ + xCellularStatus = Cellular_SocketRegisterDataReadyCallback( _cellularHandle, + socketHandle, + &prvCellularSocketDataReadyCallback, + socketEventGroup ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + xCellularStatus = Cellular_SocketRegisterSocketOpenCallback( _cellularHandle, + socketHandle, + &prvCellularSocketOpenCallback, + socketEventGroup ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + xCellularStatus = Cellular_SocketRegisterClosedCallback( _cellularHandle, + socketHandle, + &prvSocketClosedCallback, + socketEventGroup ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Connect Socket. */ + remoteSocketAddress.port = serverPort; + remoteSocketAddress.ipAddress.ipAddressType = CELLULAR_IP_ADDRESS_V4; + strncpy( remoteSocketAddress.ipAddress.ipAddress, pServerAddress, CELLULAR_IP_ADDRESS_MAX_SIZE ); + xCellularStatus = Cellular_SocketConnect( _cellularHandle, + socketHandle, + CELLULAR_ACCESSMODE_BUFFER, + &remoteSocketAddress ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + waitEventBits = xEventGroupWaitBits( socketEventGroup, + SOCKET_OPEN_CALLBACK_BIT | SOCKET_OPEN_FAILED_CALLBACK_BIT, + pdTRUE, + pdFALSE, + pdMS_TO_TICKS( testCELLULAR_SOCKET_CONNECTION_TIMEOUT_MS ) ); + TEST_ASSERT_MESSAGE( ( waitEventBits & SOCKET_OPEN_CALLBACK_BIT ) != 0, "Socket connection timeout or failed" ); + + return socketHandle; +} + + +/*-----------------------------------------------------------*/ + +/* Close socket connection. */ +static void prvSocketConnectionClose( CellularSocketHandle_t socketHandle, + PlatformEventGroupHandle_t socketEventGroup, + bool waitCallback ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + PlatformEventGroup_EventBits waitEventBits = 0; + + /* Close the socket. */ + xCellularStatus = Cellular_SocketRegisterDataReadyCallback( _cellularHandle, + socketHandle, + NULL, + NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + xCellularStatus = Cellular_SocketRegisterSocketOpenCallback( _cellularHandle, + socketHandle, + NULL, + NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + if( waitCallback == false ) + { + xCellularStatus = Cellular_SocketRegisterClosedCallback( _cellularHandle, + socketHandle, + NULL, + NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + } + + xCellularStatus = Cellular_SocketClose( _cellularHandle, socketHandle ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + if( ( waitCallback == true ) && ( socketEventGroup != NULL ) ) + { + waitEventBits = PlatformEventGroup_WaitBits( socketEventGroup, + SOCKET_CLOSED_CALLBACK_BIT, + pdTRUE, + pdFALSE, + pdMS_TO_TICKS( testCELLULAR_SOCKET_CLOSE_TIMEOUT_MS ) ); + TEST_ASSERT_MESSAGE( ( waitEventBits & SOCKET_CLOSED_CALLBACK_BIT ) != 0, "Socket close timeout or failed" ); + } + + if( socketEventGroup != NULL ) + { + vEventGroupDelete( socketEventGroup ); + } +} + +/*-----------------------------------------------------------*/ + +/* EDRX receive count test function. */ +static uint32_t prvTestSocketReceiveCount( const uint32_t testTimeMs, + const uint32_t dataReceiveIntervalMs ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularSocketHandle_t socketHandle = NULL; + uint32_t dataReceivedCount = 0; + uint32_t sentDataLen = 0; + uint8_t receiveBuff[ 100 ] = { 0 }; + uint32_t receivedDataLen = 0; + uint32_t totalReceivedDataLen = 0; + TickType_t recvStartTime = 0; + PlatformEventGroupHandle_t socketEventGroup = NULL; + + /* Setup the socket connection. */ + socketHandle = prvSocketConnectionSetup( testCELLULAR_EDRX_ECHO_SERVER_PORT, + testCELLULAR_EDRX_ECHO_SERVER_ADDRESS, + &socketEventGroup ); + + /* Send a byte to the server to start echo in time interval. */ + xCellularStatus = Cellular_SocketSend( _cellularHandle, + socketHandle, + ( const uint8_t * ) _socketDataSend, + strlen( _socketDataSend ), + &sentDataLen ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + recvStartTime = xTaskGetTickCount(); + /* Echo server will send data after received data. Wait 5 seconds for the first data. */ + configPRINTF( ( "start receive time %d, test time ms %d\r\n", recvStartTime, testTimeMs ) ); + Platform_Delay( 5000UL ); + + while( 1 ) + { + totalReceivedDataLen = 0; + + while( 1 ) + { + xCellularStatus = Cellular_SocketRecv( _cellularHandle, + socketHandle, + receiveBuff, + sizeof( receiveBuff ), + &receivedDataLen ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + if( receivedDataLen == 0 ) + { + break; + } + + totalReceivedDataLen = totalReceivedDataLen + receivedDataLen; + } + + if( totalReceivedDataLen != 0 ) + { + configPRINTF( ( "Bytes received %d\r\n", totalReceivedDataLen ) ); + dataReceivedCount = dataReceivedCount + 1; + } + + if( ( xTaskGetTickCount() - recvStartTime ) > pdMS_TO_TICKS( testTimeMs ) ) + { + break; + } + + Platform_Delay( dataReceiveIntervalMs ); + } + + prvSocketConnectionClose( socketHandle, socketEventGroup, false ); + + return dataReceivedCount; +} + +/*-----------------------------------------------------------*/ + +/* Unity TEST initializations. */ +TEST_GROUP( Full_CELLULAR_API ); + +/*-----------------------------------------------------------*/ + +TEST_SETUP( Full_CELLULAR_API ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularModemInfo_t modemInfo = { 0 }; + CellularSimCardInfo_t simCardInfo = { 0 }; + CellularSimCardStatus_t simStatus = { 0 }; + CellularSignalInfo_t signalInfo = { 0 }; + char localIP[ CELLULAR_IP_ADDRESS_MAX_SIZE ] = { '\0' }; + CellularPlmnInfo_t networkInfo = { 0 }; + CellularServiceStatus_t serviceStatus = { 0 }; + CellularTime_t networkTime = { 0 }; + CellularPsmSettings_t psmSettings = { 0 }; + CellularEidrxSettingsList_t eidrxSettingsList = { 0 }; + CellularRat_t pRatPriorities[ CELLULAR_MAX_RAT_PRIORITY_COUNT ] = { CELLULAR_RAT_INVALID }; + uint8_t receivedRatPrioritiesLength = 0; + uint32_t ratIndex = 0; + + configPRINTF( ( "\r\n==================================================================================\r\n" ) ); + + xCellularStatus = Cellular_GetModemInfo( _cellularHandle, &modemInfo ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( + ( " FW: %s \r\n IMEI: %s \r\n MfrID/ModId: %s/%s \r\n", modemInfo.firmwareVersion, modemInfo.imei, modemInfo.manufactureId, modemInfo.modelId ) ); + } + else + { + configPRINTF( ( " FW: \r\n IMEI: \r\n MfrID/ModId: \r\n" ) ); + } + + xCellularStatus = Cellular_GetSimCardInfo( _cellularHandle, &simCardInfo ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( + ( " ICCID: %s \r\n IMSI: %s \r\n HPLMN: %s-%s \r\n", simCardInfo.iccid, simCardInfo.imsi, simCardInfo.plmn.mcc, simCardInfo.plmn.mnc ) ); + } + else + { + configPRINTF( ( " ICCID: \r\n IMSI: \r\n HPLMN: \r\n" ) ); + } + + xCellularStatus = Cellular_GetSimCardStatus( _cellularHandle, &simStatus ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( ( " SIM Status: %d \r\n SIM Lock: %d \r\n", simStatus.simCardState, simStatus.simCardLockState ) ); + } + else + { + configPRINTF( ( " SIM Status: \r\n SIM Lock: \r\n" ) ); + } + + xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( + ( " rat: %d \r\n cs: %d \r\n ps: %d \r\n mode: %d \r\n csRej: %d \r\n psRej: %d \r\n plmn: %s%s \r\n", serviceStatus.rat, serviceStatus.csRegistrationStatus, serviceStatus.psRegistrationStatus, serviceStatus.networkRegistrationMode, serviceStatus.csRejectionCause, serviceStatus.psRejectionCause, serviceStatus.plmnInfo.mcc, serviceStatus.plmnInfo.mnc ) ); + } + else + { + configPRINTF( ( " rat: \r\n cs: \r\n ps: \r\n mode: \r\n csRej: \r\n psRej: \r\n plmn: \r\n" ) ); + } + + xCellularStatus = Cellular_GetRegisteredNetwork( _cellularHandle, &networkInfo ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( ( " Network: %s-%s \r\n", networkInfo.mcc, networkInfo.mnc ) ); + } + else + { + configPRINTF( ( " Network: \r\n" ) ); + } + + /* Cellular_GetSignalInfo should be called after Cellular_GetServiceStatus to set libAtData.rat to get correct bar level. */ + xCellularStatus = Cellular_GetSignalInfo( _cellularHandle, &signalInfo ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( + ( " Signal Bars: %d \r\n Signal RSSI: %d \r\n Signal RSRP: %d \r\n Signal RSRQ: %d \r\n", signalInfo.bars, signalInfo.rssi, signalInfo.rsrp, signalInfo.rsrq ) ); + } + else + { + configPRINTF( + ( " Signal Bars: N/A\r\n Signal RSSI: N/A\r\n Signal RSRP: N/A\r\n Signal RSRQ: N/A\r\n" ) ); + } + + xCellularStatus = Cellular_GetNetworkTime( _cellularHandle, &networkTime ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( + ( " Network time: %d/%d/%d %d:%d:%d \r\n", networkTime.month, networkTime.day, networkTime.year, networkTime.hour, networkTime.minute, networkTime.second ) ); + } + else + { + configPRINTF( ( " Network time: \r\n" ) ); + } + + xCellularStatus = Cellular_GetRatPriority( _cellularHandle, + pRatPriorities, CELLULAR_MAX_RAT_PRIORITY_COUNT, &receivedRatPrioritiesLength ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + for( ratIndex = 0; ratIndex < receivedRatPrioritiesLength; ratIndex++ ) + { + configPRINTF( ( " RAT Priority: %u %u\r\n", ratIndex, pRatPriorities[ ratIndex ] ) ); + } + } + + xCellularStatus = Cellular_GetIPAddress( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, localIP, sizeof( localIP ) ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( ( " IP address: %s \r\n", localIP ) ); + } + else + { + configPRINTF( ( " IP address: \r\n" ) ); + } + + xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( ( " PSM mode: %d \r\n PSM TAU Value: %d \r\n PSM RAU Value: %d \r\n PSM GPRS Timer: %d \r\n PSM Active Value: %d \r\n", + psmSettings.mode, + psmSettings.periodicTauValue, + psmSettings.periodicRauValue, + psmSettings.gprsReadyTimer, + psmSettings.activeTimeValue ) ); + } + else + { + configPRINTF( + ( " PSM mode: \r\n PSM TAU Value: \r\n PSM RAU Value: \r\n PSM GPRS Timer: \r\n PSM Active Value: \r\n" ) ); + } + + xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + for( int i = 0; i < eidrxSettingsList.count; i++ ) + { + configPRINTF( ( " eDRX index: %d eDRX mode: %d eDRX rat:%d eDRX UE Value:%d eDRX NW value:%d \r\n", + i, + eidrxSettingsList.eidrxList[ i ].mode, + eidrxSettingsList.eidrxList[ i ].rat, + eidrxSettingsList.eidrxList[ i ].requestedEdrxValue, + eidrxSettingsList.eidrxList[ i ].nwProvidedEdrxValue ) ); + } + } + else + { + configPRINTF( ( " eDRX index: eDRX mode: eDRX rat: eDRX UE Value: eDRX NW value: \r\n" ) ); + } + + configPRINTF( ( "\r\n==================================================================================\r\n" ) ); +} + +/*-----------------------------------------------------------*/ + +TEST_TEAR_DOWN( Full_CELLULAR_API ) +{ + configPRINTF( ( "\r\n==================================================================================\r\n" ) ); +} + +/*-----------------------------------------------------------*/ + +TEST_GROUP_RUNNER( Full_CELLULAR_API ) +{ + /* List of all tests under this group */ + /* In sequence tests. */ + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Configure ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Activate ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetNetworkTime ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetHostByName ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_TCPDataTransfer ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_EidrxSettings ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_PsmSettings ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_RatPriority ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_AtCommandRawAndGenericUrc ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_AirplaneMode ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Deactivate ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_UnConfigure ); + + /* Null parameter tests. */ + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetModemInfo_NullParameters ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetSimCardInfo_NullParameters ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetSimCardStatus_NullParameters ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetServiceStatus_NullParameters ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetSignalInfo_NullParameters ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetRegisteredNetwork_NullParameters ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetPsmSettings_NullParameters ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetEidrxSettings_NullParameters ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetPdnStatus_NullParameters ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_GetIPAddress_NullParameters ); + + /* Invalid parameters tests. */ + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetRatPriority_InvalidMode ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetPsmSettings_InvalidMode ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetEidrxSettings_InvalidMode ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetPdnConfig_InvalidMode ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_SetDns_InvalidMode ); + + /* Stability tests. */ + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Data_Loop ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_MultipleSocketConnection ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_AirplaneMode_Loop ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_Power_Loop ); + + /* PSM and eDRX tests. */ + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_EidrxEchoTimes ); + RUN_TEST_CASE( Full_CELLULAR_API, Cellular_PsmStatus ); + + prvFinishCellularTesting(); +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Configure CELLULAR. + */ +TEST( Full_CELLULAR_API, Cellular_Configure ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularSimCardStatus_t simStatus = { 0 }; + CellularCommInterface_t * pCommIntf = &CellularCommInterface; + uint8_t tries = 0; + uint8_t simReady = 0; + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_Init( &_cellularHandle, pCommIntf ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> Cellular module can't be initialized <<<" ); + + /* Wait until SIM is ready. */ + for( tries = 0; tries < testCELLULAR_MAX_SIM_RETRY; tries++ ) + { + xCellularStatus = Cellular_GetSimCardStatus( _cellularHandle, &simStatus ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> Cellular SIM failure <<<" ); + + if( ( simStatus.simCardState == CELLULAR_SIM_CARD_INSERTED ) && + ( simStatus.simCardLockState == CELLULAR_SIM_CARD_READY ) ) + { + simReady = 1; + break; + } + + Platform_Delay( testCELLULAR_SIM_RETRY_INTERVAL_MS ); + } + + TEST_ASSERT( simReady != 0 ); + + /* Enable Callbacks. */ + xCellularStatus = Cellular_RegisterUrcSignalStrengthChangedCallback( _cellularHandle, &prvSignalStrengthChangedCallback, _cellularHandle ); + TEST_CELLULAR_ASSERT_OPTIONAL_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + xCellularStatus = Cellular_RegisterUrcNetworkRegistrationEventCallback( _cellularHandle, &prvNetworkRegistrationCallback, _cellularHandle ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + xCellularStatus = Cellular_RegisterUrcPdnEventCallback( _cellularHandle, &prvPdnEventCallback, _cellularHandle ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief CELLULAR Activate. + */ +TEST( Full_CELLULAR_API, Cellular_Activate ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularServiceStatus_t serviceStatus = { 0 }; + CellularPdnConfig_t pdnConfig = + { CELLULAR_PDN_CONTEXT_IPV4, CELLULAR_PDN_AUTH_NONE, testCELLULAR_APN, "", "" }; + CellularPdnStatus_t PdnStatusBuffers[ testCELLULAR_MAX_PDN_STATUS_NUM ] = { 0 }; + char localIP[ CELLULAR_IP_ADDRESS_MAX_SIZE ] = { '\0' }; + uint32_t timeoutCount = 0; + uint8_t numStatus = 0; + CellularPsmSettings_t psmSettings = { 0 }; + CellularEidrxSettings_t eidrxSettings = { 0 }; + uint32_t i = 0; + + if( TEST_PROTECT() ) + { + /* Setup PDN for EPS Network Registration. */ + xCellularStatus = Cellular_SetPdnConfig( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, &pdnConfig ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> PDN configuration failed <<<" ); + + /* Rescan network. */ + if( xCellularStatus == CELLULAR_SUCCESS ) + { + xCellularStatus = Cellular_RfOff( _cellularHandle ); + } + + Platform_Delay( 5000 ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + for( timeoutCount = 0; timeoutCount < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; timeoutCount++ ) + { + xCellularStatus = Cellular_RfOn( _cellularHandle ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + break; + } + } + } + + TEST_ASSERT( xCellularStatus == CELLULAR_SUCCESS ); + + /* Verify registration. */ + for( timeoutCount = 0; timeoutCount < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; timeoutCount++ ) + { + xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> Cellular module can't be registered <<<" ); + + if( ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_REGISTERED_HOME ) || + ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_ROAMING_REGISTERED ) ) + { + break; + } + + Platform_Delay( testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ); + } + + if( timeoutCount >= testCELLULAR_MAX_NETWORK_REGISTER_RETRY ) + { + TEST_FAIL_MESSAGE( ">>> Cellular module can't be registered <<<" ); + } + + /* Configure and Activate PDN, set DNS and verify IP. */ + xCellularStatus = Cellular_ActivatePdn( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> Cellular module can't be activated <<<" ); + + /* Get PDN & IP and verify. */ + xCellularStatus = Cellular_GetIPAddress( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, localIP, sizeof( localIP ) ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, + PdnStatusBuffers, + testCELLULAR_MAX_PDN_STATUS_NUM, + &numStatus ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + for( i = 0; i < numStatus; i++ ) + { + if( PdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) + { + TEST_ASSERT_EQUAL_INT32_MESSAGE( 1, PdnStatusBuffers[ i ].state, + ">>> Cellular module failed to be activated <<<" ); + break; + } + } + + TEST_ASSERT_MESSAGE( i != numStatus, ">>> Cellular module failed to be activated, no activate PDN found <<<" ); + + /* Set DNS. */ + xCellularStatus = Cellular_SetDns( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, testCELLULAR_DNS_SERVER_ADDRESS ); + TEST_CELLULAR_ASSERT_OPTIONAL_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> DNS configuration failed <<<" ); + + /* Disable PSM and eDRX for the following tests. */ + psmSettings.mode = 0; + psmSettings.periodicTauValue = 0; + psmSettings.periodicRauValue = 0; + psmSettings.gprsReadyTimer = 0; + psmSettings.activeTimeValue = 0; + xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> Disable PSM failed <<<" ); + + eidrxSettings.mode = 0; + eidrxSettings.rat = testCELLULAR_EDRX_RAT; + eidrxSettings.requestedEdrxValue = 0; + xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> Disable EDRX failed <<<" ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Get network time. + */ +TEST( Full_CELLULAR_API, Cellular_GetNetworkTime ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularTime_t networkTime = { 0 }; + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetNetworkTime( _cellularHandle, &networkTime ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> Get network time failed <<<" ); + + /* Verify the value range. */ + TEST_ASSERT_MESSAGE( ( ( networkTime.month >= 1 ) && ( networkTime.month <= 12 ) ), + ">>> Get network time month value error <<<" ); + TEST_ASSERT_MESSAGE( ( ( networkTime.day >= 1 ) && ( networkTime.day <= 31 ) ), + ">>> Get network time day value error <<<" ); + TEST_ASSERT_MESSAGE( ( ( networkTime.hour >= 0 ) && ( networkTime.hour <= 24 ) ), + ">>> Get network time hour value error <<<" ); + TEST_ASSERT_MESSAGE( ( ( networkTime.minute >= 0 ) && ( networkTime.minute <= 59 ) ), + ">>> Get network time minute value error <<<" ); + TEST_ASSERT_MESSAGE( ( ( networkTime.second >= 0 ) && ( networkTime.second <= 59 ) ), + ">>> Get network time second value error <<<" ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Host name resolve test. + */ +TEST( Full_CELLULAR_API, Cellular_GetHostByName ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + char pIpAddress[ CELLULAR_IP_ADDRESS_MAX_SIZE ] = { '\0' }; + + if( TEST_PROTECT() ) + { + /* DNS query IP. */ + xCellularStatus = Cellular_GetHostByName( + _cellularHandle, + testCELLULAR_PDN_CONTEXT_ID, + testCELLULAR_HOST_NAME, + pIpAddress ); + TEST_CELLULAR_ASSERT_OPTIONAL_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> DNS query IP failed <<<" ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + TEST_ASSERT_MESSAGE( strncmp( pIpAddress, testCELLULAR_HOST_NAME_ADDRESS, CELLULAR_IP_ADDRESS_MAX_SIZE ) == 0, + ">>> DNS query IP incorrect <<<" ); + } + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief TCP Data Transfer. + */ +TEST( Full_CELLULAR_API, Cellular_TCPDataTransfer ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularSocketHandle_t socketHandle = NULL; + uint8_t tries = 0; + uint32_t sentDataLen = 0; + char receiveBuff[ 100 ] = { 0 }; + uint32_t receivedDataLen = 0; + + if( TEST_PROTECT() ) + { + /* Setup the test variable. */ + _dataReady = 0; + _socketOpenContext = NULL; + _socketDataReadyContext = NULL; + _socketClosedContext = NULL; + + /* Setup server connection. */ + socketHandle = prvSocketConnectionSetup( testCELLULAR_ECHO_SERVER_PORT, + testCELLULAR_ECHO_SERVER_ADDRESS, + &_socketEventGroup ); + TEST_ASSERT_MESSAGE( _socketOpenContext == _socketEventGroup, "Socket open context check failed" ); + + /* Send Data on Socket. */ + for( tries = 0; tries < SOCKET_OPERATION_POLLING_TIMES; tries++ ) + { + xCellularStatus = Cellular_SocketSend( _cellularHandle, + socketHandle, + ( const uint8_t * ) _socketDataSend, + strlen( _socketDataSend ), + &sentDataLen ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + break; + } + } + + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Receive Data on Socket in polling method. */ + for( tries = 0; tries < SOCKET_OPERATION_POLLING_TIMES; tries++ ) + { + Platform_Delay( testCELLULAR_SOCKET_WAIT_INTERVAL_MS ); + + if( _dataReady == 1 ) + { + xCellularStatus = Cellular_SocketRecv( _cellularHandle, + socketHandle, + ( uint8_t * ) receiveBuff, + sizeof( receiveBuff ), + &receivedDataLen ); + TEST_ASSERT_MESSAGE( _socketDataReadyContext == _socketEventGroup, "Socket data ready context check failed" ); + break; + } + } + + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Compare Data on Socket. */ + TEST_ASSERT_MESSAGE( strncmp( _socketDataSend, receiveBuff, strlen( _socketDataSend ) ) == 0, + "Cellular_TCPDataTransfer received data compare failed" ); + + /* Close Socket. */ + #ifdef CELLULAR_ASYNC_SOCKET_CLOSE + prvSocketConnectionClose( socketHandle, _socketEventGroup, true ); + TEST_ASSERT_MESSAGE( _socketClosedContext == _socketEventGroup, "Socket close context check failed" ); + #else + prvSocketConnectionClose( socketHandle, _socketEventGroup, false ); + #endif + _socketEventGroup = NULL; + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Enable CELLULAR Idle Discontinuous Reception. + */ +TEST( Full_CELLULAR_API, Cellular_EidrxSettings ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularEidrxSettings_t eidrxSettings = { 0 }; + CellularEidrxSettingsList_t eidrxSettingsList = { 0 }; + uint8_t drxValue = 5; /* 5 = ( 0 1 0 1 ) 81.92 seconds. */ + int i = 0; + + if( TEST_PROTECT() ) + { + /* Disable the EDRX mode. */ + eidrxSettings.mode = 0; + eidrxSettings.rat = testCELLULAR_EDRX_RAT; + eidrxSettings.requestedEdrxValue = 0; + + xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Enabling the EDRX mode and verify. */ + eidrxSettings.mode = 1; /* Enable the use of e-I-DRX. */ + eidrxSettings.rat = testCELLULAR_EDRX_RAT; + eidrxSettings.requestedEdrxValue = drxValue; + + xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + TEST_ASSERT_MESSAGE( eidrxSettingsList.count > 0, "eidrxSettingsList count is 0" ); + + for( i = 0; i < eidrxSettingsList.count; i++ ) + { + if( eidrxSettingsList.eidrxList[ i ].rat == testCELLULAR_EDRX_RAT ) + { + TEST_ASSERT_EQUAL_INT32( eidrxSettingsList.eidrxList[ i ].requestedEdrxValue, drxValue ); + } + } + + /* Disabling the EDRX mode and verify. */ + eidrxSettings.mode = 3; /* Disable the use of e-I-DRX and discard all parameters for e-I-DRX or, + * if available, reset to the manufacturer specific default values. */ + eidrxSettings.rat = testCELLULAR_EDRX_RAT; + eidrxSettings.requestedEdrxValue = 0; + + xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Enable CELLULAR Power Saving Mode attributes. + */ +TEST( Full_CELLULAR_API, Cellular_PsmSettings ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularPsmSettings_t psmSettings = { 0 }; + uint32_t psmTau = 4; /* 4 * 10 minutes = 40 minutes. */ + uint32_t psmTimer = 14; /* 14 * 2 seconds = 28 Seconds. */ + uint32_t tries = 0; + + if( TEST_PROTECT() ) + { + /* Disabling the PSM mode if ON. */ + xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + if( psmSettings.mode == 1 ) + { + psmSettings.mode = 0; + psmSettings.periodicTauValue = 0; + psmSettings.periodicRauValue = 0; + psmSettings.gprsReadyTimer = 0; + psmSettings.activeTimeValue = 0; + + xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + } + + /* Enabling the PSM mode and verify. */ + psmSettings.mode = 1; + psmSettings.periodicTauValue = psmTau; + psmSettings.periodicRauValue = 0; + psmSettings.gprsReadyTimer = 0; + psmSettings.activeTimeValue = psmTimer; + + xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + for( tries = 0; tries < testCELLULAR_MAX_GET_PSM_RETRY; tries++ ) + { + xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); + + if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( psmSettings.mode == 1 ) ) + { + break; + } + + Platform_Delay( testCELLULAR_GET_PSM_RETRY_INTERVAL_MS ); + } + + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + TEST_ASSERT_EQUAL_INT32( psmSettings.mode, 1 ); + + /* Disabling the PSM mode and verify. */ + psmSettings.mode = 0; + psmSettings.periodicTauValue = 0; + psmSettings.periodicRauValue = 0; + psmSettings.gprsReadyTimer = 0; + psmSettings.activeTimeValue = 0; + + xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + for( tries = 0; tries < testCELLULAR_MAX_GET_PSM_RETRY; tries++ ) + { + xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); + + if( ( xCellularStatus == CELLULAR_SUCCESS ) && ( psmSettings.mode == 0 ) ) + { + break; + } + + Platform_Delay( testCELLULAR_GET_PSM_RETRY_INTERVAL_MS ); + } + + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + TEST_ASSERT_EQUAL_INT32( psmSettings.mode, 0 ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Setting and checking CELLULAR RAT priority. + */ +TEST( Full_CELLULAR_API, Cellular_RatPriority ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + const CellularRat_t pRatPriorities1[ TEST_MAX_RAT_PRIORITY_COUNT ] = + { CELLULAR_RAT_NBIOT, CELLULAR_RAT_CATM1, CELLULAR_RAT_GSM }; + const CellularRat_t pRatPriorities2[ TEST_MAX_RAT_PRIORITY_COUNT ] = + { CELLULAR_RAT_CATM1, CELLULAR_RAT_NBIOT, CELLULAR_RAT_GSM }; + CellularRat_t pRatPriorities[ TEST_MAX_RAT_PRIORITY_COUNT ] = { CELLULAR_RAT_INVALID }; + uint8_t receivedRatPrioritiesLength = 0; + int i = 0; + uint32_t tries = 0; + bool ratFlag = true; + + if( TEST_PROTECT() ) + { + /* Set the first priority and verify. */ + xCellularStatus = Cellular_SetRatPriority( _cellularHandle, + ( const CellularRat_t * ) pRatPriorities1, + CELLULAR_MAX_RAT_PRIORITY_COUNT ); + TEST_CELLULAR_ASSERT_OPTIONAL_API_MSG( ( CELLULAR_SUCCESS == xCellularStatus ) || ( CELLULAR_NOT_ALLOWED == xCellularStatus ), + xCellularStatus, + "Set RAT priority failed" ); + + /* Set RAT priority may not be supported in the cellular module. */ + if( xCellularStatus == CELLULAR_SUCCESS ) + { + for( tries = 0; tries < testCELLULAR_GET_RAT_RETRY; tries++ ) + { + xCellularStatus = Cellular_GetRatPriority( _cellularHandle, + pRatPriorities, + CELLULAR_MAX_RAT_PRIORITY_COUNT, + &receivedRatPrioritiesLength ); + TEST_ASSERT_MESSAGE( CELLULAR_SUCCESS == xCellularStatus, "Get RAT priority failed" ); + + /* Check the return priority length if RAT priority is supported. */ + if( xCellularStatus == CELLULAR_SUCCESS ) + { + TEST_ASSERT_MESSAGE( receivedRatPrioritiesLength > 0, "Get RAT priority failed" ); + ratFlag = true; + + for( i = 0; i < receivedRatPrioritiesLength; i++ ) + { + if( pRatPriorities1[ i ] != pRatPriorities[ i ] ) + { + configPRINTF( ( "%d : Set RAT [%d] != Get RAT [ %d ]\r\n", + i, pRatPriorities1[ i ], pRatPriorities[ i ] ) ); + ratFlag = false; + break; + } + } + + if( ratFlag == true ) + { + break; + } + } + else + { + break; + } + + Platform_Delay( testCELLULAR_GET_RAT_RETRY_INTERVAL_MS ); + } + + TEST_ASSERT_MESSAGE( ratFlag == true, "RATs priority compare failed" ); + + /* Restore the second priority. */ + xCellularStatus = Cellular_SetRatPriority( _cellularHandle, + ( const CellularRat_t * ) pRatPriorities2, + CELLULAR_MAX_RAT_PRIORITY_COUNT ); + TEST_ASSERT_MESSAGE( CELLULAR_SUCCESS == xCellularStatus, "Set RAT priority failed" ); + } + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Send AT command with receive the generic URC. + */ +TEST( Full_CELLULAR_API, Cellular_AtCommandRawAndGenericUrc ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( TEST_PROTECT() ) + { + _genericUrcCalled = false; + xCellularStatus = Cellular_RegisterUrcGenericCallback( _cellularHandle, + prvGenericCallback, _cellularHandle ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( xCellularStatus == CELLULAR_SUCCESS, xCellularStatus, + "Register URC generic callback failed" ); + + /* Send the 3GPP get network time AT command. + * The returned network time string is handled in generic URC handler. */ + xCellularStatus = Cellular_ATCommandRaw( _cellularHandle, + NULL, + "AT+CCLK?", + CELLULAR_AT_NO_RESULT, + NULL, + NULL, + 0U ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( xCellularStatus == CELLULAR_SUCCESS, xCellularStatus, + "Send AT command raw failed" ); + + /* The maximum response time is 300ms. */ + Platform_Delay( 300U ); + TEST_ASSERT_MESSAGE( _genericUrcCalled == true, "Generic URC is not called" ); + + xCellularStatus = Cellular_RegisterUrcGenericCallback( _cellularHandle, + NULL, + NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( xCellularStatus == CELLULAR_SUCCESS, xCellularStatus, + "Register URC generic callback failed" ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Setting CELLULAR Airplane Mode On and off. + */ +TEST( Full_CELLULAR_API, Cellular_AirplaneMode ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularServiceStatus_t serviceStatus = { 0 }; + bool simReady = false; + uint32_t tries = 0; + + if( TEST_PROTECT() ) + { + /* RF Off. */ + xCellularStatus = Cellular_RfOff( _cellularHandle ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Wait until SIM is ready. */ + simReady = prvWaitSimCardReady(); + TEST_ASSERT( simReady == true ); + + /* Check network registration status. Airplane mode the register status should be + * CELLULAR_NETWORK_REGISTRATION_STATUS_NOT_REGISTERED_NOT_SEARCHING */ + for( tries = 0; tries < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; tries++ ) + { + xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + if( ( serviceStatus.psRegistrationStatus != REGISTRATION_STATUS_REGISTERED_HOME ) && + ( serviceStatus.psRegistrationStatus != REGISTRATION_STATUS_ROAMING_REGISTERED ) ) + { + break; + } + + Platform_Delay( testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ); + } + + configPRINTF( ( "serviceStatus.psRegistrationStatus %d\r\n", serviceStatus.psRegistrationStatus ) ); + + /* Add also psRegistrationStatus=4 if +CGREG: 2,0 and +CEREG: 2,4. */ + TEST_ASSERT_MESSAGE( ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_NO_REGISTERED_SEARCHING ) || + ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_UNKNOWN ), + "Airplane mode network registration check failed" ); + + /* RF On. */ + xCellularStatus = Cellular_RfOn( _cellularHandle ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Wait until SIM is ready. */ + simReady = prvWaitSimCardReady(); + TEST_ASSERT( simReady == true ); + + /* Check network registration status. Airplane mode the register status should be + * CELLULAR_NETWORK_REGISTRATION_STATUS_REGISTERED_HOME or + * CELLULAR_NETWORK_REGISTRATION_STATUS_REGISTERED_ROAMING */ + for( tries = 0; tries < testCELLULAR_MAX_NETWORK_REGISTER_RETRY; tries++ ) + { + xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, &serviceStatus ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + if( ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_REGISTERED_HOME ) || + ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_ROAMING_REGISTERED ) ) + { + break; + } + + Platform_Delay( testCELLULAR_NETWORK_REGISTER_RETRY_INTERVAL_MS ); + } + + configPRINTF( ( "serviceStatus.psRegistrationStatus %d\r\n", serviceStatus.psRegistrationStatus ) ); + TEST_ASSERT_MESSAGE( + ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_REGISTERED_HOME ) || + ( serviceStatus.psRegistrationStatus == REGISTRATION_STATUS_ROAMING_REGISTERED ), + "Airplane mode network registration check failed\r\n" ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Deactivate CELLULAR. + */ +TEST( Full_CELLULAR_API, Cellular_Deactivate ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularPdnStatus_t pdnStatusBuffers[ testCELLULAR_MAX_PDN_STATUS_NUM ] = { 0 }; + uint8_t numStatus = 0; + uint32_t i = 0; + + if( TEST_PROTECT() ) + { + /* Activate PDN for deactivate test. */ + xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, + pdnStatusBuffers, + testCELLULAR_MAX_PDN_STATUS_NUM, + &numStatus ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + for( i = 0; i < numStatus; i++ ) + { + if( pdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) + { + if( pdnStatusBuffers[ testCELLULAR_PDN_CONTEXT_ID ].state == 1 ) + { + break; + } + } + } + + if( i == numStatus ) + { + xCellularStatus = Cellular_ActivatePdn( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + } + + /* Deactivate PDN and verify. */ + xCellularStatus = Cellular_DeactivatePdn( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID ); + + /* Check also if in LTE network, modem allows default bearer context to be deactivated. */ + TEST_CELLULAR_ASSERT_REQUIRED_API( ( CELLULAR_SUCCESS == xCellularStatus ) || + ( CELLULAR_NOT_ALLOWED == xCellularStatus ), xCellularStatus ); + + if( xCellularStatus != CELLULAR_NOT_ALLOWED ) + { + xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, + pdnStatusBuffers, + testCELLULAR_MAX_PDN_STATUS_NUM, + &numStatus ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + if( numStatus != 0 ) + { + for( i = 0; i < numStatus; i++ ) + { + if( pdnStatusBuffers[ i ].contextId == testCELLULAR_PDN_CONTEXT_ID ) + { + TEST_ASSERT_MESSAGE( ( pdnStatusBuffers[ i ].state == 0 ), "Deactivate PDN should return 0" ); + break; + } + } + + TEST_ASSERT_MESSAGE( i != numStatus, "No deactivated PDN context found" ); + } + } + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief CELLULAR unconfigure. + */ +TEST( Full_CELLULAR_API, Cellular_UnConfigure ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( TEST_PROTECT() ) + { + /* Remove call backs. */ + xCellularStatus = Cellular_RegisterUrcSignalStrengthChangedCallback( _cellularHandle, NULL, NULL ); + TEST_CELLULAR_ASSERT_OPTIONAL_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + xCellularStatus = Cellular_RegisterUrcNetworkRegistrationEventCallback( _cellularHandle, NULL, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + xCellularStatus = Cellular_RegisterUrcPdnEventCallback( _cellularHandle, NULL, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + xCellularStatus = Cellular_RegisterModemEventCallback( _cellularHandle, NULL, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Clean up. */ + xCellularStatus = Cellular_Cleanup( _cellularHandle ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + _cellularHandle = NULL; + } + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_GetModemInfo( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetModemInfo_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetModemInfo( _cellularHandle, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_Cellular_GetSimCardInfo( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetSimCardInfo_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetSimCardInfo( _cellularHandle, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_GetSimCardStatus( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetSimCardStatus_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetSimCardStatus( _cellularHandle, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_GetServiceStatus( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetServiceStatus_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetServiceStatus( _cellularHandle, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_GetSignalInfo( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetSignalInfo_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetSignalInfo( _cellularHandle, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_GetRegisteredNetwork( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetRegisteredNetwork_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetRegisteredNetwork( _cellularHandle, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_GetPsmSettings( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetPsmSettings_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_GetEidrxSettings( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetEidrxSettings_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_GetPdnStatus( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetPdnStatus_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + uint8_t numStatus = 0; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetPdnStatus( _cellularHandle, NULL, testCELLULAR_PDN_CONTEXT_ID, &numStatus ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_GetIPAddress( _cellularHandle ) with Null parameters and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_GetIPAddress_NullParameters ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_GetIPAddress( _cellularHandle, + testCELLULAR_PDN_CONTEXT_ID, + NULL, + CELLULAR_IP_ADDRESS_MAX_SIZE ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_SetRatPriority( _cellularHandle ) with an invalid mode and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_SetRatPriority_InvalidMode ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + const CellularRat_t ratPriorities[ TEST_MAX_RAT_PRIORITY_COUNT ] = { 9, 8, 1 }; /* Invalid value 1. */ + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_SetRatPriority( _cellularHandle, + ( const CellularRat_t * ) &ratPriorities, + 5 /* Invalid value. */ ); + TEST_CELLULAR_ASSERT_OPTIONAL_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_SetPsmSettings( _cellularHandle ) with an invalid mode and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_SetPsmSettings_InvalidMode ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularPsmSettings_t psmSettings = { 0 }; + + psmSettings.activeTimeValue = 28; + psmSettings.gprsReadyTimer = 0; + psmSettings.mode = 2; /* Invalid value. */ + psmSettings.periodicRauValue = 0; + psmSettings.periodicTauValue = 4; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_SetEidrxSettings( _cellularHandle ) with an invalid mode and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_SetEidrxSettings_InvalidMode ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularEidrxSettings_t eidrxSettings = { 0 }; + + eidrxSettings.mode = 1; + eidrxSettings.rat = 6; /* invalid value. */ + eidrxSettings.requestedEdrxValue = 1; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_SetPdnConfig( _cellularHandle ) with an invalid mode and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_SetPdnConfig_InvalidMode ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + /* Set the invalid PDN context type. */ + CellularPdnConfig_t pdnConfig = + { CELLULAR_PDN_CONTEXT_TYPE_MAX, CELLULAR_PDN_AUTH_NONE, TEST_INVALID_CELLULAR_APN, "", "" }; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_SetPdnConfig( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, &pdnConfig ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Call Cellular_SetDns( _cellularHandle ) with an invalid mode and verify failure. + */ +TEST( Full_CELLULAR_API, Cellular_SetDns_InvalidMode ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + xCellularStatus = Cellular_SetDns( _cellularHandle, testCELLULAR_PDN_CONTEXT_ID, "123" ); + TEST_CELLULAR_ASSERT_OPTIONAL_API( CELLULAR_SUCCESS != xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief CELLULAR data transfer loop. + */ +TEST( Full_CELLULAR_API, Cellular_Data_Loop ) +{ + uint8_t index = 0; + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularSocketHandle_t socketHandle = NULL; + uint32_t sentDataLen = 0; + char receiveBuff[ 100 ] = { 0 }; + uint32_t receivedDataLen = 0; + char cBuffer[ MESSAGE_BUFFER_LENGTH ] = { '\0' }; + PlatformEventGroupHandle_t socketEventGroup = NULL; + PlatformEventGroup_EventBits eventBits = 0; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + for( index = 0; index < testCELLULARCONNECTION_LOOP_TIMES; ++index ) + { + socketHandle = prvSocketConnectionSetup( testCELLULAR_ECHO_SERVER_PORT, + testCELLULAR_ECHO_SERVER_ADDRESS, + &socketEventGroup ); + + /* Send Data on Socket. */ + xCellularStatus = Cellular_SocketSend( _cellularHandle, socketHandle, ( const uint8_t * ) _socketDataSend, strlen( _socketDataSend ), + &sentDataLen ); + snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_SocketSend( _cellularHandle ) in iteration %d", index ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); + + /* Receive Data on Socket. */ + eventBits = PlatformEventGroup_WaitBits( socketEventGroup, + SOCKET_DATA_RECEIVED_CALLBACK_BIT, + true, + false, + pdMS_TO_TICKS( testCELLULAR_SOCKET_RECEIVE_TIMEOUT_MS ) ); + TEST_ASSERT( ( eventBits & SOCKET_DATA_RECEIVED_CALLBACK_BIT ) != 0 ); + xCellularStatus = Cellular_SocketRecv( _cellularHandle, + socketHandle, + ( uint8_t * ) receiveBuff, + sizeof( receiveBuff ), + &receivedDataLen ); + + snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_SocketRecv( _cellularHandle ) in iteration %d", index ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); + + /* Compare Data on Socket. */ + TEST_ASSERT_MESSAGE( strncmp( _socketDataSend, receiveBuff, strlen( _socketDataSend ) ) == 0, + "Cellular_Data_Loop received data compare failed" ); + + /* Close Socket. */ + #ifdef CELLULAR_ASYNC_SOCKET_CLOSE + if( index < ( CELLULAR_NUM_SOCKET_MAX - 1 ) ) + { + prvSocketConnectionClose( socketHandle, socketEventGroup, false ); + } + else + { + prvSocketConnectionClose( socketHandle, socketEventGroup, true ); + } + #else + prvSocketConnectionClose( socketHandle, socketEventGroup, false ); + #endif + } + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief CELLULAR data transfer multiple connection. + */ +TEST( Full_CELLULAR_API, Cellular_MultipleSocketConnection ) +{ + uint8_t index = 0; + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularSocketHandle_t socketHandles[ CELLULAR_NUM_SOCKET_MAX ] = { 0 }; + uint32_t sentDataLen = 0; + char receiveBuff[ 100 ] = { 0 }; + uint32_t receivedDataLen = 0; + char cBuffer[ MESSAGE_BUFFER_LENGTH ] = { '\0' }; + PlatformEventGroupHandle_t socketEventGroups[ CELLULAR_NUM_SOCKET_MAX ] = { 0 }; + PlatformEventGroup_EventBits eventBits = 0; + uint32_t loopCount = 0; + + /* This test needs all the available socket. Reinitialize the cellular modem. */ + TEST_ASSERT( prvConnectCellular() == pdPASS ); + + if( TEST_PROTECT() ) + { + /* Open sockets. */ + for( index = 0; index < CELLULAR_NUM_SOCKET_MAX; ++index ) + { + socketHandles[ index ] = prvSocketConnectionSetup( testCELLULAR_ECHO_SERVER_PORT, + testCELLULAR_ECHO_SERVER_ADDRESS, + &socketEventGroups[ index ] ); + } + + /* Do more data transfer. */ + for( loopCount = 0; loopCount < testCELLULARDATA_TRANSFER_LOOP_TIMES; loopCount++ ) + { + for( index = 0; index < CELLULAR_NUM_SOCKET_MAX; ++index ) + { + /* Send Data on Socket. */ + xCellularStatus = Cellular_SocketSend( _cellularHandle, + socketHandles[ index ], + ( const uint8_t * ) _socketDataSend, + strlen( _socketDataSend ), + &sentDataLen ); + snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_SocketSend( _cellularHandle ) in iteration %d", index ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); + + /* Receive Data on Socket. */ + eventBits = PlatformEventGroup_WaitBits( socketEventGroups[ index ], + SOCKET_DATA_RECEIVED_CALLBACK_BIT, + true, + false, + pdMS_TO_TICKS( testCELLULAR_SOCKET_RECEIVE_TIMEOUT_MS ) ); + TEST_ASSERT( ( eventBits & SOCKET_DATA_RECEIVED_CALLBACK_BIT ) != 0 ); + xCellularStatus = Cellular_SocketRecv( _cellularHandle, + socketHandles[ index ], + ( uint8_t * ) receiveBuff, + sizeof( receiveBuff ), + &receivedDataLen ); + + snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_SocketRecv( _cellularHandle ) in iteration %d", index ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); + + /* Compare Data on Socket. */ + TEST_ASSERT_MESSAGE( strncmp( _socketDataSend, receiveBuff, strlen( _socketDataSend ) ) == 0, + "Cellular_Data_Loop received data compare failed" ); + } + } + + /* Close Socket. */ + for( index = 0; index < CELLULAR_NUM_SOCKET_MAX; ++index ) + { + prvSocketConnectionClose( socketHandles[ index ], socketEventGroups[ index ], false ); + } + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief CELLULAR airplane mode loop. + */ +TEST( Full_CELLULAR_API, Cellular_AirplaneMode_Loop ) +{ + char cBuffer[ MESSAGE_BUFFER_LENGTH ] = { '\0' }; + uint8_t index = 0; + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + bool simReady = false; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + for( index = 0; index < testCELLULARCONNECTION_LOOP_TIMES; ++index ) + { + /* RF Off. */ + xCellularStatus = Cellular_RfOff( _cellularHandle ); + snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_RfOff( _cellularHandle ) in iteration %d", index ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); + + /* Wait until SIM is ready. */ + simReady = prvWaitSimCardReady(); + TEST_ASSERT( simReady == true ); + + /* RF On. */ + xCellularStatus = Cellular_RfOn( _cellularHandle ); + snprintf( cBuffer, sizeof( cBuffer ), "Failed Cellular_RfOn( _cellularHandle ) in iteration %d", index ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, cBuffer ); + + /* Wait until SIM is ready. */ + simReady = prvWaitSimCardReady(); + TEST_ASSERT( simReady == true ); + } + + ( void ) Cellular_Cleanup( _cellularHandle ); + _cellularHandle = NULL; + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief CELLULAR power cycle loop. + */ +TEST( Full_CELLULAR_API, Cellular_Power_Loop ) +{ + uint8_t index = 0; + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularCommInterface_t * pCommIntf = &CellularCommInterface; + + if( TEST_PROTECT() ) + { + /* Clean previous setting. */ + ( void ) Cellular_Cleanup( _cellularHandle ); + _cellularHandle = NULL; + + for( index = 0; index < testCELLULARCONNECTION_LOOP_TIMES; ++index ) + { + xCellularStatus = Cellular_Init( &_cellularHandle, pCommIntf ); + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> Cellular module can't be initialized <<<" ); + + /* Clean up. */ + xCellularStatus = Cellular_Cleanup( _cellularHandle ); + _cellularHandle = NULL; + TEST_CELLULAR_ASSERT_REQUIRED_API_MSG( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus, + ">>> Cellular module can't be cleanup <<<" ); + } + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Test eDRX settings on echo server received times. + * + * ------------------------------|-------------------------------- + * t1 | t2 + * EDRX = 0 | EDRX = 1 + * ( RX is on ) | ( RX is off periodically ) + * ( Data reception is normal ) | ( Data reception is delayed ) + * ------------------------------|-------------------------------- + */ +TEST( Full_CELLULAR_API, Cellular_EidrxEchoTimes ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularEidrxSettings_t eidrxSettings = { 0 }; + CellularEidrxSettingsList_t eidrxSettingsList = { 0 }; + uint8_t drxValue = 5; /* 5 = ( 0 1 0 1 ) 81.92 seconds. */ + const uint32_t testTimoutMs = 80000U; /* Test waiting socket receive time. */ + uint32_t normalReceiveTimes = 0; + uint32_t edrxReceiveTimes = 0; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + /* Disable the EDRX mode. */ + eidrxSettings.mode = 0; + eidrxSettings.rat = testCELLULAR_EDRX_RAT; + eidrxSettings.requestedEdrxValue = 0; + + xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Send the data to the server and wait for response. */ + normalReceiveTimes = prvTestSocketReceiveCount( testTimoutMs, testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS ); + configPRINTF( ( "Normal echo test receive times %d\r\n", normalReceiveTimes ) ); + Platform_Delay( testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS ); + + /* Enabling the EDRX mode and verify. */ + eidrxSettings.mode = 1; + eidrxSettings.rat = testCELLULAR_EDRX_RAT; + eidrxSettings.requestedEdrxValue = drxValue; + + xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Send the data to the server and wait for response. + * Data receive times is less in eDRX mode. */ + edrxReceiveTimes = prvTestSocketReceiveCount( testTimoutMs, testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS ); + configPRINTF( ( "EDRX echo test receive times %d\r\n", edrxReceiveTimes ) ); + TEST_ASSERT_MESSAGE( ( edrxReceiveTimes < normalReceiveTimes ), + "EDRX receive more times than normal" ); + + /* Disabling the EDRX mode. */ + eidrxSettings.mode = 3; + eidrxSettings.rat = testCELLULAR_EDRX_RAT; + eidrxSettings.requestedEdrxValue = 0; + + configPRINTF( ( "Disable and reset EDRX settings\r\n" ) ); + xCellularStatus = Cellular_SetEidrxSettings( _cellularHandle, &eidrxSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + xCellularStatus = Cellular_GetEidrxSettings( _cellularHandle, &eidrxSettingsList ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + } + else + { + TEST_FAIL(); + } +} + +/*-----------------------------------------------------------*/ + +/* + * @brief Check cellular power saving mode status. + * + * --------------------|--------------------- + * t1 | t2 + * PSM = 0 | PSM = 1 + * (at cmd works) | (at cmd fails) + * --------------------|--------------------- + */ +TEST( Full_CELLULAR_API, Cellular_PsmStatus ) +{ + CellularError_t xCellularStatus = CELLULAR_SUCCESS; + CellularPsmSettings_t psmSettings = { 0 }; + uint32_t psmTau = 4; /* 4 * 10 minutes = 40 minutes. */ + uint32_t psmTimer = 14; /* 14 * 2 seconds = 28 Seconds. */ + uint32_t tries = 0; + EventBits_t waitEventBits = 0; + + if( prvIsConnectedCellular() == pdFAIL ) + { + TEST_ASSERT( prvConnectCellular() == pdPASS ); + } + + if( TEST_PROTECT() ) + { + /* Setup the modem event. */ + _modemEventGroup = xEventGroupCreate(); + TEST_ASSERT_MESSAGE( _modemEventGroup != NULL, "Create event group fail" ); + xEventGroupClearBits( _modemEventGroup, + MODEM_EVENT_BOOTUP_OR_REBOOT_BIT | MODEM_EVENT_POWERED_DOWN_BIT | MODEM_EVENT_PSM_ENTER_BIT ); + + xCellularStatus = Cellular_RegisterModemEventCallback( _cellularHandle, prvCellularModemEventCallback, NULL ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + /* Disabling the PSM mode if ON. */ + xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + if( psmSettings.mode == 1 ) + { + psmSettings.mode = 0; + psmSettings.periodicTauValue = 0; + psmSettings.periodicRauValue = 0; + psmSettings.gprsReadyTimer = 0; + psmSettings.activeTimeValue = 0; + + xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + } + + /* Enabling the PSM mode and verify. */ + psmSettings.mode = 1; + psmSettings.periodicTauValue = psmTau; + psmSettings.periodicRauValue = 0; + psmSettings.gprsReadyTimer = 0; + psmSettings.activeTimeValue = psmTimer; + + xCellularStatus = Cellular_SetPsmSettings( _cellularHandle, &psmSettings ); + TEST_CELLULAR_ASSERT_REQUIRED_API( CELLULAR_SUCCESS == xCellularStatus, xCellularStatus ); + + for( tries = 0; tries < testCELLULAR_MAX_GET_PSM_RETRY; tries++ ) + { + xCellularStatus = Cellular_GetPsmSettings( _cellularHandle, &psmSettings ); + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + configPRINTF( ( "PSM mode polling %u\r\n", psmSettings.mode ) ); + + if( psmSettings.mode == 1 ) + { + break; + } + } + + Platform_Delay( testCELLULAR_GET_PSM_RETRY_INTERVAL_MS ); + } + + if( xCellularStatus == CELLULAR_SUCCESS ) + { + TEST_ASSERT_EQUAL_INT32( psmSettings.mode, 1 ); + configPRINTF( ( "PSM active time %u\r\n", psmSettings.activeTimeValue ) ); + } + + /* Wait until active timer expired. */ + for( tries = 0; tries < testCELLULAR_WAIT_PSM_ENTER_EVENT_RETRY; tries++ ) + { + configPRINTF( ( "Waiting PSM enter event %u\r\n", tries ) ); + waitEventBits = xEventGroupWaitBits( _modemEventGroup, + MODEM_EVENT_PSM_ENTER_BIT, + pdTRUE, + pdFALSE, + pdMS_TO_TICKS( psmSettings.activeTimeValue * 1000UL ) ); + + if( ( waitEventBits & MODEM_EVENT_PSM_ENTER_BIT ) != 0 ) + { + break; + } + } + + /* Wait 5 seconds after PSM mode entered. */ + Platform_Delay( 5000 ); + + /* Send the AT command to cellular module should return error. */ + xCellularStatus = Cellular_ATCommandRaw( _cellularHandle, + NULL, + "AT", + CELLULAR_AT_NO_RESULT, + NULL, + NULL, + 0U ); + + if( CELLULAR_SUCCESS == xCellularStatus ) + { + configPRINTF( ( "Cellular modem still reply to AT. Ignore this test. \r\n" ) ); + TEST_IGNORE(); + } + } + else + { + TEST_FAIL(); + } + + if( _modemEventGroup != NULL ) + { + vEventGroupDelete( _modemEventGroup ); + _modemEventGroup = NULL; + } +} + +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/test_config.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/test_config.h index edad6ccda..e14f7d949 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/test_config.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/Test_code/test_config.h @@ -1,85 +1,85 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef TEST_CONFIG_H -#define TEST_CONFIG_H - -/** - * @brief test cellular APIs. - */ -#define testCELLULAR_API ( 1 ) - -/** - * DNS server address. - * #define testCELLULAR_DNS_SERVER_ADDRESS "...insert here..." - */ - -/** - * Host name to resolve. The host name should only has one IP address. - * #define testCELLULAR_HOST_NAME "...insert here..." - */ - -/** - * Host name resolved address. The resolved address should be the IP address of - * testCELLULAR_HOST_NAME. - * #define testCELLULAR_HOST_NAME_ADDRESS "...insert here..." - */ - -/** - * Echo server address for tcp connection test. - * #define testCELLULAR_ECHO_SERVER_ADDRESS "...insert here..." - */ - -/** - * Echo server port for tcp connection test. - * #define testCELLULAR_ECHO_SERVER_PORT ( ...insert here... ) - */ - -/** - * Repeat echo server address for EDRX echo times test. - * #define testCELLULAR_EDRX_ECHO_SERVER_ADDRESS "...insert here..." - */ - -/** - * Repeat echo server port for EDRX echo times test. - * #define testCELLULAR_EDRX_ECHO_SERVER_PORT ( ...insert here... ) - */ - -/** - * Repeat echo server send interfal for EDRX echo times test. - * This settings should align with your repeat echo server settings. - * #define testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS ( ...insert here... ) - */ - - -#define testconfigTEST_STACKSIZE ( 1024 ) - -#define testconfigTEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) - -/* UNITY test config. */ -#define UNITY_EXCLUDE_SETJMP_H - -#endif /* TEST_CONFIG_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef TEST_CONFIG_H +#define TEST_CONFIG_H + +/** + * @brief test cellular APIs. + */ +#define testCELLULAR_API ( 1 ) + +/** + * DNS server address. + * #define testCELLULAR_DNS_SERVER_ADDRESS "...insert here..." + */ + +/** + * Host name to resolve. The host name should only has one IP address. + * #define testCELLULAR_HOST_NAME "...insert here..." + */ + +/** + * Host name resolved address. The resolved address should be the IP address of + * testCELLULAR_HOST_NAME. + * #define testCELLULAR_HOST_NAME_ADDRESS "...insert here..." + */ + +/** + * Echo server address for tcp connection test. + * #define testCELLULAR_ECHO_SERVER_ADDRESS "...insert here..." + */ + +/** + * Echo server port for tcp connection test. + * #define testCELLULAR_ECHO_SERVER_PORT ( ...insert here... ) + */ + +/** + * Repeat echo server address for EDRX echo times test. + * #define testCELLULAR_EDRX_ECHO_SERVER_ADDRESS "...insert here..." + */ + +/** + * Repeat echo server port for EDRX echo times test. + * #define testCELLULAR_EDRX_ECHO_SERVER_PORT ( ...insert here... ) + */ + +/** + * Repeat echo server send interval for EDRX echo times test. + * This settings should align with your repeat echo server settings. + * #define testCELLULAR_EDRX_ECHO_SERVER_DATA_SEND_INTERVAL_MS ( ...insert here... ) + */ + + +#define testconfigTEST_STACKSIZE ( 1024 ) + +#define testconfigTEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* UNITY test config. */ +#define UNITY_EXCLUDE_SETJMP_H + +#endif /* TEST_CONFIG_H */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/Packet32.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/Packet32.h index e8a444dee..f6b7b27aa 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/Packet32.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/Packet32.h @@ -170,11 +170,11 @@ */ struct dump_bpf_hdr { - struct timeval ts; /*/< Time stamp of the packet */ - UINT caplen; /*/< Length of captured portion. The captured portion can smaller than the */ - /*/< the original packet, because it is possible (with a proper filter) to */ - /*/< instruct the driver to capture only a portion of the packets. */ - UINT len; /*/< Length of the original packet (off wire). */ + struct timeval ts; /*/< Time stamp of the packet */ + UINT caplen; /*/< Length of captured portion. The captured portion can smaller than the */ + /*/< the original packet, because it is possible (with a proper filter) to */ + /*/< instruct the driver to capture only a portion of the packets. */ + UINT len; /*/< Length of the original packet (off wire). */ }; @@ -241,7 +241,7 @@ /*/< ReadEvent will be signaled, also if no packets were captured */ CHAR Name[ ADAPTER_NAME_LENGTH ]; PWAN_ADAPTER pWanAdapter; - UINT Flags; /*/< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. */ + UINT Flags; /*/< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. */ #ifdef HAVE_AIRPCAP_API PAirpcapHandle AirpcapAd; @@ -267,14 +267,14 @@ */ typedef struct _PACKET { - HANDLE hEvent; /*/< \deprecated Still present for compatibility with old applications. */ - OVERLAPPED OverLapped; /*/< \deprecated Still present for compatibility with old applications. */ - PVOID Buffer; /*/< Buffer with containing the packets. See the PacketReceivePacket() for */ - /*/< details about the organization of the data in this buffer */ - UINT Length; /*/< Length of the buffer */ - DWORD ulBytesReceived; /*/< Number of valid bytes present in the buffer, i.e. amount of data */ - /*/< received by the last call to PacketReceivePacket() */ - BOOLEAN bIoComplete; /*/< \deprecated Still present for compatibility with old applications. */ + HANDLE hEvent; /*/< \deprecated Still present for compatibility with old applications. */ + OVERLAPPED OverLapped; /*/< \deprecated Still present for compatibility with old applications. */ + PVOID Buffer; /*/< Buffer with containing the packets. See the PacketReceivePacket() for */ + /*/< details about the organization of the data in this buffer */ + UINT Length; /*/< Length of the buffer */ + DWORD ulBytesReceived; /*/< Number of valid bytes present in the buffer, i.e. amount of data */ + /*/< received by the last call to PacketReceivePacket() */ + BOOLEAN bIoComplete; /*/< \deprecated Still present for compatibility with old applications. */ } PACKET, * LPPACKET; /*! @@ -286,16 +286,16 @@ */ struct _PACKET_OID_DATA { - ULONG Oid; /*/< OID code. See the Microsoft DDK documentation or the file ntddndis.h */ - /*/< for a complete list of valid codes. */ - ULONG Length; /*/< Length of the data field */ - UCHAR Data[ 1 ]; /*/< variable-lenght field that contains the information passed to or received */ - /*/< from the adapter. */ + ULONG Oid; /*/< OID code. See the Microsoft DDK documentation or the file ntddndis.h */ + /*/< for a complete list of valid codes. */ + ULONG Length; /*/< Length of the data field */ + UCHAR Data[ 1 ]; /*/< variable-length field that contains the information passed to or received */ + /*/< from the adapter. */ }; typedef struct _PACKET_OID_DATA PACKET_OID_DATA, * PPACKET_OID_DATA; #ifdef __cplusplus - extern "C" { + extern "C" { #endif /** @@ -392,7 +392,7 @@ #define PACKET_START_OEM_NO_NETMON 0x00000001 #ifdef __cplusplus - } +} #endif #endif //__PACKET32 diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/PacketData.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/PacketData.h index 6447af1da..5c082687a 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/PacketData.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/PacketData.h @@ -1,4 +1,5 @@ -char pkt1[] = { +char pkt1[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x30, 0x09, 0x9c, 0x40, 0x00, 0x80, 0x06, @@ -6,9 +7,11 @@ char pkt1[] = { 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, 0xc7, 0x35, 0x00, 0x00, 0x00, 0x00, 0x70, 0x02, 0x40, 0x00, 0xdf, 0xab, 0x00, 0x00, 0x02, 0x04, - 0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 }; + 0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 +}; -char pkt2[] = { +char pkt2[] = +{ 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, @@ -16,18 +19,22 @@ char pkt2[] = { 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, - 0x05, 0x92 }; + 0x05, 0x92 +}; -char pkt3[] = { +char pkt3[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0x9e, 0x40, 0x00, 0x80, 0x06, 0x6f, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, 0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, - 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt4[] = { +char pkt4[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x02, 0x27, 0x09, 0x9f, 0x40, 0x00, 0x80, 0x06, @@ -98,9 +105,11 @@ char pkt4[] = { 0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, - 0x65, 0x0d, 0x0a, 0x0d, 0x0a }; + 0x65, 0x0d, 0x0a, 0x0d, 0x0a +}; -char pkt5[] = { +char pkt5[] = +{ 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x40, 0x06, @@ -108,18 +117,22 @@ char pkt5[] = { 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, - 0x05, 0x92 }; + 0x05, 0x92 +}; -char pkt6[] = { +char pkt6[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0xa1, 0x40, 0x00, 0x80, 0x06, 0x6f, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, - 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt7[] = { +char pkt7[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x02, 0x27, 0x09, 0xa2, 0x40, 0x00, 0x80, 0x06, @@ -190,9 +203,11 @@ char pkt7[] = { 0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, - 0x65, 0x0d, 0x0a, 0x0d, 0x0a }; + 0x65, 0x0d, 0x0a, 0x0d, 0x0a +}; -char pkt8[] = { +char pkt8[] = +{ 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2c, 0x00, 0x03, 0x00, 0x00, 0x40, 0x06, @@ -200,18 +215,22 @@ char pkt8[] = { 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, - 0x05, 0x92 }; + 0x05, 0x92 +}; -char pkt9[] = { +char pkt9[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0xa3, 0x40, 0x00, 0x80, 0x06, 0x6f, 0x08, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, - 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt10[] = { +char pkt10[] = +{ 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, 0x00, 0x2c, 0x00, 0x04, 0x00, 0x00, 0x40, 0x06, @@ -219,25 +238,30 @@ char pkt10[] = { 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, - 0x05, 0x92 }; + 0x05, 0x92 +}; -char pkt11[] = { +char pkt11[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0xa6, 0x40, 0x00, 0x80, 0x06, 0x6f, 0x05, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, - 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt12[] = { +char pkt12[] = +{ 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x09, 0xa7, 0x40, 0x00, 0x80, 0x06, 0x6f, 0x04, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x14, - 0x00, 0x00, 0x43, 0xf4, 0x00, 0x00 }; + 0x00, 0x00, 0x43, 0xf4, 0x00, 0x00 +}; typedef struct diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/Win32-Extensions.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/Win32-Extensions.h index aad6a2866..9258fe0e8 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/Win32-Extensions.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/Win32-Extensions.h @@ -36,7 +36,7 @@ #define __WIN32_EXTENSIONS_H__ #ifdef __cplusplus - extern "C" { + extern "C" { #endif /* Definitions */ @@ -46,9 +46,9 @@ */ struct pcap_send_queue { - u_int maxlen; /*/< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. */ - u_int len; /*/< Current size of the queue, in bytes. */ - char * buffer; /*/< Buffer containing the packets to be sent. */ + u_int maxlen; /*/< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. */ + u_int len; /*/< Current size of the queue, in bytes. */ + char * buffer; /*/< Buffer containing the packets to be sent. */ }; typedef struct pcap_send_queue pcap_send_queue; @@ -121,7 +121,7 @@ PAirpcapHandle pcap_get_airpcap_handle( pcap_t * p ); #ifdef __cplusplus - } +} #endif #endif //__WIN32_EXTENSIONS_H__ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/arch.c b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/arch.c index ea3b82ced..cabb922ea 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/arch.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/arch.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -226,11 +226,11 @@ static void prvOpenSelectedNetworkInterface( pcap_if_t * pxAllNetworkInterfaces /* Open the selected interface. */ pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */ UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */ - PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscious mode as the MAC and + PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscuous mode as the MAC and * IP address is going to be "simulated", and * not be the real MAC and IP address. This allows - * trafic to the simulated IP address to be routed - * to uIP, and trafic to the real IP address to be + * traffic to the simulated IP address to be routed + * to uIP, and traffic to the real IP address to be * routed to the Windows TCP/IP stack. */ 0xfffffffL, /* The read time out. This is going to block * until data is available. */ @@ -289,7 +289,7 @@ static void prvConfigureCaptureBehaviour( void ) /* Create a task that simulates an interrupt in a real system. This will * block waiting for packets, then send a message to the uIP task when data * is available. */ - xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( configuIP_TASK_PRIORITY - 1 ), NULL ); + xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( ipconfigIP_TASK_PRIORITY - 1 ), NULL ); } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/netif.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/netif.h index b017d930c..c06c0a9bf 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/netif.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/netif.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/bluetooth.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/bluetooth.h index 7bf65df03..05332a3a5 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/bluetooth.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/bluetooth.h @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,7 +32,7 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/bluetooth.h,v 1.1 2007/09/22 02:10:17 guy Exp $ */ - + #ifndef _PCAP_BLUETOOTH_STRUCTS_H__ #define _PCAP_BLUETOOTH_STRUCTS_H__ @@ -40,8 +40,9 @@ * Header prepended libpcap to each bluetooth h:4 frame. * fields are in network byte order */ -typedef struct _pcap_bluetooth_h4_header { - u_int32_t direction; /* if first bit is set direction is incoming */ +typedef struct _pcap_bluetooth_h4_header +{ + u_int32_t direction; /* if first bit is set direction is incoming */ } pcap_bluetooth_h4_header; diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/bpf.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/bpf.h index 9f4ca33e3..d53a87b2f 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/bpf.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/bpf.h @@ -4,7 +4,7 @@ * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without @@ -53,45 +53,46 @@ #ifndef BPF_MAJOR_VERSION -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* BSD style release date */ -#define BPF_RELEASE 199606 + #define BPF_RELEASE 199606 -#ifdef MSDOS /* must be 32-bit */ -typedef long bpf_int32; -typedef unsigned long bpf_u_int32; -#else -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #ifdef MSDOS /* must be 32-bit */ + typedef long bpf_int32; + typedef unsigned long bpf_u_int32; + #else + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif /* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + #ifndef __NetBSD__ + #define BPF_ALIGNMENT sizeof( bpf_int32 ) + #else + #define BPF_ALIGNMENT sizeof( long ) + #endif + #define BPF_WORDALIGN( x ) ( ( ( x ) + ( BPF_ALIGNMENT - 1 ) ) & ~( BPF_ALIGNMENT - 1 ) ) -#define BPF_MAXBUFSIZE 0x8000 -#define BPF_MINBUFSIZE 32 + #define BPF_MAXBUFSIZE 0x8000 + #define BPF_MINBUFSIZE 32 /* * Structure for "pcap_compile()", "pcap_setfilter()", etc.. */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - + struct bpf_program + { + u_int bf_len; + struct bpf_insn * bf_insns; + }; + /* - * Struct return by BIOCVERSION. This represents the version number of + * Struct return by BIOCVERSION. This represents the version number of * the filter language described by the instruction encodings below. * bpf understands a program iff kernel_major == filter_major && * kernel_minor >= filter_minor, that is, if the value returned by the @@ -101,13 +102,14 @@ struct bpf_program { * may be accepted haphazardly. * It has nothing to do with the source code version. */ -struct bpf_version { - u_short bv_major; - u_short bv_minor; -}; + struct bpf_version + { + u_short bv_major; + u_short bv_minor; + }; /* Current version number of filter architecture. */ -#define BPF_MAJOR_VERSION 1 -#define BPF_MINOR_VERSION 1 + #define BPF_MAJOR_VERSION 1 + #define BPF_MINOR_VERSION 1 /* * Data-link level type codes. @@ -125,17 +127,17 @@ struct bpf_version { * These are the types that are the same on all platforms, and that * have been defined by for ages. */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* 802.5 Token Ring */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ + #define DLT_NULL 0 /* BSD loopback encapsulation */ + #define DLT_EN10MB 1 /* Ethernet (10Mb) */ + #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ + #define DLT_AX25 3 /* Amateur Radio AX.25 */ + #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ + #define DLT_CHAOS 5 /* Chaos */ + #define DLT_IEEE802 6 /* 802.5 Token Ring */ + #define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ + #define DLT_SLIP 8 /* Serial Line IP */ + #define DLT_PPP 9 /* Point-to-point Protocol */ + #define DLT_FDDI 10 /* FDDI */ /* * These are types that are different on some platforms, and that @@ -146,13 +148,13 @@ struct bpf_version { * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, * but I don't know what the right #define is for BSD/OS. */ -#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + #define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif + #ifdef __OpenBSD__ + #define DLT_RAW 14 /* raw IP */ + #else + #define DLT_RAW 12 /* raw IP */ + #endif /* * Given that the only OS that currently generates BSD/OS SLIP or PPP @@ -160,15 +162,15 @@ struct bpf_version { * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they * didn't. So it goes. */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif + #if defined( __NetBSD__ ) || defined( __FreeBSD__ ) + #ifndef DLT_SLIP_BSDOS + #define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ + #endif + #else + #define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ + #endif /* * 17 is used for DLT_OLD_PFLOG in OpenBSD; @@ -176,21 +178,21 @@ struct bpf_version { * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. */ -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + #define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ /* * Apparently Redback uses this for its SmartEdge 400/800. I hope * nobody else decided to use it, too. */ -#define DLT_REDBACK_SMARTEDGE 32 + #define DLT_REDBACK_SMARTEDGE 32 /* * These values are defined by NetBSD; other platforms should refrain from * using them for other purposes, so that NetBSD savefiles with link * types of 50 or 51 can be read as this type on all platforms. */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + #define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ + #define DLT_PPP_ETHER 51 /* PPP over Ethernet */ /* * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses @@ -199,7 +201,7 @@ struct bpf_version { * Ethernet type, and 36 bytes that appear to be 0 in at least one capture * I've seen. */ -#define DLT_SYMANTEC_FIREWALL 99 + #define DLT_SYMANTEC_FIREWALL 99 /* * Values between 100 and 103 are used in capture file headers as @@ -221,10 +223,10 @@ struct bpf_version { * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, * for source compatibility with programs written for libpcap 0.5. */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC + #define DLT_C_HDLC 104 /* Cisco HDLC */ + #define DLT_CHDLC DLT_C_HDLC -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + #define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ /* * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, @@ -239,7 +241,7 @@ struct bpf_version { * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header * (DLCI, etc.). */ -#define DLT_FRELAY 107 + #define DLT_FRELAY 107 /* * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except @@ -248,22 +250,22 @@ struct bpf_version { * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so * we don't use 12 for it in OSes other than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_LOOP 12 -#else -#define DLT_LOOP 108 -#endif + #ifdef __OpenBSD__ + #define DLT_LOOP 12 + #else + #define DLT_LOOP 108 + #endif /* * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other * than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_ENC 13 -#else -#define DLT_ENC 109 -#endif + #ifdef __OpenBSD__ + #define DLT_ENC 13 + #else + #define DLT_ENC 109 + #endif /* * Values between 110 and 112 are reserved for use in capture file headers @@ -275,22 +277,22 @@ struct bpf_version { /* * This is for Linux cooked sockets. */ -#define DLT_LINUX_SLL 113 + #define DLT_LINUX_SLL 113 /* * Apple LocalTalk hardware. */ -#define DLT_LTALK 114 + #define DLT_LTALK 114 /* * Acorn Econet. */ -#define DLT_ECONET 115 + #define DLT_ECONET 115 /* * Reserved for use with OpenBSD ipfilter. */ -#define DLT_IPFILTER 116 + #define DLT_IPFILTER 116 /* * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 @@ -298,34 +300,34 @@ struct bpf_version { * * XXX: is there a conflict with DLT_PFSYNC 18 as well? */ -#ifdef __OpenBSD__ -#define DLT_OLD_PFLOG 17 -#define DLT_PFSYNC 18 -#endif -#define DLT_PFLOG 117 + #ifdef __OpenBSD__ + #define DLT_OLD_PFLOG 17 + #define DLT_PFSYNC 18 + #endif + #define DLT_PFLOG 117 /* * Registered for Cisco-internal use. */ -#define DLT_CISCO_IOS 118 + #define DLT_CISCO_IOS 118 /* * For 802.11 cards using the Prism II chips, with a link-layer * header including Prism monitor mode information plus an 802.11 * header. */ -#define DLT_PRISM_HEADER 119 + #define DLT_PRISM_HEADER 119 /* * Reserved for Aironet 802.11 cards, with an Aironet link-layer header * (see Doug Ambrisko's FreeBSD patches). */ -#define DLT_AIRONET_HEADER 120 + #define DLT_AIRONET_HEADER 120 /* * Reserved for Siemens HiPath HDLC. */ -#define DLT_HHDLC 121 + #define DLT_HHDLC 121 /* * This is for RFC 2625 IP-over-Fibre Channel. @@ -335,7 +337,7 @@ struct bpf_version { * where the link-layer header starts with an RFC 2625 Network_Header * field. */ -#define DLT_IP_OVER_FC 122 + #define DLT_IP_OVER_FC 122 /* * This is for Full Frontal ATM on Solaris with SunATM, with a @@ -351,22 +353,22 @@ struct bpf_version { * and the like don't have to infer the presence or absence of a * pseudo-header and the form of the pseudo-header. */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ + #define DLT_SUNATM 123 /* Solaris+SunATM */ -/* +/* * Reserved as per request from Kent Dahlgren * for private use. */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + #define DLT_RIO 124 /* RapidIO */ + #define DLT_PCI_EXP 125 /* PCI Express */ + #define DLT_AURORA 126 /* Xilinx Aurora link layer */ /* * Header for 802.11 plus a number of bits of link-layer information * including radio information, used by some recent BSD drivers as * well as the madwifi Atheros driver for Linux. */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + #define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ /* * Reserved for the TZSP encapsulation, as per request from @@ -376,7 +378,7 @@ struct bpf_version { * with the packet, e.g. signal strength and channel * for 802.11 packets. */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + #define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ /* * BSD's ARCNET headers have the source host, destination host, @@ -389,7 +391,7 @@ struct bpf_version { * * We therefore have to have separate DLT_ values for them. */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ + #define DLT_ARCNET_LINUX 129 /* ARCNET */ /* * Juniper-private data link types, as per request from @@ -397,14 +399,14 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 + #define DLT_JUNIPER_MLPPP 130 + #define DLT_JUNIPER_MLFR 131 + #define DLT_JUNIPER_ES 132 + #define DLT_JUNIPER_GGSN 133 + #define DLT_JUNIPER_MFR 134 + #define DLT_JUNIPER_ATM2 135 + #define DLT_JUNIPER_SERVICES 136 + #define DLT_JUNIPER_ATM1 137 /* * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund @@ -421,21 +423,21 @@ struct bpf_version { * with "firewire_type" being an Ethernet type value, rather than, * for example, raw GASP frames being handed up. */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 + #define DLT_APPLE_IP_OVER_IEEE1394 138 /* * Various SS7 encapsulations, as per a request from Jeff Morriss * and subsequent discussions. */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + #define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ + #define DLT_MTP2 140 /* MTP2, without pseudo-header */ + #define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ + #define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ /* * DOCSIS MAC frames. */ -#define DLT_DOCSIS 143 + #define DLT_DOCSIS 143 /* * Linux-IrDA packets. Protocol defined at http://www.irda.org. @@ -446,19 +448,19 @@ struct bpf_version { * interface (irdaX), but not on a raw serial port. * Note the capture is done in "Linux-cooked" mode, so each packet include * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or + * decoding is dependant on the direction of the packet (incoming or * outgoing). * When/if other platform implement IrDA capture, we may revisit the * issue and define a real DLT_IRDA... * Jean II */ -#define DLT_LINUX_IRDA 144 + #define DLT_LINUX_IRDA 144 /* * Reserved for IBM SP switch and IBM Next Federation switch. */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 + #define DLT_IBM_SP 145 + #define DLT_IBM_SN 146 /* * Reserved for private use. If you have some link-layer header type @@ -485,22 +487,22 @@ struct bpf_version { * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, * as per the comment above, and use the type you're given. */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 + #define DLT_USER0 147 + #define DLT_USER1 148 + #define DLT_USER2 149 + #define DLT_USER3 150 + #define DLT_USER4 151 + #define DLT_USER5 152 + #define DLT_USER6 153 + #define DLT_USER7 154 + #define DLT_USER8 155 + #define DLT_USER9 156 + #define DLT_USER10 157 + #define DLT_USER11 158 + #define DLT_USER12 159 + #define DLT_USER13 160 + #define DLT_USER14 161 + #define DLT_USER15 162 /* * For future use with 802.11 captures - defined by AbsoluteValue @@ -512,7 +514,7 @@ struct bpf_version { * but it might be used by some non-AVS drivers now or in the * future. */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + #define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ /* * Juniper-private data link type, as per request from @@ -520,12 +522,12 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MONITOR 164 + #define DLT_JUNIPER_MONITOR 164 /* * Reserved for BACnet MS/TP. */ -#define DLT_BACNET_MS_TP 165 + #define DLT_BACNET_MS_TP 165 /* * Another PPP variant as per request from Karsten Keil . @@ -538,17 +540,17 @@ struct bpf_version { * input packets such as port scans, packets from old lost connections, * etc. to force the connection to stay up). * - * The first byte of the PPP header (0xff03) is modified to accomodate + * The first byte of the PPP header (0xff03) is modified to accommodate * the direction - 0x00 = IN, 0x01 = OUT. */ -#define DLT_PPP_PPPD 166 + #define DLT_PPP_PPPD 166 /* * Names for backwards compatibility with older versions of some PPP * software; new software should use DLT_PPP_PPPD. */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + #define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD + #define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD /* * Juniper-private data link type, as per request from @@ -556,26 +558,26 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, cookies, etc.. */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 + #define DLT_JUNIPER_PPPOE 167 + #define DLT_JUNIPER_PPPOE_ATM 168 -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + #define DLT_GPRS_LLC 169 /* GPRS LLC */ + #define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ + #define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ /* * Requested by Oolan Zimmer for use in Gcom's T1/E1 line * monitoring equipment. */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 + #define DLT_GCOM_T1E1 172 + #define DLT_GCOM_SERIAL 173 /* * Juniper-private data link type, as per request from * Hannes Gredler . The DLT_ is used * for internal communication to Physical Interface Cards (PIC) */ -#define DLT_JUNIPER_PIC_PEER 174 + #define DLT_JUNIPER_PIC_PEER 174 /* * Link types requested by Gregor Maier of Endace @@ -583,8 +585,8 @@ struct bpf_version { * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of * the link-layer header. */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ + #define DLT_ERF_ETH 175 /* Ethernet */ + #define DLT_ERF_POS 176 /* Packet-over-SONET */ /* * Requested by Daniele Orlandi for raw LAPD @@ -592,32 +594,32 @@ struct bpf_version { * includes additional information before the LAPD header, so it's * not necessarily a generic LAPD header. */ -#define DLT_LINUX_LAPD 177 + #define DLT_LINUX_LAPD 177 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ are used for prepending meta-information * like interface index, interface name * before standard Ethernet, PPP, Frelay & C-HDLC Frames */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 + #define DLT_JUNIPER_ETHER 178 + #define DLT_JUNIPER_PPP 179 + #define DLT_JUNIPER_FRELAY 180 + #define DLT_JUNIPER_CHDLC 181 /* * Multi Link Frame Relay (FRF.16) */ -#define DLT_MFR 182 + #define DLT_MFR 182 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * voice Adapter Card (PIC) */ -#define DLT_JUNIPER_VP 183 + #define DLT_JUNIPER_VP 183 /* * Arinc 429 frames. @@ -626,38 +628,38 @@ struct bpf_version { * More documentation on Arinc 429 can be found at * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf */ -#define DLT_A429 184 + #define DLT_A429 184 /* * Arinc 653 Interpartition Communication messages. * DLT_ requested by Gianluca Varenni . * Please refer to the A653-1 standard for more information. */ -#define DLT_A653_ICM 185 + #define DLT_A653_ICM 185 /* * USB packets, beginning with a USB setup header; requested by * Paolo Abeni . */ -#define DLT_USB 186 + #define DLT_USB 186 /* * Bluetooth HCI UART transport layer (part H:4); requested by * Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4 187 + #define DLT_BLUETOOTH_HCI_H4 187 /* * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz * . */ -#define DLT_IEEE802_16_MAC_CPS 188 + #define DLT_IEEE802_16_MAC_CPS 188 /* * USB packets, beginning with a Linux USB header; requested by * Paolo Abeni . */ -#define DLT_USB_LINUX 189 + #define DLT_USB_LINUX 189 /* * Controller Area Network (CAN) v. 2.0B packets. @@ -666,79 +668,79 @@ struct bpf_version { * More documentation on the CAN v2.0B frames can be found at * http://www.can-cia.org/downloads/?269 */ -#define DLT_CAN20B 190 + #define DLT_CAN20B 190 /* * IEEE 802.15.4, with address fields padded, as is done by Linux * drivers; requested by Juergen Schimmer. */ -#define DLT_IEEE802_15_4_LINUX 191 + #define DLT_IEEE802_15_4_LINUX 191 /* * Per Packet Information encapsulated packets. * DLT_ requested by Gianluca Varenni . */ -#define DLT_PPI 192 + #define DLT_PPI 192 /* * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; * requested by Charles Clancy. */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + #define DLT_IEEE802_16_MAC_CPS_RADIO 193 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * integrated service module (ISM). */ -#define DLT_JUNIPER_ISM 194 + #define DLT_JUNIPER_ISM 194 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no * nothing); requested by Mikko Saarnivala . */ -#define DLT_IEEE802_15_4 195 + #define DLT_IEEE802_15_4 195 /* * Various link-layer types, with a pseudo-header, for SITA * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). */ -#define DLT_SITA 196 + #define DLT_SITA 196 /* * Various link-layer types, with a pseudo-header, for Endace DAG cards; * encapsulates Endace ERF records. Requested by Stephen Donnelly * . */ -#define DLT_ERF 197 + #define DLT_ERF 197 /* * Special header prepended to Ethernet packets when capturing from a * u10 Networks board. Requested by Phil Mulholland * . */ -#define DLT_RAIF1 198 + #define DLT_RAIF1 198 /* * IPMB packet for IPMI, beginning with the I2C slave address, followed * by the netFn and LUN, etc.. Requested by Chanthy Toeung * . */ -#define DLT_IPMB 199 + #define DLT_IPMB 199 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for capturing data on a secure tunnel interface. */ -#define DLT_JUNIPER_ST 200 + #define DLT_JUNIPER_ST 200 /* * Bluetooth HCI UART transport layer (part H:4), with pseudo-header * that includes direction information; requested by Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + #define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 /* * AX.25 packet with a 1-byte KISS header; see @@ -747,14 +749,14 @@ struct bpf_version { * * as per Richard Stearn . */ -#define DLT_AX25_KISS 202 + #define DLT_AX25_KISS 202 /* * LAPD packets from an ISDN channel, starting with the address field, * with no pseudo-header. * Requested by Varuna De Silva . */ -#define DLT_LAPD 203 + #define DLT_LAPD 203 /* * Variants of various link-layer headers, with a one-byte direction @@ -762,10 +764,10 @@ struct bpf_version { * non-zero (any non-zero value) means "sent by this host" - as per * Will Barker . */ -#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ -#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ -#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ -#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + #define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ + #define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ + #define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ + #define DLT_LAPB_WITH_DIR 207 /* LAPB */ /* * 208 is reserved for an as-yet-unspecified proprietary link-layer @@ -776,39 +778,39 @@ struct bpf_version { * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman * . */ -#define DLT_IPMB_LINUX 209 + #define DLT_IPMB_LINUX 209 /* * FlexRay automotive bus - http://www.flexray.com/ - as requested * by Hannes Kaelber . */ -#define DLT_FLEXRAY 210 + #define DLT_FLEXRAY 210 /* * Media Oriented Systems Transport (MOST) bus for multimedia * transport - http://www.mostcooperation.com/ - as requested * by Hannes Kaelber . */ -#define DLT_MOST 211 + #define DLT_MOST 211 /* * Local Interconnect Network (LIN) bus for vehicle networks - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber * . */ -#define DLT_LIN 212 + #define DLT_LIN 212 /* * X2E-private data link type used for serial line capture, * as requested by Hannes Kaelber . */ -#define DLT_X2E_SERIAL 213 + #define DLT_X2E_SERIAL 213 /* * X2E-private data link type used for the Xoraya data logger * family, as requested by Hannes Kaelber . */ -#define DLT_X2E_XORAYA 214 + #define DLT_X2E_XORAYA 214 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no @@ -819,7 +821,7 @@ struct bpf_version { * * Requested by Max Filippov . */ -#define DLT_IEEE802_15_4_NONASK_PHY 215 + #define DLT_IEEE802_15_4_NONASK_PHY 215 /* @@ -827,7 +829,7 @@ struct bpf_version { * a member of that class. A class value of 0 indicates a regular * DLT_/LINKTYPE_ value. */ -#define DLT_CLASS(x) ((x) & 0x03ff0000) + #define DLT_CLASS( x ) ( ( x ) & 0x03ff0000 ) /* * NetBSD-specific generic "raw" link type. The class value indicates @@ -836,99 +838,104 @@ struct bpf_version { * do not assume that they correspond to AF_ values for your operating * system. */ -#define DLT_CLASS_NETBSD_RAWAF 0x02240000 -#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) -#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) -#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + #define DLT_CLASS_NETBSD_RAWAF 0x02240000 + #define DLT_NETBSD_RAWAF( af ) ( DLT_CLASS_NETBSD_RAWAF | ( af ) ) + #define DLT_NETBSD_RAWAF_AF( x ) ( ( x ) & 0x0000ffff ) + #define DLT_IS_NETBSD_RAWAF( x ) ( DLT_CLASS( x ) == DLT_CLASS_NETBSD_RAWAF ) /* * The instruction encodings. */ /* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 + #define BPF_CLASS( code ) ( ( code ) & 0x07 ) + #define BPF_LD 0x00 + #define BPF_LDX 0x01 + #define BPF_ST 0x02 + #define BPF_STX 0x03 + #define BPF_ALU 0x04 + #define BPF_JMP 0x05 + #define BPF_RET 0x06 + #define BPF_MISC 0x07 /* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 + #define BPF_SIZE( code ) ( ( code ) & 0x18 ) + #define BPF_W 0x00 + #define BPF_H 0x08 + #define BPF_B 0x10 + #define BPF_MODE( code ) ( ( code ) & 0xe0 ) + #define BPF_IMM 0x00 + #define BPF_ABS 0x20 + #define BPF_IND 0x40 + #define BPF_MEM 0x60 + #define BPF_LEN 0x80 + #define BPF_MSH 0xa0 /* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 + #define BPF_OP( code ) ( ( code ) & 0xf0 ) + #define BPF_ADD 0x00 + #define BPF_SUB 0x10 + #define BPF_MUL 0x20 + #define BPF_DIV 0x30 + #define BPF_OR 0x40 + #define BPF_AND 0x50 + #define BPF_LSH 0x60 + #define BPF_RSH 0x70 + #define BPF_NEG 0x80 + #define BPF_JA 0x00 + #define BPF_JEQ 0x10 + #define BPF_JGT 0x20 + #define BPF_JGE 0x30 + #define BPF_JSET 0x40 + #define BPF_SRC( code ) ( ( code ) & 0x08 ) + #define BPF_K 0x00 + #define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 + #define BPF_RVAL( code ) ( ( code ) & 0x18 ) + #define BPF_A 0x10 /* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 + #define BPF_MISCOP( code ) ( ( code ) & 0xf8 ) + #define BPF_TAX 0x00 + #define BPF_TXA 0x80 /* * The instruction data structure. */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_u_int32 k; -}; + struct bpf_insn + { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; + }; /* * Macros for insn array initializers. */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + #define BPF_STMT( code, k ) { ( u_short ) ( code ), 0, 0, k } + #define BPF_JUMP( code, k, jt, jf ) { ( u_short ) ( code ), jt, jf, k } -#if __STDC__ || defined(__cplusplus) -extern int bpf_validate(const struct bpf_insn *, int); -extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -#else -extern int bpf_validate(); -extern u_int bpf_filter(); -#endif + #if __STDC__ || defined( __cplusplus ) + extern int bpf_validate( const struct bpf_insn *, + int ); + extern u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + #else + extern int bpf_validate(); + extern u_int bpf_filter(); + #endif /* * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). */ -#define BPF_MEMWORDS 16 + #define BPF_MEMWORDS 16 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef BPF_MAJOR_VERSION */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/namedb.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/namedb.h index 9002c7509..27bcaa5cc 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/namedb.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/namedb.h @@ -34,11 +34,11 @@ */ #ifndef lib_pcap_namedb_h -#define lib_pcap_namedb_h + #define lib_pcap_namedb_h -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* * As returned by the pcap_next_etherent() @@ -47,43 +47,52 @@ extern "C" { * on systems that don't have support for /etc/ethers, we * export these hooks since they'll */ -struct pcap_etherent { - u_char addr[6]; - char name[122]; -}; -#ifndef PCAP_ETHERS_FILE -#define PCAP_ETHERS_FILE "/etc/ethers" -#endif -struct pcap_etherent *pcap_next_etherent(FILE *); -u_char *pcap_ether_hostton(const char*); -u_char *pcap_ether_aton(const char *); + struct pcap_etherent + { + u_char addr[ 6 ]; + char name[ 122 ]; + }; + #ifndef PCAP_ETHERS_FILE + #define PCAP_ETHERS_FILE "/etc/ethers" + #endif + struct pcap_etherent * pcap_next_etherent( FILE * ); + u_char * pcap_ether_hostton( const char * ); + u_char * pcap_ether_aton( const char * ); -bpf_u_int32 **pcap_nametoaddr(const char *); -#ifdef INET6 -struct addrinfo *pcap_nametoaddrinfo(const char *); -#endif -bpf_u_int32 pcap_nametonetaddr(const char *); + bpf_u_int32 ** pcap_nametoaddr( const char * ); + #ifdef INET6 + struct addrinfo * pcap_nametoaddrinfo( const char * ); + #endif + bpf_u_int32 pcap_nametonetaddr( const char * ); + + int pcap_nametoport( const char *, + int *, + int * ); + int pcap_nametoportrange( const char *, + int *, + int *, + int * ); + int pcap_nametoproto( const char * ); + int pcap_nametoeproto( const char * ); + int pcap_nametollc( const char * ); -int pcap_nametoport(const char *, int *, int *); -int pcap_nametoportrange(const char *, int *, int *, int *); -int pcap_nametoproto(const char *); -int pcap_nametoeproto(const char *); -int pcap_nametollc(const char *); /* * If a protocol is unknown, PROTO_UNDEF is returned. * Also, pcap_nametoport() returns the protocol along with the port number. * If there are ambiguous entried in /etc/services (i.e. domain * can be either tcp or udp) PROTO_UNDEF is returned. */ -#define PROTO_UNDEF -1 + #define PROTO_UNDEF -1 /* XXX move these to pcap-int.h? */ -int __pcap_atodn(const char *, bpf_u_int32 *); -int __pcap_atoin(const char *, bpf_u_int32 *); -u_short __pcap_nametodnaddr(const char *); + int __pcap_atodn( const char *, + bpf_u_int32 * ); + int __pcap_atoin( const char *, + bpf_u_int32 * ); + u_short __pcap_nametodnaddr( const char * ); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_namedb_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/pcap.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/pcap.h index ad8fc40ac..20113a9e7 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/pcap.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/pcap.h @@ -1,4 +1,5 @@ /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ + /* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. @@ -35,59 +36,59 @@ */ #ifndef lib_pcap_pcap_h -#define lib_pcap_pcap_h + #define lib_pcap_pcap_h -#if defined(WIN32) - #include -#elif defined(MSDOS) - #include - #include /* u_int, u_char etc. */ -#else /* UN*X */ - #include - #include -#endif /* WIN32/MSDOS/UN*X */ + #if defined( WIN32 ) + #include + #elif defined( MSDOS ) + #include + #include /* u_int, u_char etc. */ + #else /* UN*X */ + #include + #include + #endif /* WIN32/MSDOS/UN*X */ -#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include -#endif + #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H + #include + #endif -#include + #include -#ifdef HAVE_REMOTE - // We have to define the SOCKET here, although it has been defined in sockutils.h - // This is to avoid the distribution of the 'sockutils.h' file around - // (for example in the WinPcap developer's pack) - #ifndef SOCKET - #ifdef WIN32 - #define SOCKET unsigned int - #else - #define SOCKET int - #endif - #endif -#endif + #ifdef HAVE_REMOTE + /* We have to define the SOCKET here, although it has been defined in sockutils.h */ + /* This is to avoid the distribution of the 'sockutils.h' file around */ + /* (for example in the WinPcap developer's pack) */ + #ifndef SOCKET + #ifdef WIN32 + #define SOCKET unsigned int + #else + #define SOCKET int + #endif + #endif + #endif /* ifdef HAVE_REMOTE */ -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 + #define PCAP_VERSION_MAJOR 2 + #define PCAP_VERSION_MINOR 4 -#define PCAP_ERRBUF_SIZE 256 + #define PCAP_ERRBUF_SIZE 256 /* * Compatibility for systems that have a bpf.h that * predates the bpf typedefs for 64-bit support. */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #if BPF_RELEASE - 0 < 199406 + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; + typedef struct pcap pcap_t; + typedef struct pcap_dumper pcap_dumper_t; + typedef struct pcap_if pcap_if_t; + typedef struct pcap_addr pcap_addr_t; /* * The first record in the file contains saved values for some @@ -126,31 +127,33 @@ typedef struct pcap_addr pcap_addr_t; * so that future versions of libpcap and programs that use it (such as * tcpdump) will be able to read your new capture file format. */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; + struct pcap_file_header + { + bpf_u_int32 magic; + u_short version_major; + u_short version_minor; + bpf_int32 thiszone; /* gmt to local correction */ + bpf_u_int32 sigfigs; /* accuracy of timestamps */ + bpf_u_int32 snaplen; /* max length saved portion of each pkt */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ + }; /* * Macros for the value returned by pcap_datalink_ext(). - * + * * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro * gives the FCS length of packets in the capture. */ -#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) -#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) -#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) + #define LT_FCS_LENGTH_PRESENT( x ) ( ( x ) & 0x04000000 ) + #define LT_FCS_LENGTH( x ) ( ( ( x ) & 0xF0000000 ) >> 28 ) + #define LT_FCS_DATALINK_EXT( x ) ( ( ( ( x ) & 0xF ) << 28 ) | 0x04000000 ) -typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT -} pcap_direction_t; + typedef enum + { + PCAP_D_INOUT = 0, + PCAP_D_IN, + PCAP_D_OUT + } pcap_direction_t; /* * Generic per-packet information, as supplied by libpcap. @@ -164,85 +167,92 @@ typedef enum { * should supply the appropriate version of "struct timeval", even if * that's not what the underlying packet capture mechanism supplies. */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; + struct pcap_pkthdr + { + struct timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ + }; /* * As returned by the pcap_stats() */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface XXX not yet supported */ -#ifdef HAVE_REMOTE - u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ - u_int ps_sent; /* number of packets sent by the server on the network */ - u_int ps_netdrop; /* number of packets lost on the network */ -#endif /* HAVE_REMOTE */ -}; + struct pcap_stat + { + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface XXX not yet supported */ + #ifdef HAVE_REMOTE + u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ + u_int ps_sent; /* number of packets sent by the server on the network */ + u_int ps_netdrop; /* number of packets lost on the network */ + #endif /* HAVE_REMOTE */ + }; + + #ifdef MSDOS -#ifdef MSDOS /* * As returned by the pcap_stats_ex() */ -struct pcap_stat_ex { - u_long rx_packets; /* total packets received */ - u_long tx_packets; /* total packets transmitted */ - u_long rx_bytes; /* total bytes received */ - u_long tx_bytes; /* total bytes transmitted */ - u_long rx_errors; /* bad packets received */ - u_long tx_errors; /* packet transmit problems */ - u_long rx_dropped; /* no space in Rx buffers */ - u_long tx_dropped; /* no space available for Tx */ - u_long multicast; /* multicast packets received */ - u_long collisions; + struct pcap_stat_ex + { + u_long rx_packets; /* total packets received */ + u_long tx_packets; /* total packets transmitted */ + u_long rx_bytes; /* total bytes received */ + u_long tx_bytes; /* total bytes transmitted */ + u_long rx_errors; /* bad packets received */ + u_long tx_errors; /* packet transmit problems */ + u_long rx_dropped; /* no space in Rx buffers */ + u_long tx_dropped; /* no space available for Tx */ + u_long multicast; /* multicast packets received */ + u_long collisions; - /* detailed rx_errors: */ - u_long rx_length_errors; - u_long rx_over_errors; /* receiver ring buff overflow */ - u_long rx_crc_errors; /* recv'd pkt with crc error */ - u_long rx_frame_errors; /* recv'd frame alignment error */ - u_long rx_fifo_errors; /* recv'r fifo overrun */ - u_long rx_missed_errors; /* recv'r missed packet */ + /* detailed rx_errors: */ + u_long rx_length_errors; + u_long rx_over_errors; /* receiver ring buff overflow */ + u_long rx_crc_errors; /* recv'd pkt with crc error */ + u_long rx_frame_errors; /* recv'd frame alignment error */ + u_long rx_fifo_errors; /* recv'r fifo overrun */ + u_long rx_missed_errors; /* recv'r missed packet */ - /* detailed tx_errors */ - u_long tx_aborted_errors; - u_long tx_carrier_errors; - u_long tx_fifo_errors; - u_long tx_heartbeat_errors; - u_long tx_window_errors; - }; -#endif + /* detailed tx_errors */ + u_long tx_aborted_errors; + u_long tx_carrier_errors; + u_long tx_fifo_errors; + u_long tx_heartbeat_errors; + u_long tx_window_errors; + }; + #endif /* ifdef MSDOS */ /* * Item in a list of interfaces. */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; + struct pcap_if + { + struct pcap_if * next; + char * name; /* name to hand to "pcap_open_live()" */ + char * description; /* textual description of interface, or NULL */ + struct pcap_addr * addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ + }; -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ + #define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ /* * Representation of an interface address. */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; + struct pcap_addr + { + struct pcap_addr * next; + struct sockaddr * addr; /* address */ + struct sockaddr * netmask; /* netmask for that address */ + struct sockaddr * broadaddr; /* broadcast address for that address */ + struct sockaddr * dstaddr; /* P2P destination address for that address */ + }; -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); + typedef void (* pcap_handler)( u_char *, + const struct pcap_pkthdr *, + const u_char * ); /* * Error codes for the pcap API. @@ -250,158 +260,222 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, * failure of a call that returns these codes by checking for a * negative value. */ -#define PCAP_ERROR -1 /* generic error code */ -#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ -#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ -#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ -#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ -#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ -#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ -#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ -#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ + #define PCAP_ERROR -1 /* generic error code */ + #define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ + #define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ + #define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ + #define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ + #define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ + #define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ + #define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ + #define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ /* * Warning codes for the pcap API. * These will all be positive and non-zero, so they won't look like * errors. */ -#define PCAP_WARNING 1 /* generic warning code */ -#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ + #define PCAP_WARNING 1 /* generic warning code */ + #define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ -char *pcap_lookupdev(char *); -int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); + char * pcap_lookupdev( char * ); + int pcap_lookupnet( const char *, + bpf_u_int32 *, + bpf_u_int32 *, + char * ); -pcap_t *pcap_create(const char *, char *); -int pcap_set_snaplen(pcap_t *, int); -int pcap_set_promisc(pcap_t *, int); -int pcap_can_set_rfmon(pcap_t *); -int pcap_set_rfmon(pcap_t *, int); -int pcap_set_timeout(pcap_t *, int); -int pcap_set_buffer_size(pcap_t *, int); -int pcap_activate(pcap_t *); + pcap_t * pcap_create( const char *, + char * ); + int pcap_set_snaplen( pcap_t *, + int ); + int pcap_set_promisc( pcap_t *, + int ); + int pcap_can_set_rfmon( pcap_t * ); + int pcap_set_rfmon( pcap_t *, + int ); + int pcap_set_timeout( pcap_t *, + int ); + int pcap_set_buffer_size( pcap_t *, + int ); + int pcap_activate( pcap_t * ); -pcap_t *pcap_open_live(const char *, int, int, int, char *); -pcap_t *pcap_open_dead(int, int); -pcap_t *pcap_open_offline(const char *, char *); -#if defined(WIN32) -pcap_t *pcap_hopen_offline(intptr_t, char *); -#if !defined(LIBPCAP_EXPORTS) -#define pcap_fopen_offline(f,b) \ - pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) -#else /*LIBPCAP_EXPORTS*/ -static pcap_t *pcap_fopen_offline(FILE *, char *); -#endif -#else /*WIN32*/ -pcap_t *pcap_fopen_offline(FILE *, char *); -#endif /*WIN32*/ + pcap_t * pcap_open_live( const char *, + int, + int, + int, + char * ); + pcap_t * pcap_open_dead( int, + int ); + pcap_t * pcap_open_offline( const char *, + char * ); + #if defined( WIN32 ) + pcap_t * pcap_hopen_offline( intptr_t, + char * ); + #if !defined( LIBPCAP_EXPORTS ) + #define pcap_fopen_offline( f, b ) \ + pcap_hopen_offline( _get_osfhandle( _fileno( f ) ), b ) + #else /*LIBPCAP_EXPORTS*/ + static pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif + #else /*WIN32*/ + pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif /*WIN32*/ -void pcap_close(pcap_t *); -int pcap_loop(pcap_t *, int, pcap_handler, u_char *); -int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); -const u_char* - pcap_next(pcap_t *, struct pcap_pkthdr *); -int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); -void pcap_breakloop(pcap_t *); -int pcap_stats(pcap_t *, struct pcap_stat *); -int pcap_setfilter(pcap_t *, struct bpf_program *); -int pcap_setdirection(pcap_t *, pcap_direction_t); -int pcap_getnonblock(pcap_t *, char *); -int pcap_setnonblock(pcap_t *, int, char *); -int pcap_inject(pcap_t *, const void *, size_t); -int pcap_sendpacket(pcap_t *, const u_char *, int); -const char *pcap_statustostr(int); -const char *pcap_strerror(int); -char *pcap_geterr(pcap_t *); -void pcap_perror(pcap_t *, char *); -int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32); -int pcap_compile_nopcap(int, int, struct bpf_program *, - const char *, int, bpf_u_int32); -void pcap_freecode(struct bpf_program *); -int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *, - const u_char *); -int pcap_datalink(pcap_t *); -int pcap_datalink_ext(pcap_t *); -int pcap_list_datalinks(pcap_t *, int **); -int pcap_set_datalink(pcap_t *, int); -void pcap_free_datalinks(int *); -int pcap_datalink_name_to_val(const char *); -const char *pcap_datalink_val_to_name(int); -const char *pcap_datalink_val_to_description(int); -int pcap_snapshot(pcap_t *); -int pcap_is_swapped(pcap_t *); -int pcap_major_version(pcap_t *); -int pcap_minor_version(pcap_t *); + void pcap_close( pcap_t * ); + int pcap_loop( pcap_t *, + int, + pcap_handler, + u_char * ); + int pcap_dispatch( pcap_t *, + int, + pcap_handler, + u_char * ); + const u_char * pcap_next( pcap_t *, + struct pcap_pkthdr * ); + int pcap_next_ex( pcap_t *, + struct pcap_pkthdr **, + const u_char ** ); + void pcap_breakloop( pcap_t * ); + int pcap_stats( pcap_t *, + struct pcap_stat * ); + int pcap_setfilter( pcap_t *, + struct bpf_program * ); + int pcap_setdirection( pcap_t *, + pcap_direction_t ); + int pcap_getnonblock( pcap_t *, + char * ); + int pcap_setnonblock( pcap_t *, + int, + char * ); + int pcap_inject( pcap_t *, + const void *, + size_t ); + int pcap_sendpacket( pcap_t *, + const u_char *, + int ); + const char * pcap_statustostr( int ); + const char * pcap_strerror( int ); + char * pcap_geterr( pcap_t * ); + void pcap_perror( pcap_t *, + char * ); + int pcap_compile( pcap_t *, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + int pcap_compile_nopcap( int, + int, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + void pcap_freecode( struct bpf_program * ); + int pcap_offline_filter( struct bpf_program *, + const struct pcap_pkthdr *, + const u_char * ); + int pcap_datalink( pcap_t * ); + int pcap_datalink_ext( pcap_t * ); + int pcap_list_datalinks( pcap_t *, + int ** ); + int pcap_set_datalink( pcap_t *, + int ); + void pcap_free_datalinks( int * ); + int pcap_datalink_name_to_val( const char * ); + const char * pcap_datalink_val_to_name( int ); + const char * pcap_datalink_val_to_description( int ); + int pcap_snapshot( pcap_t * ); + int pcap_is_swapped( pcap_t * ); + int pcap_major_version( pcap_t * ); + int pcap_minor_version( pcap_t * ); /* XXX */ -FILE *pcap_file(pcap_t *); -int pcap_fileno(pcap_t *); + FILE * pcap_file( pcap_t * ); + int pcap_fileno( pcap_t * ); -pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); -pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); -FILE *pcap_dump_file(pcap_dumper_t *); -long pcap_dump_ftell(pcap_dumper_t *); -int pcap_dump_flush(pcap_dumper_t *); -void pcap_dump_close(pcap_dumper_t *); -void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); + pcap_dumper_t * pcap_dump_open( pcap_t *, + const char * ); + pcap_dumper_t * pcap_dump_fopen( pcap_t *, + FILE * fp ); + FILE * pcap_dump_file( pcap_dumper_t * ); + long pcap_dump_ftell( pcap_dumper_t * ); + int pcap_dump_flush( pcap_dumper_t * ); + void pcap_dump_close( pcap_dumper_t * ); + void pcap_dump( u_char *, + const struct pcap_pkthdr *, + const u_char * ); -int pcap_findalldevs(pcap_if_t **, char *); -void pcap_freealldevs(pcap_if_t *); + int pcap_findalldevs( pcap_if_t **, + char * ); + void pcap_freealldevs( pcap_if_t * ); -const char *pcap_lib_version(void); + const char * pcap_lib_version( void ); /* XXX this guy lives in the bpf tree */ -u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -int bpf_validate(const struct bpf_insn *f, int len); -char *bpf_image(const struct bpf_insn *, int); -void bpf_dump(const struct bpf_program *, int); + u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + int bpf_validate( const struct bpf_insn * f, + int len ); + char * bpf_image( const struct bpf_insn *, + int ); + void bpf_dump( const struct bpf_program *, + int ); -#if defined(WIN32) + #if defined( WIN32 ) /* * Win32 definitions */ -int pcap_setbuff(pcap_t *p, int dim); -int pcap_setmode(pcap_t *p, int mode); -int pcap_setmintocopy(pcap_t *p, int size); + int pcap_setbuff( pcap_t * p, + int dim ); + int pcap_setmode( pcap_t * p, + int mode ); + int pcap_setmintocopy( pcap_t * p, + int size ); -#ifdef WPCAP + #ifdef WPCAP /* Include file with the wpcap-specific extensions */ -#include -#endif /* WPCAP */ + #include + #endif /* WPCAP */ -#define MODE_CAPT 0 -#define MODE_STAT 1 -#define MODE_MON 2 + #define MODE_CAPT 0 + #define MODE_STAT 1 + #define MODE_MON 2 -#elif defined(MSDOS) + #elif defined( MSDOS ) /* * MS-DOS definitions */ -int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); -void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); -u_long pcap_mac_packets (void); + int pcap_stats_ex( pcap_t *, + struct pcap_stat_ex * ); + void pcap_set_wait( pcap_t * p, + void ( * yield )( void ), + int wait ); + u_long pcap_mac_packets( void ); -#else /* UN*X */ + #else /* UN*X */ /* * UN*X definitions */ -int pcap_get_selectable_fd(pcap_t *); + int pcap_get_selectable_fd( pcap_t * ); -#endif /* WIN32/MSDOS/UN*X */ + #endif /* WIN32/MSDOS/UN*X */ -#ifdef HAVE_REMOTE + #ifdef HAVE_REMOTE /* Includes most of the public stuff that is needed for the remote capture */ -#include -#endif /* HAVE_REMOTE */ + #include + #endif /* HAVE_REMOTE */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_pcap_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/sll.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/sll.h index e9d5452af..e5052236a 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/sll.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/sll.h @@ -79,15 +79,16 @@ /* * A DLT_LINUX_SLL fake link-layer header. */ -#define SLL_HDR_LEN 16 /* total header length */ -#define SLL_ADDRLEN 8 /* length of address field */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ -struct sll_header { - u_int16_t sll_pkttype; /* packet type */ - u_int16_t sll_hatype; /* link-layer address type */ - u_int16_t sll_halen; /* link-layer address length */ - u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ - u_int16_t sll_protocol; /* protocol */ +struct sll_header +{ + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[ SLL_ADDRLEN ]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ }; /* @@ -96,11 +97,11 @@ struct sll_header { * available even on systems other than Linux, and so that they * don't change even if the PACKET_ values change. */ -#define LINUX_SLL_HOST 0 -#define LINUX_SLL_BROADCAST 1 -#define LINUX_SLL_MULTICAST 2 -#define LINUX_SLL_OTHERHOST 3 -#define LINUX_SLL_OUTGOING 4 +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 /* * The LINUX_SLL_ values for "sll_protocol"; these correspond to the @@ -123,7 +124,7 @@ struct sll_header { * in the Linux "if_ether.h" will, I suspect, actually show up in * captures.) */ -#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ -#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ -#endif +#endif /* ifndef lib_pcap_sll_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/usb.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/usb.h index adcd19c05..44a3c9557 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/usb.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/usb.h @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,36 +32,37 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $ */ - + #ifndef _PCAP_USB_STRUCTS_H__ #define _PCAP_USB_STRUCTS_H__ -/* +/* * possible transfer mode */ -#define URB_TRANSFER_IN 0x80 -#define URB_ISOCHRONOUS 0x0 -#define URB_INTERRUPT 0x1 -#define URB_CONTROL 0x2 -#define URB_BULK 0x3 +#define URB_TRANSFER_IN 0x80 +#define URB_ISOCHRONOUS 0x0 +#define URB_INTERRUPT 0x1 +#define URB_CONTROL 0x2 +#define URB_BULK 0x3 /* * possible event type */ -#define URB_SUBMIT 'S' -#define URB_COMPLETE 'C' -#define URB_ERROR 'E' +#define URB_SUBMIT 'S' +#define URB_COMPLETE 'C' +#define URB_ERROR 'E' /* * USB setup header as defined in USB specification. * Appears at the front of each packet in DLT_USB captures. */ -typedef struct _usb_setup { - u_int8_t bmRequestType; - u_int8_t bRequest; - u_int16_t wValue; - u_int16_t wIndex; - u_int16_t wLength; +typedef struct _usb_setup +{ + u_int8_t bmRequestType; + u_int8_t bRequest; + u_int16_t wValue; + u_int16_t wIndex; + u_int16_t wLength; } pcap_usb_setup; @@ -69,22 +70,23 @@ typedef struct _usb_setup { * Header prepended by linux kernel to each event. * Appears at the front of each packet in DLT_USB_LINUX captures. */ -typedef struct _usb_header { - u_int64_t id; - u_int8_t event_type; - u_int8_t transfer_type; - u_int8_t endpoint_number; - u_int8_t device_address; - u_int16_t bus_id; - char setup_flag;/*if !=0 the urb setup header is not present*/ - char data_flag; /*if !=0 no urb data is present*/ - int64_t ts_sec; - int32_t ts_usec; - int32_t status; - u_int32_t urb_len; - u_int32_t data_len; /* amount of urb data really present in this event*/ - pcap_usb_setup setup; +typedef struct _usb_header +{ + u_int64_t id; + u_int8_t event_type; + u_int8_t transfer_type; + u_int8_t endpoint_number; + u_int8_t device_address; + u_int16_t bus_id; + char setup_flag; /*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + u_int32_t urb_len; + u_int32_t data_len; /* amount of urb data really present in this event*/ + pcap_usb_setup setup; } pcap_usb_header; -#endif +#endif /* ifndef _PCAP_USB_STRUCTS_H__ */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/vlan.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/vlan.h index b0cb7949b..e9be8bd16 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/vlan.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/pcap/vlan.h @@ -36,11 +36,12 @@ #ifndef lib_pcap_vlan_h #define lib_pcap_vlan_h -struct vlan_tag { - u_int16_t vlan_tpid; /* ETH_P_8021Q */ - u_int16_t vlan_tci; /* VLAN TCI */ +struct vlan_tag +{ + u_int16_t vlan_tpid; /* ETH_P_8021Q */ + u_int16_t vlan_tci; /* VLAN TCI */ }; -#define VLAN_TAG_LEN 4 +#define VLAN_TAG_LEN 4 -#endif +#endif /* ifndef lib_pcap_vlan_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/remote-ext.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/remote-ext.h index 580dea589..42d1fe6e9 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/remote-ext.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/WinPCap/remote-ext.h @@ -45,7 +45,7 @@ #endif #ifdef __cplusplus - extern "C" { + extern "C" { #endif /*! @@ -204,7 +204,7 @@ #define PCAP_OPENFLAG_PROMISCUOUS 1 /*! - * \brief Defines if the data trasfer (in case of a remote + * \brief Defines if the data transfer (in case of a remote * capture) has to be done with UDP protocol. * * If it is '1' if you want a UDP data connection, '0' if you want @@ -232,7 +232,7 @@ * \brief Defines if the local adapter will capture its own generated traffic. * * This flag tells the underlying capture driver to drop the packets that were sent by itself. - * This is usefult when building applications like bridges, that should ignore the traffic + * This is useful when building applications like bridges, that should ignore the traffic * they just sent. */ #define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 @@ -324,7 +324,7 @@ /*! * - * \brief This structure keeps the information needed to autheticate + * \brief This structure keeps the information needed to authenticate * the user on a remote machine. * * The remote machine can either grant or refuse the access according @@ -397,7 +397,7 @@ -/*! Maximum lenght of an host name (needed for the RPCAP active mode) */ +/*! Maximum length of an host name (needed for the RPCAP active mode) */ #define RPCAP_HOSTLIST_SIZE 1024 @@ -465,7 +465,7 @@ /* End of remote capture functions */ #ifdef __cplusplus - } +} #endif diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_config.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_config.h index 02780b5cc..45f548d2e 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_config.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_platform.c b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_platform.c index bb870eafe..d676d4768 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_platform.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_platform.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_platform.h b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_platform.h index 7e20d593a..ad29b7872 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_platform.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/cellular_platform.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -41,7 +41,7 @@ * @brief Cellular library log configuration. * * Cellular library use CellularLogLevel macro for logging. - * The prototye of these logging function is similar with printf with return type ignored. + * The prototype of these logging function is similar with printf with return type ignored. * */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/comm_if_windows.c b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/comm_if_windows.c index 995cbd259..1798497b4 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/comm_if_windows.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/comm_if_windows.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/main.c b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/main.c index ee8a2d8aa..f86723c14 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/main.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Cellular-Interface/Integration/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -111,7 +111,7 @@ int main( void ) * events are only received if implemented in the MAC driver. */ #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, - struct xNetworkEndPoint * pxEndPoint ) + struct xNetworkEndPoint * pxEndPoint ) #else void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ @@ -204,7 +204,7 @@ void vApplicationIdleHook( void ) #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, - const char * pcName ) + const char * pcName ) #else BaseType_t xApplicationDNSQueryHook( const char * pcName ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Config/FreeRTOSConfig.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Config/FreeRTOSConfig.h index 1ecb034ae..06eb516b6 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Config/FreeRTOSConfig.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Config/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -28,88 +28,89 @@ #define FREERTOS_CONFIG_H /*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * https://www.FreeRTOS.org/a00110.html - * - * The bottom of this file contains some constants specific to running the UDP - * stack in this demo. Constants specific to FreeRTOS+TCP itself (rather than - * the demo) are contained in FreeRTOSIPConfig.h. - *----------------------------------------------------------*/ -#define configENABLE_BACKWARD_COMPATIBILITY 1 -#define configUSE_PREEMPTION 1 -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 -#define configMAX_PRIORITIES ( 7 ) -#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */ -#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */ -#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2048U * 1024U ) ) -#define configMAX_TASK_NAME_LEN ( 15 ) -#define configUSE_TRACE_FACILITY 1 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 0 -#define configUSE_APPLICATION_TASK_TAG 0 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configUSE_ALTERNATIVE_API 0 -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 3 /* FreeRTOS+FAT requires 2 pointers if a CWD is supported. */ +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +* https://www.FreeRTOS.org/a00110.html +* +* The bottom of this file contains some constants specific to running the UDP +* stack in this demo. Constants specific to FreeRTOS+TCP itself (rather than +* the demo) are contained in FreeRTOSIPConfig.h. +*----------------------------------------------------------*/ +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#define configMAX_PRIORITIES ( 7 ) +#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */ +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2048U * 1024U ) ) +#define configMAX_TASK_NAME_LEN ( 15 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 0 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 3 /* FreeRTOS+FAT requires 2 pointers if a CWD is supported. */ /* Hook function related definitions. */ -#define configUSE_TICK_HOOK 0 -#define configUSE_IDLE_HOOK 1 -#define configUSE_MALLOC_FAILED_HOOK 0 -#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */ +#define configUSE_TICK_HOOK 0 +#define configUSE_IDLE_HOOK 1 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */ /* Software timer related definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) -#define configTIMER_QUEUE_LENGTH 5 -#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 5 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) /* Event group related definitions. */ -#define configUSE_EVENT_GROUPS 1 +#define configUSE_EVENT_GROUPS 1 /* Run time stats gathering definitions. */ -#define configGENERATE_RUN_TIME_STATS 0 +#define configGENERATE_RUN_TIME_STATS 0 /* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 0 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 1 -#define INCLUDE_xTaskGetSchedulerState 1 -#define INCLUDE_xTimerGetTimerTaskHandle 0 -#define INCLUDE_xTaskGetIdleTaskHandle 0 -#define INCLUDE_xQueueGetMutexHolder 1 -#define INCLUDE_eTaskGetState 1 -#define INCLUDE_xEventGroupSetBitsFromISR 1 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_pcTaskGetTaskName 1 + * to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerGetTimerTaskHandle 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xEventGroupSetBitsFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_pcTaskGetTaskName 1 /* This demo makes use of one or more example stats formatting functions. These -format the raw data provided by the uxTaskGetSystemState() function in to human -readable ASCII form. See the notes in the implementation of vTaskList() within -FreeRTOS/Source/tasks.c for limitations. configUSE_STATS_FORMATTING_FUNCTIONS -is set to 2 so the formatting functions are included without the stdio.h being -included in tasks.c. That is because this project defines its own sprintf() -functions. */ -#define configUSE_STATS_FORMATTING_FUNCTIONS 1 + * format the raw data provided by the uxTaskGetSystemState() function in to human + * readable ASCII form. See the notes in the implementation of vTaskList() within + * FreeRTOS/Source/tasks.c for limitations. configUSE_STATS_FORMATTING_FUNCTIONS + * is set to 2 so the formatting functions are included without the stdio.h being + * included in tasks.c. That is because this project defines its own sprintf() + * functions. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Assert call defined for debug builds. */ #ifdef _DEBUG - extern void vAssertCalled( const char *pcFile, uint32_t ulLine ); - #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ) + extern void vAssertCalled( const char * pcFile, + uint32_t ulLine ); + #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ) #endif /* _DEBUG */ @@ -117,97 +118,96 @@ functions. */ /* Application specific definitions follow. **********************************/ /* If configINCLUDE_DEMO_DEBUG_STATS is set to one, then a few basic IP trace -macros are defined to gather some UDP stack statistics that can then be viewed -through the CLI interface. */ -#define configINCLUDE_DEMO_DEBUG_STATS 1 + * macros are defined to gather some UDP stack statistics that can then be viewed + * through the CLI interface. */ +#define configINCLUDE_DEMO_DEBUG_STATS 1 /* The size of the global output buffer that is available for use when there -are multiple command interpreters running at once (for example, one on a UART -and one on TCP/IP). This is done to prevent an output buffer being defined by -each implementation - which would waste RAM. In this case, there is only one -command interpreter running, and it has its own local output buffer, so the -global buffer is just set to be one byte long as it is not used and should not -take up unnecessary RAM. */ -#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1 + * are multiple command interpreters running at once (for example, one on a UART + * and one on TCP/IP). This is done to prevent an output buffer being defined by + * each implementation - which would waste RAM. In this case, there is only one + * command interpreter running, and it has its own local output buffer, so the + * global buffer is just set to be one byte long as it is not used and should not + * take up unnecessary RAM. */ +#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1 /* Only used when running in the FreeRTOS Windows simulator. Defines the -priority of the task used to simulate Ethernet interrupts. */ -#define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 1 ) + * priority of the task used to simulate Ethernet interrupts. */ +#define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 1 ) /* This demo creates a virtual network connection by accessing the raw Ethernet -or WiFi data to and from a real network connection. Many computers have more -than one real network port, and configNETWORK_INTERFACE_TO_USE is used to tell -the demo which real port should be used to create the virtual port. The ports -available are displayed on the console when the application is executed. For -example, on my development laptop setting configNETWORK_INTERFACE_TO_USE to 4 -results in the wired network being used, while setting -configNETWORK_INTERFACE_TO_USE to 2 results in the wireless network being -used. */ -#define configNETWORK_INTERFACE_TO_USE 6L + * or WiFi data to and from a real network connection. Many computers have more + * than one real network port, and configNETWORK_INTERFACE_TO_USE is used to tell + * the demo which real port should be used to create the virtual port. The ports + * available are displayed on the console when the application is executed. For + * example, on my development laptop setting configNETWORK_INTERFACE_TO_USE to 4 + * results in the wired network being used, while setting + * configNETWORK_INTERFACE_TO_USE to 2 results in the wireless network being + * used. */ +#define configNETWORK_INTERFACE_TO_USE 6L /* The address of an echo server that will be used by the two demo echo client -tasks. -http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html -http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html */ -#define configECHO_SERVER_ADDR0 192 -#define configECHO_SERVER_ADDR1 168 -#define configECHO_SERVER_ADDR2 0 -#define configECHO_SERVER_ADDR3 11 + * tasks. + * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html + * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html */ +#define configECHO_SERVER_ADDR0 192 +#define configECHO_SERVER_ADDR1 168 +#define configECHO_SERVER_ADDR2 0 +#define configECHO_SERVER_ADDR3 11 /* Default MAC address configuration. The demo creates a virtual network -connection that uses this MAC address by accessing the raw Ethernet/WiFi data -to and from a real network connection on the host PC. See the -configNETWORK_INTERFACE_TO_USE definition above for information on how to -configure the real network connection to use. */ -#define configMAC_ADDR0 0x00 -#define configMAC_ADDR1 0x11 -#define configMAC_ADDR2 0x22 -#define configMAC_ADDR3 0x33 -#define configMAC_ADDR4 0x44 -#define configMAC_ADDR5 0x41 + * connection that uses this MAC address by accessing the raw Ethernet/WiFi data + * to and from a real network connection on the host PC. See the + * configNETWORK_INTERFACE_TO_USE definition above for information on how to + * configure the real network connection to use. */ +#define configMAC_ADDR0 0x00 +#define configMAC_ADDR1 0x11 +#define configMAC_ADDR2 0x22 +#define configMAC_ADDR3 0x33 +#define configMAC_ADDR4 0x44 +#define configMAC_ADDR5 0x41 /* Default IP address configuration. Used in ipconfigUSE_DNS is set to 0, or -ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ -#define configIP_ADDR0 10 -#define configIP_ADDR1 10 -#define configIP_ADDR2 10 -#define configIP_ADDR3 200 + * ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ +#define configIP_ADDR0 10 +#define configIP_ADDR1 10 +#define configIP_ADDR2 10 +#define configIP_ADDR3 200 /* Default gateway IP address configuration. Used in ipconfigUSE_DNS is set to -0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ -#define configGATEWAY_ADDR0 10 -#define configGATEWAY_ADDR1 10 -#define configGATEWAY_ADDR2 10 -#define configGATEWAY_ADDR3 1 + * 0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ +#define configGATEWAY_ADDR0 10 +#define configGATEWAY_ADDR1 10 +#define configGATEWAY_ADDR2 10 +#define configGATEWAY_ADDR3 1 /* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and -208.67.220.220. Used in ipconfigUSE_DNS is set to 0, or ipconfigUSE_DNS is set -to 1 but a DNS server cannot be contacted.*/ -#define configDNS_SERVER_ADDR0 208 -#define configDNS_SERVER_ADDR1 67 -#define configDNS_SERVER_ADDR2 222 -#define configDNS_SERVER_ADDR3 222 + * 208.67.220.220. Used in ipconfigUSE_DNS is set to 0, or ipconfigUSE_DNS is set + * to 1 but a DNS server cannot be contacted.*/ +#define configDNS_SERVER_ADDR0 208 +#define configDNS_SERVER_ADDR1 67 +#define configDNS_SERVER_ADDR2 222 +#define configDNS_SERVER_ADDR3 222 /* Default netmask configuration. Used in ipconfigUSE_DNS is set to 0, or -ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ -#define configNET_MASK0 255 -#define configNET_MASK1 0 -#define configNET_MASK2 0 -#define configNET_MASK3 0 + * ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ +#define configNET_MASK0 255 +#define configNET_MASK1 0 +#define configNET_MASK2 0 +#define configNET_MASK3 0 /* The UDP port to which print messages are sent. */ -#define configPRINT_PORT ( 15000 ) +#define configPRINT_PORT ( 15000 ) -#if( defined( _MSC_VER ) && ( _MSC_VER <= 1600 ) && !defined( snprintf ) ) - /* Map to Windows names. */ - #define snprintf _snprintf - #define vsnprintf _vsnprintf +#if ( defined( _MSC_VER ) && ( _MSC_VER <= 1600 ) && !defined( snprintf ) ) + /* Map to Windows names. */ + #define snprintf _snprintf + #define vsnprintf _vsnprintf #endif /* Visual studio does not have an implementation of strcasecmp(). */ -#define strcasecmp _stricmp -#define strncasecmp _strnicmp -#define strcmpi _strcmpi +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#define strcmpi _strcmpi #endif /* FREERTOS_CONFIG_H */ - diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Config/FreeRTOSIPConfig.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Config/FreeRTOSIPConfig.h index 8ad093824..ff15e6c11 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Config/FreeRTOSIPConfig.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Config/FreeRTOSIPConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,17 +20,17 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ /***************************************************************************** - * - * See the following URL for configuration information. - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html - * - *****************************************************************************/ +* +* See the following URL for configuration information. +* https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html +* +*****************************************************************************/ #ifndef FREERTOS_IP_CONFIG_H #define FREERTOS_IP_CONFIG_H @@ -38,272 +38,273 @@ #include /* Prototype for the function used to print out. In this case it prints to the -console before the network is connected then a UDP port after the network has -connected. */ -extern void vLoggingPrintf( const char *pcFormatString, ... ); + * console before the network is connected then a UDP port after the network has + * connected. */ +extern void vLoggingPrintf( const char * pcFormatString, + ... ); /* Set to 1 to print out debug messages. If ipconfigHAS_DEBUG_PRINTF is set to -1 then FreeRTOS_debug_printf should be defined to the function used to print -out the debugging messages. */ -#define ipconfigHAS_DEBUG_PRINTF 0 -#if( ipconfigHAS_DEBUG_PRINTF == 1 ) - #define FreeRTOS_debug_printf(X) vLoggingPrintf X + * 1 then FreeRTOS_debug_printf should be defined to the function used to print + * out the debugging messages. */ +#define ipconfigHAS_DEBUG_PRINTF 0 +#if ( ipconfigHAS_DEBUG_PRINTF == 1 ) + #define FreeRTOS_debug_printf( X ) vLoggingPrintf X #endif /* Set to 1 to print out non debugging messages, for example the output of the -FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1 -then FreeRTOS_printf should be set to the function used to print out the -messages. */ -#define ipconfigHAS_PRINTF 1 -#if( ipconfigHAS_PRINTF == 1 ) - #define FreeRTOS_printf(X) vLoggingPrintf X + * FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1 + * then FreeRTOS_printf should be set to the function used to print out the + * messages. */ +#define ipconfigHAS_PRINTF 1 +#if ( ipconfigHAS_PRINTF == 1 ) + #define FreeRTOS_printf( X ) vLoggingPrintf X #endif /* Define the byte order of the target MCU (the MCU FreeRTOS+TCP is executing -on). Valid options are pdFREERTOS_BIG_ENDIAN and pdFREERTOS_LITTLE_ENDIAN. */ -#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN + * on). Valid options are pdFREERTOS_BIG_ENDIAN and pdFREERTOS_LITTLE_ENDIAN. */ +#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN /* If the network card/driver includes checksum offloading (IP/TCP/UDP checksums) -then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software -stack repeating the checksum calculations. */ -#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1 + * then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software + * stack repeating the checksum calculations. */ +#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1 /* Several API's will block until the result is known, or the action has been -performed, for example FreeRTOS_send() and FreeRTOS_recv(). The timeouts can be -set per socket, using setsockopt(). If not set, the times below will be -used as defaults. */ -#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 5000 ) -#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 5000 ) + * performed, for example FreeRTOS_send() and FreeRTOS_recv(). The timeouts can be + * set per socket, using setsockopt(). If not set, the times below will be + * used as defaults. */ +#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 5000 ) +#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 5000 ) /* Include support for LLMNR: Link-local Multicast Name Resolution -(non-Microsoft) */ -#define ipconfigUSE_LLMNR ( 0 ) + * (non-Microsoft) */ +#define ipconfigUSE_LLMNR ( 0 ) /* Include support for NBNS: NetBIOS Name Service (Microsoft) */ -#define ipconfigUSE_NBNS ( 1 ) +#define ipconfigUSE_NBNS ( 1 ) /* Include support for DNS caching. For TCP, having a small DNS cache is very -useful. When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low -and also DNS may use small timeouts. If a DNS reply comes in after the DNS -socket has been destroyed, the result will be stored into the cache. The next -call to FreeRTOS_gethostbyname() will return immediately, without even creating -a socket. */ -#define ipconfigUSE_DNS_CACHE ( 1 ) -#define ipconfigDNS_CACHE_NAME_LENGTH ( 254 ) -#define ipconfigDNS_CACHE_ENTRIES ( 4 ) -#define ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY ( 6 ) -#define ipconfigDNS_REQUEST_ATTEMPTS ( 2 ) + * useful. When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low + * and also DNS may use small timeouts. If a DNS reply comes in after the DNS + * socket has been destroyed, the result will be stored into the cache. The next + * call to FreeRTOS_gethostbyname() will return immediately, without even creating + * a socket. */ +#define ipconfigUSE_DNS_CACHE ( 1 ) +#define ipconfigDNS_CACHE_NAME_LENGTH ( 254 ) +#define ipconfigDNS_CACHE_ENTRIES ( 4 ) +#define ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY ( 6 ) +#define ipconfigDNS_REQUEST_ATTEMPTS ( 2 ) /* The IP stack executes it its own task (although any application task can make -use of its services through the published sockets API). ipconfigUDP_TASK_PRIORITY -sets the priority of the task that executes the IP stack. The priority is a -standard FreeRTOS task priority so can take any value from 0 (the lowest -priority) to (configMAX_PRIORITIES - 1) (the highest priority). -configMAX_PRIORITIES is a standard FreeRTOS configuration parameter defined in -FreeRTOSConfig.h, not FreeRTOSIPConfig.h. Consideration needs to be given as to -the priority assigned to the task executing the IP stack relative to the -priority assigned to tasks that use the IP stack. */ -#define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) + * use of its services through the published sockets API). ipconfigUDP_TASK_PRIORITY + * sets the priority of the task that executes the IP stack. The priority is a + * standard FreeRTOS task priority so can take any value from 0 (the lowest + * priority) to (configMAX_PRIORITIES - 1) (the highest priority). + * configMAX_PRIORITIES is a standard FreeRTOS configuration parameter defined in + * FreeRTOSConfig.h, not FreeRTOSIPConfig.h. Consideration needs to be given as to + * the priority assigned to the task executing the IP stack relative to the + * priority assigned to tasks that use the IP stack. */ +#define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) /* The size, in words (not bytes), of the stack allocated to the FreeRTOS+TCP -task. This setting is less important when the FreeRTOS Win32 simulator is used -as the Win32 simulator only stores a fixed amount of information on the task -stack. FreeRTOS includes optional stack overflow detection, see: -http://www.freertos.org/Stacks-and-stack-overflow-checking.html */ -#define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 ) + * task. This setting is less important when the FreeRTOS Win32 simulator is used + * as the Win32 simulator only stores a fixed amount of information on the task + * stack. FreeRTOS includes optional stack overflow detection, see: + * http://www.freertos.org/Stacks-and-stack-overflow-checking.html */ +#define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 ) /* ipconfigRAND32() is called by the IP stack to generate random numbers for -things such as a DHCP transaction number or initial sequence number. Random -number generation is performed via this macro to allow applications to use their -own random number generation method. For example, it might be possible to -generate a random number by sampling noise on an analogue input. */ -//extern UBaseType_t rand(); -#define ipconfigRAND32() rand() + * things such as a DHCP transaction number or initial sequence number. Random + * number generation is performed via this macro to allow applications to use their + * own random number generation method. For example, it might be possible to + * generate a random number by sampling noise on an analogue input. */ +/*extern UBaseType_t rand(); */ +#define ipconfigRAND32() rand() /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the -network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK -is not set to 1 then the network event hook will never be called. See -http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml -*/ -#define ipconfigUSE_NETWORK_EVENT_HOOK 1 + * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK + * is not set to 1 then the network event hook will never be called. See + * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml + */ +#define ipconfigUSE_NETWORK_EVENT_HOOK 1 /* Sockets have a send block time attribute. If FreeRTOS_sendto() is called but -a network buffer cannot be obtained then the calling task is held in the Blocked -state (so other tasks can continue to executed) until either a network buffer -becomes available or the send block time expires. If the send block time expires -then the send operation is aborted. The maximum allowable send block time is -capped to the value set by ipconfigMAX_SEND_BLOCK_TIME_TICKS. Capping the -maximum allowable send block time prevents prevents a deadlock occurring when -all the network buffers are in use and the tasks that process (and subsequently -free) the network buffers are themselves blocked waiting for a network buffer. -ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in -milliseconds can be converted to a time in ticks by dividing the time in -milliseconds by portTICK_PERIOD_MS. */ -#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000U / portTICK_PERIOD_MS ) + * a network buffer cannot be obtained then the calling task is held in the Blocked + * state (so other tasks can continue to executed) until either a network buffer + * becomes available or the send block time expires. If the send block time expires + * then the send operation is aborted. The maximum allowable send block time is + * capped to the value set by ipconfigMAX_SEND_BLOCK_TIME_TICKS. Capping the + * maximum allowable send block time prevents prevents a deadlock occurring when + * all the network buffers are in use and the tasks that process (and subsequently + * free) the network buffers are themselves blocked waiting for a network buffer. + * ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in + * milliseconds can be converted to a time in ticks by dividing the time in + * milliseconds by portTICK_PERIOD_MS. */ +#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000U / portTICK_PERIOD_MS ) /* If ipconfigUSE_DHCP is 1 then FreeRTOS+TCP will attempt to retrieve an IP -address, netmask, DNS server address and gateway address from a DHCP server. If -ipconfigUSE_DHCP is 0 then FreeRTOS+TCP will use a static IP address. The -stack will revert to using the static IP address even when ipconfigUSE_DHCP is -set to 1 if a valid configuration cannot be obtained from a DHCP server for any -reason. The static configuration used is that passed into the stack by the -FreeRTOS_IPInit() function call. */ -#define ipconfigUSE_DHCP 1 + * address, netmask, DNS server address and gateway address from a DHCP server. If + * ipconfigUSE_DHCP is 0 then FreeRTOS+TCP will use a static IP address. The + * stack will revert to using the static IP address even when ipconfigUSE_DHCP is + * set to 1 if a valid configuration cannot be obtained from a DHCP server for any + * reason. The static configuration used is that passed into the stack by the + * FreeRTOS_IPInit() function call. */ +#define ipconfigUSE_DHCP 1 /* When ipconfigUSE_DHCP is set to 1, DHCP requests will be sent out at -increasing time intervals until either a reply is received from a DHCP server -and accepted, or the interval between transmissions reaches -ipconfigMAXIMUM_DISCOVER_TX_PERIOD. The IP stack will revert to using the -static IP address passed as a parameter to FreeRTOS_IPInit() if the -re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without -a DHCP reply being received. */ -#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( 120000U / portTICK_PERIOD_MS ) + * increasing time intervals until either a reply is received from a DHCP server + * and accepted, or the interval between transmissions reaches + * ipconfigMAXIMUM_DISCOVER_TX_PERIOD. The IP stack will revert to using the + * static IP address passed as a parameter to FreeRTOS_IPInit() if the + * re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without + * a DHCP reply being received. */ +#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( 120000U / portTICK_PERIOD_MS ) /* The ARP cache is a table that maps IP addresses to MAC addresses. The IP -stack can only send a UDP message to a remove IP address if it knowns the MAC -address associated with the IP address, or the MAC address of the router used to -contact the remote IP address. When a UDP message is received from a remote IP -address the MAC address and IP address are added to the ARP cache. When a UDP -message is sent to a remote IP address that does not already appear in the ARP -cache then the UDP message is replaced by a ARP message that solicits the -required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum -number of entries that can exist in the ARP table at any one time. */ -#define ipconfigARP_CACHE_ENTRIES 6 + * stack can only send a UDP message to a remove IP address if it knowns the MAC + * address associated with the IP address, or the MAC address of the router used to + * contact the remote IP address. When a UDP message is received from a remote IP + * address the MAC address and IP address are added to the ARP cache. When a UDP + * message is sent to a remote IP address that does not already appear in the ARP + * cache then the UDP message is replaced by a ARP message that solicits the + * required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum + * number of entries that can exist in the ARP table at any one time. */ +#define ipconfigARP_CACHE_ENTRIES 6 /* ARP requests that do not result in an ARP response will be re-transmitted a -maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is -aborted. */ -#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 ) + * maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is + * aborted. */ +#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 ) /* ipconfigMAX_ARP_AGE defines the maximum time between an entry in the ARP -table being created or refreshed and the entry being removed because it is stale. -New ARP requests are sent for ARP cache entries that are nearing their maximum -age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is -equal to 1500 seconds (or 25 minutes). */ -#define ipconfigMAX_ARP_AGE 150 + * table being created or refreshed and the entry being removed because it is stale. + * New ARP requests are sent for ARP cache entries that are nearing their maximum + * age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is + * equal to 1500 seconds (or 25 minutes). */ +#define ipconfigMAX_ARP_AGE 150 /* Implementing FreeRTOS_inet_addr() necessitates the use of string handling -routines, which are relatively large. To save code space the full -FreeRTOS_inet_addr() implementation is made optional, and a smaller and faster -alternative called FreeRTOS_inet_addr_quick() is provided. FreeRTOS_inet_addr() -takes an IP in decimal dot format (for example, "192.168.0.1") as its parameter. -FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets -(for example, 192, 168, 0, 1) as its parameters. If -ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and -FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is -not set to 1 then only FreeRTOS_indet_addr_quick() is available. */ -#define ipconfigINCLUDE_FULL_INET_ADDR 1 + * routines, which are relatively large. To save code space the full + * FreeRTOS_inet_addr() implementation is made optional, and a smaller and faster + * alternative called FreeRTOS_inet_addr_quick() is provided. FreeRTOS_inet_addr() + * takes an IP in decimal dot format (for example, "192.168.0.1") as its parameter. + * FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets + * (for example, 192, 168, 0, 1) as its parameters. If + * ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and + * FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is + * not set to 1 then only FreeRTOS_indet_addr_quick() is available. */ +#define ipconfigINCLUDE_FULL_INET_ADDR 1 /* ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS defines the total number of network buffer that -are available to the IP stack. The total number of network buffers is limited -to ensure the total amount of RAM that can be consumed by the IP stack is capped -to a pre-determinable value. */ -#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60 + * are available to the IP stack. The total number of network buffers is limited + * to ensure the total amount of RAM that can be consumed by the IP stack is capped + * to a pre-determinable value. */ +#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60 /* A FreeRTOS queue is used to send events from application tasks to the IP -stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can -be queued for processing at any one time. The event queue must be a minimum of -5 greater than the total number of network buffers. */ -#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) + * stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can + * be queued for processing at any one time. The event queue must be a minimum of + * 5 greater than the total number of network buffers. */ +#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) /* The address of a socket is the combination of its IP address and its port -number. FreeRTOS_bind() is used to manually allocate a port number to a socket -(to 'bind' the socket to a port), but manual binding is not normally necessary -for client sockets (those sockets that initiate outgoing connections rather than -wait for incoming connections on a known port number). If -ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 then calling -FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP -stack automatically binding the socket to a port number from the range -socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If -ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto() -on a socket that has not yet been bound will result in the send operation being -aborted. */ -#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 + * number. FreeRTOS_bind() is used to manually allocate a port number to a socket + * (to 'bind' the socket to a port), but manual binding is not normally necessary + * for client sockets (those sockets that initiate outgoing connections rather than + * wait for incoming connections on a known port number). If + * ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 then calling + * FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP + * stack automatically binding the socket to a port number from the range + * socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If + * ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto() + * on a socket that has not yet been bound will result in the send operation being + * aborted. */ +#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 /* Defines the Time To Live (TTL) values used in outgoing UDP packets. */ -#define ipconfigUDP_TIME_TO_LIVE 128 -#define ipconfigTCP_TIME_TO_LIVE 128 /* also defined in FreeRTOSIPConfigDefaults.h */ +#define ipconfigUDP_TIME_TO_LIVE 128 +#define ipconfigTCP_TIME_TO_LIVE 128 /* also defined in FreeRTOSIPConfigDefaults.h */ /* USE_TCP: Use TCP and all its features */ -#define ipconfigUSE_TCP ( 1 ) +#define ipconfigUSE_TCP ( 1 ) /* USE_WIN: Let TCP use windowing mechanism. */ -#define ipconfigUSE_TCP_WIN ( 1 ) +#define ipconfigUSE_TCP_WIN ( 1 ) /* The MTU is the maximum number of bytes the payload of a network frame can -contain. For normal Ethernet V2 frames the maximum MTU is 1500. Setting a -lower value can save RAM, depending on the buffer management scheme used. If -ipconfigCAN_FRAGMENT_OUTGOING_PACKETS is 1 then (ipconfigNETWORK_MTU - 28) must -be divisible by 8. */ -#define ipconfigNETWORK_MTU 1200U + * contain. For normal Ethernet V2 frames the maximum MTU is 1500. Setting a + * lower value can save RAM, depending on the buffer management scheme used. If + * ipconfigCAN_FRAGMENT_OUTGOING_PACKETS is 1 then (ipconfigNETWORK_MTU - 28) must + * be divisible by 8. */ +#define ipconfigNETWORK_MTU 1200U /* Set ipconfigUSE_DNS to 1 to include a basic DNS client/resolver. DNS is used -through the FreeRTOS_gethostbyname() API function. */ -#define ipconfigUSE_DNS 1 + * through the FreeRTOS_gethostbyname() API function. */ +#define ipconfigUSE_DNS 1 /* If ipconfigREPLY_TO_INCOMING_PINGS is set to 1 then the IP stack will -generate replies to incoming ICMP echo (ping) requests. */ -#define ipconfigREPLY_TO_INCOMING_PINGS 1 + * generate replies to incoming ICMP echo (ping) requests. */ +#define ipconfigREPLY_TO_INCOMING_PINGS 1 /* If ipconfigSUPPORT_OUTGOING_PINGS is set to 1 then the -FreeRTOS_SendPingRequest() API function is available. */ -#define ipconfigSUPPORT_OUTGOING_PINGS 0 + * FreeRTOS_SendPingRequest() API function is available. */ +#define ipconfigSUPPORT_OUTGOING_PINGS 0 /* If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select() -(and associated) API function is available. */ -#define ipconfigSUPPORT_SELECT_FUNCTION 1 + * (and associated) API function is available. */ +#define ipconfigSUPPORT_SELECT_FUNCTION 1 /* If ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is set to 1 then Ethernet frames -that are not in Ethernet II format will be dropped. This option is included for -potential future IP stack developments. */ -#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1 + * that are not in Ethernet II format will be dropped. This option is included for + * potential future IP stack developments. */ +#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1 /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 then it is the -responsibility of the Ethernet interface to filter out packets that are of no -interest. If the Ethernet interface does not implement this functionality, then -set ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES to 0 to have the IP stack -perform the filtering instead (it is much less efficient for the stack to do it -because the packet will already have been passed into the stack). If the -Ethernet driver does all the necessary filtering in hardware then software -filtering can be removed by using a value other than 1 or 0. */ -#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 + * responsibility of the Ethernet interface to filter out packets that are of no + * interest. If the Ethernet interface does not implement this functionality, then + * set ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES to 0 to have the IP stack + * perform the filtering instead (it is much less efficient for the stack to do it + * because the packet will already have been passed into the stack). If the + * Ethernet driver does all the necessary filtering in hardware then software + * filtering can be removed by using a value other than 1 or 0. */ +#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 /* The windows simulator cannot really simulate MAC interrupts, and needs to -block occasionally to allow other tasks to run. */ -#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS ) + * block occasionally to allow other tasks to run. */ +#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS ) /* Advanced only: in order to access 32-bit fields in the IP packets with -32-bit memory instructions, all packets will be stored 32-bit-aligned, plus 16-bits. -This has to do with the contents of the IP-packets: all 32-bit fields are -32-bit-aligned, plus 16-bit(!) */ -#define ipconfigPACKET_FILLER_SIZE 2U + * 32-bit memory instructions, all packets will be stored 32-bit-aligned, plus 16-bits. + * This has to do with the contents of the IP-packets: all 32-bit fields are + * 32-bit-aligned, plus 16-bit(!) */ +#define ipconfigPACKET_FILLER_SIZE 2U /* Define the size of the pool of TCP window descriptors. On the average, each -TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6 -outstanding packets (for Rx and Tx). When using up to 10 TP sockets -simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */ -#define ipconfigTCP_WIN_SEG_COUNT 240 + * TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6 + * outstanding packets (for Rx and Tx). When using up to 10 TP sockets + * simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */ +#define ipconfigTCP_WIN_SEG_COUNT 240 /* Each TCP socket has a circular buffers for Rx and Tx, which have a fixed -maximum size. Define the size of Rx buffer for TCP sockets. */ -#define ipconfigTCP_RX_BUFFER_LENGTH ( 1000 ) + * maximum size. Define the size of Rx buffer for TCP sockets. */ +#define ipconfigTCP_RX_BUFFER_LENGTH ( 1000 ) /* Define the size of Tx buffer for TCP sockets. */ -#define ipconfigTCP_TX_BUFFER_LENGTH ( 1000 ) +#define ipconfigTCP_TX_BUFFER_LENGTH ( 1000 ) /* When using call-back handlers, the driver may check if the handler points to -real program memory (RAM or flash) or just has a random non-zero value. */ -#define ipconfigIS_VALID_PROG_ADDRESS(x) ( (x) != NULL ) + * real program memory (RAM or flash) or just has a random non-zero value. */ +#define ipconfigIS_VALID_PROG_ADDRESS( x ) ( ( x ) != NULL ) /* Include support for TCP hang protection. All sockets in a connecting or -disconnecting stage will timeout after a period of non-activity. */ -#define ipconfigTCP_HANG_PROTECTION ( 1 ) -#define ipconfigTCP_HANG_PROTECTION_TIME ( 30 ) + * disconnecting stage will timeout after a period of non-activity. */ +#define ipconfigTCP_HANG_PROTECTION ( 1 ) +#define ipconfigTCP_HANG_PROTECTION_TIME ( 30 ) /* Include support for TCP keep-alive messages. */ -#define ipconfigTCP_KEEP_ALIVE ( 1 ) -#define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20 ) /* in seconds */ +#define ipconfigTCP_KEEP_ALIVE ( 1 ) +#define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20 ) /* in seconds */ -#define portINLINE __inline +#define portINLINE __inline #endif /* FREERTOS_IP_CONFIG_H */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Full-TCP-Networkless.sln b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Full-TCP-Networkless.sln index f907d968a..ae4add02d 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Full-TCP-Networkless.sln +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Full-TCP-Networkless.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}" diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/ReadMe.txt b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/ReadMe.txt index 6039423b8..5838e7bf1 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/ReadMe.txt +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/ReadMe.txt @@ -11,7 +11,7 @@ This project is a version of the standard FreeRTOS demos that includes the integration tests of +TCP. It tests 4 functions in the TCP source code. To Run this project, make sure that the computer is connected to a network via ethernet cable. Open the project (using file named "FreeRTOS_Plus_TCP_Integration_Tests.sln") and -choose the required network interface by modifying this line #define +choose the required network interface by modifying this line #define configNETWORK_INTERFACE_TO_USE in FreeRTOSConfig.h. Once these changes are made, just build and run the project. It should run 4 test diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_declare.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_declare.h index d8c8cce9c..7c574a110 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_declare.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_declare.h @@ -1,6 +1,6 @@ /* - * FreeRTOS+TCP V2.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #ifndef _FREERTOS_TCP_TEST_ACCESS_DECLARE_H_ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_dns_define.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_dns_define.h index df6997f89..4cc2995c3 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_dns_define.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_dns_define.h @@ -1,6 +1,6 @@ /* - * FreeRTOS+TCP V2.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /** diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_tcp_define.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_tcp_define.h index 7ee0dd3ee..74b5657b0 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_tcp_define.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/freertos_tcp_test_access_tcp_define.h @@ -1,6 +1,6 @@ /* - * FreeRTOS+TCP V2.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /** diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/test_freertos_tcp.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/test_freertos_tcp.c index fa0d087bd..05a459697 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/test_freertos_tcp.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Cases/test_freertos_tcp.c @@ -1,6 +1,6 @@ /* - * FreeRTOS+TCP V2.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /* Standard includes. */ @@ -344,18 +345,18 @@ TEST( Full_FREERTOS_TCP, UDPPacketLength ) uint16_t usPort = 65535; NetworkBufferDescriptor_t xNetworkBuffer; - /* This test fails now since there is an assert + /* This test fails now since there is an assert * checking for NULL pucEthernetBuffer. Also, the * next tests do not run and this whole test case * is scrapped. - - xNetworkBuffer.pucEthernetBuffer = NULL; - xNetworkBuffer.xDataLength = 0; - - xReturn = xProcessReceivedUDPPacket( &xNetworkBuffer, usPort ); - TEST_ASSERT_EQUAL_UINT32_MESSAGE( pdFAIL, xReturn, "Failed to parse 0 size packet" ); + * + * xNetworkBuffer.pucEthernetBuffer = NULL; + * xNetworkBuffer.xDataLength = 0; + * + * xReturn = xProcessReceivedUDPPacket( &xNetworkBuffer, usPort ); + * TEST_ASSERT_EQUAL_UINT32_MESSAGE( pdFAIL, xReturn, "Failed to parse 0 size packet" ); */ - + xNetworkBuffer.pucEthernetBuffer = ucBadUdpPacketA; xNetworkBuffer.xDataLength = sizeof( ucBadUdpPacketA ); diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner.c index e0e483fa6..e7c2b605d 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,16 +19,17 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ - /** - * @file aws_test_runner.c - * @brief The function to be called to run all the tests. - */ +/** + * @file aws_test_runner.c + * @brief The function to be called to run all the tests. + */ - /* Test runner interface includes. */ +/* Test runner interface includes. */ #include "test_runner.h" /* FreeRTOS includes. */ @@ -39,7 +40,7 @@ #include "unity_fixture.h" #include "unity_internals.h" -char cBuffer[testrunnerBUFFER_SIZE]; +char cBuffer[ testrunnerBUFFER_SIZE ]; /* Heap leak variables. */ unsigned int xHeapBefore; @@ -50,16 +51,16 @@ unsigned int xHeapAfter; * do not change the signature of it. You could, however, add or remove * RUN_TEST_GROUP statements. */ -static void RunTests(void) +static void RunTests( void ) { - RUN_TEST_GROUP(Full_FREERTOS_TCP); + RUN_TEST_GROUP( Full_FREERTOS_TCP ); } /*-----------------------------------------------------------*/ -void TEST_RUNNER_RunTests_task(void* pvParameters) +void TEST_RUNNER_RunTests_task( void * pvParameters ) { /* Disable unused parameter warning. */ - (void)pvParameters; + ( void ) pvParameters; /* Initialize unity. */ UnityFixture.Verbose = 1; @@ -70,39 +71,39 @@ void TEST_RUNNER_RunTests_task(void* pvParameters) UNITY_BEGIN(); /* Give the print buffer time to empty */ - vTaskDelay(pdMS_TO_TICKS(500)); + vTaskDelay( pdMS_TO_TICKS( 500 ) ); /* Measure the heap size before any tests are run. */ -#if ( testrunnerFULL_MEMORYLEAK_ENABLED == 1 ) - xHeapBefore = xPortGetFreeHeapSize(); -#endif + #if ( testrunnerFULL_MEMORYLEAK_ENABLED == 1 ) + xHeapBefore = xPortGetFreeHeapSize(); + #endif RunTests(); -#if ( testrunnerFULL_MEMORYLEAK_ENABLED == 1 ) + #if ( testrunnerFULL_MEMORYLEAK_ENABLED == 1 ) - /* Measure the heap size after tests are done running. - * This test must run last. */ + /* Measure the heap size after tests are done running. + * This test must run last. */ - /* Perform any global resource cleanup necessary to avoid memory leaks. */ -#ifdef testrunnerMEMORYLEAK_CLEANUP - testrunnerMEMORYLEAK_CLEANUP(); -#endif + /* Perform any global resource cleanup necessary to avoid memory leaks. */ + #ifdef testrunnerMEMORYLEAK_CLEANUP + testrunnerMEMORYLEAK_CLEANUP(); + #endif - /* Give the print buffer time to empty */ - vTaskDelay(pdMS_TO_TICKS(500)); - xHeapAfter = xPortGetFreeHeapSize(); - RUN_TEST_GROUP(Full_MemoryLeak); -#endif /* if ( testrunnerFULL_MEMORYLEAK_ENABLED == 1 ) */ + /* Give the print buffer time to empty */ + vTaskDelay( pdMS_TO_TICKS( 500 ) ); + xHeapAfter = xPortGetFreeHeapSize(); + RUN_TEST_GROUP( Full_MemoryLeak ); + #endif /* if ( testrunnerFULL_MEMORYLEAK_ENABLED == 1 ) */ /* Currently disabled. Will be enabled after cleanup. */ UNITY_END(); -#ifdef CODE_COVERAGE - exit(0); -#endif + #ifdef CODE_COVERAGE + exit( 0 ); + #endif /* This task has finished. FreeRTOS does not allow a task to run off the * end of its implementing function, so the task must be deleted. */ - vTaskDelete(NULL); + vTaskDelete( NULL ); } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner.h index ca1f59222..ed3c1cef9 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,42 +19,43 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ - /** - * @file aws_test_runner.h - * @brief The function to be called to run all the tests. - */ +/** + * @file aws_test_runner.h + * @brief The function to be called to run all the tests. + */ #ifndef _TEST_RUNNER_H_ #define _TEST_RUNNER_H_ #include "test_runner_config.h" - /* - * @brief If set to 1, will run DQP_FR tests only. - */ +/* + * @brief If set to 1, will run DQP_FR tests only. + */ #ifdef testrunnerAFQP_ENABLED -#define testrunnerTEST_FILTER "AFQP" + #define testrunnerTEST_FILTER "AFQP" #else -#define testrunnerTEST_FILTER 0 + #define testrunnerTEST_FILTER 0 #endif - /** - * @brief Size of shared array. - * - */ +/** + * @brief Size of shared array. + * + */ #define testrunnerBUFFER_SIZE ( 4000 ) - /** - * @brief Buffer used for all tests. - * - * Since tests are run in series, they can use the same memory array. - * This makes significant heap savings. - */ -extern char cBuffer[testrunnerBUFFER_SIZE]; +/** + * @brief Buffer used for all tests. + * + * Since tests are run in series, they can use the same memory array. + * This makes significant heap savings. + */ +extern char cBuffer[ testrunnerBUFFER_SIZE ]; /** * @brief FreeRTOS heap measurement taken before tests are run. @@ -70,7 +71,7 @@ extern unsigned int xHeapAfter; /** * @brief Runs all the tests. */ -void TEST_RUNNER_RunTests_task(void* pvParameters); +void TEST_RUNNER_RunTests_task( void * pvParameters ); diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner_config.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner_config.h index d30e75904..69a483ca6 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner_config.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/Test_code/Test_Runner/test_runner_config.h @@ -1,38 +1,38 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #ifndef AWS_TEST_RUNNER_CONFIG_H #define AWS_TEST_RUNNER_CONFIG_H - /* Uncomment this line if you want to run DQP_FR tests only. */ - /* #define testrunnerAFQP_ENABLED */ +/* Uncomment this line if you want to run DQP_FR tests only. */ +/* #define testrunnerAFQP_ENABLED */ #define testrunnerUNSUPPORTED 0 -#define FREERTOS_ENABLE_UNIT_TESTS 1 +#define FREERTOS_ENABLE_UNIT_TESTS 1 /* Unsupported tests. */ #define testrunnerFULL_WIFI_ENABLED testrunnerUNSUPPORTED @@ -69,8 +69,8 @@ /* On systems using FreeRTOS+TCP (such as this one) the TCP segments must be * cleaned up before running the memory leak check. */ #if ( testrunnerFULL_MEMORYLEAK_ENABLED == 1 ) -extern void vTCPSegmentCleanup(); -#define testrunnerMEMORYLEAK_CLEANUP() vTCPSegmentCleanup() + extern void vTCPSegmentCleanup(); + #define testrunnerMEMORYLEAK_CLEANUP() vTCPSegmentCleanup() #endif #endif /* AWS_TEST_RUNNER_CONFIG_H */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/Packet32.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/Packet32.h index 64be055d9..f6b7b27aa 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/Packet32.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/Packet32.h @@ -12,9 +12,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino, CACE Technologies - * nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,7 +32,7 @@ */ /** @ingroup packetapi - * @{ + * @{ */ /** @defgroup packet32h Packet.dll definitions and data structures @@ -43,317 +43,356 @@ */ #ifndef __PACKET32 -#define __PACKET32 + #define __PACKET32 -#include + #include -#ifdef HAVE_AIRPCAP_API -#include -#else -#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) -#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ -typedef struct _AirpcapHandle *PAirpcapHandle; -#endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */ -#endif /* HAVE_AIRPCAP_API */ + #ifdef HAVE_AIRPCAP_API + #include + #else + #if !defined( AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ ) + #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ + typedef struct _AirpcapHandle * PAirpcapHandle; + #endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */ + #endif /* HAVE_AIRPCAP_API */ -#ifdef HAVE_DAG_API -#include -#endif /* HAVE_DAG_API */ + #ifdef HAVE_DAG_API + #include + #endif /* HAVE_DAG_API */ -// Working modes -#define PACKET_MODE_CAPT 0x0 ///< Capture mode -#define PACKET_MODE_STAT 0x1 ///< Statistical mode -#define PACKET_MODE_MON 0x2 ///< Monitoring mode -#define PACKET_MODE_DUMP 0x10 ///< Dump mode -#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode +/* Working modes */ + #define PACKET_MODE_CAPT 0x0 /*/< Capture mode */ + #define PACKET_MODE_STAT 0x1 /*/< Statistical mode */ + #define PACKET_MODE_MON 0x2 /*/< Monitoring mode */ + #define PACKET_MODE_DUMP 0x10 /*/< Dump mode */ + #define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT /*/< Statistical dump Mode */ -/// Alignment macro. Defines the alignment size. -#define Packet_ALIGNMENT sizeof(int) -/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. -#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) +/*/ Alignment macro. Defines the alignment size. */ + #define Packet_ALIGNMENT sizeof( int ) +/*/ Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. */ + #define Packet_WORDALIGN( x ) ( ( ( x ) + ( Packet_ALIGNMENT - 1 ) ) & ~( Packet_ALIGNMENT - 1 ) ) -#define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumPpi -6 ///< Custom linktype: NDIS doesn't provide an equivalent + #define NdisMediumNull -1 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumCHDLC -2 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumPPPSerial -3 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumBare80211 -4 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumRadio80211 -5 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumPpi -6 /*/< Custom linktype: NDIS doesn't provide an equivalent */ -// Loopback behaviour definitions -#define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver -#define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver +/* Loopback behaviour definitions */ + #define NPF_DISABLE_LOOPBACK 1 /*/< Drop the packets sent by the NPF driver */ + #define NPF_ENABLE_LOOPBACK 2 /*/< Capture the packets sent by the NPF driver */ /*! - \brief Network type structure. - - This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. -*/ -typedef struct NetType -{ - UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information) - ULONGLONG LinkSpeed; ///< The speed of the network in bits per second -}NetType; + * \brief Network type structure. + * + * This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. + */ + typedef struct NetType + { + UINT LinkType; /*/< The MAC of the current network adapter (see function PacketGetNetType() for more information) */ + ULONGLONG LinkSpeed; /*/< The speed of the network in bits per second */ + } NetType; -//some definitions stolen from libpcap +/*some definitions stolen from libpcap */ -#ifndef BPF_MAJOR_VERSION + #ifndef BPF_MAJOR_VERSION /*! - \brief A BPF pseudo-assembly program. - - The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. -*/ -struct bpf_program -{ - UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. - struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program. -}; + * \brief A BPF pseudo-assembly program. + * + * The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. + */ + struct bpf_program + { + UINT bf_len; /*/< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. */ + struct bpf_insn * bf_insns; /*/< A pointer to the first instruction of the program. */ + }; /*! - \brief A single BPF pseudo-instruction. - - bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. -*/ -struct bpf_insn -{ - USHORT code; ///< Instruction type and addressing mode. - UCHAR jt; ///< Jump if true - UCHAR jf; ///< Jump if false - int k; ///< Generic field used for various purposes. -}; + * \brief A single BPF pseudo-instruction. + * + * bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. + */ + struct bpf_insn + { + USHORT code; /*/< Instruction type and addressing mode. */ + UCHAR jt; /*/< Jump if true */ + UCHAR jf; /*/< Jump if false */ + int k; /*/< Generic field used for various purposes. */ + }; /*! - \brief Structure that contains a couple of statistics values on the current capture. - - It is used by packet.dll to return statistics about a capture session. -*/ -struct bpf_stat -{ - UINT bs_recv; ///< Number of packets that the driver received from the network adapter - ///< from the beginning of the current capture. This value includes the packets - ///< lost by the driver. - UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture. - ///< Basically, a packet is lost when the the buffer of the driver is full. - ///< In this situation the packet cannot be stored and the driver rejects it. - UINT ps_ifdrop; ///< drops by interface. XXX not yet supported - UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and - ///< thus reach the application. -}; + * \brief Structure that contains a couple of statistics values on the current capture. + * + * It is used by packet.dll to return statistics about a capture session. + */ + struct bpf_stat + { + UINT bs_recv; /*/< Number of packets that the driver received from the network adapter */ + /*/< from the beginning of the current capture. This value includes the packets */ + /*/< lost by the driver. */ + UINT bs_drop; /*/< number of packets that the driver lost from the beginning of a capture. */ + /*/< Basically, a packet is lost when the the buffer of the driver is full. */ + /*/< In this situation the packet cannot be stored and the driver rejects it. */ + UINT ps_ifdrop; /*/< drops by interface. XXX not yet supported */ + UINT bs_capt; /*/< number of packets that pass the filter, find place in the kernel buffer and */ + /*/< thus reach the application. */ + }; /*! - \brief Packet header. - - This structure defines the header associated with every packet delivered to the application. -*/ -struct bpf_hdr -{ - struct timeval bh_tstamp; ///< The timestamp associated with the captured packet. - ///< It is stored in a TimeVal structure. - UINT bh_caplen; ///< Length of captured portion. The captured portion can be different - ///< from the original packet, because it is possible (with a proper filter) - ///< to instruct the driver to capture only a portion of the packets. - UINT bh_datalen; ///< Original length of packet - USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases, - ///< a padding could be added between the end of this structure and the packet - ///< data for performance reasons. This filed can be used to retrieve the actual data - ///< of the packet. -}; + * \brief Packet header. + * + * This structure defines the header associated with every packet delivered to the application. + */ + struct bpf_hdr + { + struct timeval bh_tstamp; /*/< The timestamp associated with the captured packet. */ + /*/< It is stored in a TimeVal structure. */ + UINT bh_caplen; /*/< Length of captured portion. The captured portion can be different */ + /*/< from the original packet, because it is possible (with a proper filter) */ + /*/< to instruct the driver to capture only a portion of the packets. */ + UINT bh_datalen; /*/< Original length of packet */ + USHORT bh_hdrlen; /*/< Length of bpf header (this struct plus alignment padding). In some cases, */ + /*/< a padding could be added between the end of this structure and the packet */ + /*/< data for performance reasons. This filed can be used to retrieve the actual data */ + /*/< of the packet. */ + }; /*! - \brief Dump packet header. - - This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). - It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a - packet in a dump file. This makes straightforward sending WinPcap dump files to the network. -*/ -struct dump_bpf_hdr{ - struct timeval ts; ///< Time stamp of the packet - UINT caplen; ///< Length of captured portion. The captured portion can smaller than the - ///< the original packet, because it is possible (with a proper filter) to - ///< instruct the driver to capture only a portion of the packets. - UINT len; ///< Length of the original packet (off wire). -}; + * \brief Dump packet header. + * + * This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). + * It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a + * packet in a dump file. This makes straightforward sending WinPcap dump files to the network. + */ + struct dump_bpf_hdr + { + struct timeval ts; /*/< Time stamp of the packet */ + UINT caplen; /*/< Length of captured portion. The captured portion can smaller than the */ + /*/< the original packet, because it is possible (with a proper filter) to */ + /*/< instruct the driver to capture only a portion of the packets. */ + UINT len; /*/< Length of the original packet (off wire). */ + }; -#endif + #endif /* ifndef BPF_MAJOR_VERSION */ -struct bpf_stat; + struct bpf_stat; -#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices -#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links -#define NMAX_PACKET 65535 + #define DOSNAMEPREFIX TEXT( "Packet_" ) /*/< Prefix added to the adapters device names to create the WinPcap devices */ + #define MAX_LINK_NAME_LENGTH 64 /*< Maximum length of the devices symbolic links */ + #define NMAX_PACKET 65535 /*! - \brief Addresses of a network adapter. - - This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with - an adapter. -*/ -typedef struct npf_if_addr { - struct sockaddr_storage IPAddress; ///< IP address. - struct sockaddr_storage SubnetMask; ///< Netmask for that address. - struct sockaddr_storage Broadcast; ///< Broadcast address. -}npf_if_addr; + * \brief Addresses of a network adapter. + * + * This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with + * an adapter. + */ + typedef struct npf_if_addr + { + struct sockaddr_storage IPAddress; /*/< IP address. */ + struct sockaddr_storage SubnetMask; /*/< Netmask for that address. */ + struct sockaddr_storage Broadcast; /*/< Broadcast address. */ + } npf_if_addr; -#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API. -#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API. -#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. -#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. + #define ADAPTER_NAME_LENGTH 256 + 12 /*/< Maximum length for the name of an adapter. The value is the same used by the IP Helper API. */ + #define ADAPTER_DESC_LENGTH 128 /*/< Maximum length for the description of an adapter. The value is the same used by the IP Helper API. */ + #define MAX_MAC_ADDR_LENGTH 8 /*/< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. */ + #define MAX_NETWORK_ADDRESSES 16 /*/< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. */ -typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API -typedef WAN_ADAPTER *PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API + typedef struct WAN_ADAPTER_INT WAN_ADAPTER; /*/< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API */ + typedef WAN_ADAPTER * PWAN_ADAPTER; /*/< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API */ -#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter -#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET -#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card -#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file -#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones. -#define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card -#define INFO_FLAG_NPFIM_DEVICE 32 + #define INFO_FLAG_NDIS_ADAPTER 0 /*/< Flag for ADAPTER_INFO: this is a traditional ndis adapter */ + #define INFO_FLAG_NDISWAN_ADAPTER 1 /*/< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET */ + #define INFO_FLAG_DAG_CARD 2 /*/< Flag for ADAPTER_INFO: this is a DAG card */ + #define INFO_FLAG_DAG_FILE 6 /*/< Flag for ADAPTER_INFO: this is a DAG file */ + #define INFO_FLAG_DONT_EXPORT 8 /*/< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones. */ + #define INFO_FLAG_AIRPCAP_CARD 16 /*/< Flag for ADAPTER_INFO: this is an airpcap card */ + #define INFO_FLAG_NPFIM_DEVICE 32 /*! - \brief Describes an opened network adapter. + * \brief Describes an opened network adapter. + * + * This structure is the most important for the functioning of packet.dll, but the great part of its fields + * should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters + */ + typedef struct _ADAPTER + { + HANDLE hFile; /*/< \internal Handle to an open instance of the NPF driver. */ + CHAR SymbolicLink[ MAX_LINK_NAME_LENGTH ]; /*/< \internal A string containing the name of the network adapter currently opened. */ + int NumWrites; /*/< \internal Number of times a packets written on this adapter will be repeated */ + /*/< on the wire. */ + HANDLE ReadEvent; /*/< A notification event associated with the read calls on the adapter. */ + /*/< It can be passed to standard Win32 functions (like WaitForSingleObject */ + /*/< or WaitForMultipleObjects) to wait until the driver's buffer contains some */ + /*/< data. It is particularly useful in GUI applications that need to wait */ + /*/< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() */ + /*/< function can be used to define the minimum amount of data in the kernel buffer */ + /*/< that will cause the event to be signalled. */ - This structure is the most important for the functioning of packet.dll, but the great part of its fields - should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters -*/ -typedef struct _ADAPTER { - HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver. - CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened. - int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated - ///< on the wire. - HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter. - ///< It can be passed to standard Win32 functions (like WaitForSingleObject - ///< or WaitForMultipleObjects) to wait until the driver's buffer contains some - ///< data. It is particularly useful in GUI applications that need to wait - ///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() - ///< function can be used to define the minimum amount of data in the kernel buffer - ///< that will cause the event to be signalled. - - UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and - ///< ReadEvent will be signaled, also if no packets were captured - CHAR Name[ADAPTER_NAME_LENGTH]; - PWAN_ADAPTER pWanAdapter; - UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. + UINT ReadTimeOut; /*/< \internal The amount of time after which a read on the driver will be released and */ + /*/< ReadEvent will be signaled, also if no packets were captured */ + CHAR Name[ ADAPTER_NAME_LENGTH ]; + PWAN_ADAPTER pWanAdapter; + UINT Flags; /*/< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. */ -#ifdef HAVE_AIRPCAP_API - PAirpcapHandle AirpcapAd; -#endif // HAVE_AIRPCAP_API + #ifdef HAVE_AIRPCAP_API + PAirpcapHandle AirpcapAd; + #endif // HAVE_AIRPCAP_API -#ifdef HAVE_NPFIM_API - void* NpfImHandle; -#endif // HAVE_NPFIM_API + #ifdef HAVE_NPFIM_API + void * NpfImHandle; + #endif // HAVE_NPFIM_API -#ifdef HAVE_DAG_API - dagc_t *pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter - PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card - struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure - unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry - DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps). -#endif // HAVE_DAG_API -} ADAPTER, *LPADAPTER; + #ifdef HAVE_DAG_API + dagc_t * pDagCard; /*/< Pointer to the dagc API adapter descriptor for this adapter */ + PCHAR DagBuffer; /*/< Pointer to the buffer with the packets that is received from the DAG card */ + struct timeval DagReadTimeout; /*/< Read timeout. The dagc API requires a timeval structure */ + unsigned DagFcsLen; /*/< Length of the frame check sequence attached to any packet by the card. Obtained from the registry */ + DWORD DagFastProcess; /*/< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps). */ + #endif // HAVE_DAG_API + } ADAPTER, * LPADAPTER; /*! - \brief Structure that contains a group of packets coming from the driver. - - This structure defines the header associated with every packet delivered to the application. -*/ -typedef struct _PACKET { - HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications. - OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications. - PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for - ///< details about the organization of the data in this buffer - UINT Length; ///< Length of the buffer - DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data - ///< received by the last call to PacketReceivePacket() - BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications. -} PACKET, *LPPACKET; + * \brief Structure that contains a group of packets coming from the driver. + * + * This structure defines the header associated with every packet delivered to the application. + */ + typedef struct _PACKET + { + HANDLE hEvent; /*/< \deprecated Still present for compatibility with old applications. */ + OVERLAPPED OverLapped; /*/< \deprecated Still present for compatibility with old applications. */ + PVOID Buffer; /*/< Buffer with containing the packets. See the PacketReceivePacket() for */ + /*/< details about the organization of the data in this buffer */ + UINT Length; /*/< Length of the buffer */ + DWORD ulBytesReceived; /*/< Number of valid bytes present in the buffer, i.e. amount of data */ + /*/< received by the last call to PacketReceivePacket() */ + BOOLEAN bIoComplete; /*/< \deprecated Still present for compatibility with old applications. */ + } PACKET, * LPPACKET; /*! - \brief Structure containing an OID request. + * \brief Structure containing an OID request. + * + * It is used by the PacketRequest() function to send an OID to the interface card driver. + * It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, + * the list of the multicast groups defined on it, and so on. + */ + struct _PACKET_OID_DATA + { + ULONG Oid; /*/< OID code. See the Microsoft DDK documentation or the file ntddndis.h */ + /*/< for a complete list of valid codes. */ + ULONG Length; /*/< Length of the data field */ + UCHAR Data[ 1 ]; /*/< variable-length field that contains the information passed to or received */ + /*/< from the adapter. */ + }; + typedef struct _PACKET_OID_DATA PACKET_OID_DATA, * PPACKET_OID_DATA; - It is used by the PacketRequest() function to send an OID to the interface card driver. - It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, - the list of the multicast groups defined on it, and so on. -*/ -struct _PACKET_OID_DATA { - ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h - ///< for a complete list of valid codes. - ULONG Length; ///< Length of the data field - UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received - ///< from the adapter. -}; -typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; - -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /** * @} */ /* -BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, - CHAR *Value, - UINT *pValueLen, - CHAR *DefaultVal); + * BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, + * CHAR *Value, + * UINT *pValueLen, + * CHAR *DefaultVal); + * + * BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, + * WCHAR *Value, + * UINT *pValueLen, + * WCHAR *DefaultVal); + */ -BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, - WCHAR *Value, - UINT *pValueLen, - WCHAR *DefaultVal); -*/ - -//--------------------------------------------------------------------------- -// EXPORTED FUNCTIONS -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- */ +/* EXPORTED FUNCTIONS */ +/*--------------------------------------------------------------------------- */ -PCHAR PacketGetVersion(); -PCHAR PacketGetDriverVersion(); -BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes); -BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites); -BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode); -BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout); -BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp); -BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior); -INT PacketSetSnapLen(LPADAPTER AdapterObject,int snaplen); -BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s); -BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s); -BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim); -BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type); -LPADAPTER PacketOpenAdapter(PCHAR AdapterName); -BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync); -INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync); -LPPACKET PacketAllocatePacket(void); -VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length); -VOID PacketFreePacket(LPPACKET lpPacket); -BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync); -BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter); -BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize); -BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries); -BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData); -HANDLE PacketGetReadEvent(LPADAPTER AdapterObject); -BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len); -BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks); -BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync); -BOOL PacketStopDriver(); -VOID PacketCloseAdapter(LPADAPTER lpAdapter); -BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength); -BOOLEAN PacketStartOemEx(PCHAR errorString, UINT errorStringLength, ULONG flags); -PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject); + PCHAR PacketGetVersion(); + PCHAR PacketGetDriverVersion(); + BOOLEAN PacketSetMinToCopy( LPADAPTER AdapterObject, + int nbytes ); + BOOLEAN PacketSetNumWrites( LPADAPTER AdapterObject, + int nwrites ); + BOOLEAN PacketSetMode( LPADAPTER AdapterObject, + int mode ); + BOOLEAN PacketSetReadTimeout( LPADAPTER AdapterObject, + int timeout ); + BOOLEAN PacketSetBpf( LPADAPTER AdapterObject, + struct bpf_program * fp ); + BOOLEAN PacketSetLoopbackBehavior( LPADAPTER AdapterObject, + UINT LoopbackBehavior ); + INT PacketSetSnapLen( LPADAPTER AdapterObject, + int snaplen ); + BOOLEAN PacketGetStats( LPADAPTER AdapterObject, + struct bpf_stat * s ); + BOOLEAN PacketGetStatsEx( LPADAPTER AdapterObject, + struct bpf_stat * s ); + BOOLEAN PacketSetBuff( LPADAPTER AdapterObject, + int dim ); + BOOLEAN PacketGetNetType( LPADAPTER AdapterObject, + NetType * type ); + LPADAPTER PacketOpenAdapter( PCHAR AdapterName ); + BOOLEAN PacketSendPacket( LPADAPTER AdapterObject, + LPPACKET pPacket, + BOOLEAN Sync ); + INT PacketSendPackets( LPADAPTER AdapterObject, + PVOID PacketBuff, + ULONG Size, + BOOLEAN Sync ); + LPPACKET PacketAllocatePacket( void ); + VOID PacketInitPacket( LPPACKET lpPacket, + PVOID Buffer, + UINT Length ); + VOID PacketFreePacket( LPPACKET lpPacket ); + BOOLEAN PacketReceivePacket( LPADAPTER AdapterObject, + LPPACKET lpPacket, + BOOLEAN Sync ); + BOOLEAN PacketSetHwFilter( LPADAPTER AdapterObject, + ULONG Filter ); + BOOLEAN PacketGetAdapterNames( PTSTR pStr, + PULONG BufferSize ); + BOOLEAN PacketGetNetInfoEx( PCHAR AdapterName, + npf_if_addr * buffer, + PLONG NEntries ); + BOOLEAN PacketRequest( LPADAPTER AdapterObject, + BOOLEAN Set, + PPACKET_OID_DATA OidData ); + HANDLE PacketGetReadEvent( LPADAPTER AdapterObject ); + BOOLEAN PacketSetDumpName( LPADAPTER AdapterObject, + void * name, + int len ); + BOOLEAN PacketSetDumpLimits( LPADAPTER AdapterObject, + UINT maxfilesize, + UINT maxnpacks ); + BOOLEAN PacketIsDumpEnded( LPADAPTER AdapterObject, + BOOLEAN sync ); + BOOL PacketStopDriver(); + VOID PacketCloseAdapter( LPADAPTER lpAdapter ); + BOOLEAN PacketStartOem( PCHAR errorString, + UINT errorStringLength ); + BOOLEAN PacketStartOemEx( PCHAR errorString, + UINT errorStringLength, + ULONG flags ); + PAirpcapHandle PacketGetAirPcapHandle( LPADAPTER AdapterObject ); -// -// Used by PacketStartOemEx -// -#define PACKET_START_OEM_NO_NETMON 0x00000001 +/* */ +/* Used by PacketStartOemEx */ +/* */ + #define PACKET_START_OEM_NO_NETMON 0x00000001 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif //__PACKET32 diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/PacketData.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/PacketData.h index dd3d225e4..5c082687a 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/PacketData.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/PacketData.h @@ -1,249 +1,273 @@ -char pkt1[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x30, 0x09, 0x9c, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x07, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc7, 0x35, 0x00, 0x00, 0x00, 0x00, 0x70, 0x02, -0x40, 0x00, 0xdf, 0xab, 0x00, 0x00, 0x02, 0x04, -0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 }; +char pkt1[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x30, 0x09, 0x9c, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x07, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc7, 0x35, 0x00, 0x00, 0x00, 0x00, 0x70, 0x02, + 0x40, 0x00, 0xdf, 0xab, 0x00, 0x00, 0x02, 0x04, + 0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 +}; -char pkt2[] = { -0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, -0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, -0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, -0xf8, 0xa6, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, -0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, -0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, -0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, -0x05, 0x92 }; +char pkt2[] = +{ + 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, + 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, + 0xf8, 0xa6, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, + 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, + 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, + 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, + 0x05, 0x92 +}; -char pkt3[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0x9e, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, -0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; +char pkt3[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0x9e, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt4[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x02, 0x27, 0x09, 0x9f, 0x40, 0x00, 0x80, 0x06, -0x6d, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18, -0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45, -0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, -0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, -0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d, -0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c, -0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, -0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, -0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, -0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d, -0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65, -0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, -0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, -0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78, -0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c, -0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, -0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, -0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65, -0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20, -0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, -0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, -0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, -0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70, -0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, -0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78, -0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, -0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d, -0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, -0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, -0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, -0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, -0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a, -0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, -0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, -0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64, -0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a, -0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, -0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, -0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20, -0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, -0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49, -0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57, -0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e, -0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53, -0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67, -0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e, -0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32, -0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37, -0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, -0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30, -0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38, -0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, -0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32, -0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48, -0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, -0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, -0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, -0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, -0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, -0x65, 0x0d, 0x0a, 0x0d, 0x0a }; +char pkt4[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x02, 0x27, 0x09, 0x9f, 0x40, 0x00, 0x80, 0x06, + 0x6d, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18, + 0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45, + 0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, + 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c, + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, + 0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, + 0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, + 0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65, + 0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78, + 0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, + 0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65, + 0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, + 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78, + 0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, + 0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, + 0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, + 0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64, + 0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a, + 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, + 0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20, + 0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49, + 0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e, + 0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53, + 0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e, + 0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32, + 0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37, + 0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, + 0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30, + 0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38, + 0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, + 0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32, + 0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48, + 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, + 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, + 0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, + 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, + 0x65, 0x0d, 0x0a, 0x0d, 0x0a +}; -char pkt5[] = { -0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, -0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, -0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x40, 0x06, -0xf8, 0xa5, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, -0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, -0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, -0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, -0x05, 0x92 }; +char pkt5[] = +{ + 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, + 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x40, 0x06, + 0xf8, 0xa5, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, + 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, + 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, + 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, + 0x05, 0x92 +}; -char pkt6[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0xa1, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, -0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; +char pkt6[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0xa1, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt7[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x02, 0x27, 0x09, 0xa2, 0x40, 0x00, 0x80, 0x06, -0x6d, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18, -0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45, -0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, -0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, -0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d, -0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c, -0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, -0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, -0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, -0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d, -0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65, -0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, -0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, -0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78, -0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c, -0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, -0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, -0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65, -0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20, -0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, -0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, -0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, -0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70, -0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, -0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78, -0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, -0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d, -0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, -0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, -0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, -0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, -0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a, -0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, -0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, -0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64, -0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a, -0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, -0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, -0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20, -0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, -0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49, -0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57, -0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e, -0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53, -0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67, -0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e, -0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32, -0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37, -0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, -0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30, -0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38, -0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, -0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32, -0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48, -0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, -0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, -0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, -0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, -0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, -0x65, 0x0d, 0x0a, 0x0d, 0x0a }; +char pkt7[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x02, 0x27, 0x09, 0xa2, 0x40, 0x00, 0x80, 0x06, + 0x6d, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18, + 0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45, + 0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, + 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c, + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, + 0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, + 0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, + 0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65, + 0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78, + 0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, + 0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65, + 0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, + 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78, + 0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, + 0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, + 0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, + 0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64, + 0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a, + 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, + 0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20, + 0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49, + 0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e, + 0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53, + 0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e, + 0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32, + 0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37, + 0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, + 0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30, + 0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38, + 0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, + 0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32, + 0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48, + 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, + 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, + 0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, + 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, + 0x65, 0x0d, 0x0a, 0x0d, 0x0a +}; -char pkt8[] = { -0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, -0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, -0x00, 0x2c, 0x00, 0x03, 0x00, 0x00, 0x40, 0x06, -0xf8, 0xa4, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, -0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, -0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, -0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, -0x05, 0x92 }; +char pkt8[] = +{ + 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, + 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2c, 0x00, 0x03, 0x00, 0x00, 0x40, 0x06, + 0xf8, 0xa4, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, + 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, + 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, + 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, + 0x05, 0x92 +}; -char pkt9[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0xa3, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x08, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, -0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; +char pkt9[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0xa3, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x08, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt10[] = { -0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, -0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, -0x00, 0x2c, 0x00, 0x04, 0x00, 0x00, 0x40, 0x06, -0xf8, 0xa3, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, -0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, -0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, -0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, -0x05, 0x92 }; +char pkt10[] = +{ + 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, + 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2c, 0x00, 0x04, 0x00, 0x00, 0x40, 0x06, + 0xf8, 0xa3, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, + 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, + 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, + 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, + 0x05, 0x92 +}; -char pkt11[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0xa6, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x05, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, -0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; +char pkt11[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0xa6, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x05, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt12[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0xa7, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x04, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x14, -0x00, 0x00, 0x43, 0xf4, 0x00, 0x00 }; +char pkt12[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0xa7, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x04, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x14, + 0x00, 0x00, 0x43, 0xf4, 0x00, 0x00 +}; typedef struct { - char *pcData; - int iDataLen; + char * pcData; + int iDataLen; } xPacketData; xPacketData xAllPackets[] = @@ -251,16 +275,16 @@ xPacketData xAllPackets[] = /* These comments below are there so that we may modify * them as and when required. Keeping them unmodified. * Might be removed in later incremental PRs */ - { pkt1, sizeof( pkt1 ) }, + { pkt1, sizeof( pkt1 ) }, /* { pkt2, sizeof( pkt2 ) }, */ - { pkt3, sizeof( pkt3 ) }, - { pkt4, sizeof( pkt4 ) }, + { pkt3, sizeof( pkt3 ) }, + { pkt4, sizeof( pkt4 ) }, /* { pkt5, sizeof( pkt5 ) }, */ - { pkt6, sizeof( pkt6 ) }, - { pkt7, sizeof( pkt7 ) }, - { pkt8, sizeof( pkt8 ) }, - { pkt9, sizeof( pkt9 ) }, - { pkt10, sizeof( pkt10 ) }, + { pkt6, sizeof( pkt6 ) }, + { pkt7, sizeof( pkt7 ) }, + { pkt8, sizeof( pkt8 ) }, + { pkt9, sizeof( pkt9 ) }, + { pkt10, sizeof( pkt10 ) }, /* { pkt11, sizeof( pkt11 ) }, */ /* { pkt12, sizeof( pkt12 ) }, */ /* { pkt13, sizeof( pkt13 ) }, */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/Win32-Extensions.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/Win32-Extensions.h index bad7c33ac..9258fe0e8 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/Win32-Extensions.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/Win32-Extensions.h @@ -12,9 +12,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino, CACE Technologies - * nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -33,82 +33,95 @@ #ifndef __WIN32_EXTENSIONS_H__ -#define __WIN32_EXTENSIONS_H__ + #define __WIN32_EXTENSIONS_H__ -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* Definitions */ /*! - \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). -*/ -struct pcap_send_queue -{ - u_int maxlen; ///< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. - u_int len; ///< Current size of the queue, in bytes. - char *buffer; ///< Buffer containing the packets to be sent. -}; + * \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). + */ + struct pcap_send_queue + { + u_int maxlen; /*/< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. */ + u_int len; /*/< Current size of the queue, in bytes. */ + char * buffer; /*/< Buffer containing the packets to be sent. */ + }; -typedef struct pcap_send_queue pcap_send_queue; + typedef struct pcap_send_queue pcap_send_queue; /*! - \brief This typedef is a support for the pcap_get_airpcap_handle() function -*/ -#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) -#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ -typedef struct _AirpcapHandle *PAirpcapHandle; -#endif + * \brief This typedef is a support for the pcap_get_airpcap_handle() function + */ + #if !defined( AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ ) + #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ + typedef struct _AirpcapHandle * PAirpcapHandle; + #endif -#define BPF_MEM_EX_IMM 0xc0 -#define BPF_MEM_EX_IND 0xe0 + #define BPF_MEM_EX_IMM 0xc0 + #define BPF_MEM_EX_IND 0xe0 /*used for ST*/ -#define BPF_MEM_EX 0xc0 -#define BPF_TME 0x08 + #define BPF_MEM_EX 0xc0 + #define BPF_TME 0x08 -#define BPF_LOOKUP 0x90 -#define BPF_EXECUTE 0xa0 -#define BPF_INIT 0xb0 -#define BPF_VALIDATE 0xc0 -#define BPF_SET_ACTIVE 0xd0 -#define BPF_RESET 0xe0 -#define BPF_SET_MEMORY 0x80 -#define BPF_GET_REGISTER_VALUE 0x70 -#define BPF_SET_REGISTER_VALUE 0x60 -#define BPF_SET_WORKING 0x50 -#define BPF_SET_ACTIVE_READ 0x40 -#define BPF_SET_AUTODELETION 0x30 -#define BPF_SEPARATION 0xff + #define BPF_LOOKUP 0x90 + #define BPF_EXECUTE 0xa0 + #define BPF_INIT 0xb0 + #define BPF_VALIDATE 0xc0 + #define BPF_SET_ACTIVE 0xd0 + #define BPF_RESET 0xe0 + #define BPF_SET_MEMORY 0x80 + #define BPF_GET_REGISTER_VALUE 0x70 + #define BPF_SET_REGISTER_VALUE 0x60 + #define BPF_SET_WORKING 0x50 + #define BPF_SET_ACTIVE_READ 0x40 + #define BPF_SET_AUTODELETION 0x30 + #define BPF_SEPARATION 0xff /* Prototypes */ -pcap_send_queue* pcap_sendqueue_alloc(u_int memsize); + pcap_send_queue * pcap_sendqueue_alloc( u_int memsize ); -void pcap_sendqueue_destroy(pcap_send_queue* queue); + void pcap_sendqueue_destroy( pcap_send_queue * queue ); -int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); + int pcap_sendqueue_queue( pcap_send_queue * queue, + const struct pcap_pkthdr * pkt_header, + const u_char * pkt_data ); -u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync); + u_int pcap_sendqueue_transmit( pcap_t * p, + pcap_send_queue * queue, + int sync ); -HANDLE pcap_getevent(pcap_t *p); + HANDLE pcap_getevent( pcap_t * p ); -struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size); + struct pcap_stat * pcap_stats_ex( pcap_t * p, + int * pcap_stat_size ); -int pcap_setuserbuffer(pcap_t *p, int size); + int pcap_setuserbuffer( pcap_t * p, + int size ); -int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks); + int pcap_live_dump( pcap_t * p, + char * filename, + int maxsize, + int maxpacks ); -int pcap_live_dump_ended(pcap_t *p, int sync); + int pcap_live_dump_ended( pcap_t * p, + int sync ); -int pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data); + int pcap_offline_filter( struct bpf_program * prog, + const struct pcap_pkthdr * header, + const u_char * pkt_data ); -int pcap_start_oem(char* err_str, int flags); + int pcap_start_oem( char * err_str, + int flags ); -PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); + PAirpcapHandle pcap_get_airpcap_handle( pcap_t * p ); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif //__WIN32_EXTENSIONS_H__ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/arch.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/arch.c index 37cb290d6..cabb922ea 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/arch.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/arch.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,7 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ @@ -48,7 +48,7 @@ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void ); * Open the network interface. The number of the interface to be opened is set * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h. */ -static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces ); +static void prvOpenSelectedNetworkInterface( pcap_if_t * pxAllNetworkInterfaces ); /* * Configure the capture filter to allow blocking reads, and to filter out @@ -56,105 +56,105 @@ static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces ) */ static void prvConfigureCaptureBehaviour( void ); -pcap_t *pxOpenedInterfaceHandle = NULL; +pcap_t * pxOpenedInterfaceHandle = NULL; LARGE_INTEGER freq, sys_start_time; -#define archNUM_BUFFERS 5 -#define archNUM_BUFFER_POINTERS ( archNUM_BUFFERS - 1 ) +#define archNUM_BUFFERS 5 +#define archNUM_BUFFER_POINTERS ( archNUM_BUFFERS - 1 ) -static void prvInterruptSimulator( void *pvParameters ); +static void prvInterruptSimulator( void * pvParameters ); static unsigned char ucEthernetBuffer[ archNUM_BUFFERS ][ UIP_CONF_BUFFER_SIZE ]; -static unsigned char *pucEthernetBufferPointers[ archNUM_BUFFER_POINTERS ]; +static unsigned char * pucEthernetBufferPointers[ archNUM_BUFFER_POINTERS ]; static long lLengthOfDataInBuffer[ archNUM_BUFFER_POINTERS ] = { 0 }; static unsigned char ucNextBufferToFill = 0U, ucNextBufferToProcess = 0U; -unsigned char *uip_buf = NULL; -char cErrorBuffer[PCAP_ERRBUF_SIZE]; +unsigned char * uip_buf = NULL; +char cErrorBuffer[ PCAP_ERRBUF_SIZE ]; void vNetifTx( void ) { - pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); - pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); + pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); + pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); } /*-----------------------------------------------------------*/ UBaseType_t uxNetifRx( void ) { -UBaseType_t xDataLen; -unsigned char *pucTemp; + UBaseType_t xDataLen; + unsigned char * pucTemp; - /* Check there is really data available. */ - xDataLen = lLengthOfDataInBuffer[ ucNextBufferToProcess ]; - if( xDataLen != 0L ) - { + /* Check there is really data available. */ + xDataLen = lLengthOfDataInBuffer[ ucNextBufferToProcess ]; - /* The buffer pointed to by uip_buf is going to change. Remember which - buffer uip_buf is currently pointing to. */ - pucTemp = uip_buf; + if( xDataLen != 0L ) + { + /* The buffer pointed to by uip_buf is going to change. Remember which + * buffer uip_buf is currently pointing to. */ + pucTemp = uip_buf; - /* Point uip_buf at the next buffer that contains data. */ - uip_buf = pucEthernetBufferPointers[ ucNextBufferToProcess ]; + /* Point uip_buf at the next buffer that contains data. */ + uip_buf = pucEthernetBufferPointers[ ucNextBufferToProcess ]; - /* The buffer pointed to by - pucEthernetBufferPointeres[ ucNextBufferToProcess ] is now in use by - uip_buf, but the buffer uip_buf was pointing to on entry to this - function is free. Set - pucEthernetBufferPointeres[ ucNextBufferToProcess ] to the free - buffer. */ - pucEthernetBufferPointers[ ucNextBufferToProcess ] = pucTemp; - lLengthOfDataInBuffer[ ucNextBufferToProcess ] = 0L; + /* The buffer pointed to by + * pucEthernetBufferPointeres[ ucNextBufferToProcess ] is now in use by + * uip_buf, but the buffer uip_buf was pointing to on entry to this + * function is free. Set + * pucEthernetBufferPointeres[ ucNextBufferToProcess ] to the free + * buffer. */ + pucEthernetBufferPointers[ ucNextBufferToProcess ] = pucTemp; + lLengthOfDataInBuffer[ ucNextBufferToProcess ] = 0L; - ucNextBufferToProcess++; - if( ucNextBufferToProcess >= archNUM_BUFFER_POINTERS ) - { - ucNextBufferToProcess = 0L; - } - } + ucNextBufferToProcess++; - return xDataLen; + if( ucNextBufferToProcess >= archNUM_BUFFER_POINTERS ) + { + ucNextBufferToProcess = 0L; + } + } + + return xDataLen; } /*-----------------------------------------------------------*/ BaseType_t xNetifInit( void ) { -BaseType_t x; -pcap_if_t *pxAllNetworkInterfaces; + BaseType_t x; + pcap_if_t * pxAllNetworkInterfaces; - /* Allocate a free buffer to each buffer pointer. */ - for( x = 0; x < sizeof( pucEthernetBufferPointers ) / sizeof( unsigned char * ); x++ ) - { - pucEthernetBufferPointers[ x ] = &( ucEthernetBuffer[ x ][ 0 ] ); - } + /* Allocate a free buffer to each buffer pointer. */ + for( x = 0; x < sizeof( pucEthernetBufferPointers ) / sizeof( unsigned char * ); x++ ) + { + pucEthernetBufferPointers[ x ] = &( ucEthernetBuffer[ x ][ 0 ] ); + } - /* Start with uip_buf pointing to a buffer that is not referenced from the - pucEthernetBufferPointers[] array. */ - uip_buf = &( ucEthernetBuffer[ archNUM_BUFFERS - 1 ][ 0 ] ); + /* Start with uip_buf pointing to a buffer that is not referenced from the + * pucEthernetBufferPointers[] array. */ + uip_buf = &( ucEthernetBuffer[ archNUM_BUFFERS - 1 ][ 0 ] ); - /* Query the computer the simulation is being executed on to find the - network interfaces it has installed. */ - pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces(); - - /* Open the network interface. The number of the interface to be opened is - set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h. - Calling this function will set the pxOpenedInterfaceHandle variable. If, - after calling this function, pxOpenedInterfaceHandle is equal to NULL, then - the interface could not be opened. */ - if( pxAllNetworkInterfaces != NULL ) - { - prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces ); - } - + /* Query the computer the simulation is being executed on to find the + * network interfaces it has installed. */ + pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces(); - return x; + /* Open the network interface. The number of the interface to be opened is + * set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h. + * Calling this function will set the pxOpenedInterfaceHandle variable. If, + * after calling this function, pxOpenedInterfaceHandle is equal to NULL, then + * the interface could not be opened. */ + if( pxAllNetworkInterfaces != NULL ) + { + prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces ); + } + + return x; } /*-----------------------------------------------------------*/ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void ) -{ -pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface; -long lInterfaceNumber = 1; +{ + pcap_if_t * pxAllNetworkInterfaces = NULL, * xInterface; + long lInterfaceNumber = 1; if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 ) { @@ -162,174 +162,176 @@ long lInterfaceNumber = 1; pxAllNetworkInterfaces = NULL; } - if( pxAllNetworkInterfaces != NULL ) - { - /* Print out the list of network interfaces. The first in the list - is interface '1', not interface '0'. */ - for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next ) - { - printf( "%d. %s", lInterfaceNumber, xInterface->name ); - - if( xInterface->description != NULL ) - { - printf( " (%s)\r\n", xInterface->description ); - } - else - { - printf( " (No description available)\r\n") ; - } - - lInterfaceNumber++; - } - } + if( pxAllNetworkInterfaces != NULL ) + { + /* Print out the list of network interfaces. The first in the list + * is interface '1', not interface '0'. */ + for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next ) + { + printf( "%d. %s", lInterfaceNumber, xInterface->name ); + + if( xInterface->description != NULL ) + { + printf( " (%s)\r\n", xInterface->description ); + } + else + { + printf( " (No description available)\r\n" ); + } + + lInterfaceNumber++; + } + } if( lInterfaceNumber == 1 ) { - /* The interface number was never incremented, so the above for() loop - did not execute meaning no interfaces were found. */ + /* The interface number was never incremented, so the above for() loop + * did not execute meaning no interfaces were found. */ printf( " \r\nNo network interfaces were found.\r\n" ); pxAllNetworkInterfaces = NULL; } - printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" ); - printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE ); - + printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" ); + printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE ); + if( ( configNETWORK_INTERFACE_TO_USE < 1L ) || ( configNETWORK_INTERFACE_TO_USE > lInterfaceNumber ) ) { - printf("\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" ); - - if( pxAllNetworkInterfaces != NULL ) - { - /* Free the device list, as no devices are going to be opened. */ - pcap_freealldevs( pxAllNetworkInterfaces ); - pxAllNetworkInterfaces = NULL; - } + printf( "\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" ); + + if( pxAllNetworkInterfaces != NULL ) + { + /* Free the device list, as no devices are going to be opened. */ + pcap_freealldevs( pxAllNetworkInterfaces ); + pxAllNetworkInterfaces = NULL; + } } - return pxAllNetworkInterfaces; + return pxAllNetworkInterfaces; } /*-----------------------------------------------------------*/ -static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces ) +static void prvOpenSelectedNetworkInterface( pcap_if_t * pxAllNetworkInterfaces ) { -pcap_if_t *xInterface; -long x; + pcap_if_t * xInterface; + long x; /* Walk the list of devices until the selected device is located. */ - xInterface = pxAllNetworkInterfaces; + xInterface = pxAllNetworkInterfaces; + for( x = 0L; x < ( configNETWORK_INTERFACE_TO_USE - 1L ); x++ ) - { - xInterface = xInterface->next; - } + { + xInterface = xInterface->next; + } /* Open the selected interface. */ - pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */ - UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */ - PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscious mode as the MAC and - IP address is going to be "simulated", and - not be the real MAC and IP address. This allows - trafic to the simulated IP address to be routed - to uIP, and trafic to the real IP address to be - routed to the Windows TCP/IP stack. */ - 0xfffffffL, /* The read time out. This is going to block - until data is available. */ - NULL, /* No authentication is required as this is - not a remote capture session. */ - cErrorBuffer - ); - - if ( pxOpenedInterfaceHandle == NULL ) + pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */ + UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */ + PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscuous mode as the MAC and + * IP address is going to be "simulated", and + * not be the real MAC and IP address. This allows + * traffic to the simulated IP address to be routed + * to uIP, and traffic to the real IP address to be + * routed to the Windows TCP/IP stack. */ + 0xfffffffL, /* The read time out. This is going to block + * until data is available. */ + NULL, /* No authentication is required as this is + * not a remote capture session. */ + cErrorBuffer + ); + + if( pxOpenedInterfaceHandle == NULL ) { printf( "\r\n%s is not supported by WinPcap and cannot be opened\r\n", xInterface->name ); } - else - { - /* Configure the capture filter to allow blocking reads, and to filter - out packets that are not of interest to this demo. */ - prvConfigureCaptureBehaviour(); - } + else + { + /* Configure the capture filter to allow blocking reads, and to filter + * out packets that are not of interest to this demo. */ + prvConfigureCaptureBehaviour(); + } - /* The device list is no longer required. */ - pcap_freealldevs( pxAllNetworkInterfaces ); + /* The device list is no longer required. */ + pcap_freealldevs( pxAllNetworkInterfaces ); } /*-----------------------------------------------------------*/ static void prvConfigureCaptureBehaviour( void ) { -struct bpf_program xFilterCode; -const long lMinBytesToCopy = 10L, lBlocking = 0L; -unsigned long ulNetMask; + struct bpf_program xFilterCode; + const long lMinBytesToCopy = 10L, lBlocking = 0L; + unsigned long ulNetMask; - /* Unblock a read as soon as anything is received. */ - pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy ); + /* Unblock a read as soon as anything is received. */ + pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy ); - /* Allow blocking. */ - pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer ); + /* Allow blocking. */ + pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer ); - /* Set up a filter so only the packets of interest are passed to the uIP - stack. cErrorBuffer is used for convenience to create the string. Don't - confuse this with an error message. */ - sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); + /* Set up a filter so only the packets of interest are passed to the uIP + * stack. cErrorBuffer is used for convenience to create the string. Don't + * confuse this with an error message. */ + sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); - ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0; + ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0; - if( pcap_compile(pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 ) + if( pcap_compile( pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 ) { - printf("\r\nThe packet filter string is invalid\r\n" ); + printf( "\r\nThe packet filter string is invalid\r\n" ); + } + else + { + if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 ) + { + printf( "\r\nAn error occurred setting the packet filter.\r\n" ); + } } - else - { - if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 ) - { - printf( "\r\nAn error occurred setting the packet filter.\r\n" ); - } - } - /* Create a task that simulates an interrupt in a real system. This will - block waiting for packets, then send a message to the uIP task when data - is available. */ - xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( configuIP_TASK_PRIORITY - 1 ), NULL ); + /* Create a task that simulates an interrupt in a real system. This will + * block waiting for packets, then send a message to the uIP task when data + * is available. */ + xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( ipconfigIP_TASK_PRIORITY - 1 ), NULL ); } /*-----------------------------------------------------------*/ -static void prvInterruptSimulator( void *pvParameters ) +static void prvInterruptSimulator( void * pvParameters ) { -static struct pcap_pkthdr *pxHeader; -const unsigned char *pucPacketData; -extern QueueHandle_t xEMACEventQueue; -const unsigned long ulRxEvent = uipETHERNET_RX_EVENT; -long lResult; + static struct pcap_pkthdr * pxHeader; + const unsigned char * pucPacketData; + extern QueueHandle_t xEMACEventQueue; + const unsigned long ulRxEvent = uipETHERNET_RX_EVENT; + long lResult; - /* Just to kill the compiler warning. */ - ( void ) pvParameters; + /* Just to kill the compiler warning. */ + ( void ) pvParameters; - for( ;; ) - { - /* Get the next packet. */ - lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData ); - if( lResult ) - { - /* Is the next buffer into which data should be placed free? */ - if( lLengthOfDataInBuffer[ ucNextBufferToFill ] == 0L ) - { - /* Copy the data from the captured packet into the buffer. */ - memcpy( pucEthernetBufferPointers[ ucNextBufferToFill ], pucPacketData, pxHeader->len ); + for( ; ; ) + { + /* Get the next packet. */ + lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData ); - /* Note the amount of data that was copied. */ - lLengthOfDataInBuffer[ ucNextBufferToFill ] = pxHeader->len; + if( lResult ) + { + /* Is the next buffer into which data should be placed free? */ + if( lLengthOfDataInBuffer[ ucNextBufferToFill ] == 0L ) + { + /* Copy the data from the captured packet into the buffer. */ + memcpy( pucEthernetBufferPointers[ ucNextBufferToFill ], pucPacketData, pxHeader->len ); - /* Move onto the next buffer, wrapping around if necessary. */ - ucNextBufferToFill++; - if( ucNextBufferToFill >= archNUM_BUFFER_POINTERS ) - { - ucNextBufferToFill = 0U; - } + /* Note the amount of data that was copied. */ + lLengthOfDataInBuffer[ ucNextBufferToFill ] = pxHeader->len; - /* Data was received and stored. Send a message to the uIP task - to let it know. */ - xQueueSendToBack( xEMACEventQueue, &ulRxEvent, portMAX_DELAY ); - } - } - } + /* Move onto the next buffer, wrapping around if necessary. */ + ucNextBufferToFill++; + + if( ucNextBufferToFill >= archNUM_BUFFER_POINTERS ) + { + ucNextBufferToFill = 0U; + } + + /* Data was received and stored. Send a message to the uIP task + * to let it know. */ + xQueueSendToBack( xEMACEventQueue, &ulRxEvent, portMAX_DELAY ); + } + } + } } - diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/bittypes.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/bittypes.h index f55fcecfd..2be3d28db 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/bittypes.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/bittypes.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,107 +31,107 @@ #ifndef HAVE_U_INT8_T -#if SIZEOF_CHAR == 1 -typedef unsigned char u_int8_t; -typedef signed char _int8_t; -#elif SIZEOF_INT == 1 -typedef unsigned int u_int8_t; -typedef signed int int8_t; -#else /* XXX */ -#error "there's no appropriate type for u_int8_t" -#endif -#define HAVE_U_INT8_T 1 -#define HAVE_INT8_T 1 + #if SIZEOF_CHAR == 1 + typedef unsigned char u_int8_t; + typedef signed char _int8_t; + #elif SIZEOF_INT == 1 + typedef unsigned int u_int8_t; + typedef signed int int8_t; + #else /* XXX */ + #error "there's no appropriate type for u_int8_t" + #endif + #define HAVE_U_INT8_T 1 + #define HAVE_INT8_T 1 #endif /* HAVE_U_INT8_T */ -#ifndef HAVE_U_INT16_T +#ifndef HAVE_U_INT16_T -#if SIZEOF_SHORT == 2 -typedef unsigned short u_int16_t; -typedef signed short _int16_t; -#elif SIZEOF_INT == 2 -typedef unsigned int u_int16_t; -typedef signed int int16_t; -#elif SIZEOF_CHAR == 2 -typedef unsigned char u_int16_t; -typedef signed char int16_t; -#else /* XXX */ -#error "there's no appropriate type for u_int16_t" -#endif -#define HAVE_U_INT16_T 1 -#define HAVE_INT16_T 1 + #if SIZEOF_SHORT == 2 + typedef unsigned short u_int16_t; + typedef signed short _int16_t; + #elif SIZEOF_INT == 2 + typedef unsigned int u_int16_t; + typedef signed int int16_t; + #elif SIZEOF_CHAR == 2 + typedef unsigned char u_int16_t; + typedef signed char int16_t; + #else /* XXX */ + #error "there's no appropriate type for u_int16_t" + #endif /* if SIZEOF_SHORT == 2 */ + #define HAVE_U_INT16_T 1 + #define HAVE_INT16_T 1 #endif /* HAVE_U_INT16_T */ #ifndef HAVE_U_INT32_T -#if SIZEOF_INT == 4 -typedef unsigned int u_int32_t; -typedef signed int _int32_t; -#elif SIZEOF_LONG == 4 -typedef unsigned long u_int32_t; -typedef signed long int32_t; -#elif SIZEOF_SHORT == 4 -typedef unsigned short u_int32_t; -typedef signed short int32_t; -#else /* XXX */ -#error "there's no appropriate type for u_int32_t" -#endif -#define HAVE_U_INT32_T 1 -#define HAVE_INT32_T 1 + #if SIZEOF_INT == 4 + typedef unsigned int u_int32_t; + typedef signed int _int32_t; + #elif SIZEOF_LONG == 4 + typedef unsigned long u_int32_t; + typedef signed long int32_t; + #elif SIZEOF_SHORT == 4 + typedef unsigned short u_int32_t; + typedef signed short int32_t; + #else /* XXX */ + #error "there's no appropriate type for u_int32_t" + #endif /* if SIZEOF_INT == 4 */ + #define HAVE_U_INT32_T 1 + #define HAVE_INT32_T 1 #endif /* HAVE_U_INT32_T */ #ifndef HAVE_U_INT64_T -#if SIZEOF_LONG_LONG == 8 -typedef unsigned long long u_int64_t; -typedef long long int64_t; -#elif defined(_MSC_EXTENSIONS) -typedef unsigned _int64 u_int64_t; -typedef _int64 int64_t; -#elif SIZEOF_INT == 8 -typedef unsigned int u_int64_t; -#elif SIZEOF_LONG == 8 -typedef unsigned long u_int64_t; -#elif SIZEOF_SHORT == 8 -typedef unsigned short u_int64_t; -#else /* XXX */ -#error "there's no appropriate type for u_int64_t" -#endif + #if SIZEOF_LONG_LONG == 8 + typedef unsigned long long u_int64_t; + typedef long long int64_t; + #elif defined( _MSC_EXTENSIONS ) + typedef unsigned _int64 u_int64_t; + typedef _int64 int64_t; + #elif SIZEOF_INT == 8 + typedef unsigned int u_int64_t; + #elif SIZEOF_LONG == 8 + typedef unsigned long u_int64_t; + #elif SIZEOF_SHORT == 8 + typedef unsigned short u_int64_t; + #else /* XXX */ + #error "there's no appropriate type for u_int64_t" + #endif /* if SIZEOF_LONG_LONG == 8 */ #endif /* HAVE_U_INT64_T */ #ifndef PRId64 -#ifdef _MSC_EXTENSIONS -#define PRId64 "I64d" -#else /* _MSC_EXTENSIONS */ -#define PRId64 "lld" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRId64 "I64d" + #else /* _MSC_EXTENSIONS */ + #define PRId64 "lld" + #endif /* _MSC_EXTENSIONS */ #endif /* PRId64 */ #ifndef PRIo64 -#ifdef _MSC_EXTENSIONS -#define PRIo64 "I64o" -#else /* _MSC_EXTENSIONS */ -#define PRIo64 "llo" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRIo64 "I64o" + #else /* _MSC_EXTENSIONS */ + #define PRIo64 "llo" + #endif /* _MSC_EXTENSIONS */ #endif /* PRIo64 */ #ifndef PRIx64 -#ifdef _MSC_EXTENSIONS -#define PRIx64 "I64x" -#else /* _MSC_EXTENSIONS */ -#define PRIx64 "llx" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRIx64 "I64x" + #else /* _MSC_EXTENSIONS */ + #define PRIx64 "llx" + #endif /* _MSC_EXTENSIONS */ #endif /* PRIx64 */ #ifndef PRIu64 -#ifdef _MSC_EXTENSIONS -#define PRIu64 "I64u" -#else /* _MSC_EXTENSIONS */ -#define PRIu64 "llu" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRIu64 "I64u" + #else /* _MSC_EXTENSIONS */ + #define PRIu64 "llu" + #endif /* _MSC_EXTENSIONS */ #endif /* PRIu64 */ #endif /* _BITTYPES_H */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/ip6_misc.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/ip6_misc.h index 562fa6184..1b2e4337b 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/ip6_misc.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/ip6_misc.h @@ -30,134 +30,136 @@ #include #ifndef __MINGW32__ -#define IN_MULTICAST(a) IN_CLASSD(a) + #define IN_MULTICAST( a ) IN_CLASSD( a ) #endif -#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xf0000000) == 0xf0000000) +#define IN_EXPERIMENTAL( a ) ( ( ( ( u_int32_t ) ( a ) ) & 0xf0000000 ) == 0xf0000000 ) -#define IN_LOOPBACKNET 127 +#define IN_LOOPBACKNET 127 -#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) +#if defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) /* IPv6 address */ -struct in6_addr - { - union - { - u_int8_t u6_addr8[16]; - u_int16_t u6_addr16[8]; - u_int32_t u6_addr32[4]; - } in6_u; -#define s6_addr in6_u.u6_addr8 -#define s6_addr16 in6_u.u6_addr16 -#define s6_addr32 in6_u.u6_addr32 -#define s6_addr64 in6_u.u6_addr64 - }; + struct in6_addr + { + union + { + u_int8_t u6_addr8[ 16 ]; + u_int16_t u6_addr16[ 8 ]; + u_int32_t u6_addr32[ 4 ]; + } + in6_u; + #define s6_addr in6_u.u6_addr8 + #define s6_addr16 in6_u.u6_addr16 + #define s6_addr32 in6_u.u6_addr32 + #define s6_addr64 in6_u.u6_addr64 + }; -#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } + #define IN6ADDR_ANY_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + #define IN6ADDR_LOOPBACK_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } #endif /* __MINGW32__ */ -#if (defined _MSC_VER) || (defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)) -typedef unsigned short sa_family_t; +#if ( defined _MSC_VER ) || ( defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) ) + typedef unsigned short sa_family_t; #endif -#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) +#if defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) -#define __SOCKADDR_COMMON(sa_prefix) \ - sa_family_t sa_prefix##family + #define __SOCKADDR_COMMON( sa_prefix ) \ + sa_family_t sa_prefix ## family /* Ditto, for IPv6. */ -struct sockaddr_in6 - { - __SOCKADDR_COMMON (sin6_); - u_int16_t sin6_port; /* Transport layer port # */ - u_int32_t sin6_flowinfo; /* IPv6 flow information */ - struct in6_addr sin6_addr; /* IPv6 address */ - }; + struct sockaddr_in6 + { + __SOCKADDR_COMMON( sin6_ ); + u_int16_t sin6_port; /* Transport layer port # */ + u_int32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + }; -#define IN6_IS_ADDR_V4MAPPED(a) \ - ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ - (((u_int32_t *) (a))[2] == htonl (0xffff))) + #define IN6_IS_ADDR_V4MAPPED( a ) \ + ( ( ( ( u_int32_t * ) ( a ) )[ 0 ] == 0 ) && ( ( ( u_int32_t * ) ( a ) )[ 1 ] == 0 ) && \ + ( ( ( u_int32_t * ) ( a ) )[ 2 ] == htonl( 0xffff ) ) ) -#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff) + #define IN6_IS_ADDR_MULTICAST( a ) ( ( ( u_int8_t * ) ( a ) )[ 0 ] == 0xff ) -#define IN6_IS_ADDR_LINKLOCAL(a) \ - ((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000)) + #define IN6_IS_ADDR_LINKLOCAL( a ) \ + ( ( ( ( u_int32_t * ) ( a ) )[ 0 ] & htonl( 0xffc00000 ) ) == htonl( 0xfe800000 ) ) -#define IN6_IS_ADDR_LOOPBACK(a) \ - (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ - ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) + #define IN6_IS_ADDR_LOOPBACK( a ) \ + ( ( ( u_int32_t * ) ( a ) )[ 0 ] == 0 && ( ( u_int32_t * ) ( a ) )[ 1 ] == 0 && \ + ( ( u_int32_t * ) ( a ) )[ 2 ] == 0 && ( ( u_int32_t * ) ( a ) )[ 3 ] == htonl( 1 ) ) #endif /* __MINGW32__ */ -#define ip6_vfc ip6_ctlun.ip6_un2_vfc -#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow -#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen -#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt -#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim -#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim +#define ip6_vfc ip6_ctlun.ip6_un2_vfc +#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow +#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen +#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt +#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim +#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim #define nd_rd_type nd_rd_hdr.icmp6_type #define nd_rd_code nd_rd_hdr.icmp6_code #define nd_rd_cksum nd_rd_hdr.icmp6_cksum -#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] +#define nd_rd_reserved nd_rd_hdr.icmp6_data32[ 0 ] /* * IPV6 extension headers */ -#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ -#define IPPROTO_IPV6 41 /* IPv6 header. */ -#define IPPROTO_ROUTING 43 /* IPv6 routing header */ -#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ -#define IPPROTO_ESP 50 /* encapsulating security payload */ -#define IPPROTO_AH 51 /* authentication header */ -#define IPPROTO_ICMPV6 58 /* ICMPv6 */ -#define IPPROTO_NONE 59 /* IPv6 no next header */ -#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ -#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */ +#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ +#define IPPROTO_IPV6 41 /* IPv6 header. */ +#define IPPROTO_ROUTING 43 /* IPv6 routing header */ +#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ +#define IPPROTO_ESP 50 /* encapsulating security payload */ +#define IPPROTO_AH 51 /* authentication header */ +#define IPPROTO_ICMPV6 58 /* ICMPv6 */ +#define IPPROTO_NONE 59 /* IPv6 no next header */ +#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ +#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */ -#define IPV6_RTHDR_TYPE_0 0 +#define IPV6_RTHDR_TYPE_0 0 /* Option types and related macros */ -#define IP6OPT_PAD1 0x00 /* 00 0 00000 */ -#define IP6OPT_PADN 0x01 /* 00 0 00001 */ -#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ -#define IP6OPT_JUMBO_LEN 6 -#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ +#define IP6OPT_PAD1 0x00 /* 00 0 00000 */ +#define IP6OPT_PADN 0x01 /* 00 0 00001 */ +#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ +#define IP6OPT_JUMBO_LEN 6 +#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ -#define IP6OPT_RTALERT_LEN 4 -#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ -#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ -#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ -#define IP6OPT_MINLEN 2 +#define IP6OPT_RTALERT_LEN 4 +#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ +#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ +#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ +#define IP6OPT_MINLEN 2 -#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ -#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ -#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ -#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ -#define IP6OPT_EID 0x8a /* 10 0 01010 */ +#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ +#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ +#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ +#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ +#define IP6OPT_EID 0x8a /* 10 0 01010 */ -#define IP6OPT_TYPE(o) ((o) & 0xC0) -#define IP6OPT_TYPE_SKIP 0x00 -#define IP6OPT_TYPE_DISCARD 0x40 -#define IP6OPT_TYPE_FORCEICMP 0x80 -#define IP6OPT_TYPE_ICMP 0xC0 +#define IP6OPT_TYPE( o ) ( ( o ) & 0xC0 ) +#define IP6OPT_TYPE_SKIP 0x00 +#define IP6OPT_TYPE_DISCARD 0x40 +#define IP6OPT_TYPE_FORCEICMP 0x80 +#define IP6OPT_TYPE_ICMP 0xC0 -#define IP6OPT_MUTABLE 0x20 +#define IP6OPT_MUTABLE 0x20 -#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) -#ifndef EAI_ADDRFAMILY -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -#endif +#if defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) + #ifndef EAI_ADDRFAMILY + struct addrinfo + { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char * ai_canonname; /* canonical name for hostname */ + struct sockaddr * ai_addr; /* binary address */ + struct addrinfo * ai_next; /* next structure in linked list */ + }; + #endif /* ifndef EAI_ADDRFAMILY */ #endif /* __MINGW32__ */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/netif.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/netif.h index fded3b944..c06c0a9bf 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/netif.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/netif.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,7 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ @@ -28,13 +28,13 @@ #define NET_IF_H /* - * Send uip_len bytes from uip_buf to the network interface selected by the - * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h). + * Send uip_len bytes from uip_buf to the network interface selected by the + * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h). */ void vNetifTx( void ); /* - * Receive bytes from the network interface selected by the + * Receive bytes from the network interface selected by the * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h). The * bytes are placed in uip_buf. The number of bytes copied into uip_buf is * returned. @@ -42,9 +42,9 @@ void vNetifTx( void ); UBaseType_t uxNetifRx( void ); /* - * Prepare a packet capture session. This will print out all the network - * interfaces available, and the one actually used is set by the - * configNETWORK_INTERFACE_TO_USE constant that is defined in + * Prepare a packet capture session. This will print out all the network + * interfaces available, and the one actually used is set by the + * configNETWORK_INTERFACE_TO_USE constant that is defined in * FreeRTOSConfig.h. */ BaseType_t xNetifInit( void ); diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap-bpf.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap-bpf.h index 5fe129dbb..2657827e0 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap-bpf.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap-bpf.h @@ -4,7 +4,7 @@ * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap-stdinc.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap-stdinc.h index 417604177..9cde17fb3 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap-stdinc.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap-stdinc.h @@ -31,20 +31,20 @@ * @(#) $Header: /tcpdump/master/libpcap/pcap-stdinc.h,v 1.10.2.1 2008-10-06 15:38:39 gianluca Exp $ (LBL) */ -#define SIZEOF_CHAR 1 -#define SIZEOF_SHORT 2 -#define SIZEOF_INT 4 +#define SIZEOF_CHAR 1 +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 #ifndef _MSC_EXTENSIONS -#define SIZEOF_LONG_LONG 8 + #define SIZEOF_LONG_LONG 8 #endif /* - * Avoids a compiler warning in case this was already defined + * Avoids a compiler warning in case this was already defined * (someone defined _WINSOCKAPI_ when including 'windows.h', in order * to prevent it from including 'winsock.h') */ #ifdef _WINSOCKAPI_ -#undef _WINSOCKAPI_ + #undef _WINSOCKAPI_ #endif #include @@ -55,39 +55,39 @@ #include #ifndef __MINGW32__ -#include "IP6_misc.h" + #include "IP6_misc.h" #endif -#define caddr_t char* +#define caddr_t char * #if _MSC_VER < 1500 -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define strdup _strdup + #define snprintf _snprintf + #define vsnprintf _vsnprintf + #define strdup _strdup #endif -#define inline __inline +#define inline __inline #ifdef __MINGW32__ -#include + #include #else /*__MINGW32__*/ /* MSVC compiler */ -#ifndef _UINTPTR_T_DEFINED -#ifdef _WIN64 -typedef unsigned __int64 uintptr_t; -#else -typedef _W64 unsigned int uintptr_t; -#endif -#define _UINTPTR_T_DEFINED -#endif + #ifndef _UINTPTR_T_DEFINED + #ifdef _WIN64 + typedef unsigned __int64 uintptr_t; + #else + typedef _W64 unsigned int uintptr_t; + #endif + #define _UINTPTR_T_DEFINED + #endif -#ifndef _INTPTR_T_DEFINED -#ifdef _WIN64 -typedef __int64 intptr_t; -#else -typedef _W64 int intptr_t; -#endif -#define _INTPTR_T_DEFINED -#endif + #ifndef _INTPTR_T_DEFINED + #ifdef _WIN64 + typedef __int64 intptr_t; + #else + typedef _W64 int intptr_t; + #endif + #define _INTPTR_T_DEFINED + #endif #endif /*__MINGW32__*/ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/bluetooth.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/bluetooth.h index 7bf65df03..05332a3a5 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/bluetooth.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/bluetooth.h @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,7 +32,7 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/bluetooth.h,v 1.1 2007/09/22 02:10:17 guy Exp $ */ - + #ifndef _PCAP_BLUETOOTH_STRUCTS_H__ #define _PCAP_BLUETOOTH_STRUCTS_H__ @@ -40,8 +40,9 @@ * Header prepended libpcap to each bluetooth h:4 frame. * fields are in network byte order */ -typedef struct _pcap_bluetooth_h4_header { - u_int32_t direction; /* if first bit is set direction is incoming */ +typedef struct _pcap_bluetooth_h4_header +{ + u_int32_t direction; /* if first bit is set direction is incoming */ } pcap_bluetooth_h4_header; diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/bpf.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/bpf.h index 9f4ca33e3..d53a87b2f 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/bpf.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/bpf.h @@ -4,7 +4,7 @@ * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without @@ -53,45 +53,46 @@ #ifndef BPF_MAJOR_VERSION -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* BSD style release date */ -#define BPF_RELEASE 199606 + #define BPF_RELEASE 199606 -#ifdef MSDOS /* must be 32-bit */ -typedef long bpf_int32; -typedef unsigned long bpf_u_int32; -#else -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #ifdef MSDOS /* must be 32-bit */ + typedef long bpf_int32; + typedef unsigned long bpf_u_int32; + #else + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif /* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + #ifndef __NetBSD__ + #define BPF_ALIGNMENT sizeof( bpf_int32 ) + #else + #define BPF_ALIGNMENT sizeof( long ) + #endif + #define BPF_WORDALIGN( x ) ( ( ( x ) + ( BPF_ALIGNMENT - 1 ) ) & ~( BPF_ALIGNMENT - 1 ) ) -#define BPF_MAXBUFSIZE 0x8000 -#define BPF_MINBUFSIZE 32 + #define BPF_MAXBUFSIZE 0x8000 + #define BPF_MINBUFSIZE 32 /* * Structure for "pcap_compile()", "pcap_setfilter()", etc.. */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - + struct bpf_program + { + u_int bf_len; + struct bpf_insn * bf_insns; + }; + /* - * Struct return by BIOCVERSION. This represents the version number of + * Struct return by BIOCVERSION. This represents the version number of * the filter language described by the instruction encodings below. * bpf understands a program iff kernel_major == filter_major && * kernel_minor >= filter_minor, that is, if the value returned by the @@ -101,13 +102,14 @@ struct bpf_program { * may be accepted haphazardly. * It has nothing to do with the source code version. */ -struct bpf_version { - u_short bv_major; - u_short bv_minor; -}; + struct bpf_version + { + u_short bv_major; + u_short bv_minor; + }; /* Current version number of filter architecture. */ -#define BPF_MAJOR_VERSION 1 -#define BPF_MINOR_VERSION 1 + #define BPF_MAJOR_VERSION 1 + #define BPF_MINOR_VERSION 1 /* * Data-link level type codes. @@ -125,17 +127,17 @@ struct bpf_version { * These are the types that are the same on all platforms, and that * have been defined by for ages. */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* 802.5 Token Ring */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ + #define DLT_NULL 0 /* BSD loopback encapsulation */ + #define DLT_EN10MB 1 /* Ethernet (10Mb) */ + #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ + #define DLT_AX25 3 /* Amateur Radio AX.25 */ + #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ + #define DLT_CHAOS 5 /* Chaos */ + #define DLT_IEEE802 6 /* 802.5 Token Ring */ + #define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ + #define DLT_SLIP 8 /* Serial Line IP */ + #define DLT_PPP 9 /* Point-to-point Protocol */ + #define DLT_FDDI 10 /* FDDI */ /* * These are types that are different on some platforms, and that @@ -146,13 +148,13 @@ struct bpf_version { * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, * but I don't know what the right #define is for BSD/OS. */ -#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + #define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif + #ifdef __OpenBSD__ + #define DLT_RAW 14 /* raw IP */ + #else + #define DLT_RAW 12 /* raw IP */ + #endif /* * Given that the only OS that currently generates BSD/OS SLIP or PPP @@ -160,15 +162,15 @@ struct bpf_version { * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they * didn't. So it goes. */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif + #if defined( __NetBSD__ ) || defined( __FreeBSD__ ) + #ifndef DLT_SLIP_BSDOS + #define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ + #endif + #else + #define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ + #endif /* * 17 is used for DLT_OLD_PFLOG in OpenBSD; @@ -176,21 +178,21 @@ struct bpf_version { * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. */ -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + #define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ /* * Apparently Redback uses this for its SmartEdge 400/800. I hope * nobody else decided to use it, too. */ -#define DLT_REDBACK_SMARTEDGE 32 + #define DLT_REDBACK_SMARTEDGE 32 /* * These values are defined by NetBSD; other platforms should refrain from * using them for other purposes, so that NetBSD savefiles with link * types of 50 or 51 can be read as this type on all platforms. */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + #define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ + #define DLT_PPP_ETHER 51 /* PPP over Ethernet */ /* * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses @@ -199,7 +201,7 @@ struct bpf_version { * Ethernet type, and 36 bytes that appear to be 0 in at least one capture * I've seen. */ -#define DLT_SYMANTEC_FIREWALL 99 + #define DLT_SYMANTEC_FIREWALL 99 /* * Values between 100 and 103 are used in capture file headers as @@ -221,10 +223,10 @@ struct bpf_version { * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, * for source compatibility with programs written for libpcap 0.5. */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC + #define DLT_C_HDLC 104 /* Cisco HDLC */ + #define DLT_CHDLC DLT_C_HDLC -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + #define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ /* * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, @@ -239,7 +241,7 @@ struct bpf_version { * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header * (DLCI, etc.). */ -#define DLT_FRELAY 107 + #define DLT_FRELAY 107 /* * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except @@ -248,22 +250,22 @@ struct bpf_version { * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so * we don't use 12 for it in OSes other than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_LOOP 12 -#else -#define DLT_LOOP 108 -#endif + #ifdef __OpenBSD__ + #define DLT_LOOP 12 + #else + #define DLT_LOOP 108 + #endif /* * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other * than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_ENC 13 -#else -#define DLT_ENC 109 -#endif + #ifdef __OpenBSD__ + #define DLT_ENC 13 + #else + #define DLT_ENC 109 + #endif /* * Values between 110 and 112 are reserved for use in capture file headers @@ -275,22 +277,22 @@ struct bpf_version { /* * This is for Linux cooked sockets. */ -#define DLT_LINUX_SLL 113 + #define DLT_LINUX_SLL 113 /* * Apple LocalTalk hardware. */ -#define DLT_LTALK 114 + #define DLT_LTALK 114 /* * Acorn Econet. */ -#define DLT_ECONET 115 + #define DLT_ECONET 115 /* * Reserved for use with OpenBSD ipfilter. */ -#define DLT_IPFILTER 116 + #define DLT_IPFILTER 116 /* * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 @@ -298,34 +300,34 @@ struct bpf_version { * * XXX: is there a conflict with DLT_PFSYNC 18 as well? */ -#ifdef __OpenBSD__ -#define DLT_OLD_PFLOG 17 -#define DLT_PFSYNC 18 -#endif -#define DLT_PFLOG 117 + #ifdef __OpenBSD__ + #define DLT_OLD_PFLOG 17 + #define DLT_PFSYNC 18 + #endif + #define DLT_PFLOG 117 /* * Registered for Cisco-internal use. */ -#define DLT_CISCO_IOS 118 + #define DLT_CISCO_IOS 118 /* * For 802.11 cards using the Prism II chips, with a link-layer * header including Prism monitor mode information plus an 802.11 * header. */ -#define DLT_PRISM_HEADER 119 + #define DLT_PRISM_HEADER 119 /* * Reserved for Aironet 802.11 cards, with an Aironet link-layer header * (see Doug Ambrisko's FreeBSD patches). */ -#define DLT_AIRONET_HEADER 120 + #define DLT_AIRONET_HEADER 120 /* * Reserved for Siemens HiPath HDLC. */ -#define DLT_HHDLC 121 + #define DLT_HHDLC 121 /* * This is for RFC 2625 IP-over-Fibre Channel. @@ -335,7 +337,7 @@ struct bpf_version { * where the link-layer header starts with an RFC 2625 Network_Header * field. */ -#define DLT_IP_OVER_FC 122 + #define DLT_IP_OVER_FC 122 /* * This is for Full Frontal ATM on Solaris with SunATM, with a @@ -351,22 +353,22 @@ struct bpf_version { * and the like don't have to infer the presence or absence of a * pseudo-header and the form of the pseudo-header. */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ + #define DLT_SUNATM 123 /* Solaris+SunATM */ -/* +/* * Reserved as per request from Kent Dahlgren * for private use. */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + #define DLT_RIO 124 /* RapidIO */ + #define DLT_PCI_EXP 125 /* PCI Express */ + #define DLT_AURORA 126 /* Xilinx Aurora link layer */ /* * Header for 802.11 plus a number of bits of link-layer information * including radio information, used by some recent BSD drivers as * well as the madwifi Atheros driver for Linux. */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + #define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ /* * Reserved for the TZSP encapsulation, as per request from @@ -376,7 +378,7 @@ struct bpf_version { * with the packet, e.g. signal strength and channel * for 802.11 packets. */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + #define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ /* * BSD's ARCNET headers have the source host, destination host, @@ -389,7 +391,7 @@ struct bpf_version { * * We therefore have to have separate DLT_ values for them. */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ + #define DLT_ARCNET_LINUX 129 /* ARCNET */ /* * Juniper-private data link types, as per request from @@ -397,14 +399,14 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 + #define DLT_JUNIPER_MLPPP 130 + #define DLT_JUNIPER_MLFR 131 + #define DLT_JUNIPER_ES 132 + #define DLT_JUNIPER_GGSN 133 + #define DLT_JUNIPER_MFR 134 + #define DLT_JUNIPER_ATM2 135 + #define DLT_JUNIPER_SERVICES 136 + #define DLT_JUNIPER_ATM1 137 /* * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund @@ -421,21 +423,21 @@ struct bpf_version { * with "firewire_type" being an Ethernet type value, rather than, * for example, raw GASP frames being handed up. */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 + #define DLT_APPLE_IP_OVER_IEEE1394 138 /* * Various SS7 encapsulations, as per a request from Jeff Morriss * and subsequent discussions. */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + #define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ + #define DLT_MTP2 140 /* MTP2, without pseudo-header */ + #define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ + #define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ /* * DOCSIS MAC frames. */ -#define DLT_DOCSIS 143 + #define DLT_DOCSIS 143 /* * Linux-IrDA packets. Protocol defined at http://www.irda.org. @@ -446,19 +448,19 @@ struct bpf_version { * interface (irdaX), but not on a raw serial port. * Note the capture is done in "Linux-cooked" mode, so each packet include * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or + * decoding is dependant on the direction of the packet (incoming or * outgoing). * When/if other platform implement IrDA capture, we may revisit the * issue and define a real DLT_IRDA... * Jean II */ -#define DLT_LINUX_IRDA 144 + #define DLT_LINUX_IRDA 144 /* * Reserved for IBM SP switch and IBM Next Federation switch. */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 + #define DLT_IBM_SP 145 + #define DLT_IBM_SN 146 /* * Reserved for private use. If you have some link-layer header type @@ -485,22 +487,22 @@ struct bpf_version { * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, * as per the comment above, and use the type you're given. */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 + #define DLT_USER0 147 + #define DLT_USER1 148 + #define DLT_USER2 149 + #define DLT_USER3 150 + #define DLT_USER4 151 + #define DLT_USER5 152 + #define DLT_USER6 153 + #define DLT_USER7 154 + #define DLT_USER8 155 + #define DLT_USER9 156 + #define DLT_USER10 157 + #define DLT_USER11 158 + #define DLT_USER12 159 + #define DLT_USER13 160 + #define DLT_USER14 161 + #define DLT_USER15 162 /* * For future use with 802.11 captures - defined by AbsoluteValue @@ -512,7 +514,7 @@ struct bpf_version { * but it might be used by some non-AVS drivers now or in the * future. */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + #define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ /* * Juniper-private data link type, as per request from @@ -520,12 +522,12 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MONITOR 164 + #define DLT_JUNIPER_MONITOR 164 /* * Reserved for BACnet MS/TP. */ -#define DLT_BACNET_MS_TP 165 + #define DLT_BACNET_MS_TP 165 /* * Another PPP variant as per request from Karsten Keil . @@ -538,17 +540,17 @@ struct bpf_version { * input packets such as port scans, packets from old lost connections, * etc. to force the connection to stay up). * - * The first byte of the PPP header (0xff03) is modified to accomodate + * The first byte of the PPP header (0xff03) is modified to accommodate * the direction - 0x00 = IN, 0x01 = OUT. */ -#define DLT_PPP_PPPD 166 + #define DLT_PPP_PPPD 166 /* * Names for backwards compatibility with older versions of some PPP * software; new software should use DLT_PPP_PPPD. */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + #define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD + #define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD /* * Juniper-private data link type, as per request from @@ -556,26 +558,26 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, cookies, etc.. */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 + #define DLT_JUNIPER_PPPOE 167 + #define DLT_JUNIPER_PPPOE_ATM 168 -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + #define DLT_GPRS_LLC 169 /* GPRS LLC */ + #define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ + #define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ /* * Requested by Oolan Zimmer for use in Gcom's T1/E1 line * monitoring equipment. */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 + #define DLT_GCOM_T1E1 172 + #define DLT_GCOM_SERIAL 173 /* * Juniper-private data link type, as per request from * Hannes Gredler . The DLT_ is used * for internal communication to Physical Interface Cards (PIC) */ -#define DLT_JUNIPER_PIC_PEER 174 + #define DLT_JUNIPER_PIC_PEER 174 /* * Link types requested by Gregor Maier of Endace @@ -583,8 +585,8 @@ struct bpf_version { * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of * the link-layer header. */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ + #define DLT_ERF_ETH 175 /* Ethernet */ + #define DLT_ERF_POS 176 /* Packet-over-SONET */ /* * Requested by Daniele Orlandi for raw LAPD @@ -592,32 +594,32 @@ struct bpf_version { * includes additional information before the LAPD header, so it's * not necessarily a generic LAPD header. */ -#define DLT_LINUX_LAPD 177 + #define DLT_LINUX_LAPD 177 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ are used for prepending meta-information * like interface index, interface name * before standard Ethernet, PPP, Frelay & C-HDLC Frames */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 + #define DLT_JUNIPER_ETHER 178 + #define DLT_JUNIPER_PPP 179 + #define DLT_JUNIPER_FRELAY 180 + #define DLT_JUNIPER_CHDLC 181 /* * Multi Link Frame Relay (FRF.16) */ -#define DLT_MFR 182 + #define DLT_MFR 182 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * voice Adapter Card (PIC) */ -#define DLT_JUNIPER_VP 183 + #define DLT_JUNIPER_VP 183 /* * Arinc 429 frames. @@ -626,38 +628,38 @@ struct bpf_version { * More documentation on Arinc 429 can be found at * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf */ -#define DLT_A429 184 + #define DLT_A429 184 /* * Arinc 653 Interpartition Communication messages. * DLT_ requested by Gianluca Varenni . * Please refer to the A653-1 standard for more information. */ -#define DLT_A653_ICM 185 + #define DLT_A653_ICM 185 /* * USB packets, beginning with a USB setup header; requested by * Paolo Abeni . */ -#define DLT_USB 186 + #define DLT_USB 186 /* * Bluetooth HCI UART transport layer (part H:4); requested by * Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4 187 + #define DLT_BLUETOOTH_HCI_H4 187 /* * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz * . */ -#define DLT_IEEE802_16_MAC_CPS 188 + #define DLT_IEEE802_16_MAC_CPS 188 /* * USB packets, beginning with a Linux USB header; requested by * Paolo Abeni . */ -#define DLT_USB_LINUX 189 + #define DLT_USB_LINUX 189 /* * Controller Area Network (CAN) v. 2.0B packets. @@ -666,79 +668,79 @@ struct bpf_version { * More documentation on the CAN v2.0B frames can be found at * http://www.can-cia.org/downloads/?269 */ -#define DLT_CAN20B 190 + #define DLT_CAN20B 190 /* * IEEE 802.15.4, with address fields padded, as is done by Linux * drivers; requested by Juergen Schimmer. */ -#define DLT_IEEE802_15_4_LINUX 191 + #define DLT_IEEE802_15_4_LINUX 191 /* * Per Packet Information encapsulated packets. * DLT_ requested by Gianluca Varenni . */ -#define DLT_PPI 192 + #define DLT_PPI 192 /* * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; * requested by Charles Clancy. */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + #define DLT_IEEE802_16_MAC_CPS_RADIO 193 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * integrated service module (ISM). */ -#define DLT_JUNIPER_ISM 194 + #define DLT_JUNIPER_ISM 194 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no * nothing); requested by Mikko Saarnivala . */ -#define DLT_IEEE802_15_4 195 + #define DLT_IEEE802_15_4 195 /* * Various link-layer types, with a pseudo-header, for SITA * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). */ -#define DLT_SITA 196 + #define DLT_SITA 196 /* * Various link-layer types, with a pseudo-header, for Endace DAG cards; * encapsulates Endace ERF records. Requested by Stephen Donnelly * . */ -#define DLT_ERF 197 + #define DLT_ERF 197 /* * Special header prepended to Ethernet packets when capturing from a * u10 Networks board. Requested by Phil Mulholland * . */ -#define DLT_RAIF1 198 + #define DLT_RAIF1 198 /* * IPMB packet for IPMI, beginning with the I2C slave address, followed * by the netFn and LUN, etc.. Requested by Chanthy Toeung * . */ -#define DLT_IPMB 199 + #define DLT_IPMB 199 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for capturing data on a secure tunnel interface. */ -#define DLT_JUNIPER_ST 200 + #define DLT_JUNIPER_ST 200 /* * Bluetooth HCI UART transport layer (part H:4), with pseudo-header * that includes direction information; requested by Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + #define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 /* * AX.25 packet with a 1-byte KISS header; see @@ -747,14 +749,14 @@ struct bpf_version { * * as per Richard Stearn . */ -#define DLT_AX25_KISS 202 + #define DLT_AX25_KISS 202 /* * LAPD packets from an ISDN channel, starting with the address field, * with no pseudo-header. * Requested by Varuna De Silva . */ -#define DLT_LAPD 203 + #define DLT_LAPD 203 /* * Variants of various link-layer headers, with a one-byte direction @@ -762,10 +764,10 @@ struct bpf_version { * non-zero (any non-zero value) means "sent by this host" - as per * Will Barker . */ -#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ -#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ -#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ -#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + #define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ + #define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ + #define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ + #define DLT_LAPB_WITH_DIR 207 /* LAPB */ /* * 208 is reserved for an as-yet-unspecified proprietary link-layer @@ -776,39 +778,39 @@ struct bpf_version { * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman * . */ -#define DLT_IPMB_LINUX 209 + #define DLT_IPMB_LINUX 209 /* * FlexRay automotive bus - http://www.flexray.com/ - as requested * by Hannes Kaelber . */ -#define DLT_FLEXRAY 210 + #define DLT_FLEXRAY 210 /* * Media Oriented Systems Transport (MOST) bus for multimedia * transport - http://www.mostcooperation.com/ - as requested * by Hannes Kaelber . */ -#define DLT_MOST 211 + #define DLT_MOST 211 /* * Local Interconnect Network (LIN) bus for vehicle networks - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber * . */ -#define DLT_LIN 212 + #define DLT_LIN 212 /* * X2E-private data link type used for serial line capture, * as requested by Hannes Kaelber . */ -#define DLT_X2E_SERIAL 213 + #define DLT_X2E_SERIAL 213 /* * X2E-private data link type used for the Xoraya data logger * family, as requested by Hannes Kaelber . */ -#define DLT_X2E_XORAYA 214 + #define DLT_X2E_XORAYA 214 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no @@ -819,7 +821,7 @@ struct bpf_version { * * Requested by Max Filippov . */ -#define DLT_IEEE802_15_4_NONASK_PHY 215 + #define DLT_IEEE802_15_4_NONASK_PHY 215 /* @@ -827,7 +829,7 @@ struct bpf_version { * a member of that class. A class value of 0 indicates a regular * DLT_/LINKTYPE_ value. */ -#define DLT_CLASS(x) ((x) & 0x03ff0000) + #define DLT_CLASS( x ) ( ( x ) & 0x03ff0000 ) /* * NetBSD-specific generic "raw" link type. The class value indicates @@ -836,99 +838,104 @@ struct bpf_version { * do not assume that they correspond to AF_ values for your operating * system. */ -#define DLT_CLASS_NETBSD_RAWAF 0x02240000 -#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) -#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) -#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + #define DLT_CLASS_NETBSD_RAWAF 0x02240000 + #define DLT_NETBSD_RAWAF( af ) ( DLT_CLASS_NETBSD_RAWAF | ( af ) ) + #define DLT_NETBSD_RAWAF_AF( x ) ( ( x ) & 0x0000ffff ) + #define DLT_IS_NETBSD_RAWAF( x ) ( DLT_CLASS( x ) == DLT_CLASS_NETBSD_RAWAF ) /* * The instruction encodings. */ /* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 + #define BPF_CLASS( code ) ( ( code ) & 0x07 ) + #define BPF_LD 0x00 + #define BPF_LDX 0x01 + #define BPF_ST 0x02 + #define BPF_STX 0x03 + #define BPF_ALU 0x04 + #define BPF_JMP 0x05 + #define BPF_RET 0x06 + #define BPF_MISC 0x07 /* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 + #define BPF_SIZE( code ) ( ( code ) & 0x18 ) + #define BPF_W 0x00 + #define BPF_H 0x08 + #define BPF_B 0x10 + #define BPF_MODE( code ) ( ( code ) & 0xe0 ) + #define BPF_IMM 0x00 + #define BPF_ABS 0x20 + #define BPF_IND 0x40 + #define BPF_MEM 0x60 + #define BPF_LEN 0x80 + #define BPF_MSH 0xa0 /* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 + #define BPF_OP( code ) ( ( code ) & 0xf0 ) + #define BPF_ADD 0x00 + #define BPF_SUB 0x10 + #define BPF_MUL 0x20 + #define BPF_DIV 0x30 + #define BPF_OR 0x40 + #define BPF_AND 0x50 + #define BPF_LSH 0x60 + #define BPF_RSH 0x70 + #define BPF_NEG 0x80 + #define BPF_JA 0x00 + #define BPF_JEQ 0x10 + #define BPF_JGT 0x20 + #define BPF_JGE 0x30 + #define BPF_JSET 0x40 + #define BPF_SRC( code ) ( ( code ) & 0x08 ) + #define BPF_K 0x00 + #define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 + #define BPF_RVAL( code ) ( ( code ) & 0x18 ) + #define BPF_A 0x10 /* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 + #define BPF_MISCOP( code ) ( ( code ) & 0xf8 ) + #define BPF_TAX 0x00 + #define BPF_TXA 0x80 /* * The instruction data structure. */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_u_int32 k; -}; + struct bpf_insn + { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; + }; /* * Macros for insn array initializers. */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + #define BPF_STMT( code, k ) { ( u_short ) ( code ), 0, 0, k } + #define BPF_JUMP( code, k, jt, jf ) { ( u_short ) ( code ), jt, jf, k } -#if __STDC__ || defined(__cplusplus) -extern int bpf_validate(const struct bpf_insn *, int); -extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -#else -extern int bpf_validate(); -extern u_int bpf_filter(); -#endif + #if __STDC__ || defined( __cplusplus ) + extern int bpf_validate( const struct bpf_insn *, + int ); + extern u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + #else + extern int bpf_validate(); + extern u_int bpf_filter(); + #endif /* * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). */ -#define BPF_MEMWORDS 16 + #define BPF_MEMWORDS 16 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef BPF_MAJOR_VERSION */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/namedb.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/namedb.h index 9002c7509..27bcaa5cc 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/namedb.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/namedb.h @@ -34,11 +34,11 @@ */ #ifndef lib_pcap_namedb_h -#define lib_pcap_namedb_h + #define lib_pcap_namedb_h -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* * As returned by the pcap_next_etherent() @@ -47,43 +47,52 @@ extern "C" { * on systems that don't have support for /etc/ethers, we * export these hooks since they'll */ -struct pcap_etherent { - u_char addr[6]; - char name[122]; -}; -#ifndef PCAP_ETHERS_FILE -#define PCAP_ETHERS_FILE "/etc/ethers" -#endif -struct pcap_etherent *pcap_next_etherent(FILE *); -u_char *pcap_ether_hostton(const char*); -u_char *pcap_ether_aton(const char *); + struct pcap_etherent + { + u_char addr[ 6 ]; + char name[ 122 ]; + }; + #ifndef PCAP_ETHERS_FILE + #define PCAP_ETHERS_FILE "/etc/ethers" + #endif + struct pcap_etherent * pcap_next_etherent( FILE * ); + u_char * pcap_ether_hostton( const char * ); + u_char * pcap_ether_aton( const char * ); -bpf_u_int32 **pcap_nametoaddr(const char *); -#ifdef INET6 -struct addrinfo *pcap_nametoaddrinfo(const char *); -#endif -bpf_u_int32 pcap_nametonetaddr(const char *); + bpf_u_int32 ** pcap_nametoaddr( const char * ); + #ifdef INET6 + struct addrinfo * pcap_nametoaddrinfo( const char * ); + #endif + bpf_u_int32 pcap_nametonetaddr( const char * ); + + int pcap_nametoport( const char *, + int *, + int * ); + int pcap_nametoportrange( const char *, + int *, + int *, + int * ); + int pcap_nametoproto( const char * ); + int pcap_nametoeproto( const char * ); + int pcap_nametollc( const char * ); -int pcap_nametoport(const char *, int *, int *); -int pcap_nametoportrange(const char *, int *, int *, int *); -int pcap_nametoproto(const char *); -int pcap_nametoeproto(const char *); -int pcap_nametollc(const char *); /* * If a protocol is unknown, PROTO_UNDEF is returned. * Also, pcap_nametoport() returns the protocol along with the port number. * If there are ambiguous entried in /etc/services (i.e. domain * can be either tcp or udp) PROTO_UNDEF is returned. */ -#define PROTO_UNDEF -1 + #define PROTO_UNDEF -1 /* XXX move these to pcap-int.h? */ -int __pcap_atodn(const char *, bpf_u_int32 *); -int __pcap_atoin(const char *, bpf_u_int32 *); -u_short __pcap_nametodnaddr(const char *); + int __pcap_atodn( const char *, + bpf_u_int32 * ); + int __pcap_atoin( const char *, + bpf_u_int32 * ); + u_short __pcap_nametodnaddr( const char * ); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_namedb_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/pcap.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/pcap.h index ad8fc40ac..20113a9e7 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/pcap.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/pcap.h @@ -1,4 +1,5 @@ /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ + /* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. @@ -35,59 +36,59 @@ */ #ifndef lib_pcap_pcap_h -#define lib_pcap_pcap_h + #define lib_pcap_pcap_h -#if defined(WIN32) - #include -#elif defined(MSDOS) - #include - #include /* u_int, u_char etc. */ -#else /* UN*X */ - #include - #include -#endif /* WIN32/MSDOS/UN*X */ + #if defined( WIN32 ) + #include + #elif defined( MSDOS ) + #include + #include /* u_int, u_char etc. */ + #else /* UN*X */ + #include + #include + #endif /* WIN32/MSDOS/UN*X */ -#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include -#endif + #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H + #include + #endif -#include + #include -#ifdef HAVE_REMOTE - // We have to define the SOCKET here, although it has been defined in sockutils.h - // This is to avoid the distribution of the 'sockutils.h' file around - // (for example in the WinPcap developer's pack) - #ifndef SOCKET - #ifdef WIN32 - #define SOCKET unsigned int - #else - #define SOCKET int - #endif - #endif -#endif + #ifdef HAVE_REMOTE + /* We have to define the SOCKET here, although it has been defined in sockutils.h */ + /* This is to avoid the distribution of the 'sockutils.h' file around */ + /* (for example in the WinPcap developer's pack) */ + #ifndef SOCKET + #ifdef WIN32 + #define SOCKET unsigned int + #else + #define SOCKET int + #endif + #endif + #endif /* ifdef HAVE_REMOTE */ -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 + #define PCAP_VERSION_MAJOR 2 + #define PCAP_VERSION_MINOR 4 -#define PCAP_ERRBUF_SIZE 256 + #define PCAP_ERRBUF_SIZE 256 /* * Compatibility for systems that have a bpf.h that * predates the bpf typedefs for 64-bit support. */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #if BPF_RELEASE - 0 < 199406 + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; + typedef struct pcap pcap_t; + typedef struct pcap_dumper pcap_dumper_t; + typedef struct pcap_if pcap_if_t; + typedef struct pcap_addr pcap_addr_t; /* * The first record in the file contains saved values for some @@ -126,31 +127,33 @@ typedef struct pcap_addr pcap_addr_t; * so that future versions of libpcap and programs that use it (such as * tcpdump) will be able to read your new capture file format. */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; + struct pcap_file_header + { + bpf_u_int32 magic; + u_short version_major; + u_short version_minor; + bpf_int32 thiszone; /* gmt to local correction */ + bpf_u_int32 sigfigs; /* accuracy of timestamps */ + bpf_u_int32 snaplen; /* max length saved portion of each pkt */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ + }; /* * Macros for the value returned by pcap_datalink_ext(). - * + * * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro * gives the FCS length of packets in the capture. */ -#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) -#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) -#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) + #define LT_FCS_LENGTH_PRESENT( x ) ( ( x ) & 0x04000000 ) + #define LT_FCS_LENGTH( x ) ( ( ( x ) & 0xF0000000 ) >> 28 ) + #define LT_FCS_DATALINK_EXT( x ) ( ( ( ( x ) & 0xF ) << 28 ) | 0x04000000 ) -typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT -} pcap_direction_t; + typedef enum + { + PCAP_D_INOUT = 0, + PCAP_D_IN, + PCAP_D_OUT + } pcap_direction_t; /* * Generic per-packet information, as supplied by libpcap. @@ -164,85 +167,92 @@ typedef enum { * should supply the appropriate version of "struct timeval", even if * that's not what the underlying packet capture mechanism supplies. */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; + struct pcap_pkthdr + { + struct timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ + }; /* * As returned by the pcap_stats() */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface XXX not yet supported */ -#ifdef HAVE_REMOTE - u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ - u_int ps_sent; /* number of packets sent by the server on the network */ - u_int ps_netdrop; /* number of packets lost on the network */ -#endif /* HAVE_REMOTE */ -}; + struct pcap_stat + { + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface XXX not yet supported */ + #ifdef HAVE_REMOTE + u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ + u_int ps_sent; /* number of packets sent by the server on the network */ + u_int ps_netdrop; /* number of packets lost on the network */ + #endif /* HAVE_REMOTE */ + }; + + #ifdef MSDOS -#ifdef MSDOS /* * As returned by the pcap_stats_ex() */ -struct pcap_stat_ex { - u_long rx_packets; /* total packets received */ - u_long tx_packets; /* total packets transmitted */ - u_long rx_bytes; /* total bytes received */ - u_long tx_bytes; /* total bytes transmitted */ - u_long rx_errors; /* bad packets received */ - u_long tx_errors; /* packet transmit problems */ - u_long rx_dropped; /* no space in Rx buffers */ - u_long tx_dropped; /* no space available for Tx */ - u_long multicast; /* multicast packets received */ - u_long collisions; + struct pcap_stat_ex + { + u_long rx_packets; /* total packets received */ + u_long tx_packets; /* total packets transmitted */ + u_long rx_bytes; /* total bytes received */ + u_long tx_bytes; /* total bytes transmitted */ + u_long rx_errors; /* bad packets received */ + u_long tx_errors; /* packet transmit problems */ + u_long rx_dropped; /* no space in Rx buffers */ + u_long tx_dropped; /* no space available for Tx */ + u_long multicast; /* multicast packets received */ + u_long collisions; - /* detailed rx_errors: */ - u_long rx_length_errors; - u_long rx_over_errors; /* receiver ring buff overflow */ - u_long rx_crc_errors; /* recv'd pkt with crc error */ - u_long rx_frame_errors; /* recv'd frame alignment error */ - u_long rx_fifo_errors; /* recv'r fifo overrun */ - u_long rx_missed_errors; /* recv'r missed packet */ + /* detailed rx_errors: */ + u_long rx_length_errors; + u_long rx_over_errors; /* receiver ring buff overflow */ + u_long rx_crc_errors; /* recv'd pkt with crc error */ + u_long rx_frame_errors; /* recv'd frame alignment error */ + u_long rx_fifo_errors; /* recv'r fifo overrun */ + u_long rx_missed_errors; /* recv'r missed packet */ - /* detailed tx_errors */ - u_long tx_aborted_errors; - u_long tx_carrier_errors; - u_long tx_fifo_errors; - u_long tx_heartbeat_errors; - u_long tx_window_errors; - }; -#endif + /* detailed tx_errors */ + u_long tx_aborted_errors; + u_long tx_carrier_errors; + u_long tx_fifo_errors; + u_long tx_heartbeat_errors; + u_long tx_window_errors; + }; + #endif /* ifdef MSDOS */ /* * Item in a list of interfaces. */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; + struct pcap_if + { + struct pcap_if * next; + char * name; /* name to hand to "pcap_open_live()" */ + char * description; /* textual description of interface, or NULL */ + struct pcap_addr * addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ + }; -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ + #define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ /* * Representation of an interface address. */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; + struct pcap_addr + { + struct pcap_addr * next; + struct sockaddr * addr; /* address */ + struct sockaddr * netmask; /* netmask for that address */ + struct sockaddr * broadaddr; /* broadcast address for that address */ + struct sockaddr * dstaddr; /* P2P destination address for that address */ + }; -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); + typedef void (* pcap_handler)( u_char *, + const struct pcap_pkthdr *, + const u_char * ); /* * Error codes for the pcap API. @@ -250,158 +260,222 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, * failure of a call that returns these codes by checking for a * negative value. */ -#define PCAP_ERROR -1 /* generic error code */ -#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ -#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ -#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ -#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ -#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ -#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ -#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ -#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ + #define PCAP_ERROR -1 /* generic error code */ + #define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ + #define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ + #define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ + #define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ + #define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ + #define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ + #define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ + #define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ /* * Warning codes for the pcap API. * These will all be positive and non-zero, so they won't look like * errors. */ -#define PCAP_WARNING 1 /* generic warning code */ -#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ + #define PCAP_WARNING 1 /* generic warning code */ + #define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ -char *pcap_lookupdev(char *); -int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); + char * pcap_lookupdev( char * ); + int pcap_lookupnet( const char *, + bpf_u_int32 *, + bpf_u_int32 *, + char * ); -pcap_t *pcap_create(const char *, char *); -int pcap_set_snaplen(pcap_t *, int); -int pcap_set_promisc(pcap_t *, int); -int pcap_can_set_rfmon(pcap_t *); -int pcap_set_rfmon(pcap_t *, int); -int pcap_set_timeout(pcap_t *, int); -int pcap_set_buffer_size(pcap_t *, int); -int pcap_activate(pcap_t *); + pcap_t * pcap_create( const char *, + char * ); + int pcap_set_snaplen( pcap_t *, + int ); + int pcap_set_promisc( pcap_t *, + int ); + int pcap_can_set_rfmon( pcap_t * ); + int pcap_set_rfmon( pcap_t *, + int ); + int pcap_set_timeout( pcap_t *, + int ); + int pcap_set_buffer_size( pcap_t *, + int ); + int pcap_activate( pcap_t * ); -pcap_t *pcap_open_live(const char *, int, int, int, char *); -pcap_t *pcap_open_dead(int, int); -pcap_t *pcap_open_offline(const char *, char *); -#if defined(WIN32) -pcap_t *pcap_hopen_offline(intptr_t, char *); -#if !defined(LIBPCAP_EXPORTS) -#define pcap_fopen_offline(f,b) \ - pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) -#else /*LIBPCAP_EXPORTS*/ -static pcap_t *pcap_fopen_offline(FILE *, char *); -#endif -#else /*WIN32*/ -pcap_t *pcap_fopen_offline(FILE *, char *); -#endif /*WIN32*/ + pcap_t * pcap_open_live( const char *, + int, + int, + int, + char * ); + pcap_t * pcap_open_dead( int, + int ); + pcap_t * pcap_open_offline( const char *, + char * ); + #if defined( WIN32 ) + pcap_t * pcap_hopen_offline( intptr_t, + char * ); + #if !defined( LIBPCAP_EXPORTS ) + #define pcap_fopen_offline( f, b ) \ + pcap_hopen_offline( _get_osfhandle( _fileno( f ) ), b ) + #else /*LIBPCAP_EXPORTS*/ + static pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif + #else /*WIN32*/ + pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif /*WIN32*/ -void pcap_close(pcap_t *); -int pcap_loop(pcap_t *, int, pcap_handler, u_char *); -int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); -const u_char* - pcap_next(pcap_t *, struct pcap_pkthdr *); -int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); -void pcap_breakloop(pcap_t *); -int pcap_stats(pcap_t *, struct pcap_stat *); -int pcap_setfilter(pcap_t *, struct bpf_program *); -int pcap_setdirection(pcap_t *, pcap_direction_t); -int pcap_getnonblock(pcap_t *, char *); -int pcap_setnonblock(pcap_t *, int, char *); -int pcap_inject(pcap_t *, const void *, size_t); -int pcap_sendpacket(pcap_t *, const u_char *, int); -const char *pcap_statustostr(int); -const char *pcap_strerror(int); -char *pcap_geterr(pcap_t *); -void pcap_perror(pcap_t *, char *); -int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32); -int pcap_compile_nopcap(int, int, struct bpf_program *, - const char *, int, bpf_u_int32); -void pcap_freecode(struct bpf_program *); -int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *, - const u_char *); -int pcap_datalink(pcap_t *); -int pcap_datalink_ext(pcap_t *); -int pcap_list_datalinks(pcap_t *, int **); -int pcap_set_datalink(pcap_t *, int); -void pcap_free_datalinks(int *); -int pcap_datalink_name_to_val(const char *); -const char *pcap_datalink_val_to_name(int); -const char *pcap_datalink_val_to_description(int); -int pcap_snapshot(pcap_t *); -int pcap_is_swapped(pcap_t *); -int pcap_major_version(pcap_t *); -int pcap_minor_version(pcap_t *); + void pcap_close( pcap_t * ); + int pcap_loop( pcap_t *, + int, + pcap_handler, + u_char * ); + int pcap_dispatch( pcap_t *, + int, + pcap_handler, + u_char * ); + const u_char * pcap_next( pcap_t *, + struct pcap_pkthdr * ); + int pcap_next_ex( pcap_t *, + struct pcap_pkthdr **, + const u_char ** ); + void pcap_breakloop( pcap_t * ); + int pcap_stats( pcap_t *, + struct pcap_stat * ); + int pcap_setfilter( pcap_t *, + struct bpf_program * ); + int pcap_setdirection( pcap_t *, + pcap_direction_t ); + int pcap_getnonblock( pcap_t *, + char * ); + int pcap_setnonblock( pcap_t *, + int, + char * ); + int pcap_inject( pcap_t *, + const void *, + size_t ); + int pcap_sendpacket( pcap_t *, + const u_char *, + int ); + const char * pcap_statustostr( int ); + const char * pcap_strerror( int ); + char * pcap_geterr( pcap_t * ); + void pcap_perror( pcap_t *, + char * ); + int pcap_compile( pcap_t *, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + int pcap_compile_nopcap( int, + int, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + void pcap_freecode( struct bpf_program * ); + int pcap_offline_filter( struct bpf_program *, + const struct pcap_pkthdr *, + const u_char * ); + int pcap_datalink( pcap_t * ); + int pcap_datalink_ext( pcap_t * ); + int pcap_list_datalinks( pcap_t *, + int ** ); + int pcap_set_datalink( pcap_t *, + int ); + void pcap_free_datalinks( int * ); + int pcap_datalink_name_to_val( const char * ); + const char * pcap_datalink_val_to_name( int ); + const char * pcap_datalink_val_to_description( int ); + int pcap_snapshot( pcap_t * ); + int pcap_is_swapped( pcap_t * ); + int pcap_major_version( pcap_t * ); + int pcap_minor_version( pcap_t * ); /* XXX */ -FILE *pcap_file(pcap_t *); -int pcap_fileno(pcap_t *); + FILE * pcap_file( pcap_t * ); + int pcap_fileno( pcap_t * ); -pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); -pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); -FILE *pcap_dump_file(pcap_dumper_t *); -long pcap_dump_ftell(pcap_dumper_t *); -int pcap_dump_flush(pcap_dumper_t *); -void pcap_dump_close(pcap_dumper_t *); -void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); + pcap_dumper_t * pcap_dump_open( pcap_t *, + const char * ); + pcap_dumper_t * pcap_dump_fopen( pcap_t *, + FILE * fp ); + FILE * pcap_dump_file( pcap_dumper_t * ); + long pcap_dump_ftell( pcap_dumper_t * ); + int pcap_dump_flush( pcap_dumper_t * ); + void pcap_dump_close( pcap_dumper_t * ); + void pcap_dump( u_char *, + const struct pcap_pkthdr *, + const u_char * ); -int pcap_findalldevs(pcap_if_t **, char *); -void pcap_freealldevs(pcap_if_t *); + int pcap_findalldevs( pcap_if_t **, + char * ); + void pcap_freealldevs( pcap_if_t * ); -const char *pcap_lib_version(void); + const char * pcap_lib_version( void ); /* XXX this guy lives in the bpf tree */ -u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -int bpf_validate(const struct bpf_insn *f, int len); -char *bpf_image(const struct bpf_insn *, int); -void bpf_dump(const struct bpf_program *, int); + u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + int bpf_validate( const struct bpf_insn * f, + int len ); + char * bpf_image( const struct bpf_insn *, + int ); + void bpf_dump( const struct bpf_program *, + int ); -#if defined(WIN32) + #if defined( WIN32 ) /* * Win32 definitions */ -int pcap_setbuff(pcap_t *p, int dim); -int pcap_setmode(pcap_t *p, int mode); -int pcap_setmintocopy(pcap_t *p, int size); + int pcap_setbuff( pcap_t * p, + int dim ); + int pcap_setmode( pcap_t * p, + int mode ); + int pcap_setmintocopy( pcap_t * p, + int size ); -#ifdef WPCAP + #ifdef WPCAP /* Include file with the wpcap-specific extensions */ -#include -#endif /* WPCAP */ + #include + #endif /* WPCAP */ -#define MODE_CAPT 0 -#define MODE_STAT 1 -#define MODE_MON 2 + #define MODE_CAPT 0 + #define MODE_STAT 1 + #define MODE_MON 2 -#elif defined(MSDOS) + #elif defined( MSDOS ) /* * MS-DOS definitions */ -int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); -void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); -u_long pcap_mac_packets (void); + int pcap_stats_ex( pcap_t *, + struct pcap_stat_ex * ); + void pcap_set_wait( pcap_t * p, + void ( * yield )( void ), + int wait ); + u_long pcap_mac_packets( void ); -#else /* UN*X */ + #else /* UN*X */ /* * UN*X definitions */ -int pcap_get_selectable_fd(pcap_t *); + int pcap_get_selectable_fd( pcap_t * ); -#endif /* WIN32/MSDOS/UN*X */ + #endif /* WIN32/MSDOS/UN*X */ -#ifdef HAVE_REMOTE + #ifdef HAVE_REMOTE /* Includes most of the public stuff that is needed for the remote capture */ -#include -#endif /* HAVE_REMOTE */ + #include + #endif /* HAVE_REMOTE */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_pcap_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/sll.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/sll.h index e9d5452af..e5052236a 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/sll.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/sll.h @@ -79,15 +79,16 @@ /* * A DLT_LINUX_SLL fake link-layer header. */ -#define SLL_HDR_LEN 16 /* total header length */ -#define SLL_ADDRLEN 8 /* length of address field */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ -struct sll_header { - u_int16_t sll_pkttype; /* packet type */ - u_int16_t sll_hatype; /* link-layer address type */ - u_int16_t sll_halen; /* link-layer address length */ - u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ - u_int16_t sll_protocol; /* protocol */ +struct sll_header +{ + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[ SLL_ADDRLEN ]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ }; /* @@ -96,11 +97,11 @@ struct sll_header { * available even on systems other than Linux, and so that they * don't change even if the PACKET_ values change. */ -#define LINUX_SLL_HOST 0 -#define LINUX_SLL_BROADCAST 1 -#define LINUX_SLL_MULTICAST 2 -#define LINUX_SLL_OTHERHOST 3 -#define LINUX_SLL_OUTGOING 4 +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 /* * The LINUX_SLL_ values for "sll_protocol"; these correspond to the @@ -123,7 +124,7 @@ struct sll_header { * in the Linux "if_ether.h" will, I suspect, actually show up in * captures.) */ -#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ -#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ -#endif +#endif /* ifndef lib_pcap_sll_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/usb.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/usb.h index adcd19c05..44a3c9557 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/usb.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/usb.h @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,36 +32,37 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $ */ - + #ifndef _PCAP_USB_STRUCTS_H__ #define _PCAP_USB_STRUCTS_H__ -/* +/* * possible transfer mode */ -#define URB_TRANSFER_IN 0x80 -#define URB_ISOCHRONOUS 0x0 -#define URB_INTERRUPT 0x1 -#define URB_CONTROL 0x2 -#define URB_BULK 0x3 +#define URB_TRANSFER_IN 0x80 +#define URB_ISOCHRONOUS 0x0 +#define URB_INTERRUPT 0x1 +#define URB_CONTROL 0x2 +#define URB_BULK 0x3 /* * possible event type */ -#define URB_SUBMIT 'S' -#define URB_COMPLETE 'C' -#define URB_ERROR 'E' +#define URB_SUBMIT 'S' +#define URB_COMPLETE 'C' +#define URB_ERROR 'E' /* * USB setup header as defined in USB specification. * Appears at the front of each packet in DLT_USB captures. */ -typedef struct _usb_setup { - u_int8_t bmRequestType; - u_int8_t bRequest; - u_int16_t wValue; - u_int16_t wIndex; - u_int16_t wLength; +typedef struct _usb_setup +{ + u_int8_t bmRequestType; + u_int8_t bRequest; + u_int16_t wValue; + u_int16_t wIndex; + u_int16_t wLength; } pcap_usb_setup; @@ -69,22 +70,23 @@ typedef struct _usb_setup { * Header prepended by linux kernel to each event. * Appears at the front of each packet in DLT_USB_LINUX captures. */ -typedef struct _usb_header { - u_int64_t id; - u_int8_t event_type; - u_int8_t transfer_type; - u_int8_t endpoint_number; - u_int8_t device_address; - u_int16_t bus_id; - char setup_flag;/*if !=0 the urb setup header is not present*/ - char data_flag; /*if !=0 no urb data is present*/ - int64_t ts_sec; - int32_t ts_usec; - int32_t status; - u_int32_t urb_len; - u_int32_t data_len; /* amount of urb data really present in this event*/ - pcap_usb_setup setup; +typedef struct _usb_header +{ + u_int64_t id; + u_int8_t event_type; + u_int8_t transfer_type; + u_int8_t endpoint_number; + u_int8_t device_address; + u_int16_t bus_id; + char setup_flag; /*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + u_int32_t urb_len; + u_int32_t data_len; /* amount of urb data really present in this event*/ + pcap_usb_setup setup; } pcap_usb_header; -#endif +#endif /* ifndef _PCAP_USB_STRUCTS_H__ */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/vlan.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/vlan.h index b0cb7949b..e9be8bd16 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/vlan.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/pcap/vlan.h @@ -36,11 +36,12 @@ #ifndef lib_pcap_vlan_h #define lib_pcap_vlan_h -struct vlan_tag { - u_int16_t vlan_tpid; /* ETH_P_8021Q */ - u_int16_t vlan_tci; /* VLAN TCI */ +struct vlan_tag +{ + u_int16_t vlan_tpid; /* ETH_P_8021Q */ + u_int16_t vlan_tci; /* VLAN TCI */ }; -#define VLAN_TAG_LEN 4 +#define VLAN_TAG_LEN 4 -#endif +#endif /* ifndef lib_pcap_vlan_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/remote-ext.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/remote-ext.h index 35a2fff6c..42d1fe6e9 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/remote-ext.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/WinPCap/remote-ext.h @@ -2,443 +2,471 @@ * Copyright (c) 2002 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions * are met: - * - * 1. Redistributions of source code must retain the above copyright + * + * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * */ #ifndef __REMOTE_EXT_H__ -#define __REMOTE_EXT_H__ + #define __REMOTE_EXT_H__ -#ifndef HAVE_REMOTE -#error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h -#endif + #ifndef HAVE_REMOTE + #error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h + #endif -// Definition for Microsoft Visual Studio -#if _MSC_VER > 1000 -#pragma once -#endif +/* Definition for Microsoft Visual Studio */ + #if _MSC_VER > 1000 + #pragma once + #endif -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /*! - \file remote-ext.h - - The goal of this file it to include most of the new definitions that should be - placed into the pcap.h file. - - It includes all new definitions (structures and functions like pcap_open(). - Some of the functions are not really a remote feature, but, right now, - they are placed here. -*/ + * \file remote-ext.h + * + * The goal of this file it to include most of the new definitions that should be + * placed into the pcap.h file. + * + * It includes all new definitions (structures and functions like pcap_open(). + * Some of the functions are not really a remote feature, but, right now, + * they are placed here. + */ -// All this stuff is public +/* All this stuff is public */ + /*! \addtogroup remote_struct - \{ -*/ - + \{ + */ /*! - \brief Defines the maximum buffer size in which address, port, interface names are kept. - - In case the adapter name or such is larger than this value, it is truncated. - This is not used by the user; however it must be aware that an hostname / interface - name longer than this value will be truncated. -*/ -#define PCAP_BUF_SIZE 1024 + * \brief Defines the maximum buffer size in which address, port, interface names are kept. + * + * In case the adapter name or such is larger than this value, it is truncated. + * This is not used by the user; however it must be aware that an hostname / interface + * name longer than this value will be truncated. + */ + #define PCAP_BUF_SIZE 1024 /*! \addtogroup remote_source_ID - \{ -*/ + \{ + */ /*! - \brief Internal representation of the type of source in use (file, - remote/local interface). - - This indicates a file, i.e. the user want to open a capture from a local file. -*/ -#define PCAP_SRC_FILE 2 -/*! - \brief Internal representation of the type of source in use (file, - remote/local interface). - - This indicates a local interface, i.e. the user want to open a capture from - a local interface. This does not involve the RPCAP protocol. -*/ -#define PCAP_SRC_IFLOCAL 3 -/*! - \brief Internal representation of the type of source in use (file, - remote/local interface). - - This indicates a remote interface, i.e. the user want to open a capture from - an interface on a remote host. This does involve the RPCAP protocol. -*/ -#define PCAP_SRC_IFREMOTE 4 + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a file, i.e. the user want to open a capture from a local file. + */ + #define PCAP_SRC_FILE 2 /*! - \} -*/ + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a local interface, i.e. the user want to open a capture from + * a local interface. This does not involve the RPCAP protocol. + */ + #define PCAP_SRC_IFLOCAL 3 + +/*! + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a remote interface, i.e. the user want to open a capture from + * an interface on a remote host. This does involve the RPCAP protocol. + */ + #define PCAP_SRC_IFREMOTE 4 + +/*! + \} + */ /*! \addtogroup remote_source_string - - The formats allowed by the pcap_open() are the following: - - file://path_and_filename [opens a local file] - - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] - - rpcap://host/devicename [opens the selected device available on a remote host] - - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] - - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] - - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] - - The formats allowed by the pcap_findalldevs_ex() are the following: - - file://folder/ [lists all the files in the given folder] - - rpcap:// [lists all local adapters] - - rpcap://host:port/ [lists the devices available on a remote host] - - Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since - IPv6 is fully supported, these are the allowed formats: - - - host (literal): e.g. host.foo.bar - - host (numeric IPv4): e.g. 10.11.12.13 - - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] - - host (numeric IPv6): e.g. [1:2:3::4] - - port: can be either numeric (e.g. '80') or literal (e.g. 'http') - - Here you find some allowed examples: - - rpcap://host.foo.bar/devicename [everything literal, no port number] - - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] - - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] - - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] - - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] - - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] - - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] - - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] - - \{ -*/ + * + * The formats allowed by the pcap_open() are the following: + * - file://path_and_filename [opens a local file] + * - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] + * - rpcap://host/devicename [opens the selected device available on a remote host] + * - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] + * - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] + * - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] + * + * The formats allowed by the pcap_findalldevs_ex() are the following: + * - file://folder/ [lists all the files in the given folder] + * - rpcap:// [lists all local adapters] + * - rpcap://host:port/ [lists the devices available on a remote host] + * + * Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since + * IPv6 is fully supported, these are the allowed formats: + * + * - host (literal): e.g. host.foo.bar + * - host (numeric IPv4): e.g. 10.11.12.13 + * - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] + * - host (numeric IPv6): e.g. [1:2:3::4] + * - port: can be either numeric (e.g. '80') or literal (e.g. 'http') + * + * Here you find some allowed examples: + * - rpcap://host.foo.bar/devicename [everything literal, no port number] + * - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] + * - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] + * - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] + * - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] + * - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] + * - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] + * - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] + * + \{ + */ /*! - \brief String that will be used to determine the type of source in use (file, - remote/local interface). - - This string will be prepended to the interface name in order to create a string - that contains all the information required to open the source. - - This string indicates that the user wants to open a capture from a local file. -*/ -#define PCAP_SRC_FILE_STRING "file://" -/*! - \brief String that will be used to determine the type of source in use (file, - remote/local interface). - - This string will be prepended to the interface name in order to create a string - that contains all the information required to open the source. - - This string indicates that the user wants to open a capture from a network interface. - This string does not necessarily involve the use of the RPCAP protocol. If the - interface required resides on the local host, the RPCAP protocol is not involved - and the local functions are used. -*/ -#define PCAP_SRC_IF_STRING "rpcap://" + * \brief String that will be used to determine the type of source in use (file, + * remote/local interface). + * + * This string will be prepended to the interface name in order to create a string + * that contains all the information required to open the source. + * + * This string indicates that the user wants to open a capture from a local file. + */ + #define PCAP_SRC_FILE_STRING "file://" /*! - \} -*/ - + * \brief String that will be used to determine the type of source in use (file, + * remote/local interface). + * + * This string will be prepended to the interface name in order to create a string + * that contains all the information required to open the source. + * + * This string indicates that the user wants to open a capture from a network interface. + * This string does not necessarily involve the use of the RPCAP protocol. If the + * interface required resides on the local host, the RPCAP protocol is not involved + * and the local functions are used. + */ + #define PCAP_SRC_IF_STRING "rpcap://" +/*! + \} + */ /*! - \addtogroup remote_open_flags - \{ -*/ + * \addtogroup remote_open_flags + \{ + */ /*! - \brief Defines if the adapter has to go in promiscuous mode. - - It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise. - Note that even if this parameter is false, the interface could well be in promiscuous - mode for some other reason (for example because another capture process with - promiscuous mode enabled is currently using that interface). - On on Linux systems with 2.2 or later kernels (that have the "any" device), this - flag does not work on the "any" device; if an argument of "any" is supplied, - the 'promisc' flag is ignored. -*/ -#define PCAP_OPENFLAG_PROMISCUOUS 1 + * \brief Defines if the adapter has to go in promiscuous mode. + * + * It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise. + * Note that even if this parameter is false, the interface could well be in promiscuous + * mode for some other reason (for example because another capture process with + * promiscuous mode enabled is currently using that interface). + * On on Linux systems with 2.2 or later kernels (that have the "any" device), this + * flag does not work on the "any" device; if an argument of "any" is supplied, + * the 'promisc' flag is ignored. + */ + #define PCAP_OPENFLAG_PROMISCUOUS 1 /*! - \brief Defines if the data trasfer (in case of a remote - capture) has to be done with UDP protocol. - - If it is '1' if you want a UDP data connection, '0' if you want - a TCP data connection; control connection is always TCP-based. - A UDP connection is much lighter, but it does not guarantee that all - the captured packets arrive to the client workstation. Moreover, - it could be harmful in case of network congestion. - This flag is meaningless if the source is not a remote interface. - In that case, it is simply ignored. -*/ -#define PCAP_OPENFLAG_DATATX_UDP 2 + * \brief Defines if the data transfer (in case of a remote + * capture) has to be done with UDP protocol. + * + * If it is '1' if you want a UDP data connection, '0' if you want + * a TCP data connection; control connection is always TCP-based. + * A UDP connection is much lighter, but it does not guarantee that all + * the captured packets arrive to the client workstation. Moreover, + * it could be harmful in case of network congestion. + * This flag is meaningless if the source is not a remote interface. + * In that case, it is simply ignored. + */ + #define PCAP_OPENFLAG_DATATX_UDP 2 /*! - \brief Defines if the remote probe will capture its own generated traffic. - - In case the remote probe uses the same interface to capture traffic and to send - data back to the caller, the captured traffic includes the RPCAP traffic as well. - If this flag is turned on, the RPCAP traffic is excluded from the capture, so that - the trace returned back to the collector is does not include this traffic. -*/ -#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 + * \brief Defines if the remote probe will capture its own generated traffic. + * + * In case the remote probe uses the same interface to capture traffic and to send + * data back to the caller, the captured traffic includes the RPCAP traffic as well. + * If this flag is turned on, the RPCAP traffic is excluded from the capture, so that + * the trace returned back to the collector is does not include this traffic. + */ + #define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 /*! - \brief Defines if the local adapter will capture its own generated traffic. - - This flag tells the underlying capture driver to drop the packets that were sent by itself. - This is usefult when building applications like bridges, that should ignore the traffic - they just sent. -*/ -#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 + * \brief Defines if the local adapter will capture its own generated traffic. + * + * This flag tells the underlying capture driver to drop the packets that were sent by itself. + * This is useful when building applications like bridges, that should ignore the traffic + * they just sent. + */ + #define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 /*! - \brief This flag configures the adapter for maximum responsiveness. - - In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before - copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, - i.e. better performance, which is good for applications like sniffers. If the user sets the - PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application - is ready to receive them. This is suggested for real time applications (like, for example, a bridge) - that need the best responsiveness.*/ -#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 + * \brief This flag configures the adapter for maximum responsiveness. + * + * In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before + * copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, + * i.e. better performance, which is good for applications like sniffers. If the user sets the + * PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application + * is ready to receive them. This is suggested for real time applications (like, for example, a bridge) + * that need the best responsiveness.*/ + #define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 /*! - \} -*/ + \} + */ /*! - \addtogroup remote_samp_methods - \{ -*/ + * \addtogroup remote_samp_methods + \{ + */ /*! - \brief No sampling has to be done on the current capture. - - In this case, no sampling algorithms are applied to the current capture. -*/ -#define PCAP_SAMP_NOSAMP 0 + * \brief No sampling has to be done on the current capture. + * + * In this case, no sampling algorithms are applied to the current capture. + */ + #define PCAP_SAMP_NOSAMP 0 /*! - \brief It defines that only 1 out of N packets must be returned to the user. - - In this case, the 'value' field of the 'pcap_samp' structure indicates the - number of packets (minus 1) that must be discarded before one packet got accepted. - In other words, if 'value = 10', the first packet is returned to the caller, while - the following 9 are discarded. -*/ -#define PCAP_SAMP_1_EVERY_N 1 + * \brief It defines that only 1 out of N packets must be returned to the user. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates the + * number of packets (minus 1) that must be discarded before one packet got accepted. + * In other words, if 'value = 10', the first packet is returned to the caller, while + * the following 9 are discarded. + */ + #define PCAP_SAMP_1_EVERY_N 1 /*! - \brief It defines that we have to return 1 packet every N milliseconds. - - In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting - time' in milliseconds before one packet got accepted. - In other words, if 'value = 10', the first packet is returned to the caller; the next - returned one will be the first packet that arrives when 10ms have elapsed. -*/ -#define PCAP_SAMP_FIRST_AFTER_N_MS 2 + * \brief It defines that we have to return 1 packet every N milliseconds. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting + * time' in milliseconds before one packet got accepted. + * In other words, if 'value = 10', the first packet is returned to the caller; the next + * returned one will be the first packet that arrives when 10ms have elapsed. + */ + #define PCAP_SAMP_FIRST_AFTER_N_MS 2 /*! - \} -*/ + \} + */ /*! - \addtogroup remote_auth_methods - \{ -*/ + * \addtogroup remote_auth_methods + \{ + */ /*! - \brief It defines the NULL authentication. - - This value has to be used within the 'type' member of the pcap_rmtauth structure. - The 'NULL' authentication has to be equal to 'zero', so that old applications - can just put every field of struct pcap_rmtauth to zero, and it does work. -*/ -#define RPCAP_RMTAUTH_NULL 0 -/*! - \brief It defines the username/password authentication. - - With this type of authentication, the RPCAP protocol will use the username/ - password provided to authenticate the user on the remote machine. If the - authentication is successful (and the user has the right to open network devices) - the RPCAP connection will continue; otherwise it will be dropped. - - This value has to be used within the 'type' member of the pcap_rmtauth structure. -*/ -#define RPCAP_RMTAUTH_PWD 1 + * \brief It defines the NULL authentication. + * + * This value has to be used within the 'type' member of the pcap_rmtauth structure. + * The 'NULL' authentication has to be equal to 'zero', so that old applications + * can just put every field of struct pcap_rmtauth to zero, and it does work. + */ + #define RPCAP_RMTAUTH_NULL 0 /*! - \} -*/ + * \brief It defines the username/password authentication. + * + * With this type of authentication, the RPCAP protocol will use the username/ + * password provided to authenticate the user on the remote machine. If the + * authentication is successful (and the user has the right to open network devices) + * the RPCAP connection will continue; otherwise it will be dropped. + * + * This value has to be used within the 'type' member of the pcap_rmtauth structure. + */ + #define RPCAP_RMTAUTH_PWD 1 +/*! + \} + */ /*! + * + * \brief This structure keeps the information needed to authenticate + * the user on a remote machine. + * + * The remote machine can either grant or refuse the access according + * to the information provided. + * In case the NULL authentication is required, both 'username' and + * 'password' can be NULL pointers. + * + * This structure is meaningless if the source is not a remote interface; + * in that case, the functions which requires such a structure can accept + * a NULL pointer as well. + */ + struct pcap_rmtauth + { + /*! + * \brief Type of the authentication required. + * + * In order to provide maximum flexibility, we can support different types + * of authentication based on the value of this 'type' variable. The currently + * supported authentication methods are defined into the + * \link remote_auth_methods Remote Authentication Methods Section\endlink. + * + */ + int type; - \brief This structure keeps the information needed to autheticate - the user on a remote machine. - - The remote machine can either grant or refuse the access according - to the information provided. - In case the NULL authentication is required, both 'username' and - 'password' can be NULL pointers. - - This structure is meaningless if the source is not a remote interface; - in that case, the functions which requires such a structure can accept - a NULL pointer as well. -*/ -struct pcap_rmtauth -{ - /*! - \brief Type of the authentication required. + /*! + * \brief Zero-terminated string containing the username that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char * username; - In order to provide maximum flexibility, we can support different types - of authentication based on the value of this 'type' variable. The currently - supported authentication methods are defined into the - \link remote_auth_methods Remote Authentication Methods Section\endlink. - - */ - int type; - /*! - \brief Zero-terminated string containing the username that has to be - used on the remote machine for authentication. - - This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication - and it can be NULL. - */ - char *username; - /*! - \brief Zero-terminated string containing the password that has to be - used on the remote machine for authentication. - - This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication - and it can be NULL. - */ - char *password; -}; + /*! + * \brief Zero-terminated string containing the password that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char * password; + }; /*! - \brief This structure defines the information related to sampling. + * \brief This structure defines the information related to sampling. + * + * In case the sampling is requested, the capturing device should read + * only a subset of the packets coming from the source. The returned packets depend + * on the sampling parameters. + * + * \warning The sampling process is applied after the filtering process. + * In other words, packets are filtered first, then the sampling process selects a + * subset of the 'filtered' packets and it returns them to the caller. + */ + struct pcap_samp + { + /*! + * Method used for sampling. Currently, the supported methods are listed in the + * \link remote_samp_methods Sampling Methods Section\endlink. + */ + int method; - In case the sampling is requested, the capturing device should read - only a subset of the packets coming from the source. The returned packets depend - on the sampling parameters. - - \warning The sampling process is applied after the filtering process. - In other words, packets are filtered first, then the sampling process selects a - subset of the 'filtered' packets and it returns them to the caller. -*/ -struct pcap_samp -{ - /*! - Method used for sampling. Currently, the supported methods are listed in the - \link remote_samp_methods Sampling Methods Section\endlink. - */ - int method; - - /*! - This value depends on the sampling method defined. For its meaning, please check - at the \link remote_samp_methods Sampling Methods Section\endlink. - */ - int value; -}; + /*! + * This value depends on the sampling method defined. For its meaning, please check + * at the \link remote_samp_methods Sampling Methods Section\endlink. + */ + int value; + }; - -//! Maximum lenght of an host name (needed for the RPCAP active mode) -#define RPCAP_HOSTLIST_SIZE 1024 +/*! Maximum length of an host name (needed for the RPCAP active mode) */ + #define RPCAP_HOSTLIST_SIZE 1024 /*! - \} -*/ // end of public documentation + \} + *//* end of public documentation */ -// Exported functions +/* Exported functions */ /** \name New WinPcap functions - - This section lists the new functions that are able to help considerably in writing - WinPcap programs because of their easiness of use. + * + * This section lists the new functions that are able to help considerably in writing + * WinPcap programs because of their easiness of use. */ -//\{ -pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf); -int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf); -int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf); -int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf); -struct pcap_samp *pcap_setsampling(pcap_t *p); +/*\{ */ + pcap_t * pcap_open( const char * source, + int snaplen, + int flags, + int read_timeout, + struct pcap_rmtauth * auth, + char * errbuf ); + int pcap_createsrcstr( char * source, + int type, + const char * host, + const char * port, + const char * name, + char * errbuf ); + int pcap_parsesrcstr( const char * source, + int * type, + char * host, + char * port, + char * name, + char * errbuf ); + int pcap_findalldevs_ex( char * source, + struct pcap_rmtauth * auth, + pcap_if_t ** alldevs, + char * errbuf ); + struct pcap_samp * pcap_setsampling( pcap_t * p ); -//\} -// End of new winpcap functions +/*\} */ +/* End of new winpcap functions */ /** \name Remote Capture functions */ -//\{ -SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf); -int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf); -int pcap_remoteact_close(const char *host, char *errbuf); -void pcap_remoteact_cleanup(); -//\} -// End of remote capture functions +/*\{ */ + SOCKET pcap_remoteact_accept( const char * address, + const char * port, + const char * hostlist, + char * connectinghost, + struct pcap_rmtauth * auth, + char * errbuf ); + int pcap_remoteact_list( char * hostlist, + char sep, + int size, + char * errbuf ); + int pcap_remoteact_close( const char * host, + char * errbuf ); + void pcap_remoteact_cleanup(); +/*\} */ +/* End of remote capture functions */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif - +#endif /* ifndef __REMOTE_EXT_H__ */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/main.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/main.c index 1a4c57c54..f0b813baa 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/main.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Networkless/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -23,6 +23,7 @@ * https://github.com/FreeRTOS * */ + /** * @file main.c * @brief Implements the main function. @@ -162,7 +163,7 @@ int main( void ) #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, - struct xNetworkEndPoint * pxEndPoint ) + struct xNetworkEndPoint * pxEndPoint ) #else void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ @@ -212,7 +213,7 @@ static LONG CALLBACK prvExceptionHandler( _In_ PEXCEPTION_POINTERS ExceptionInfo #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, - const char * pcName ) + const char * pcName ) #else BaseType_t xApplicationDNSQueryHook( const char * pcName ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Config/FreeRTOSConfig.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Config/FreeRTOSConfig.h index 0e51c4e80..6baeea97a 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Config/FreeRTOSConfig.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Config/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -28,20 +28,20 @@ #include "unity_internals.h" - /*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * https://www.FreeRTOS.org/a00110.html - * - * The bottom of this file contains some constants specific to running the UDP - * stack in this demo. Constants specific to FreeRTOS+TCP itself (rather than - * the demo) are contained in FreeRTOSIPConfig.h. - *----------------------------------------------------------*/ +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +* https://www.FreeRTOS.org/a00110.html +* +* The bottom of this file contains some constants specific to running the UDP +* stack in this demo. Constants specific to FreeRTOS+TCP itself (rather than +* the demo) are contained in FreeRTOSIPConfig.h. +*----------------------------------------------------------*/ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 @@ -62,7 +62,7 @@ #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 3 /* FreeRTOS+FAT requires 2 pointers if a CWD is supported. */ #define configRECORD_STACK_HIGH_ADDRESS 1 - /* Hook function related definitions. */ +/* Hook function related definitions. */ #define configUSE_TICK_HOOK 0 #define configUSE_IDLE_HOOK 1 #define configUSE_MALLOC_FAILED_HOOK 1 @@ -78,8 +78,8 @@ #define configUSE_EVENT_GROUPS 1 /* Run time stats gathering definitions. */ -unsigned long ulGetRunTimeCounterValue(void); -void vConfigureTimerForRunTimeStats(void); +unsigned long ulGetRunTimeCounterValue( void ); +void vConfigureTimerForRunTimeStats( void ); #define configGENERATE_RUN_TIME_STATS 1 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() #define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() @@ -89,8 +89,8 @@ void vConfigureTimerForRunTimeStats(void); #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configSUPPORT_STATIC_ALLOCATION 1 - /* Set the following definitions to 1 to include the API function, or zero - * to exclude the API function. */ +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 @@ -109,30 +109,30 @@ void vConfigureTimerForRunTimeStats(void); #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_xTaskAbortDelay 1 - /* This demo makes use of one or more example stats formatting functions. These - * format the raw data provided by the uxTaskGetSystemState() function in to human - * readable ASCII form. See the notes in the implementation of vTaskList() within - * FreeRTOS/Source/tasks.c for limitations. configUSE_STATS_FORMATTING_FUNCTIONS - * is set to 2 so the formatting functions are included without the stdio.h being - * included in tasks.c. That is because this project defines its own sprintf() - * functions. */ +/* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to human + * readable ASCII form. See the notes in the implementation of vTaskList() within + * FreeRTOS/Source/tasks.c for limitations. configUSE_STATS_FORMATTING_FUNCTIONS + * is set to 2 so the formatting functions are included without the stdio.h being + * included in tasks.c. That is because this project defines its own sprintf() + * functions. */ #define configUSE_STATS_FORMATTING_FUNCTIONS 1 - /* Assert call defined for debug builds. */ -void vAssertCalled(const char* pcFile, - uint32_t ulLine); +/* Assert call defined for debug builds. */ +void vAssertCalled( const char * pcFile, + uint32_t ulLine ); -#define configASSERT( x ) if( ( x ) == 0 ) TEST_ABORT() +#define configASSERT( x ) if( ( x ) == 0 ) TEST_ABORT( ) /* The function that implements FreeRTOS printf style output, and the macro * that maps the configPRINTF() macros to that function. */ -void vLoggingPrintf(char const* pcFormat, - ...); +void vLoggingPrintf( char const * pcFormat, + ... ); #define configPRINTF( X ) vLoggingPrintf X /* Non-format version thread-safe print. */ -extern void vLoggingPrint(const char* pcMessage); -#define configPRINT( X ) vLoggingPrint( X ) +extern void vLoggingPrint( const char * pcMessage ); +#define configPRINT( X ) vLoggingPrint( X ) /* Non-format version thread-safe print. */ #define configPRINT_STRING( X ) vLoggingPrintf( X ) @@ -144,45 +144,45 @@ extern void vLoggingPrint(const char* pcMessage); * through the CLI interface. */ #define configINCLUDE_DEMO_DEBUG_STATS 1 - /* The size of the global output buffer that is available for use when there - * are multiple command interpreters running at once (for example, one on a UART - * and one on TCP/IP). This is done to prevent an output buffer being defined by - * each implementation - which would waste RAM. In this case, there is only one - * command interpreter running, and it has its own local output buffer, so the - * global buffer is just set to be one byte long as it is not used and should not - * take up unnecessary RAM. */ +/* The size of the global output buffer that is available for use when there + * are multiple command interpreters running at once (for example, one on a UART + * and one on TCP/IP). This is done to prevent an output buffer being defined by + * each implementation - which would waste RAM. In this case, there is only one + * command interpreter running, and it has its own local output buffer, so the + * global buffer is just set to be one byte long as it is not used and should not + * take up unnecessary RAM. */ #define configCOMMAND_INT_MAX_OUTPUT_SIZE 1 - /* Only used when running in the FreeRTOS Windows simulator. Defines the - * priority of the task used to simulate Ethernet interrupts. */ +/* Only used when running in the FreeRTOS Windows simulator. Defines the + * priority of the task used to simulate Ethernet interrupts. */ #define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 1 ) - /* This demo creates a virtual network connection by accessing the raw Ethernet - * or WiFi data to and from a real network connection. Many computers have more - * than one real network port, and configNETWORK_INTERFACE_TO_USE is used to tell - * the demo which real port should be used to create the virtual port. The ports - * available are displayed on the console when the application is executed. For - * example, on my development laptop setting configNETWORK_INTERFACE_TO_USE to 4 - * results in the wired network being used, while setting - * configNETWORK_INTERFACE_TO_USE to 2 results in the wireless network being - * used. */ +/* This demo creates a virtual network connection by accessing the raw Ethernet + * or WiFi data to and from a real network connection. Many computers have more + * than one real network port, and configNETWORK_INTERFACE_TO_USE is used to tell + * the demo which real port should be used to create the virtual port. The ports + * available are displayed on the console when the application is executed. For + * example, on my development laptop setting configNETWORK_INTERFACE_TO_USE to 4 + * results in the wired network being used, while setting + * configNETWORK_INTERFACE_TO_USE to 2 results in the wireless network being + * used. */ #define configNETWORK_INTERFACE_TO_USE ( 0L ) - /* The address of an echo server that will be used by the two demo echo client - * tasks: - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html, - * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html. */ +/* The address of an echo server that will be used by the two demo echo client + * tasks: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html, + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html. */ #define configECHO_SERVER_ADDR0 192 #define configECHO_SERVER_ADDR1 168 #define configECHO_SERVER_ADDR2 2 #define configECHO_SERVER_ADDR3 6 #define configTCP_ECHO_CLIENT_PORT 7 - /* Default MAC address configuration. The demo creates a virtual network - * connection that uses this MAC address by accessing the raw Ethernet/WiFi data - * to and from a real network connection on the host PC. See the - * configNETWORK_INTERFACE_TO_USE definition above for information on how to - * configure the real network connection to use. */ +/* Default MAC address configuration. The demo creates a virtual network + * connection that uses this MAC address by accessing the raw Ethernet/WiFi data + * to and from a real network connection on the host PC. See the + * configNETWORK_INTERFACE_TO_USE definition above for information on how to + * configure the real network connection to use. */ #define configMAC_ADDR0 0x00 #define configMAC_ADDR1 0x11 #define configMAC_ADDR2 0x22 @@ -190,36 +190,36 @@ extern void vLoggingPrint(const char* pcMessage); #define configMAC_ADDR4 0x44 #define configMAC_ADDR5 0x32 - /* Default IP address configuration. Used in ipconfigUSE_DHCP is set to 0, or - * ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */ +/* Default IP address configuration. Used in ipconfigUSE_DHCP is set to 0, or + * ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */ #define configIP_ADDR0 192 #define configIP_ADDR1 168 #define configIP_ADDR2 0 #define configIP_ADDR3 105 - /* Default gateway IP address configuration. Used in ipconfigUSE_DHCP is set to - * 0, or ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */ +/* Default gateway IP address configuration. Used in ipconfigUSE_DHCP is set to + * 0, or ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */ #define configGATEWAY_ADDR0 192 #define configGATEWAY_ADDR1 168 #define configGATEWAY_ADDR2 0 #define configGATEWAY_ADDR3 1 - /* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and - * 208.67.220.220. Used in ipconfigUSE_DHCP is set to 0, or ipconfigUSE_DHCP is - * set to 1 but a DNS server cannot be contacted.*/ +/* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and + * 208.67.220.220. Used in ipconfigUSE_DHCP is set to 0, or ipconfigUSE_DHCP is + * set to 1 but a DNS server cannot be contacted.*/ #define configDNS_SERVER_ADDR0 208 #define configDNS_SERVER_ADDR1 67 #define configDNS_SERVER_ADDR2 222 #define configDNS_SERVER_ADDR3 222 - /* Default netmask configuration. Used in ipconfigUSE_DHCP is set to 0, or - * ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */ +/* Default netmask configuration. Used in ipconfigUSE_DHCP is set to 0, or + * ipconfigUSE_DHCP is set to 1 but a DNS server cannot be contacted. */ #define configNET_MASK0 255 #define configNET_MASK1 255 #define configNET_MASK2 255 #define configNET_MASK3 0 - /* The UDP port to which print messages are sent. */ +/* The UDP port to which print messages are sent. */ #define configPRINT_PORT ( 15000 ) #define configPROFILING ( 0 ) diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Config/FreeRTOSIPConfig.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Config/FreeRTOSIPConfig.h index c34b05460..5bda66528 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Config/FreeRTOSIPConfig.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Config/FreeRTOSIPConfig.h @@ -1,27 +1,28 @@ /* -FreeRTOS V202212.00 -Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - http://aws.amazon.com/freertos - http://www.FreeRTOS.org -*/ + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ /***************************************************************************** @@ -39,68 +40,68 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * out the debugging messages. */ #define ipconfigHAS_DEBUG_PRINTF 0 #if ( ipconfigHAS_DEBUG_PRINTF == 1 ) -#define FreeRTOS_debug_printf( X ) configPRINTF( X ) + #define FreeRTOS_debug_printf( X ) configPRINTF( X ) #endif - /* Set to 1 to print out non debugging messages, for example the output of the - * FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1 - * then FreeRTOS_printf should be set to the function used to print out the - * messages. */ +/* Set to 1 to print out non debugging messages, for example the output of the + * FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1 + * then FreeRTOS_printf should be set to the function used to print out the + * messages. */ #define ipconfigHAS_PRINTF 1 #if ( ipconfigHAS_PRINTF == 1 ) -#define FreeRTOS_printf( X ) configPRINTF( X ) + #define FreeRTOS_printf( X ) configPRINTF( X ) #endif - /* Define the byte order of the target MCU (the MCU FreeRTOS+TCP is executing - * on). Valid options are pdFREERTOS_BIG_ENDIAN and pdFREERTOS_LITTLE_ENDIAN. */ +/* Define the byte order of the target MCU (the MCU FreeRTOS+TCP is executing + * on). Valid options are pdFREERTOS_BIG_ENDIAN and pdFREERTOS_LITTLE_ENDIAN. */ #define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN - /* If the network card/driver includes checksum offloading (IP/TCP/UDP checksums) - * then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software - * stack repeating the checksum calculations. */ +/* If the network card/driver includes checksum offloading (IP/TCP/UDP checksums) + * then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software + * stack repeating the checksum calculations. */ #define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1 - /* Several API's will block until the result is known, or the action has been - * performed, for example FreeRTOS_send() and FreeRTOS_recv(). The timeouts can be - * set per socket, using setsockopt(). If not set, the times below will be - * used as defaults. */ +/* Several API's will block until the result is known, or the action has been + * performed, for example FreeRTOS_send() and FreeRTOS_recv(). The timeouts can be + * set per socket, using setsockopt(). If not set, the times below will be + * used as defaults. */ #define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 5000 ) #define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 5000 ) - /* Include support for DNS caching. For TCP, having a small DNS cache is very - * useful. When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low - * and also DNS may use small timeouts. If a DNS reply comes in after the DNS - * socket has been destroyed, the result will be stored into the cache. The next - * call to FreeRTOS_gethostbyname() will return immediately, without even creating - * a socket. - */ +/* Include support for DNS caching. For TCP, having a small DNS cache is very + * useful. When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low + * and also DNS may use small timeouts. If a DNS reply comes in after the DNS + * socket has been destroyed, the result will be stored into the cache. The next + * call to FreeRTOS_gethostbyname() will return immediately, without even creating + * a socket. + */ #define ipconfigUSE_DNS_CACHE ( 1 ) #define ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY ( 6 ) #define ipconfigDNS_REQUEST_ATTEMPTS ( 2 ) - /* The IP stack executes it its own task (although any application task can make - * use of its services through the published sockets API). ipconfigUDP_TASK_PRIORITY - * sets the priority of the task that executes the IP stack. The priority is a - * standard FreeRTOS task priority so can take any value from 0 (the lowest - * priority) to (configMAX_PRIORITIES - 1) (the highest priority). - * configMAX_PRIORITIES is a standard FreeRTOS configuration parameter defined in - * FreeRTOSConfig.h, not FreeRTOSIPConfig.h. Consideration needs to be given as to - * the priority assigned to the task executing the IP stack relative to the - * priority assigned to tasks that use the IP stack. */ +/* The IP stack executes it its own task (although any application task can make + * use of its services through the published sockets API). ipconfigUDP_TASK_PRIORITY + * sets the priority of the task that executes the IP stack. The priority is a + * standard FreeRTOS task priority so can take any value from 0 (the lowest + * priority) to (configMAX_PRIORITIES - 1) (the highest priority). + * configMAX_PRIORITIES is a standard FreeRTOS configuration parameter defined in + * FreeRTOSConfig.h, not FreeRTOSIPConfig.h. Consideration needs to be given as to + * the priority assigned to the task executing the IP stack relative to the + * priority assigned to tasks that use the IP stack. */ #define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) - /* The size, in words (not bytes), of the stack allocated to the FreeRTOS+TCP - * task. This setting is less important when the FreeRTOS Win32 simulator is used - * as the Win32 simulator only stores a fixed amount of information on the task - * stack. FreeRTOS includes optional stack overflow detection, see: - * https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html. */ +/* The size, in words (not bytes), of the stack allocated to the FreeRTOS+TCP + * task. This setting is less important when the FreeRTOS Win32 simulator is used + * as the Win32 simulator only stores a fixed amount of information on the task + * stack. FreeRTOS includes optional stack overflow detection, see: + * https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html. */ #define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 ) - /* ipconfigRAND32() is called by the IP stack to generate random numbers for - * things such as a DHCP transaction number or initial sequence number. Random - * number generation is performed via this macro to allow applications to use their - * own random number generation method. For example, it might be possible to - * generate a random number by sampling noise on an analogue input. */ +/* ipconfigRAND32() is called by the IP stack to generate random numbers for + * things such as a DHCP transaction number or initial sequence number. Random + * number generation is performed via this macro to allow applications to use their + * own random number generation method. For example, it might be possible to + * generate a random number by sampling noise on an analogue input. */ extern uint32_t ulRand(); #define ipconfigRAND32() ulRand() @@ -111,109 +112,109 @@ extern uint32_t ulRand(); */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 - /* Sockets have a send block time attribute. If FreeRTOS_sendto() is called but - * a network buffer cannot be obtained then the calling task is held in the Blocked - * state (so other tasks can continue to executed) until either a network buffer - * becomes available or the send block time expires. If the send block time expires - * then the send operation is aborted. The maximum allowable send block time is - * capped to the value set by ipconfigMAX_SEND_BLOCK_TIME_TICKS. Capping the - * maximum allowable send block time prevents prevents a deadlock occurring when - * all the network buffers are in use and the tasks that process (and subsequently - * free) the network buffers are themselves blocked waiting for a network buffer. - * ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in - * milliseconds can be converted to a time in ticks by dividing the time in - * milliseconds by portTICK_PERIOD_MS. */ +/* Sockets have a send block time attribute. If FreeRTOS_sendto() is called but + * a network buffer cannot be obtained then the calling task is held in the Blocked + * state (so other tasks can continue to executed) until either a network buffer + * becomes available or the send block time expires. If the send block time expires + * then the send operation is aborted. The maximum allowable send block time is + * capped to the value set by ipconfigMAX_SEND_BLOCK_TIME_TICKS. Capping the + * maximum allowable send block time prevents prevents a deadlock occurring when + * all the network buffers are in use and the tasks that process (and subsequently + * free) the network buffers are themselves blocked waiting for a network buffer. + * ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in + * milliseconds can be converted to a time in ticks by dividing the time in + * milliseconds by portTICK_PERIOD_MS. */ #define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000U / portTICK_PERIOD_MS ) - /* If ipconfigUSE_DHCP is 1 then FreeRTOS+TCP will attempt to retrieve an IP - * address, netmask, DNS server address and gateway address from a DHCP server. If - * ipconfigUSE_DHCP is 0 then FreeRTOS+TCP will use a static IP address. The - * stack will revert to using the static IP address even when ipconfigUSE_DHCP is - * set to 1 if a valid configuration cannot be obtained from a DHCP server for any - * reason. The static configuration used is that passed into the stack by the - * FreeRTOS_IPInit() function call. */ +/* If ipconfigUSE_DHCP is 1 then FreeRTOS+TCP will attempt to retrieve an IP + * address, netmask, DNS server address and gateway address from a DHCP server. If + * ipconfigUSE_DHCP is 0 then FreeRTOS+TCP will use a static IP address. The + * stack will revert to using the static IP address even when ipconfigUSE_DHCP is + * set to 1 if a valid configuration cannot be obtained from a DHCP server for any + * reason. The static configuration used is that passed into the stack by the + * FreeRTOS_IPInit() function call. */ #define ipconfigUSE_DHCP 1 #define ipconfigDHCP_REGISTER_HOSTNAME 1 #define ipconfigDHCP_USES_UNICAST 1 - /* If ipconfigDHCP_USES_USER_HOOK is set to 1 then the application writer must - * provide an implementation of the DHCP callback function, - * xApplicationDHCPUserHook(). */ +/* If ipconfigDHCP_USES_USER_HOOK is set to 1 then the application writer must + * provide an implementation of the DHCP callback function, + * xApplicationDHCPUserHook(). */ #define ipconfigUSE_DHCP_HOOK 0 - /* When ipconfigUSE_DHCP is set to 1, DHCP requests will be sent out at - * increasing time intervals until either a reply is received from a DHCP server - * and accepted, or the interval between transmissions reaches - * ipconfigMAXIMUM_DISCOVER_TX_PERIOD. The IP stack will revert to using the - * static IP address passed as a parameter to FreeRTOS_IPInit() if the - * re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without - * a DHCP reply being received. */ +/* When ipconfigUSE_DHCP is set to 1, DHCP requests will be sent out at + * increasing time intervals until either a reply is received from a DHCP server + * and accepted, or the interval between transmissions reaches + * ipconfigMAXIMUM_DISCOVER_TX_PERIOD. The IP stack will revert to using the + * static IP address passed as a parameter to FreeRTOS_IPInit() if the + * re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without + * a DHCP reply being received. */ #define ipconfigMAXIMUM_DISCOVER_TX_PERIOD \ ( 120000U / portTICK_PERIOD_MS ) - /* The ARP cache is a table that maps IP addresses to MAC addresses. The IP - * stack can only send a UDP message to a remove IP address if it knowns the MAC - * address associated with the IP address, or the MAC address of the router used to - * contact the remote IP address. When a UDP message is received from a remote IP - * address the MAC address and IP address are added to the ARP cache. When a UDP - * message is sent to a remote IP address that does not already appear in the ARP - * cache then the UDP message is replaced by a ARP message that solicits the - * required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum - * number of entries that can exist in the ARP table at any one time. */ +/* The ARP cache is a table that maps IP addresses to MAC addresses. The IP + * stack can only send a UDP message to a remove IP address if it knowns the MAC + * address associated with the IP address, or the MAC address of the router used to + * contact the remote IP address. When a UDP message is received from a remote IP + * address the MAC address and IP address are added to the ARP cache. When a UDP + * message is sent to a remote IP address that does not already appear in the ARP + * cache then the UDP message is replaced by a ARP message that solicits the + * required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum + * number of entries that can exist in the ARP table at any one time. */ #define ipconfigARP_CACHE_ENTRIES 6 - /* ARP requests that do not result in an ARP response will be re-transmitted a - * maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is - * aborted. */ +/* ARP requests that do not result in an ARP response will be re-transmitted a + * maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is + * aborted. */ #define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 ) - /* ipconfigMAX_ARP_AGE defines the maximum time between an entry in the ARP - * table being created or refreshed and the entry being removed because it is stale. - * New ARP requests are sent for ARP cache entries that are nearing their maximum - * age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is - * equal to 1500 seconds (or 25 minutes). */ +/* ipconfigMAX_ARP_AGE defines the maximum time between an entry in the ARP + * table being created or refreshed and the entry being removed because it is stale. + * New ARP requests are sent for ARP cache entries that are nearing their maximum + * age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is + * equal to 1500 seconds (or 25 minutes). */ #define ipconfigMAX_ARP_AGE 150 - /* Implementing FreeRTOS_inet_addr() necessitates the use of string handling - * routines, which are relatively large. To save code space the full - * FreeRTOS_inet_addr() implementation is made optional, and a smaller and faster - * alternative called FreeRTOS_inet_addr_quick() is provided. FreeRTOS_inet_addr() - * takes an IP in decimal dot format (for example, "192.168.0.1") as its parameter. - * FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets - * (for example, 192, 168, 0, 1) as its parameters. If - * ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and - * FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is - * not set to 1 then only FreeRTOS_indet_addr_quick() is available. */ +/* Implementing FreeRTOS_inet_addr() necessitates the use of string handling + * routines, which are relatively large. To save code space the full + * FreeRTOS_inet_addr() implementation is made optional, and a smaller and faster + * alternative called FreeRTOS_inet_addr_quick() is provided. FreeRTOS_inet_addr() + * takes an IP in decimal dot format (for example, "192.168.0.1") as its parameter. + * FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets + * (for example, 192, 168, 0, 1) as its parameters. If + * ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and + * FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is + * not set to 1 then only FreeRTOS_indet_addr_quick() is available. */ #define ipconfigINCLUDE_FULL_INET_ADDR 1 - /* ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS defines the total number of network buffer that - * are available to the IP stack. The total number of network buffers is limited - * to ensure the total amount of RAM that can be consumed by the IP stack is capped - * to a pre-determinable value. */ +/* ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS defines the total number of network buffer that + * are available to the IP stack. The total number of network buffers is limited + * to ensure the total amount of RAM that can be consumed by the IP stack is capped + * to a pre-determinable value. */ #define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60 - /* A FreeRTOS queue is used to send events from application tasks to the IP - * stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can - * be queued for processing at any one time. The event queue must be a minimum of - * 5 greater than the total number of network buffers. */ +/* A FreeRTOS queue is used to send events from application tasks to the IP + * stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can + * be queued for processing at any one time. The event queue must be a minimum of + * 5 greater than the total number of network buffers. */ #define ipconfigEVENT_QUEUE_LENGTH \ ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) - /* The address of a socket is the combination of its IP address and its port - * number. FreeRTOS_bind() is used to manually allocate a port number to a socket - * (to 'bind' the socket to a port), but manual binding is not normally necessary - * for client sockets (those sockets that initiate outgoing connections rather than - * wait for incoming connections on a known port number). If - * ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 then calling - * FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP - * stack automatically binding the socket to a port number from the range - * socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If - * ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto() - * on a socket that has not yet been bound will result in the send operation being - * aborted. */ +/* The address of a socket is the combination of its IP address and its port + * number. FreeRTOS_bind() is used to manually allocate a port number to a socket + * (to 'bind' the socket to a port), but manual binding is not normally necessary + * for client sockets (those sockets that initiate outgoing connections rather than + * wait for incoming connections on a known port number). If + * ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 then calling + * FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP + * stack automatically binding the socket to a port number from the range + * socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If + * ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto() + * on a socket that has not yet been bound will result in the send operation being + * aborted. */ #define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 - /* Defines the Time To Live (TTL) values used in outgoing UDP packets. */ +/* Defines the Time To Live (TTL) values used in outgoing UDP packets. */ #define ipconfigUDP_TIME_TO_LIVE 128 /* Also defined in FreeRTOSIPConfigDefaults.h. */ #define ipconfigTCP_TIME_TO_LIVE 128 @@ -231,65 +232,65 @@ extern uint32_t ulRand(); * be divisible by 8. */ #define ipconfigNETWORK_MTU 1200U - /* Set ipconfigUSE_DNS to 1 to include a basic DNS client/resolver. DNS is used - * through the FreeRTOS_gethostbyname() API function. */ +/* Set ipconfigUSE_DNS to 1 to include a basic DNS client/resolver. DNS is used + * through the FreeRTOS_gethostbyname() API function. */ #define ipconfigUSE_DNS 1 - /* If ipconfigREPLY_TO_INCOMING_PINGS is set to 1 then the IP stack will - * generate replies to incoming ICMP echo (ping) requests. */ +/* If ipconfigREPLY_TO_INCOMING_PINGS is set to 1 then the IP stack will + * generate replies to incoming ICMP echo (ping) requests. */ #define ipconfigREPLY_TO_INCOMING_PINGS 1 - /* If ipconfigSUPPORT_OUTGOING_PINGS is set to 1 then the - * FreeRTOS_SendPingRequest() API function is available. */ +/* If ipconfigSUPPORT_OUTGOING_PINGS is set to 1 then the + * FreeRTOS_SendPingRequest() API function is available. */ #define ipconfigSUPPORT_OUTGOING_PINGS 0 - /* If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select() - * (and associated) API function is available. */ +/* If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select() + * (and associated) API function is available. */ #define ipconfigSUPPORT_SELECT_FUNCTION 0 - /* If ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is set to 1 then Ethernet frames - * that are not in Ethernet II format will be dropped. This option is included for - * potential future IP stack developments. */ +/* If ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is set to 1 then Ethernet frames + * that are not in Ethernet II format will be dropped. This option is included for + * potential future IP stack developments. */ #define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1 - /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 then it is the - * responsibility of the Ethernet interface to filter out packets that are of no - * interest. If the Ethernet interface does not implement this functionality, then - * set ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES to 0 to have the IP stack - * perform the filtering instead (it is much less efficient for the stack to do it - * because the packet will already have been passed into the stack). If the - * Ethernet driver does all the necessary filtering in hardware then software - * filtering can be removed by using a value other than 1 or 0. */ +/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 then it is the + * responsibility of the Ethernet interface to filter out packets that are of no + * interest. If the Ethernet interface does not implement this functionality, then + * set ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES to 0 to have the IP stack + * perform the filtering instead (it is much less efficient for the stack to do it + * because the packet will already have been passed into the stack). If the + * Ethernet driver does all the necessary filtering in hardware then software + * filtering can be removed by using a value other than 1 or 0. */ #define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 - /* The windows simulator cannot really simulate MAC interrupts, and needs to - * block occasionally to allow other tasks to run. */ +/* The windows simulator cannot really simulate MAC interrupts, and needs to + * block occasionally to allow other tasks to run. */ #define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS ) - /* Advanced only: in order to access 32-bit fields in the IP packets with - * 32-bit memory instructions, all packets will be stored 32-bit-aligned, - * plus 16-bits. This has to do with the contents of the IP-packets: all - * 32-bit fields are 32-bit-aligned, plus 16-bit. */ +/* Advanced only: in order to access 32-bit fields in the IP packets with + * 32-bit memory instructions, all packets will be stored 32-bit-aligned, + * plus 16-bits. This has to do with the contents of the IP-packets: all + * 32-bit fields are 32-bit-aligned, plus 16-bit. */ #define ipconfigPACKET_FILLER_SIZE 2U - /* Define the size of the pool of TCP window descriptors. On the average, each - * TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6 - * outstanding packets (for Rx and Tx). When using up to 10 TP sockets - * simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */ +/* Define the size of the pool of TCP window descriptors. On the average, each + * TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6 + * outstanding packets (for Rx and Tx). When using up to 10 TP sockets + * simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */ #define ipconfigTCP_WIN_SEG_COUNT 240 - /* Each TCP socket has a circular buffers for Rx and Tx, which have a fixed - * maximum size. Define the size of Rx buffer for TCP sockets. */ +/* Each TCP socket has a circular buffers for Rx and Tx, which have a fixed + * maximum size. Define the size of Rx buffer for TCP sockets. */ #define ipconfigTCP_RX_BUFFER_LENGTH ( 10000 ) - /* Define the size of Tx buffer for TCP sockets. */ +/* Define the size of Tx buffer for TCP sockets. */ #define ipconfigTCP_TX_BUFFER_LENGTH ( 10000 ) /* When using call-back handlers, the driver may check if the handler points to * real program memory (RAM or flash) or just has a random non-zero value. */ #define ipconfigIS_VALID_PROG_ADDRESS( x ) ( ( x ) != NULL ) - /* Include support for TCP keep-alive messages. */ +/* Include support for TCP keep-alive messages. */ #define ipconfigTCP_KEEP_ALIVE ( 1 ) #define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20 ) /* Seconds. */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Full-TCP-Suite.sln b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Full-TCP-Suite.sln index f907d968a..ae4add02d 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Full-TCP-Suite.sln +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Full-TCP-Suite.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}" diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Logging/run-time-stats-utils.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Logging/run-time-stats-utils.c index d07f95b69..b217641c0 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Logging/run-time-stats-utils.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Logging/run-time-stats-utils.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ @@ -41,7 +42,7 @@ /* Variables used in the creation of the run time stats time base. Run time * stats record how much time each task spends in the Running state. */ -static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL; +static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundredthMillisecond = 0LL; /*-----------------------------------------------------------*/ @@ -55,13 +56,13 @@ void vConfigureTimerForRunTimeStats( void ) if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 ) { - llTicksPerHundedthMillisecond = 1; + llTicksPerHundredthMillisecond = 1; } else { /* How many times does the performance counter increment in 1/100th * millisecond. */ - llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL; + llTicksPerHundredthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL; /* What is the performance counter value now, this will be subtracted * from readings taken at run time. */ @@ -82,10 +83,10 @@ unsigned long ulGetRunTimeCounterValue( void ) /* Subtract the performance counter value reading taken when the * application started to get a count from that reference point, then * scale to (simulated) 1/100ths of a millisecond. */ - if( llTicksPerHundedthMillisecond == 0 ) + if( llTicksPerHundredthMillisecond == 0 ) { /* The trace macros can call this function before the kernel has been - * started, in which case llTicksPerHundedthMillisecond will not have been + * started, in which case llTicksPerHundredthMillisecond will not have been * initialised. */ ulReturn = 0; } @@ -93,7 +94,7 @@ unsigned long ulGetRunTimeCounterValue( void ) { ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / - llTicksPerHundedthMillisecond ); + llTicksPerHundredthMillisecond ); } return ulReturn; diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/ReadMe.txt b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/ReadMe.txt index 34adcf735..aabe371b9 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/ReadMe.txt +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/ReadMe.txt @@ -10,13 +10,13 @@ directory: FreeRTOS-Plus\Test\FreeRTOS-Plus-TCP\Integration\Full-TCP-Suite This project is a version of the standard FreeRTOS demos that includes the integration tests of +TCP. It tests the +TCP stack through the use of FreeRTOS_Sockets API. To Run this project, make sure that the computer is connected to a network -via ethernet cable. +via ethernet cable. - Open the project (using file named `Full-TCP-Suite.sln`) and -choose the required network interface by modifying this line `#define -configNETWORK_INTERFACE_TO_USE` in FreeRTOSConfig.h. -- Modify the `tcptestECHO_SERVER_ADDR[0-3]` and `tcptestECHO_PORT` in the file +choose the required network interface by modifying this line `#define +configNETWORK_INTERFACE_TO_USE` in FreeRTOSConfig.h. +- Modify the `tcptestECHO_SERVER_ADDR[0-3]` and `tcptestECHO_PORT` in the file `test_tcp.h` according to the address of the unsecure echo server of your choosing. -An implementation of echo server is provided here: +An implementation of echo server is provided here: https://docs.aws.amazon.com/freertos/latest/portingguide/afr-echo-server.html Once these changes are made, just build and run the project. It should run 23 test diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/application_version.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/application_version.h index d86dba74c..30fc47a67 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/application_version.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/application_version.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #ifndef _AWS_APPLICATION_VERSION_H_ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/clientcredential.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/clientcredential.h index 5a491237b..7dc93a08b 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/clientcredential.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/clientcredential.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,36 +19,37 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #ifndef __CLIENTCREDENTIAL__H__ #define __CLIENTCREDENTIAL__H__ - /* - * @brief Wi-Fi network to join. - * - * @todo If you are using Wi-Fi, set this to your network name. - */ -#define clientcredentialWIFI_SSID "" +/* + * @brief Wi-Fi network to join. + * + * @todo If you are using Wi-Fi, set this to your network name. + */ +#define clientcredentialWIFI_SSID "" - /* - * @brief Password needed to join Wi-Fi network. - * - * @todo If you are using WPA, set this to your network password. - */ -#define clientcredentialWIFI_PASSWORD "" +/* + * @brief Password needed to join Wi-Fi network. + * + * @todo If you are using WPA, set this to your network password. + */ +#define clientcredentialWIFI_PASSWORD "" - /* - * @brief Wi-Fi network security type. - * - * @see WIFISecurity_t. - * - * @note Possible values are eWiFiSecurityOpen, eWiFiSecurityWEP, eWiFiSecurityWPA, - * eWiFiSecurityWPA2 (depending on the support of your device Wi-Fi radio). - */ -#define clientcredentialWIFI_SECURITY eWiFiSecurityWPA2 +/* + * @brief Wi-Fi network security type. + * + * @see WIFISecurity_t. + * + * @note Possible values are eWiFiSecurityOpen, eWiFiSecurityWEP, eWiFiSecurityWPA, + * eWiFiSecurityWPA2 (depending on the support of your device Wi-Fi radio). + */ +#define clientcredentialWIFI_SECURITY eWiFiSecurityWPA2 -#endif +#endif /* ifndef __CLIENTCREDENTIAL__H__ */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/config_common.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/config_common.h index 37c6dd8ea..8e2c9bd16 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/config_common.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/config_common.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /* This file contains default configuration settings for the tests on FreeRTOS. */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_framework.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_framework.h index 29c8e0bba..c627d9e1a 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_framework.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_framework.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /** diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_runner.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_runner.h index ccf0fc95a..bebab8637 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_runner.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_runner.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /** diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_tcp.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_tcp.h index db773f511..29494cb8e 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_tcp.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_tcp.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,29 +19,30 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #ifndef TEST_TCP_H #define TEST_TCP_H - /* Non-Encrypted Echo Server. - * Update tcptestECHO_SERVER_ADDR# and - * tcptestECHO_PORT with IP address - * and port of unencrypted TCP echo server. */ +/* Non-Encrypted Echo Server. + * Update tcptestECHO_SERVER_ADDR# and + * tcptestECHO_PORT with IP address + * and port of unencrypted TCP echo server. */ - /* You can find the code to setup an echo server in the Repo */ +/* You can find the code to setup an echo server in the Repo */ - /* Assume ECHO server IP-address A.B.C.D And Port Z*/ -#define tcptestECHO_SERVER_ADDR0 ( 255 ) /* Replace with Your Echo Server Addr First Byte i.e. A */ -#define tcptestECHO_SERVER_ADDR1 ( 255 ) /* Replace with Your Echo Server Addr Second Byte i.e. B */ -#define tcptestECHO_SERVER_ADDR2 ( 255 ) /* Replace with Your Echo Server Addr Third Byte i.e. C */ -#define tcptestECHO_SERVER_ADDR3 ( 255 ) /* Replace with Your Echo Server Addr Fourth Byte i.e. D */ -#define tcptestECHO_PORT ( 0 ) /* Replace with Your Echo Server Port Number i.e. Z */ +/* Assume ECHO server IP-address A.B.C.D And Port Z*/ +#define tcptestECHO_SERVER_ADDR0 ( 255 ) /* Replace with Your Echo Server Addr First Byte i.e. A */ +#define tcptestECHO_SERVER_ADDR1 ( 255 ) /* Replace with Your Echo Server Addr Second Byte i.e. B */ +#define tcptestECHO_SERVER_ADDR2 ( 255 ) /* Replace with Your Echo Server Addr Third Byte i.e. C */ +#define tcptestECHO_SERVER_ADDR3 ( 255 ) /* Replace with Your Echo Server Addr Fourth Byte i.e. D */ +#define tcptestECHO_PORT ( 0 ) /* Replace with Your Echo Server Port Number i.e. Z */ #if tcptestECHO_PORT == 0 -#error "Use Correct Port number and Correct IP address by setting tcptestECHO_SERVER_ADDR[0-3] and tcptestECHO_PORT in test_tcp.h" + #error "Use Correct Port number and Correct IP address by setting tcptestECHO_SERVER_ADDR[0-3] and tcptestECHO_PORT in test_tcp.h" #endif /* Number of times to retry a connection if it fails. */ #define tcptestRETRY_CONNECTION_TIMES 6 diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_tcp_config.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_tcp_config.h index a5c466d94..508f7dbbf 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_tcp_config.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_tcp_config.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -18,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #ifndef AWS_INTEGRATION_TEST_TCP_CONFIG_H @@ -37,7 +39,7 @@ * This value can be used to compensate for clock differences, and other * code overhead. */ -#define integrationtestportableTIMEOUT_OVER_TOLERANCE 1 +#define integrationtestportableTIMEOUT_OVER_TOLERANCE 1 /** * @brief Indicates how much less time than the specified timeout is acceptable for @@ -47,27 +49,27 @@ * If networking and tests are on different CPUs, an "under tolerance" is acceptable. * For tests where same clock is used for networking and tests. */ -#define integrationtestportableTIMEOUT_UNDER_TOLERANCE 0 +#define integrationtestportableTIMEOUT_UNDER_TOLERANCE 0 /** * @brief Indicates how long receive needs to wait for data before Timeout happens. * */ -#define integrationtestportableRECEIVE_TIMEOUT 2000 +#define integrationtestportableRECEIVE_TIMEOUT 2000 /** * @brief Indicates how long send needs to wait before Timeout happens. * */ -#define integrationtestportableSEND_TIMEOUT 2000 +#define integrationtestportableSEND_TIMEOUT 2000 - /** - * @brief Choose a desired hostname to be resolved. - * Also, select the number of IP-addresses the test should expect by modifying - * dnstestNUM_UNIQUE_IP_ADDRESSES in test_tcp.c source file. - */ -#define HostNameUNIQUE_ADDRESSES_TEST "freertos.org" +/** + * @brief Choose a desired hostname to be resolved. + * Also, select the number of IP-addresses the test should expect by modifying + * dnstestNUM_UNIQUE_IP_ADDRESSES in test_tcp.c source file. + */ +#define HostNameUNIQUE_ADDRESSES_TEST "freertos.org" #endif /*AWS_INTEGRATION_TEST_TCP_CONFIG_H */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_utils.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_utils.h index ce6856fcc..2f492d8c8 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_utils.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/test_utils.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #ifndef _TEST_UTILS_H_ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/unity_config.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/unity_config.h index f21c8e8cb..505b031f0 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/unity_config.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/include/unity_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /* Unity Configuration diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test.c index cc279e715..02652fb57 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /** diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_framework.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_framework.c index f496bed6a..4ad84361d 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_framework.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_framework.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /* Standard includes. */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_freertos.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_freertos.c index 187b6be19..afa423b54 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_freertos.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_freertos.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /** diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_tcp.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_tcp.c index 228935410..fefac1fc6 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_tcp.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Cases/test_tcp.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -48,7 +48,7 @@ /* Update this file with port-specific values. */ #include "test_tcp_config.h" -/* Update this file with AWS Crredentials. */ +/* Update this file with AWS Credentials. */ #include "clientcredential.h" /* Verbose printing. */ @@ -413,7 +413,7 @@ typedef enum } tcptestEchoTestModes_t; typedef struct -{ +{ uint16_t usTaskTag; BaseType_t xResult; TaskHandle_t xTaskHandle; @@ -509,7 +509,7 @@ static Socket_t prvTcpSocketHelper( volatile BaseType_t * pxSocketOpen ) /*-----------------------------------------------------------*/ static BaseType_t prvNonSecureConnectHelper( Socket_t xSocketLocal, - struct freertos_sockaddr* pxHostAddress ) + struct freertos_sockaddr * pxHostAddress ) { /* Disable unused parameter warning. */ ( void ) xSocketLocal; @@ -520,9 +520,9 @@ static BaseType_t prvNonSecureConnectHelper( Socket_t xSocketLocal, #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) { pxHostAddress->sin_address.ulIP_IPv4 = FreeRTOS_inet_addr_quick( tcptestECHO_SERVER_ADDR0, - tcptestECHO_SERVER_ADDR1, - tcptestECHO_SERVER_ADDR2, - tcptestECHO_SERVER_ADDR3 ); + tcptestECHO_SERVER_ADDR1, + tcptestECHO_SERVER_ADDR2, + tcptestECHO_SERVER_ADDR3 ); } #else { @@ -542,38 +542,38 @@ static BaseType_t prvNonSecureConnectHelper( Socket_t xSocketLocal, /*-----------------------------------------------------------*/ -static BaseType_t prvConnect( Socket_t xSocketLocal) +static BaseType_t prvConnect( Socket_t xSocketLocal ) { BaseType_t xResult = pdFAIL; struct freertos_sockaddr xAddress; xResult = prvNonSecureConnectHelper( xSocketLocal, &xAddress ); - + if( xResult == pdFREERTOS_ERRNO_NONE ) { xResult = FreeRTOS_connect( xSocketLocal, - &xAddress, - sizeof( xAddress ) ); + &xAddress, + sizeof( xAddress ) ); } else { - tcptestFAILUREPRINTF( ("%s: Non Secure connect helper failed", __FUNCTION__) ); + tcptestFAILUREPRINTF( ( "%s: Non Secure connect helper failed", __FUNCTION__ ) ); } return xResult; } /*-----------------------------------------------------------*/ -static BaseType_t prvConnectHelper( Socket_t xSocketLocal) +static BaseType_t prvConnectHelper( Socket_t xSocketLocal ) { BaseType_t xResult = pdFAIL; uint32_t ulInitialRetryPeriodMs = tcptestLOOP_DELAY_MS; BaseType_t xMaxRetries = tcptestRETRY_CONNECTION_TIMES; - RETRY_EXPONENTIAL( xResult = prvConnect( xSocketLocal), - pdFREERTOS_ERRNO_NONE, - ulInitialRetryPeriodMs, - xMaxRetries ); + RETRY_EXPONENTIAL( xResult = prvConnect( xSocketLocal ), + pdFREERTOS_ERRNO_NONE, + ulInitialRetryPeriodMs, + xMaxRetries ); return xResult; } @@ -589,18 +589,18 @@ static BaseType_t prvSetSockOptHelper( Socket_t xSocketLocal, /* Set a time out so a missing reply does not cause the task to block * indefinitely. */ xResult = FreeRTOS_setsockopt( xSocketLocal, - 0, - FREERTOS_SO_RCVTIMEO, - &xRxTimeOut, - sizeof( xRxTimeOut ) ); + 0, + FREERTOS_SO_RCVTIMEO, + &xRxTimeOut, + sizeof( xRxTimeOut ) ); if( xResult == pdFREERTOS_ERRNO_NONE ) { xResult = FreeRTOS_setsockopt( xSocketLocal, - 0, - FREERTOS_SO_SNDTIMEO, - &xTxTimeOut, - sizeof( xTxTimeOut ) ); + 0, + FREERTOS_SO_SNDTIMEO, + &xTxTimeOut, + sizeof( xTxTimeOut ) ); if( xResult != pdFREERTOS_ERRNO_NONE ) { @@ -643,7 +643,7 @@ static BaseType_t prvConnectHelperWithRetry( volatile Socket_t * pxSocket, /* Set the appropriate socket options for the destination. */ if( pdFREERTOS_ERRNO_NONE == xResult ) { - xResult = prvNonSecureConnectHelper( *pxSocket, &xEchoServerAddress ); + xResult = prvNonSecureConnectHelper( *pxSocket, &xEchoServerAddress ); } /* Set socket timeout options. */ @@ -656,15 +656,15 @@ static BaseType_t prvConnectHelperWithRetry( volatile Socket_t * pxSocket, if( pdFREERTOS_ERRNO_NONE == xResult ) { xResult = FreeRTOS_connect( *pxSocket, - &xEchoServerAddress, - sizeof( xEchoServerAddress ) ); + &xEchoServerAddress, + sizeof( xEchoServerAddress ) ); if( pdFREERTOS_ERRNO_NONE == xResult ) { xIsConnected = pdTRUE; } else - { + { if( xRetry < tcptestRETRY_CONNECTION_TIMES ) { FreeRTOS_closesocket( *pxSocket ); @@ -703,10 +703,10 @@ static BaseType_t prvSendHelper( Socket_t xSocketLocal, while( ( size_t ) xNumBytesSentTotal < xLength ) { - xNumBytes = FreeRTOS_send( xSocketLocal, /* The socket being sent to. */ - &pucTxBuffer[ xNumBytesSentTotal ], /* The data being sent. */ - xLength - xNumBytesSentTotal, /* The length of the data being sent. */ - 0 ); /* No flags. */ + xNumBytes = FreeRTOS_send( xSocketLocal, /* The socket being sent to. */ + &pucTxBuffer[ xNumBytesSentTotal ], /* The data being sent. */ + xLength - xNumBytesSentTotal, /* The length of the data being sent. */ + 0 ); /* No flags. */ if( xNumBytes <= 0 ) { @@ -742,9 +742,9 @@ static BaseType_t prvRecvHelper( Socket_t xSocketLocal, while( ( size_t ) xNumBytesRecvTotal < xLength ) { xNumBytes = FreeRTOS_recv( xSocketLocal, - &pucRxBuffer[ xNumBytesRecvTotal ], - xLength - xNumBytesRecvTotal, - 0 ); + &pucRxBuffer[ xNumBytesRecvTotal ], + xLength - xNumBytesRecvTotal, + 0 ); if( xNumBytes == 0 ) { @@ -774,7 +774,7 @@ static BaseType_t prvRecvHelper( Socket_t xSocketLocal, /*-----------------------------------------------------------*/ -static BaseType_t prvShutdownHelper( Socket_t xSocketLocal) +static BaseType_t prvShutdownHelper( Socket_t xSocketLocal ) { BaseType_t xResult; @@ -787,10 +787,10 @@ static BaseType_t prvShutdownHelper( Socket_t xSocketLocal) /* Keep calling receive until an error code is returned. */ do { - xResult = FreeRTOS_recv( xSocketLocal, /* The socket being received from. */ - pcRxBuffer, /* The buffer into which the received data will be written. */ - tcptestBUFFER_SIZE, /* The size of the buffer provided to receive the data. */ - 0 ); + xResult = FreeRTOS_recv( xSocketLocal, /* The socket being received from. */ + pcRxBuffer, /* The buffer into which the received data will be written. */ + tcptestBUFFER_SIZE, /* The size of the buffer provided to receive the data. */ + 0 ); } while( xResult >= 0 ); @@ -943,7 +943,7 @@ static BaseType_t prvCheckTimeout( TickType_t xStartTime, TEST_GROUP_RUNNER( Full_TCP ) { - RUN_TEST_CASE( Full_TCP, TCP_Socket ); + RUN_TEST_CASE( Full_TCP, TCP_Socket ); RUN_TEST_CASE( Full_TCP, TCP_Socket_InvalidInputParams ); RUN_TEST_CASE( Full_TCP, TCP_Socket_Setsockopt_InvalidParams ); RUN_TEST_CASE( Full_TCP, TCP_Socket_Close_InvalidParams ); @@ -964,7 +964,7 @@ TEST_GROUP_RUNNER( Full_TCP ) RUN_TEST_CASE( Full_TCP, TCP_Socket_Recv_ByteByByte ); RUN_TEST_CASE( Full_TCP, TCP_Socket_SendRecv_VaryLength ); RUN_TEST_CASE( Full_TCP, TCP_test_dns_multiple_addresses ); - + /* Thread safety tests */ RUN_TEST_CASE( Full_TCP, TCP_Threadsafe_SameSocketDifferentTasks ); RUN_TEST_CASE( Full_TCP, TCP_Threadsafe_DifferentSocketsDifferentTasks ); @@ -1053,7 +1053,7 @@ static void prvSOCKETS_ShutdownWithoutReceiving( void ) xResult = FreeRTOS_send( xSocket, &cTransmittedString, tcptestTWICE_MAX_FRAME_SIZE, 0 ); TEST_ASSERT_GREATER_THAN_MESSAGE( 0, xResult, "Socket was not able to send" ); - xResult = FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR); + xResult = FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR ); TEST_ASSERT_EQUAL_INT32_MESSAGE( pdFREERTOS_ERRNO_NONE, xResult, "Socket failed to shutdown" ); xResult = prvCloseHelper( xSocket, &xSocketOpen ); @@ -1136,8 +1136,8 @@ static void prvSOCKETS_Socket_TCP( void ) /* Make TCP socket. */ xSocket = FreeRTOS_socket( FREERTOS_AF_INET, - FREERTOS_SOCK_STREAM, - FREERTOS_IPPROTO_TCP ); + FREERTOS_SOCK_STREAM, + FREERTOS_IPPROTO_TCP ); TEST_ASSERT_NOT_EQUAL( xSocket, FREERTOS_INVALID_SOCKET ); @@ -1257,7 +1257,7 @@ static void prvSOCKETS_NonBlocking_Test( void ) */ xResult = FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xTimeout, sizeof( TickType_t ) ); TEST_ASSERT_EQUAL_INT32_MESSAGE( pdFREERTOS_ERRNO_NONE, xResult, "Failed to set receive timeout" ); - + xStartTime = xTaskGetTickCount(); xResult = FreeRTOS_recv( xSocket, &pucRxBuffer, 1, 0 ); xEndTime = xTaskGetTickCount(); @@ -1333,11 +1333,11 @@ static void prvSetSockOpt_InvalidParams( void ) /* Try to set the invalid option. */ xResult = FreeRTOS_setsockopt( xSocket, - 0, /* lLevel - Not used. */ - -1, /* Invalid option name. */ - NULL, /* pvOptionValue - This is insignificant as the option name is invalid. */ - 0 /* xOptionLength - zero for NULL value. */ - ); + 0, /* lLevel - Not used. */ + -1, /* Invalid option name. */ + NULL, /* pvOptionValue - This is insignificant as the option name is invalid. */ + 0 /* xOptionLength - zero for NULL value. */ + ); /* Since the option name supplied in the previous * call was invalid, we expect the call to the API @@ -1346,10 +1346,10 @@ static void prvSetSockOpt_InvalidParams( void ) /* Try to set a valid option on an invalid socket. */ xResult = FreeRTOS_setsockopt( FREERTOS_INVALID_SOCKET, /* Invalid socket. */ - 0, /* lLevel - Not used. */ - FREERTOS_SO_RCVTIMEO, /* Receive timeout. */ - &( xReceiveTimeOut ), - sizeof( TickType_t ) ); + 0, /* lLevel - Not used. */ + FREERTOS_SO_RCVTIMEO, /* Receive timeout. */ + &( xReceiveTimeOut ), + sizeof( TickType_t ) ); /* Since the socket passed in the previous call was * invalid, we expect the call to the API @@ -1380,7 +1380,7 @@ TEST( Full_TCP, TCP_Socket_Setsockopt_InvalidParams ) /*-----------------------------------------------------------*/ static void prvSOCKETS_SetSockOpt_SNDTIMEO( void ) -{ +{ /* TODO: This is a stub function. */ TEST_FAIL_MESSAGE( "This test is not implemented." ); } @@ -1423,7 +1423,7 @@ static void prvSOCKETS_Shutdown( void ) /* Shutdown: Write. Expected behavior of send after * Shutdown/WRITE is ambiguous. Therefore, we cannot - * test anything except the read/recv. */ + * test anything except the read/recv. */ } TEST( Full_TCP, TCP_Socket_Shutdown ) @@ -1659,8 +1659,8 @@ static void prvSOCKETS_Socket_InvalidInputParams( void ) if( TEST_PROTECT() ) { xSocket = FreeRTOS_socket( ( FREERTOS_AF_INET + 1 ), - FREERTOS_SOCK_STREAM, - FREERTOS_IPPROTO_TCP ); + FREERTOS_SOCK_STREAM, + FREERTOS_IPPROTO_TCP ); /* If the test code reaches here, it failed. */ TEST_FAIL_MESSAGE( "Invalid socket domain accepted" ); @@ -1672,8 +1672,8 @@ static void prvSOCKETS_Socket_InvalidInputParams( void ) if( TEST_PROTECT() ) { xSocket = FreeRTOS_socket( FREERTOS_AF_INET, - ( FREERTOS_SOCK_STREAM | FREERTOS_SOCK_DGRAM ), - FREERTOS_IPPROTO_TCP ); + ( FREERTOS_SOCK_STREAM | FREERTOS_SOCK_DGRAM ), + FREERTOS_IPPROTO_TCP ); TEST_FAIL_MESSAGE( "Invalid socket type accepted" ); xResult = prvCloseHelper( xSocket, &xSocketOpen ); @@ -1683,9 +1683,9 @@ static void prvSOCKETS_Socket_InvalidInputParams( void ) /* Providing invalid protocol. */ if( TEST_PROTECT() ) { - xSocket = FreeRTOS_socket(FREERTOS_AF_INET, - FREERTOS_SOCK_STREAM, - ( FREERTOS_IPPROTO_TCP | FREERTOS_IPPROTO_UDP ) ); + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, + FREERTOS_SOCK_STREAM, + ( FREERTOS_IPPROTO_TCP | FREERTOS_IPPROTO_UDP ) ); TEST_FAIL_MESSAGE( "Invalid socket protocol accepted" ); xResult = prvCloseHelper( xSocket, &xSocketOpen ); @@ -1695,9 +1695,9 @@ static void prvSOCKETS_Socket_InvalidInputParams( void ) if( TEST_PROTECT() ) { /* Mixing DGRAM type with TCP protocol (instead of UDP). */ - xSocket = FreeRTOS_socket( FREERTOS_AF_INET, - FREERTOS_SOCK_DGRAM, - FREERTOS_IPPROTO_TCP ); + xSocket = FreeRTOS_socket( FREERTOS_AF_INET, + FREERTOS_SOCK_DGRAM, + FREERTOS_IPPROTO_TCP ); TEST_FAIL_MESSAGE( "Invalid socket created - mixed TCP with DGRAM " ); xResult = prvCloseHelper( xSocket, &xSocketOpen ); @@ -1708,8 +1708,8 @@ static void prvSOCKETS_Socket_InvalidInputParams( void ) if( TEST_PROTECT() ) { xSocket = FreeRTOS_socket( FREERTOS_AF_INET, - FREERTOS_SOCK_STREAM, - FREERTOS_IPPROTO_UDP ); + FREERTOS_SOCK_STREAM, + FREERTOS_IPPROTO_UDP ); TEST_FAIL_MESSAGE( "Invalid socket created - mixed UDP with STREAM" ); xResult = prvCloseHelper( xSocket, &xSocketOpen ); @@ -1773,7 +1773,7 @@ static void prvSOCKETS_Socket_ConcurrentCount( void ) #ifdef integrationtestportableMAX_NUM_UNSECURE_SOCKETS if( xResult == pdPASS ) { - xSocketLocal = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP); + xSocketLocal = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP ); if( xSocketLocal != FREERTOS_INVALID_SOCKET ) { @@ -1784,17 +1784,17 @@ static void prvSOCKETS_Socket_ConcurrentCount( void ) } } #endif /* ifdef integrationtestportableMAX_NUM_UNSECURE_SOCKETS */ - - TEST_ASSERT_EQUAL_UINT32_MESSAGE(pdPASS, xResult, "Concurrent num sockets test failed"); + + TEST_ASSERT_EQUAL_UINT32_MESSAGE( pdPASS, xResult, "Concurrent num sockets test failed" ); /* Cleanup. */ while( xSocketsCreated > 0 ) { --xSocketsCreated; xResult = FreeRTOS_closesocket( xCreatedSockets[ xSocketsCreated ] ); - TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(0, xResult, "Closing Socket in Multiple Concurrent Socket test failed\n"); + TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE( 0, xResult, "Closing Socket in Multiple Concurrent Socket test failed\n" ); } - + /* Report Test Results. */ tcptestPRINTF( ( "%s passed\r\n", __FUNCTION__ ) ); } @@ -1841,18 +1841,18 @@ static void prvFreeRTOS_connect_InvalidParams( void ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ xEchoServerAddress.sin_family = FREERTOS_AF_INET; - + /* Invalid socket. */ xResult = FreeRTOS_connect( FREERTOS_INVALID_SOCKET, - &xEchoServerAddress, - sizeof( xEchoServerAddress ) ); + &xEchoServerAddress, + sizeof( xEchoServerAddress ) ); TEST_ASSERT_LESS_THAN_INT32_MESSAGE( 0, xResult, "Connect on an invalid socket succeeded\n" ); xResult = prvCloseHelper( xSocket, &xSocketOpen ); TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE( pdFREERTOS_ERRNO_NONE, xResult, "Socket failed to close" ); - + /* Invalid IP address (0.0.0.0). TODO: Investigate reserved IP addresses */ @@ -1870,10 +1870,10 @@ static void prvFreeRTOS_connect_InvalidParams( void ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ xEchoServerAddress.sin_family = FREERTOS_AF_INET; - + xResult = FreeRTOS_connect( xSocket, - &xEchoServerAddress, - sizeof( xEchoServerAddress ) ); + &xEchoServerAddress, + sizeof( xEchoServerAddress ) ); TEST_ASSERT_LESS_THAN_INT32_MESSAGE( 0, xResult, "Connect to IP Address 0.0.0.0 worked" ); @@ -1899,10 +1899,10 @@ static void prvFreeRTOS_connect_InvalidParams( void ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ xEchoServerAddress.sin_family = FREERTOS_AF_INET; - + xResult = FreeRTOS_connect( xSocket, - &xEchoServerAddress, - sizeof( xEchoServerAddress ) ); + &xEchoServerAddress, + sizeof( xEchoServerAddress ) ); TEST_ASSERT_LESS_THAN_INT32_MESSAGE( 0, xResult, "Connect to Port 0 worked" ); @@ -2239,9 +2239,9 @@ static void prvEchoClientTxTask( void * pvParameters ) } xReturned = FreeRTOS_send( xSocket, /* The socket being sent to. */ - ( void * ) &( cTransmittedString[ xTransmitted ] ), /* The data being sent. */ - xLenToSend, /* The length of the data being sent. */ - 0 ); /* ulFlags. */ + ( void * ) &( cTransmittedString[ xTransmitted ] ), /* The data being sent. */ + xLenToSend, /* The length of the data being sent. */ + 0 ); /* ulFlags. */ if( xReturned >= 0 ) { @@ -2300,7 +2300,7 @@ void prvStartTCPEchoClientTasks_DifferentSockets( void ) /* Create the echo client tasks. */ for( usIndex = 0; usIndex < tcptestNUM_ECHO_CLIENTS; usIndex++ ) { - xTcptestEchoClientsTaskParams[ usIndex ].usTaskTag = usIndex; + xTcptestEchoClientsTaskParams[ usIndex ].usTaskTag = usIndex; xTcptestEchoClientsTaskParams[ usIndex ].xResult = FREERTOS_SOCKET_ERROR; xResult = xTaskCreate( prvThreadSafeDifferentSocketsDifferentTasks, /* The function that implements the task. */ @@ -2387,7 +2387,7 @@ static void prvThreadSafeDifferentSocketsDifferentTasks( void * pvParameters ) xResult = prvConnectHelperWithRetry( &xTaskSocket, xEchoTestRxTxTimeOut, xEchoTestRxTxTimeOut, - &xSocketOpenLocal); + &xSocketOpenLocal ); if( xResult != pdFREERTOS_ERRNO_NONE ) { @@ -2401,9 +2401,9 @@ static void prvThreadSafeDifferentSocketsDifferentTasks( void * pvParameters ) /* Send the string to the socket. */ xTransmitted = FreeRTOS_send( xTaskSocket, /* The socket being sent to. */ - ( void * ) cTransmittedString, /* The data being sent. */ - ipconfigTCP_MSS, /* The length of the data being sent. */ - 0 ); /* No flags. */ + ( void * ) cTransmittedString, /* The data being sent. */ + ipconfigTCP_MSS, /* The length of the data being sent. */ + 0 ); /* No flags. */ if( xTransmitted < ipconfigTCP_MSS ) { @@ -2423,9 +2423,9 @@ static void prvThreadSafeDifferentSocketsDifferentTasks( void * pvParameters ) while( xReceivedBytes < xTransmitted ) { xReturned = FreeRTOS_recv( xTaskSocket, /* The socket being received from. */ - &( pcReceivedString[ xReceivedBytes ] ), /* The buffer into which the received data will be written. */ - ipconfigTCP_MSS - xReceivedBytes, /* The size of the buffer provided to receive the data. */ - 0 ); /* No flags. */ + &( pcReceivedString[ xReceivedBytes ] ), /* The buffer into which the received data will be written. */ + ipconfigTCP_MSS - xReceivedBytes, /* The size of the buffer provided to receive the data. */ + 0 ); /* No flags. */ if( xReturned <= 0 ) { @@ -2461,7 +2461,7 @@ static void prvThreadSafeDifferentSocketsDifferentTasks( void * pvParameters ) /* Close this socket before looping back to create another. */ ( void ) prvShutdownHelper( xTaskSocket ); - ( void ) prvCloseHelper( xTaskSocket, &xSocketOpenLocal); + ( void ) prvCloseHelper( xTaskSocket, &xSocketOpenLocal ); } } @@ -2500,7 +2500,7 @@ TEST( Full_TCP, TCP_htons_HappyCase ) * value. */ usNetworkOrderValue = FreeRTOS_htons( 0x1234 ); - #if defined(ipconfigBYTE_ORDER) && ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) + #if defined( ipconfigBYTE_ORDER ) && ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) /* If the platform we are running on, is little * endian, bytes must have been swapped. */ @@ -2560,15 +2560,16 @@ TEST( Full_TCP, TCP_test_dns_multiple_addresses ) } tcptestPRINTF( ( "%s: identified %d different IP addresses for %s.\r\n", - __FUNCTION__, - ulNumUniqueIPAddresses, - HostNameUNIQUE_ADDRESSES_TEST ) ); + __FUNCTION__, + ulNumUniqueIPAddresses, + HostNameUNIQUE_ADDRESSES_TEST ) ); /* Require a minimum number of IP addresses for AWS IoT Core endpoints */ if( ulNumUniqueIPAddresses >= dnstestNUM_UNIQUE_IP_ADDRESSES ) { xResult = pdPASS; } + TEST_ASSERT_EQUAL_UINT32_MESSAGE( pdPASS, xResult, "Less number of IP addresses per entry than expected\n" ); tcptestPRINTF( ( "%s complete.\r\n", __FUNCTION__ ) ); @@ -2584,7 +2585,7 @@ TEST( Full_TCP, TCP_inet_addr_quick_HappyCase ) ulPackedIpAddress = FreeRTOS_inet_addr_quick( 192, 168, 2, 6 ); - #if defined(ipconfigBYTE_ORDER) && ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) + #if defined( ipconfigBYTE_ORDER ) && ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) /* The expected return value of FreeRTOS_inet_addr_quick * on a little endian platform must be same as the correct diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Runner/test_runner.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Runner/test_runner.c index e2843af65..91827e5f5 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Runner/test_runner.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Runner/test_runner.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /** @@ -51,8 +52,8 @@ unsigned int xHeapAfter; * RUN_TEST_GROUP statements. */ static void RunTests( void ) -{ - RUN_TEST_GROUP( Full_TCP ); +{ + RUN_TEST_GROUP( Full_TCP ); } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Runner/test_runner_config.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Runner/test_runner_config.h index 65e3ea0d8..a593832c8 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Runner/test_runner_config.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/Test_Code/Test_Runner/test_runner_config.h @@ -1,34 +1,34 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #ifndef AWS_TEST_RUNNER_CONFIG_H #define AWS_TEST_RUNNER_CONFIG_H - /* Uncomment this line if you want to run DQP_FR tests only. */ - /* #define testrunnerAFQP_ENABLED */ +/* Uncomment this line if you want to run DQP_FR tests only. */ +/* #define testrunnerAFQP_ENABLED */ #define testrunnerUNSUPPORTED 0 @@ -67,8 +67,8 @@ /* On systems using FreeRTOS+TCP (such as this one) the TCP segments must be * cleaned up before running the memory leak check. */ #if ( testrunnerFULL_MEMORYLEAK_ENABLED == 1 ) -extern void vTCPSegmentCleanup(); -#define testrunnerMEMORYLEAK_CLEANUP() vTCPSegmentCleanup() + extern void vTCPSegmentCleanup(); + #define testrunnerMEMORYLEAK_CLEANUP() vTCPSegmentCleanup() #endif #endif /* AWS_TEST_RUNNER_CONFIG_H */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/Packet32.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/Packet32.h index 64be055d9..f6b7b27aa 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/Packet32.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/Packet32.h @@ -12,9 +12,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino, CACE Technologies - * nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,7 +32,7 @@ */ /** @ingroup packetapi - * @{ + * @{ */ /** @defgroup packet32h Packet.dll definitions and data structures @@ -43,317 +43,356 @@ */ #ifndef __PACKET32 -#define __PACKET32 + #define __PACKET32 -#include + #include -#ifdef HAVE_AIRPCAP_API -#include -#else -#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) -#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ -typedef struct _AirpcapHandle *PAirpcapHandle; -#endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */ -#endif /* HAVE_AIRPCAP_API */ + #ifdef HAVE_AIRPCAP_API + #include + #else + #if !defined( AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ ) + #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ + typedef struct _AirpcapHandle * PAirpcapHandle; + #endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */ + #endif /* HAVE_AIRPCAP_API */ -#ifdef HAVE_DAG_API -#include -#endif /* HAVE_DAG_API */ + #ifdef HAVE_DAG_API + #include + #endif /* HAVE_DAG_API */ -// Working modes -#define PACKET_MODE_CAPT 0x0 ///< Capture mode -#define PACKET_MODE_STAT 0x1 ///< Statistical mode -#define PACKET_MODE_MON 0x2 ///< Monitoring mode -#define PACKET_MODE_DUMP 0x10 ///< Dump mode -#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode +/* Working modes */ + #define PACKET_MODE_CAPT 0x0 /*/< Capture mode */ + #define PACKET_MODE_STAT 0x1 /*/< Statistical mode */ + #define PACKET_MODE_MON 0x2 /*/< Monitoring mode */ + #define PACKET_MODE_DUMP 0x10 /*/< Dump mode */ + #define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT /*/< Statistical dump Mode */ -/// Alignment macro. Defines the alignment size. -#define Packet_ALIGNMENT sizeof(int) -/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. -#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) +/*/ Alignment macro. Defines the alignment size. */ + #define Packet_ALIGNMENT sizeof( int ) +/*/ Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. */ + #define Packet_WORDALIGN( x ) ( ( ( x ) + ( Packet_ALIGNMENT - 1 ) ) & ~( Packet_ALIGNMENT - 1 ) ) -#define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumPpi -6 ///< Custom linktype: NDIS doesn't provide an equivalent + #define NdisMediumNull -1 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumCHDLC -2 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumPPPSerial -3 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumBare80211 -4 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumRadio80211 -5 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumPpi -6 /*/< Custom linktype: NDIS doesn't provide an equivalent */ -// Loopback behaviour definitions -#define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver -#define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver +/* Loopback behaviour definitions */ + #define NPF_DISABLE_LOOPBACK 1 /*/< Drop the packets sent by the NPF driver */ + #define NPF_ENABLE_LOOPBACK 2 /*/< Capture the packets sent by the NPF driver */ /*! - \brief Network type structure. - - This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. -*/ -typedef struct NetType -{ - UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information) - ULONGLONG LinkSpeed; ///< The speed of the network in bits per second -}NetType; + * \brief Network type structure. + * + * This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. + */ + typedef struct NetType + { + UINT LinkType; /*/< The MAC of the current network adapter (see function PacketGetNetType() for more information) */ + ULONGLONG LinkSpeed; /*/< The speed of the network in bits per second */ + } NetType; -//some definitions stolen from libpcap +/*some definitions stolen from libpcap */ -#ifndef BPF_MAJOR_VERSION + #ifndef BPF_MAJOR_VERSION /*! - \brief A BPF pseudo-assembly program. - - The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. -*/ -struct bpf_program -{ - UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. - struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program. -}; + * \brief A BPF pseudo-assembly program. + * + * The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. + */ + struct bpf_program + { + UINT bf_len; /*/< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. */ + struct bpf_insn * bf_insns; /*/< A pointer to the first instruction of the program. */ + }; /*! - \brief A single BPF pseudo-instruction. - - bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. -*/ -struct bpf_insn -{ - USHORT code; ///< Instruction type and addressing mode. - UCHAR jt; ///< Jump if true - UCHAR jf; ///< Jump if false - int k; ///< Generic field used for various purposes. -}; + * \brief A single BPF pseudo-instruction. + * + * bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. + */ + struct bpf_insn + { + USHORT code; /*/< Instruction type and addressing mode. */ + UCHAR jt; /*/< Jump if true */ + UCHAR jf; /*/< Jump if false */ + int k; /*/< Generic field used for various purposes. */ + }; /*! - \brief Structure that contains a couple of statistics values on the current capture. - - It is used by packet.dll to return statistics about a capture session. -*/ -struct bpf_stat -{ - UINT bs_recv; ///< Number of packets that the driver received from the network adapter - ///< from the beginning of the current capture. This value includes the packets - ///< lost by the driver. - UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture. - ///< Basically, a packet is lost when the the buffer of the driver is full. - ///< In this situation the packet cannot be stored and the driver rejects it. - UINT ps_ifdrop; ///< drops by interface. XXX not yet supported - UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and - ///< thus reach the application. -}; + * \brief Structure that contains a couple of statistics values on the current capture. + * + * It is used by packet.dll to return statistics about a capture session. + */ + struct bpf_stat + { + UINT bs_recv; /*/< Number of packets that the driver received from the network adapter */ + /*/< from the beginning of the current capture. This value includes the packets */ + /*/< lost by the driver. */ + UINT bs_drop; /*/< number of packets that the driver lost from the beginning of a capture. */ + /*/< Basically, a packet is lost when the the buffer of the driver is full. */ + /*/< In this situation the packet cannot be stored and the driver rejects it. */ + UINT ps_ifdrop; /*/< drops by interface. XXX not yet supported */ + UINT bs_capt; /*/< number of packets that pass the filter, find place in the kernel buffer and */ + /*/< thus reach the application. */ + }; /*! - \brief Packet header. - - This structure defines the header associated with every packet delivered to the application. -*/ -struct bpf_hdr -{ - struct timeval bh_tstamp; ///< The timestamp associated with the captured packet. - ///< It is stored in a TimeVal structure. - UINT bh_caplen; ///< Length of captured portion. The captured portion can be different - ///< from the original packet, because it is possible (with a proper filter) - ///< to instruct the driver to capture only a portion of the packets. - UINT bh_datalen; ///< Original length of packet - USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases, - ///< a padding could be added between the end of this structure and the packet - ///< data for performance reasons. This filed can be used to retrieve the actual data - ///< of the packet. -}; + * \brief Packet header. + * + * This structure defines the header associated with every packet delivered to the application. + */ + struct bpf_hdr + { + struct timeval bh_tstamp; /*/< The timestamp associated with the captured packet. */ + /*/< It is stored in a TimeVal structure. */ + UINT bh_caplen; /*/< Length of captured portion. The captured portion can be different */ + /*/< from the original packet, because it is possible (with a proper filter) */ + /*/< to instruct the driver to capture only a portion of the packets. */ + UINT bh_datalen; /*/< Original length of packet */ + USHORT bh_hdrlen; /*/< Length of bpf header (this struct plus alignment padding). In some cases, */ + /*/< a padding could be added between the end of this structure and the packet */ + /*/< data for performance reasons. This filed can be used to retrieve the actual data */ + /*/< of the packet. */ + }; /*! - \brief Dump packet header. - - This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). - It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a - packet in a dump file. This makes straightforward sending WinPcap dump files to the network. -*/ -struct dump_bpf_hdr{ - struct timeval ts; ///< Time stamp of the packet - UINT caplen; ///< Length of captured portion. The captured portion can smaller than the - ///< the original packet, because it is possible (with a proper filter) to - ///< instruct the driver to capture only a portion of the packets. - UINT len; ///< Length of the original packet (off wire). -}; + * \brief Dump packet header. + * + * This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). + * It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a + * packet in a dump file. This makes straightforward sending WinPcap dump files to the network. + */ + struct dump_bpf_hdr + { + struct timeval ts; /*/< Time stamp of the packet */ + UINT caplen; /*/< Length of captured portion. The captured portion can smaller than the */ + /*/< the original packet, because it is possible (with a proper filter) to */ + /*/< instruct the driver to capture only a portion of the packets. */ + UINT len; /*/< Length of the original packet (off wire). */ + }; -#endif + #endif /* ifndef BPF_MAJOR_VERSION */ -struct bpf_stat; + struct bpf_stat; -#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices -#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links -#define NMAX_PACKET 65535 + #define DOSNAMEPREFIX TEXT( "Packet_" ) /*/< Prefix added to the adapters device names to create the WinPcap devices */ + #define MAX_LINK_NAME_LENGTH 64 /*< Maximum length of the devices symbolic links */ + #define NMAX_PACKET 65535 /*! - \brief Addresses of a network adapter. - - This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with - an adapter. -*/ -typedef struct npf_if_addr { - struct sockaddr_storage IPAddress; ///< IP address. - struct sockaddr_storage SubnetMask; ///< Netmask for that address. - struct sockaddr_storage Broadcast; ///< Broadcast address. -}npf_if_addr; + * \brief Addresses of a network adapter. + * + * This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with + * an adapter. + */ + typedef struct npf_if_addr + { + struct sockaddr_storage IPAddress; /*/< IP address. */ + struct sockaddr_storage SubnetMask; /*/< Netmask for that address. */ + struct sockaddr_storage Broadcast; /*/< Broadcast address. */ + } npf_if_addr; -#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API. -#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API. -#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. -#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. + #define ADAPTER_NAME_LENGTH 256 + 12 /*/< Maximum length for the name of an adapter. The value is the same used by the IP Helper API. */ + #define ADAPTER_DESC_LENGTH 128 /*/< Maximum length for the description of an adapter. The value is the same used by the IP Helper API. */ + #define MAX_MAC_ADDR_LENGTH 8 /*/< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. */ + #define MAX_NETWORK_ADDRESSES 16 /*/< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. */ -typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API -typedef WAN_ADAPTER *PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API + typedef struct WAN_ADAPTER_INT WAN_ADAPTER; /*/< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API */ + typedef WAN_ADAPTER * PWAN_ADAPTER; /*/< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API */ -#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter -#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET -#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card -#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file -#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones. -#define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card -#define INFO_FLAG_NPFIM_DEVICE 32 + #define INFO_FLAG_NDIS_ADAPTER 0 /*/< Flag for ADAPTER_INFO: this is a traditional ndis adapter */ + #define INFO_FLAG_NDISWAN_ADAPTER 1 /*/< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET */ + #define INFO_FLAG_DAG_CARD 2 /*/< Flag for ADAPTER_INFO: this is a DAG card */ + #define INFO_FLAG_DAG_FILE 6 /*/< Flag for ADAPTER_INFO: this is a DAG file */ + #define INFO_FLAG_DONT_EXPORT 8 /*/< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones. */ + #define INFO_FLAG_AIRPCAP_CARD 16 /*/< Flag for ADAPTER_INFO: this is an airpcap card */ + #define INFO_FLAG_NPFIM_DEVICE 32 /*! - \brief Describes an opened network adapter. + * \brief Describes an opened network adapter. + * + * This structure is the most important for the functioning of packet.dll, but the great part of its fields + * should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters + */ + typedef struct _ADAPTER + { + HANDLE hFile; /*/< \internal Handle to an open instance of the NPF driver. */ + CHAR SymbolicLink[ MAX_LINK_NAME_LENGTH ]; /*/< \internal A string containing the name of the network adapter currently opened. */ + int NumWrites; /*/< \internal Number of times a packets written on this adapter will be repeated */ + /*/< on the wire. */ + HANDLE ReadEvent; /*/< A notification event associated with the read calls on the adapter. */ + /*/< It can be passed to standard Win32 functions (like WaitForSingleObject */ + /*/< or WaitForMultipleObjects) to wait until the driver's buffer contains some */ + /*/< data. It is particularly useful in GUI applications that need to wait */ + /*/< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() */ + /*/< function can be used to define the minimum amount of data in the kernel buffer */ + /*/< that will cause the event to be signalled. */ - This structure is the most important for the functioning of packet.dll, but the great part of its fields - should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters -*/ -typedef struct _ADAPTER { - HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver. - CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened. - int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated - ///< on the wire. - HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter. - ///< It can be passed to standard Win32 functions (like WaitForSingleObject - ///< or WaitForMultipleObjects) to wait until the driver's buffer contains some - ///< data. It is particularly useful in GUI applications that need to wait - ///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() - ///< function can be used to define the minimum amount of data in the kernel buffer - ///< that will cause the event to be signalled. - - UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and - ///< ReadEvent will be signaled, also if no packets were captured - CHAR Name[ADAPTER_NAME_LENGTH]; - PWAN_ADAPTER pWanAdapter; - UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. + UINT ReadTimeOut; /*/< \internal The amount of time after which a read on the driver will be released and */ + /*/< ReadEvent will be signaled, also if no packets were captured */ + CHAR Name[ ADAPTER_NAME_LENGTH ]; + PWAN_ADAPTER pWanAdapter; + UINT Flags; /*/< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. */ -#ifdef HAVE_AIRPCAP_API - PAirpcapHandle AirpcapAd; -#endif // HAVE_AIRPCAP_API + #ifdef HAVE_AIRPCAP_API + PAirpcapHandle AirpcapAd; + #endif // HAVE_AIRPCAP_API -#ifdef HAVE_NPFIM_API - void* NpfImHandle; -#endif // HAVE_NPFIM_API + #ifdef HAVE_NPFIM_API + void * NpfImHandle; + #endif // HAVE_NPFIM_API -#ifdef HAVE_DAG_API - dagc_t *pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter - PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card - struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure - unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry - DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps). -#endif // HAVE_DAG_API -} ADAPTER, *LPADAPTER; + #ifdef HAVE_DAG_API + dagc_t * pDagCard; /*/< Pointer to the dagc API adapter descriptor for this adapter */ + PCHAR DagBuffer; /*/< Pointer to the buffer with the packets that is received from the DAG card */ + struct timeval DagReadTimeout; /*/< Read timeout. The dagc API requires a timeval structure */ + unsigned DagFcsLen; /*/< Length of the frame check sequence attached to any packet by the card. Obtained from the registry */ + DWORD DagFastProcess; /*/< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps). */ + #endif // HAVE_DAG_API + } ADAPTER, * LPADAPTER; /*! - \brief Structure that contains a group of packets coming from the driver. - - This structure defines the header associated with every packet delivered to the application. -*/ -typedef struct _PACKET { - HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications. - OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications. - PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for - ///< details about the organization of the data in this buffer - UINT Length; ///< Length of the buffer - DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data - ///< received by the last call to PacketReceivePacket() - BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications. -} PACKET, *LPPACKET; + * \brief Structure that contains a group of packets coming from the driver. + * + * This structure defines the header associated with every packet delivered to the application. + */ + typedef struct _PACKET + { + HANDLE hEvent; /*/< \deprecated Still present for compatibility with old applications. */ + OVERLAPPED OverLapped; /*/< \deprecated Still present for compatibility with old applications. */ + PVOID Buffer; /*/< Buffer with containing the packets. See the PacketReceivePacket() for */ + /*/< details about the organization of the data in this buffer */ + UINT Length; /*/< Length of the buffer */ + DWORD ulBytesReceived; /*/< Number of valid bytes present in the buffer, i.e. amount of data */ + /*/< received by the last call to PacketReceivePacket() */ + BOOLEAN bIoComplete; /*/< \deprecated Still present for compatibility with old applications. */ + } PACKET, * LPPACKET; /*! - \brief Structure containing an OID request. + * \brief Structure containing an OID request. + * + * It is used by the PacketRequest() function to send an OID to the interface card driver. + * It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, + * the list of the multicast groups defined on it, and so on. + */ + struct _PACKET_OID_DATA + { + ULONG Oid; /*/< OID code. See the Microsoft DDK documentation or the file ntddndis.h */ + /*/< for a complete list of valid codes. */ + ULONG Length; /*/< Length of the data field */ + UCHAR Data[ 1 ]; /*/< variable-length field that contains the information passed to or received */ + /*/< from the adapter. */ + }; + typedef struct _PACKET_OID_DATA PACKET_OID_DATA, * PPACKET_OID_DATA; - It is used by the PacketRequest() function to send an OID to the interface card driver. - It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, - the list of the multicast groups defined on it, and so on. -*/ -struct _PACKET_OID_DATA { - ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h - ///< for a complete list of valid codes. - ULONG Length; ///< Length of the data field - UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received - ///< from the adapter. -}; -typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; - -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /** * @} */ /* -BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, - CHAR *Value, - UINT *pValueLen, - CHAR *DefaultVal); + * BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, + * CHAR *Value, + * UINT *pValueLen, + * CHAR *DefaultVal); + * + * BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, + * WCHAR *Value, + * UINT *pValueLen, + * WCHAR *DefaultVal); + */ -BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, - WCHAR *Value, - UINT *pValueLen, - WCHAR *DefaultVal); -*/ - -//--------------------------------------------------------------------------- -// EXPORTED FUNCTIONS -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- */ +/* EXPORTED FUNCTIONS */ +/*--------------------------------------------------------------------------- */ -PCHAR PacketGetVersion(); -PCHAR PacketGetDriverVersion(); -BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes); -BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites); -BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode); -BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout); -BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp); -BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior); -INT PacketSetSnapLen(LPADAPTER AdapterObject,int snaplen); -BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s); -BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s); -BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim); -BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type); -LPADAPTER PacketOpenAdapter(PCHAR AdapterName); -BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync); -INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync); -LPPACKET PacketAllocatePacket(void); -VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length); -VOID PacketFreePacket(LPPACKET lpPacket); -BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync); -BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter); -BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize); -BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries); -BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData); -HANDLE PacketGetReadEvent(LPADAPTER AdapterObject); -BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len); -BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks); -BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync); -BOOL PacketStopDriver(); -VOID PacketCloseAdapter(LPADAPTER lpAdapter); -BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength); -BOOLEAN PacketStartOemEx(PCHAR errorString, UINT errorStringLength, ULONG flags); -PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject); + PCHAR PacketGetVersion(); + PCHAR PacketGetDriverVersion(); + BOOLEAN PacketSetMinToCopy( LPADAPTER AdapterObject, + int nbytes ); + BOOLEAN PacketSetNumWrites( LPADAPTER AdapterObject, + int nwrites ); + BOOLEAN PacketSetMode( LPADAPTER AdapterObject, + int mode ); + BOOLEAN PacketSetReadTimeout( LPADAPTER AdapterObject, + int timeout ); + BOOLEAN PacketSetBpf( LPADAPTER AdapterObject, + struct bpf_program * fp ); + BOOLEAN PacketSetLoopbackBehavior( LPADAPTER AdapterObject, + UINT LoopbackBehavior ); + INT PacketSetSnapLen( LPADAPTER AdapterObject, + int snaplen ); + BOOLEAN PacketGetStats( LPADAPTER AdapterObject, + struct bpf_stat * s ); + BOOLEAN PacketGetStatsEx( LPADAPTER AdapterObject, + struct bpf_stat * s ); + BOOLEAN PacketSetBuff( LPADAPTER AdapterObject, + int dim ); + BOOLEAN PacketGetNetType( LPADAPTER AdapterObject, + NetType * type ); + LPADAPTER PacketOpenAdapter( PCHAR AdapterName ); + BOOLEAN PacketSendPacket( LPADAPTER AdapterObject, + LPPACKET pPacket, + BOOLEAN Sync ); + INT PacketSendPackets( LPADAPTER AdapterObject, + PVOID PacketBuff, + ULONG Size, + BOOLEAN Sync ); + LPPACKET PacketAllocatePacket( void ); + VOID PacketInitPacket( LPPACKET lpPacket, + PVOID Buffer, + UINT Length ); + VOID PacketFreePacket( LPPACKET lpPacket ); + BOOLEAN PacketReceivePacket( LPADAPTER AdapterObject, + LPPACKET lpPacket, + BOOLEAN Sync ); + BOOLEAN PacketSetHwFilter( LPADAPTER AdapterObject, + ULONG Filter ); + BOOLEAN PacketGetAdapterNames( PTSTR pStr, + PULONG BufferSize ); + BOOLEAN PacketGetNetInfoEx( PCHAR AdapterName, + npf_if_addr * buffer, + PLONG NEntries ); + BOOLEAN PacketRequest( LPADAPTER AdapterObject, + BOOLEAN Set, + PPACKET_OID_DATA OidData ); + HANDLE PacketGetReadEvent( LPADAPTER AdapterObject ); + BOOLEAN PacketSetDumpName( LPADAPTER AdapterObject, + void * name, + int len ); + BOOLEAN PacketSetDumpLimits( LPADAPTER AdapterObject, + UINT maxfilesize, + UINT maxnpacks ); + BOOLEAN PacketIsDumpEnded( LPADAPTER AdapterObject, + BOOLEAN sync ); + BOOL PacketStopDriver(); + VOID PacketCloseAdapter( LPADAPTER lpAdapter ); + BOOLEAN PacketStartOem( PCHAR errorString, + UINT errorStringLength ); + BOOLEAN PacketStartOemEx( PCHAR errorString, + UINT errorStringLength, + ULONG flags ); + PAirpcapHandle PacketGetAirPcapHandle( LPADAPTER AdapterObject ); -// -// Used by PacketStartOemEx -// -#define PACKET_START_OEM_NO_NETMON 0x00000001 +/* */ +/* Used by PacketStartOemEx */ +/* */ + #define PACKET_START_OEM_NO_NETMON 0x00000001 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif //__PACKET32 diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/PacketData.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/PacketData.h index dd3d225e4..5c082687a 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/PacketData.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/PacketData.h @@ -1,249 +1,273 @@ -char pkt1[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x30, 0x09, 0x9c, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x07, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc7, 0x35, 0x00, 0x00, 0x00, 0x00, 0x70, 0x02, -0x40, 0x00, 0xdf, 0xab, 0x00, 0x00, 0x02, 0x04, -0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 }; +char pkt1[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x30, 0x09, 0x9c, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x07, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc7, 0x35, 0x00, 0x00, 0x00, 0x00, 0x70, 0x02, + 0x40, 0x00, 0xdf, 0xab, 0x00, 0x00, 0x02, 0x04, + 0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 +}; -char pkt2[] = { -0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, -0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, -0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, -0xf8, 0xa6, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, -0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, -0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, -0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, -0x05, 0x92 }; +char pkt2[] = +{ + 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, + 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, + 0xf8, 0xa6, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, + 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, + 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, + 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, + 0x05, 0x92 +}; -char pkt3[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0x9e, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, -0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; +char pkt3[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0x9e, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt4[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x02, 0x27, 0x09, 0x9f, 0x40, 0x00, 0x80, 0x06, -0x6d, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18, -0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45, -0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, -0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, -0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d, -0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c, -0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, -0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, -0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, -0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d, -0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65, -0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, -0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, -0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78, -0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c, -0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, -0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, -0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65, -0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20, -0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, -0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, -0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, -0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70, -0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, -0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78, -0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, -0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d, -0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, -0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, -0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, -0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, -0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a, -0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, -0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, -0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64, -0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a, -0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, -0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, -0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20, -0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, -0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49, -0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57, -0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e, -0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53, -0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67, -0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e, -0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32, -0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37, -0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, -0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30, -0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38, -0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, -0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32, -0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48, -0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, -0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, -0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, -0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, -0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, -0x65, 0x0d, 0x0a, 0x0d, 0x0a }; +char pkt4[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x02, 0x27, 0x09, 0x9f, 0x40, 0x00, 0x80, 0x06, + 0x6d, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18, + 0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45, + 0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, + 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c, + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, + 0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, + 0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, + 0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65, + 0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78, + 0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, + 0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65, + 0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, + 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78, + 0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, + 0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, + 0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, + 0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64, + 0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a, + 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, + 0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20, + 0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49, + 0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e, + 0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53, + 0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e, + 0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32, + 0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37, + 0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, + 0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30, + 0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38, + 0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, + 0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32, + 0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48, + 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, + 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, + 0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, + 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, + 0x65, 0x0d, 0x0a, 0x0d, 0x0a +}; -char pkt5[] = { -0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, -0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, -0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x40, 0x06, -0xf8, 0xa5, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, -0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, -0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, -0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, -0x05, 0x92 }; +char pkt5[] = +{ + 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, + 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x40, 0x06, + 0xf8, 0xa5, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, + 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, + 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, + 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, + 0x05, 0x92 +}; -char pkt6[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0xa1, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, -0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; +char pkt6[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0xa1, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt7[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x02, 0x27, 0x09, 0xa2, 0x40, 0x00, 0x80, 0x06, -0x6d, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18, -0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45, -0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, -0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, -0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d, -0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c, -0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, -0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, -0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, -0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d, -0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65, -0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, -0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, -0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78, -0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c, -0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, -0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, -0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65, -0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20, -0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, -0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, -0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, -0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70, -0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, -0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78, -0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, -0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d, -0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70, -0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, -0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, -0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, -0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, -0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, -0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a, -0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, -0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, -0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64, -0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a, -0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, -0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, -0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20, -0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, -0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49, -0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57, -0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e, -0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53, -0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67, -0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e, -0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32, -0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37, -0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, -0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30, -0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38, -0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, -0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32, -0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48, -0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, -0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, -0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, -0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, -0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, -0x65, 0x0d, 0x0a, 0x0d, 0x0a }; +char pkt7[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x02, 0x27, 0x09, 0xa2, 0x40, 0x00, 0x80, 0x06, + 0x6d, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18, + 0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45, + 0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, + 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c, + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78, + 0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, + 0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, + 0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65, + 0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78, + 0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64, + 0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65, + 0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, + 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78, + 0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, + 0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, + 0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, + 0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64, + 0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a, + 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, + 0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20, + 0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49, + 0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e, + 0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53, + 0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e, + 0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32, + 0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37, + 0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, + 0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30, + 0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38, + 0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43, + 0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32, + 0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48, + 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, + 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, + 0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, + 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, + 0x65, 0x0d, 0x0a, 0x0d, 0x0a +}; -char pkt8[] = { -0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, -0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, -0x00, 0x2c, 0x00, 0x03, 0x00, 0x00, 0x40, 0x06, -0xf8, 0xa4, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, -0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, -0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, -0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, -0x05, 0x92 }; +char pkt8[] = +{ + 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, + 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2c, 0x00, 0x03, 0x00, 0x00, 0x40, 0x06, + 0xf8, 0xa4, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, + 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, + 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, + 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, + 0x05, 0x92 +}; -char pkt9[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0xa3, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x08, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, -0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; +char pkt9[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0xa3, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x08, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt10[] = { -0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, -0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, -0x00, 0x2c, 0x00, 0x04, 0x00, 0x00, 0x40, 0x06, -0xf8, 0xa3, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, -0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, -0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, -0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, -0x05, 0x92 }; +char pkt10[] = +{ + 0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01, + 0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2c, 0x00, 0x04, 0x00, 0x00, 0x40, 0x06, + 0xf8, 0xa3, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8, + 0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00, + 0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12, + 0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04, + 0x05, 0x92 +}; -char pkt11[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0xa6, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x05, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, -0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 }; +char pkt11[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0xa6, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x05, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10, + 0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 +}; -char pkt12[] = { -0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, -0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, -0x00, 0x28, 0x09, 0xa7, 0x40, 0x00, 0x80, 0x06, -0x6f, 0x04, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, -0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, -0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x14, -0x00, 0x00, 0x43, 0xf4, 0x00, 0x00 }; +char pkt12[] = +{ + 0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14, + 0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x28, 0x09, 0xa7, 0x40, 0x00, 0x80, 0x06, + 0x6f, 0x04, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8, + 0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7, + 0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x14, + 0x00, 0x00, 0x43, 0xf4, 0x00, 0x00 +}; typedef struct { - char *pcData; - int iDataLen; + char * pcData; + int iDataLen; } xPacketData; xPacketData xAllPackets[] = @@ -251,16 +275,16 @@ xPacketData xAllPackets[] = /* These comments below are there so that we may modify * them as and when required. Keeping them unmodified. * Might be removed in later incremental PRs */ - { pkt1, sizeof( pkt1 ) }, + { pkt1, sizeof( pkt1 ) }, /* { pkt2, sizeof( pkt2 ) }, */ - { pkt3, sizeof( pkt3 ) }, - { pkt4, sizeof( pkt4 ) }, + { pkt3, sizeof( pkt3 ) }, + { pkt4, sizeof( pkt4 ) }, /* { pkt5, sizeof( pkt5 ) }, */ - { pkt6, sizeof( pkt6 ) }, - { pkt7, sizeof( pkt7 ) }, - { pkt8, sizeof( pkt8 ) }, - { pkt9, sizeof( pkt9 ) }, - { pkt10, sizeof( pkt10 ) }, + { pkt6, sizeof( pkt6 ) }, + { pkt7, sizeof( pkt7 ) }, + { pkt8, sizeof( pkt8 ) }, + { pkt9, sizeof( pkt9 ) }, + { pkt10, sizeof( pkt10 ) }, /* { pkt11, sizeof( pkt11 ) }, */ /* { pkt12, sizeof( pkt12 ) }, */ /* { pkt13, sizeof( pkt13 ) }, */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/Win32-Extensions.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/Win32-Extensions.h index bad7c33ac..9258fe0e8 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/Win32-Extensions.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/Win32-Extensions.h @@ -12,9 +12,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino, CACE Technologies - * nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -33,82 +33,95 @@ #ifndef __WIN32_EXTENSIONS_H__ -#define __WIN32_EXTENSIONS_H__ + #define __WIN32_EXTENSIONS_H__ -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* Definitions */ /*! - \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). -*/ -struct pcap_send_queue -{ - u_int maxlen; ///< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. - u_int len; ///< Current size of the queue, in bytes. - char *buffer; ///< Buffer containing the packets to be sent. -}; + * \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). + */ + struct pcap_send_queue + { + u_int maxlen; /*/< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. */ + u_int len; /*/< Current size of the queue, in bytes. */ + char * buffer; /*/< Buffer containing the packets to be sent. */ + }; -typedef struct pcap_send_queue pcap_send_queue; + typedef struct pcap_send_queue pcap_send_queue; /*! - \brief This typedef is a support for the pcap_get_airpcap_handle() function -*/ -#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) -#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ -typedef struct _AirpcapHandle *PAirpcapHandle; -#endif + * \brief This typedef is a support for the pcap_get_airpcap_handle() function + */ + #if !defined( AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ ) + #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ + typedef struct _AirpcapHandle * PAirpcapHandle; + #endif -#define BPF_MEM_EX_IMM 0xc0 -#define BPF_MEM_EX_IND 0xe0 + #define BPF_MEM_EX_IMM 0xc0 + #define BPF_MEM_EX_IND 0xe0 /*used for ST*/ -#define BPF_MEM_EX 0xc0 -#define BPF_TME 0x08 + #define BPF_MEM_EX 0xc0 + #define BPF_TME 0x08 -#define BPF_LOOKUP 0x90 -#define BPF_EXECUTE 0xa0 -#define BPF_INIT 0xb0 -#define BPF_VALIDATE 0xc0 -#define BPF_SET_ACTIVE 0xd0 -#define BPF_RESET 0xe0 -#define BPF_SET_MEMORY 0x80 -#define BPF_GET_REGISTER_VALUE 0x70 -#define BPF_SET_REGISTER_VALUE 0x60 -#define BPF_SET_WORKING 0x50 -#define BPF_SET_ACTIVE_READ 0x40 -#define BPF_SET_AUTODELETION 0x30 -#define BPF_SEPARATION 0xff + #define BPF_LOOKUP 0x90 + #define BPF_EXECUTE 0xa0 + #define BPF_INIT 0xb0 + #define BPF_VALIDATE 0xc0 + #define BPF_SET_ACTIVE 0xd0 + #define BPF_RESET 0xe0 + #define BPF_SET_MEMORY 0x80 + #define BPF_GET_REGISTER_VALUE 0x70 + #define BPF_SET_REGISTER_VALUE 0x60 + #define BPF_SET_WORKING 0x50 + #define BPF_SET_ACTIVE_READ 0x40 + #define BPF_SET_AUTODELETION 0x30 + #define BPF_SEPARATION 0xff /* Prototypes */ -pcap_send_queue* pcap_sendqueue_alloc(u_int memsize); + pcap_send_queue * pcap_sendqueue_alloc( u_int memsize ); -void pcap_sendqueue_destroy(pcap_send_queue* queue); + void pcap_sendqueue_destroy( pcap_send_queue * queue ); -int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); + int pcap_sendqueue_queue( pcap_send_queue * queue, + const struct pcap_pkthdr * pkt_header, + const u_char * pkt_data ); -u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync); + u_int pcap_sendqueue_transmit( pcap_t * p, + pcap_send_queue * queue, + int sync ); -HANDLE pcap_getevent(pcap_t *p); + HANDLE pcap_getevent( pcap_t * p ); -struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size); + struct pcap_stat * pcap_stats_ex( pcap_t * p, + int * pcap_stat_size ); -int pcap_setuserbuffer(pcap_t *p, int size); + int pcap_setuserbuffer( pcap_t * p, + int size ); -int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks); + int pcap_live_dump( pcap_t * p, + char * filename, + int maxsize, + int maxpacks ); -int pcap_live_dump_ended(pcap_t *p, int sync); + int pcap_live_dump_ended( pcap_t * p, + int sync ); -int pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data); + int pcap_offline_filter( struct bpf_program * prog, + const struct pcap_pkthdr * header, + const u_char * pkt_data ); -int pcap_start_oem(char* err_str, int flags); + int pcap_start_oem( char * err_str, + int flags ); -PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); + PAirpcapHandle pcap_get_airpcap_handle( pcap_t * p ); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif //__WIN32_EXTENSIONS_H__ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/arch.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/arch.c index 37cb290d6..cabb922ea 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/arch.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/arch.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,7 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ @@ -48,7 +48,7 @@ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void ); * Open the network interface. The number of the interface to be opened is set * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h. */ -static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces ); +static void prvOpenSelectedNetworkInterface( pcap_if_t * pxAllNetworkInterfaces ); /* * Configure the capture filter to allow blocking reads, and to filter out @@ -56,105 +56,105 @@ static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces ) */ static void prvConfigureCaptureBehaviour( void ); -pcap_t *pxOpenedInterfaceHandle = NULL; +pcap_t * pxOpenedInterfaceHandle = NULL; LARGE_INTEGER freq, sys_start_time; -#define archNUM_BUFFERS 5 -#define archNUM_BUFFER_POINTERS ( archNUM_BUFFERS - 1 ) +#define archNUM_BUFFERS 5 +#define archNUM_BUFFER_POINTERS ( archNUM_BUFFERS - 1 ) -static void prvInterruptSimulator( void *pvParameters ); +static void prvInterruptSimulator( void * pvParameters ); static unsigned char ucEthernetBuffer[ archNUM_BUFFERS ][ UIP_CONF_BUFFER_SIZE ]; -static unsigned char *pucEthernetBufferPointers[ archNUM_BUFFER_POINTERS ]; +static unsigned char * pucEthernetBufferPointers[ archNUM_BUFFER_POINTERS ]; static long lLengthOfDataInBuffer[ archNUM_BUFFER_POINTERS ] = { 0 }; static unsigned char ucNextBufferToFill = 0U, ucNextBufferToProcess = 0U; -unsigned char *uip_buf = NULL; -char cErrorBuffer[PCAP_ERRBUF_SIZE]; +unsigned char * uip_buf = NULL; +char cErrorBuffer[ PCAP_ERRBUF_SIZE ]; void vNetifTx( void ) { - pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); - pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); + pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); + pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len ); } /*-----------------------------------------------------------*/ UBaseType_t uxNetifRx( void ) { -UBaseType_t xDataLen; -unsigned char *pucTemp; + UBaseType_t xDataLen; + unsigned char * pucTemp; - /* Check there is really data available. */ - xDataLen = lLengthOfDataInBuffer[ ucNextBufferToProcess ]; - if( xDataLen != 0L ) - { + /* Check there is really data available. */ + xDataLen = lLengthOfDataInBuffer[ ucNextBufferToProcess ]; - /* The buffer pointed to by uip_buf is going to change. Remember which - buffer uip_buf is currently pointing to. */ - pucTemp = uip_buf; + if( xDataLen != 0L ) + { + /* The buffer pointed to by uip_buf is going to change. Remember which + * buffer uip_buf is currently pointing to. */ + pucTemp = uip_buf; - /* Point uip_buf at the next buffer that contains data. */ - uip_buf = pucEthernetBufferPointers[ ucNextBufferToProcess ]; + /* Point uip_buf at the next buffer that contains data. */ + uip_buf = pucEthernetBufferPointers[ ucNextBufferToProcess ]; - /* The buffer pointed to by - pucEthernetBufferPointeres[ ucNextBufferToProcess ] is now in use by - uip_buf, but the buffer uip_buf was pointing to on entry to this - function is free. Set - pucEthernetBufferPointeres[ ucNextBufferToProcess ] to the free - buffer. */ - pucEthernetBufferPointers[ ucNextBufferToProcess ] = pucTemp; - lLengthOfDataInBuffer[ ucNextBufferToProcess ] = 0L; + /* The buffer pointed to by + * pucEthernetBufferPointeres[ ucNextBufferToProcess ] is now in use by + * uip_buf, but the buffer uip_buf was pointing to on entry to this + * function is free. Set + * pucEthernetBufferPointeres[ ucNextBufferToProcess ] to the free + * buffer. */ + pucEthernetBufferPointers[ ucNextBufferToProcess ] = pucTemp; + lLengthOfDataInBuffer[ ucNextBufferToProcess ] = 0L; - ucNextBufferToProcess++; - if( ucNextBufferToProcess >= archNUM_BUFFER_POINTERS ) - { - ucNextBufferToProcess = 0L; - } - } + ucNextBufferToProcess++; - return xDataLen; + if( ucNextBufferToProcess >= archNUM_BUFFER_POINTERS ) + { + ucNextBufferToProcess = 0L; + } + } + + return xDataLen; } /*-----------------------------------------------------------*/ BaseType_t xNetifInit( void ) { -BaseType_t x; -pcap_if_t *pxAllNetworkInterfaces; + BaseType_t x; + pcap_if_t * pxAllNetworkInterfaces; - /* Allocate a free buffer to each buffer pointer. */ - for( x = 0; x < sizeof( pucEthernetBufferPointers ) / sizeof( unsigned char * ); x++ ) - { - pucEthernetBufferPointers[ x ] = &( ucEthernetBuffer[ x ][ 0 ] ); - } + /* Allocate a free buffer to each buffer pointer. */ + for( x = 0; x < sizeof( pucEthernetBufferPointers ) / sizeof( unsigned char * ); x++ ) + { + pucEthernetBufferPointers[ x ] = &( ucEthernetBuffer[ x ][ 0 ] ); + } - /* Start with uip_buf pointing to a buffer that is not referenced from the - pucEthernetBufferPointers[] array. */ - uip_buf = &( ucEthernetBuffer[ archNUM_BUFFERS - 1 ][ 0 ] ); + /* Start with uip_buf pointing to a buffer that is not referenced from the + * pucEthernetBufferPointers[] array. */ + uip_buf = &( ucEthernetBuffer[ archNUM_BUFFERS - 1 ][ 0 ] ); - /* Query the computer the simulation is being executed on to find the - network interfaces it has installed. */ - pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces(); - - /* Open the network interface. The number of the interface to be opened is - set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h. - Calling this function will set the pxOpenedInterfaceHandle variable. If, - after calling this function, pxOpenedInterfaceHandle is equal to NULL, then - the interface could not be opened. */ - if( pxAllNetworkInterfaces != NULL ) - { - prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces ); - } - + /* Query the computer the simulation is being executed on to find the + * network interfaces it has installed. */ + pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces(); - return x; + /* Open the network interface. The number of the interface to be opened is + * set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h. + * Calling this function will set the pxOpenedInterfaceHandle variable. If, + * after calling this function, pxOpenedInterfaceHandle is equal to NULL, then + * the interface could not be opened. */ + if( pxAllNetworkInterfaces != NULL ) + { + prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces ); + } + + return x; } /*-----------------------------------------------------------*/ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void ) -{ -pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface; -long lInterfaceNumber = 1; +{ + pcap_if_t * pxAllNetworkInterfaces = NULL, * xInterface; + long lInterfaceNumber = 1; if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 ) { @@ -162,174 +162,176 @@ long lInterfaceNumber = 1; pxAllNetworkInterfaces = NULL; } - if( pxAllNetworkInterfaces != NULL ) - { - /* Print out the list of network interfaces. The first in the list - is interface '1', not interface '0'. */ - for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next ) - { - printf( "%d. %s", lInterfaceNumber, xInterface->name ); - - if( xInterface->description != NULL ) - { - printf( " (%s)\r\n", xInterface->description ); - } - else - { - printf( " (No description available)\r\n") ; - } - - lInterfaceNumber++; - } - } + if( pxAllNetworkInterfaces != NULL ) + { + /* Print out the list of network interfaces. The first in the list + * is interface '1', not interface '0'. */ + for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next ) + { + printf( "%d. %s", lInterfaceNumber, xInterface->name ); + + if( xInterface->description != NULL ) + { + printf( " (%s)\r\n", xInterface->description ); + } + else + { + printf( " (No description available)\r\n" ); + } + + lInterfaceNumber++; + } + } if( lInterfaceNumber == 1 ) { - /* The interface number was never incremented, so the above for() loop - did not execute meaning no interfaces were found. */ + /* The interface number was never incremented, so the above for() loop + * did not execute meaning no interfaces were found. */ printf( " \r\nNo network interfaces were found.\r\n" ); pxAllNetworkInterfaces = NULL; } - printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" ); - printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE ); - + printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" ); + printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE ); + if( ( configNETWORK_INTERFACE_TO_USE < 1L ) || ( configNETWORK_INTERFACE_TO_USE > lInterfaceNumber ) ) { - printf("\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" ); - - if( pxAllNetworkInterfaces != NULL ) - { - /* Free the device list, as no devices are going to be opened. */ - pcap_freealldevs( pxAllNetworkInterfaces ); - pxAllNetworkInterfaces = NULL; - } + printf( "\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" ); + + if( pxAllNetworkInterfaces != NULL ) + { + /* Free the device list, as no devices are going to be opened. */ + pcap_freealldevs( pxAllNetworkInterfaces ); + pxAllNetworkInterfaces = NULL; + } } - return pxAllNetworkInterfaces; + return pxAllNetworkInterfaces; } /*-----------------------------------------------------------*/ -static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces ) +static void prvOpenSelectedNetworkInterface( pcap_if_t * pxAllNetworkInterfaces ) { -pcap_if_t *xInterface; -long x; + pcap_if_t * xInterface; + long x; /* Walk the list of devices until the selected device is located. */ - xInterface = pxAllNetworkInterfaces; + xInterface = pxAllNetworkInterfaces; + for( x = 0L; x < ( configNETWORK_INTERFACE_TO_USE - 1L ); x++ ) - { - xInterface = xInterface->next; - } + { + xInterface = xInterface->next; + } /* Open the selected interface. */ - pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */ - UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */ - PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscious mode as the MAC and - IP address is going to be "simulated", and - not be the real MAC and IP address. This allows - trafic to the simulated IP address to be routed - to uIP, and trafic to the real IP address to be - routed to the Windows TCP/IP stack. */ - 0xfffffffL, /* The read time out. This is going to block - until data is available. */ - NULL, /* No authentication is required as this is - not a remote capture session. */ - cErrorBuffer - ); - - if ( pxOpenedInterfaceHandle == NULL ) + pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */ + UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */ + PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscuous mode as the MAC and + * IP address is going to be "simulated", and + * not be the real MAC and IP address. This allows + * traffic to the simulated IP address to be routed + * to uIP, and traffic to the real IP address to be + * routed to the Windows TCP/IP stack. */ + 0xfffffffL, /* The read time out. This is going to block + * until data is available. */ + NULL, /* No authentication is required as this is + * not a remote capture session. */ + cErrorBuffer + ); + + if( pxOpenedInterfaceHandle == NULL ) { printf( "\r\n%s is not supported by WinPcap and cannot be opened\r\n", xInterface->name ); } - else - { - /* Configure the capture filter to allow blocking reads, and to filter - out packets that are not of interest to this demo. */ - prvConfigureCaptureBehaviour(); - } + else + { + /* Configure the capture filter to allow blocking reads, and to filter + * out packets that are not of interest to this demo. */ + prvConfigureCaptureBehaviour(); + } - /* The device list is no longer required. */ - pcap_freealldevs( pxAllNetworkInterfaces ); + /* The device list is no longer required. */ + pcap_freealldevs( pxAllNetworkInterfaces ); } /*-----------------------------------------------------------*/ static void prvConfigureCaptureBehaviour( void ) { -struct bpf_program xFilterCode; -const long lMinBytesToCopy = 10L, lBlocking = 0L; -unsigned long ulNetMask; + struct bpf_program xFilterCode; + const long lMinBytesToCopy = 10L, lBlocking = 0L; + unsigned long ulNetMask; - /* Unblock a read as soon as anything is received. */ - pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy ); + /* Unblock a read as soon as anything is received. */ + pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy ); - /* Allow blocking. */ - pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer ); + /* Allow blocking. */ + pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer ); - /* Set up a filter so only the packets of interest are passed to the uIP - stack. cErrorBuffer is used for convenience to create the string. Don't - confuse this with an error message. */ - sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); + /* Set up a filter so only the packets of interest are passed to the uIP + * stack. cErrorBuffer is used for convenience to create the string. Don't + * confuse this with an error message. */ + sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); - ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0; + ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0; - if( pcap_compile(pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 ) + if( pcap_compile( pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 ) { - printf("\r\nThe packet filter string is invalid\r\n" ); + printf( "\r\nThe packet filter string is invalid\r\n" ); + } + else + { + if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 ) + { + printf( "\r\nAn error occurred setting the packet filter.\r\n" ); + } } - else - { - if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 ) - { - printf( "\r\nAn error occurred setting the packet filter.\r\n" ); - } - } - /* Create a task that simulates an interrupt in a real system. This will - block waiting for packets, then send a message to the uIP task when data - is available. */ - xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( configuIP_TASK_PRIORITY - 1 ), NULL ); + /* Create a task that simulates an interrupt in a real system. This will + * block waiting for packets, then send a message to the uIP task when data + * is available. */ + xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( ipconfigIP_TASK_PRIORITY - 1 ), NULL ); } /*-----------------------------------------------------------*/ -static void prvInterruptSimulator( void *pvParameters ) +static void prvInterruptSimulator( void * pvParameters ) { -static struct pcap_pkthdr *pxHeader; -const unsigned char *pucPacketData; -extern QueueHandle_t xEMACEventQueue; -const unsigned long ulRxEvent = uipETHERNET_RX_EVENT; -long lResult; + static struct pcap_pkthdr * pxHeader; + const unsigned char * pucPacketData; + extern QueueHandle_t xEMACEventQueue; + const unsigned long ulRxEvent = uipETHERNET_RX_EVENT; + long lResult; - /* Just to kill the compiler warning. */ - ( void ) pvParameters; + /* Just to kill the compiler warning. */ + ( void ) pvParameters; - for( ;; ) - { - /* Get the next packet. */ - lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData ); - if( lResult ) - { - /* Is the next buffer into which data should be placed free? */ - if( lLengthOfDataInBuffer[ ucNextBufferToFill ] == 0L ) - { - /* Copy the data from the captured packet into the buffer. */ - memcpy( pucEthernetBufferPointers[ ucNextBufferToFill ], pucPacketData, pxHeader->len ); + for( ; ; ) + { + /* Get the next packet. */ + lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData ); - /* Note the amount of data that was copied. */ - lLengthOfDataInBuffer[ ucNextBufferToFill ] = pxHeader->len; + if( lResult ) + { + /* Is the next buffer into which data should be placed free? */ + if( lLengthOfDataInBuffer[ ucNextBufferToFill ] == 0L ) + { + /* Copy the data from the captured packet into the buffer. */ + memcpy( pucEthernetBufferPointers[ ucNextBufferToFill ], pucPacketData, pxHeader->len ); - /* Move onto the next buffer, wrapping around if necessary. */ - ucNextBufferToFill++; - if( ucNextBufferToFill >= archNUM_BUFFER_POINTERS ) - { - ucNextBufferToFill = 0U; - } + /* Note the amount of data that was copied. */ + lLengthOfDataInBuffer[ ucNextBufferToFill ] = pxHeader->len; - /* Data was received and stored. Send a message to the uIP task - to let it know. */ - xQueueSendToBack( xEMACEventQueue, &ulRxEvent, portMAX_DELAY ); - } - } - } + /* Move onto the next buffer, wrapping around if necessary. */ + ucNextBufferToFill++; + + if( ucNextBufferToFill >= archNUM_BUFFER_POINTERS ) + { + ucNextBufferToFill = 0U; + } + + /* Data was received and stored. Send a message to the uIP task + * to let it know. */ + xQueueSendToBack( xEMACEventQueue, &ulRxEvent, portMAX_DELAY ); + } + } + } } - diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/bittypes.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/bittypes.h index f55fcecfd..2be3d28db 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/bittypes.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/bittypes.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,107 +31,107 @@ #ifndef HAVE_U_INT8_T -#if SIZEOF_CHAR == 1 -typedef unsigned char u_int8_t; -typedef signed char _int8_t; -#elif SIZEOF_INT == 1 -typedef unsigned int u_int8_t; -typedef signed int int8_t; -#else /* XXX */ -#error "there's no appropriate type for u_int8_t" -#endif -#define HAVE_U_INT8_T 1 -#define HAVE_INT8_T 1 + #if SIZEOF_CHAR == 1 + typedef unsigned char u_int8_t; + typedef signed char _int8_t; + #elif SIZEOF_INT == 1 + typedef unsigned int u_int8_t; + typedef signed int int8_t; + #else /* XXX */ + #error "there's no appropriate type for u_int8_t" + #endif + #define HAVE_U_INT8_T 1 + #define HAVE_INT8_T 1 #endif /* HAVE_U_INT8_T */ -#ifndef HAVE_U_INT16_T +#ifndef HAVE_U_INT16_T -#if SIZEOF_SHORT == 2 -typedef unsigned short u_int16_t; -typedef signed short _int16_t; -#elif SIZEOF_INT == 2 -typedef unsigned int u_int16_t; -typedef signed int int16_t; -#elif SIZEOF_CHAR == 2 -typedef unsigned char u_int16_t; -typedef signed char int16_t; -#else /* XXX */ -#error "there's no appropriate type for u_int16_t" -#endif -#define HAVE_U_INT16_T 1 -#define HAVE_INT16_T 1 + #if SIZEOF_SHORT == 2 + typedef unsigned short u_int16_t; + typedef signed short _int16_t; + #elif SIZEOF_INT == 2 + typedef unsigned int u_int16_t; + typedef signed int int16_t; + #elif SIZEOF_CHAR == 2 + typedef unsigned char u_int16_t; + typedef signed char int16_t; + #else /* XXX */ + #error "there's no appropriate type for u_int16_t" + #endif /* if SIZEOF_SHORT == 2 */ + #define HAVE_U_INT16_T 1 + #define HAVE_INT16_T 1 #endif /* HAVE_U_INT16_T */ #ifndef HAVE_U_INT32_T -#if SIZEOF_INT == 4 -typedef unsigned int u_int32_t; -typedef signed int _int32_t; -#elif SIZEOF_LONG == 4 -typedef unsigned long u_int32_t; -typedef signed long int32_t; -#elif SIZEOF_SHORT == 4 -typedef unsigned short u_int32_t; -typedef signed short int32_t; -#else /* XXX */ -#error "there's no appropriate type for u_int32_t" -#endif -#define HAVE_U_INT32_T 1 -#define HAVE_INT32_T 1 + #if SIZEOF_INT == 4 + typedef unsigned int u_int32_t; + typedef signed int _int32_t; + #elif SIZEOF_LONG == 4 + typedef unsigned long u_int32_t; + typedef signed long int32_t; + #elif SIZEOF_SHORT == 4 + typedef unsigned short u_int32_t; + typedef signed short int32_t; + #else /* XXX */ + #error "there's no appropriate type for u_int32_t" + #endif /* if SIZEOF_INT == 4 */ + #define HAVE_U_INT32_T 1 + #define HAVE_INT32_T 1 #endif /* HAVE_U_INT32_T */ #ifndef HAVE_U_INT64_T -#if SIZEOF_LONG_LONG == 8 -typedef unsigned long long u_int64_t; -typedef long long int64_t; -#elif defined(_MSC_EXTENSIONS) -typedef unsigned _int64 u_int64_t; -typedef _int64 int64_t; -#elif SIZEOF_INT == 8 -typedef unsigned int u_int64_t; -#elif SIZEOF_LONG == 8 -typedef unsigned long u_int64_t; -#elif SIZEOF_SHORT == 8 -typedef unsigned short u_int64_t; -#else /* XXX */ -#error "there's no appropriate type for u_int64_t" -#endif + #if SIZEOF_LONG_LONG == 8 + typedef unsigned long long u_int64_t; + typedef long long int64_t; + #elif defined( _MSC_EXTENSIONS ) + typedef unsigned _int64 u_int64_t; + typedef _int64 int64_t; + #elif SIZEOF_INT == 8 + typedef unsigned int u_int64_t; + #elif SIZEOF_LONG == 8 + typedef unsigned long u_int64_t; + #elif SIZEOF_SHORT == 8 + typedef unsigned short u_int64_t; + #else /* XXX */ + #error "there's no appropriate type for u_int64_t" + #endif /* if SIZEOF_LONG_LONG == 8 */ #endif /* HAVE_U_INT64_T */ #ifndef PRId64 -#ifdef _MSC_EXTENSIONS -#define PRId64 "I64d" -#else /* _MSC_EXTENSIONS */ -#define PRId64 "lld" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRId64 "I64d" + #else /* _MSC_EXTENSIONS */ + #define PRId64 "lld" + #endif /* _MSC_EXTENSIONS */ #endif /* PRId64 */ #ifndef PRIo64 -#ifdef _MSC_EXTENSIONS -#define PRIo64 "I64o" -#else /* _MSC_EXTENSIONS */ -#define PRIo64 "llo" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRIo64 "I64o" + #else /* _MSC_EXTENSIONS */ + #define PRIo64 "llo" + #endif /* _MSC_EXTENSIONS */ #endif /* PRIo64 */ #ifndef PRIx64 -#ifdef _MSC_EXTENSIONS -#define PRIx64 "I64x" -#else /* _MSC_EXTENSIONS */ -#define PRIx64 "llx" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRIx64 "I64x" + #else /* _MSC_EXTENSIONS */ + #define PRIx64 "llx" + #endif /* _MSC_EXTENSIONS */ #endif /* PRIx64 */ #ifndef PRIu64 -#ifdef _MSC_EXTENSIONS -#define PRIu64 "I64u" -#else /* _MSC_EXTENSIONS */ -#define PRIu64 "llu" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRIu64 "I64u" + #else /* _MSC_EXTENSIONS */ + #define PRIu64 "llu" + #endif /* _MSC_EXTENSIONS */ #endif /* PRIu64 */ #endif /* _BITTYPES_H */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/ip6_misc.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/ip6_misc.h index 562fa6184..1b2e4337b 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/ip6_misc.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/ip6_misc.h @@ -30,134 +30,136 @@ #include #ifndef __MINGW32__ -#define IN_MULTICAST(a) IN_CLASSD(a) + #define IN_MULTICAST( a ) IN_CLASSD( a ) #endif -#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xf0000000) == 0xf0000000) +#define IN_EXPERIMENTAL( a ) ( ( ( ( u_int32_t ) ( a ) ) & 0xf0000000 ) == 0xf0000000 ) -#define IN_LOOPBACKNET 127 +#define IN_LOOPBACKNET 127 -#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) +#if defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) /* IPv6 address */ -struct in6_addr - { - union - { - u_int8_t u6_addr8[16]; - u_int16_t u6_addr16[8]; - u_int32_t u6_addr32[4]; - } in6_u; -#define s6_addr in6_u.u6_addr8 -#define s6_addr16 in6_u.u6_addr16 -#define s6_addr32 in6_u.u6_addr32 -#define s6_addr64 in6_u.u6_addr64 - }; + struct in6_addr + { + union + { + u_int8_t u6_addr8[ 16 ]; + u_int16_t u6_addr16[ 8 ]; + u_int32_t u6_addr32[ 4 ]; + } + in6_u; + #define s6_addr in6_u.u6_addr8 + #define s6_addr16 in6_u.u6_addr16 + #define s6_addr32 in6_u.u6_addr32 + #define s6_addr64 in6_u.u6_addr64 + }; -#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } + #define IN6ADDR_ANY_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + #define IN6ADDR_LOOPBACK_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } #endif /* __MINGW32__ */ -#if (defined _MSC_VER) || (defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)) -typedef unsigned short sa_family_t; +#if ( defined _MSC_VER ) || ( defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) ) + typedef unsigned short sa_family_t; #endif -#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) +#if defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) -#define __SOCKADDR_COMMON(sa_prefix) \ - sa_family_t sa_prefix##family + #define __SOCKADDR_COMMON( sa_prefix ) \ + sa_family_t sa_prefix ## family /* Ditto, for IPv6. */ -struct sockaddr_in6 - { - __SOCKADDR_COMMON (sin6_); - u_int16_t sin6_port; /* Transport layer port # */ - u_int32_t sin6_flowinfo; /* IPv6 flow information */ - struct in6_addr sin6_addr; /* IPv6 address */ - }; + struct sockaddr_in6 + { + __SOCKADDR_COMMON( sin6_ ); + u_int16_t sin6_port; /* Transport layer port # */ + u_int32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + }; -#define IN6_IS_ADDR_V4MAPPED(a) \ - ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ - (((u_int32_t *) (a))[2] == htonl (0xffff))) + #define IN6_IS_ADDR_V4MAPPED( a ) \ + ( ( ( ( u_int32_t * ) ( a ) )[ 0 ] == 0 ) && ( ( ( u_int32_t * ) ( a ) )[ 1 ] == 0 ) && \ + ( ( ( u_int32_t * ) ( a ) )[ 2 ] == htonl( 0xffff ) ) ) -#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff) + #define IN6_IS_ADDR_MULTICAST( a ) ( ( ( u_int8_t * ) ( a ) )[ 0 ] == 0xff ) -#define IN6_IS_ADDR_LINKLOCAL(a) \ - ((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000)) + #define IN6_IS_ADDR_LINKLOCAL( a ) \ + ( ( ( ( u_int32_t * ) ( a ) )[ 0 ] & htonl( 0xffc00000 ) ) == htonl( 0xfe800000 ) ) -#define IN6_IS_ADDR_LOOPBACK(a) \ - (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ - ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) + #define IN6_IS_ADDR_LOOPBACK( a ) \ + ( ( ( u_int32_t * ) ( a ) )[ 0 ] == 0 && ( ( u_int32_t * ) ( a ) )[ 1 ] == 0 && \ + ( ( u_int32_t * ) ( a ) )[ 2 ] == 0 && ( ( u_int32_t * ) ( a ) )[ 3 ] == htonl( 1 ) ) #endif /* __MINGW32__ */ -#define ip6_vfc ip6_ctlun.ip6_un2_vfc -#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow -#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen -#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt -#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim -#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim +#define ip6_vfc ip6_ctlun.ip6_un2_vfc +#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow +#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen +#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt +#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim +#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim #define nd_rd_type nd_rd_hdr.icmp6_type #define nd_rd_code nd_rd_hdr.icmp6_code #define nd_rd_cksum nd_rd_hdr.icmp6_cksum -#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] +#define nd_rd_reserved nd_rd_hdr.icmp6_data32[ 0 ] /* * IPV6 extension headers */ -#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ -#define IPPROTO_IPV6 41 /* IPv6 header. */ -#define IPPROTO_ROUTING 43 /* IPv6 routing header */ -#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ -#define IPPROTO_ESP 50 /* encapsulating security payload */ -#define IPPROTO_AH 51 /* authentication header */ -#define IPPROTO_ICMPV6 58 /* ICMPv6 */ -#define IPPROTO_NONE 59 /* IPv6 no next header */ -#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ -#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */ +#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ +#define IPPROTO_IPV6 41 /* IPv6 header. */ +#define IPPROTO_ROUTING 43 /* IPv6 routing header */ +#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ +#define IPPROTO_ESP 50 /* encapsulating security payload */ +#define IPPROTO_AH 51 /* authentication header */ +#define IPPROTO_ICMPV6 58 /* ICMPv6 */ +#define IPPROTO_NONE 59 /* IPv6 no next header */ +#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ +#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */ -#define IPV6_RTHDR_TYPE_0 0 +#define IPV6_RTHDR_TYPE_0 0 /* Option types and related macros */ -#define IP6OPT_PAD1 0x00 /* 00 0 00000 */ -#define IP6OPT_PADN 0x01 /* 00 0 00001 */ -#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ -#define IP6OPT_JUMBO_LEN 6 -#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ +#define IP6OPT_PAD1 0x00 /* 00 0 00000 */ +#define IP6OPT_PADN 0x01 /* 00 0 00001 */ +#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ +#define IP6OPT_JUMBO_LEN 6 +#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ -#define IP6OPT_RTALERT_LEN 4 -#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ -#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ -#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ -#define IP6OPT_MINLEN 2 +#define IP6OPT_RTALERT_LEN 4 +#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ +#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ +#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ +#define IP6OPT_MINLEN 2 -#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ -#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ -#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ -#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ -#define IP6OPT_EID 0x8a /* 10 0 01010 */ +#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ +#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ +#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ +#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ +#define IP6OPT_EID 0x8a /* 10 0 01010 */ -#define IP6OPT_TYPE(o) ((o) & 0xC0) -#define IP6OPT_TYPE_SKIP 0x00 -#define IP6OPT_TYPE_DISCARD 0x40 -#define IP6OPT_TYPE_FORCEICMP 0x80 -#define IP6OPT_TYPE_ICMP 0xC0 +#define IP6OPT_TYPE( o ) ( ( o ) & 0xC0 ) +#define IP6OPT_TYPE_SKIP 0x00 +#define IP6OPT_TYPE_DISCARD 0x40 +#define IP6OPT_TYPE_FORCEICMP 0x80 +#define IP6OPT_TYPE_ICMP 0xC0 -#define IP6OPT_MUTABLE 0x20 +#define IP6OPT_MUTABLE 0x20 -#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) -#ifndef EAI_ADDRFAMILY -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -#endif +#if defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) + #ifndef EAI_ADDRFAMILY + struct addrinfo + { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char * ai_canonname; /* canonical name for hostname */ + struct sockaddr * ai_addr; /* binary address */ + struct addrinfo * ai_next; /* next structure in linked list */ + }; + #endif /* ifndef EAI_ADDRFAMILY */ #endif /* __MINGW32__ */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/netif.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/netif.h index fded3b944..c06c0a9bf 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/netif.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/netif.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -20,7 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org - * https://aws.amazon.com/freertos + * https://github.com/FreeRTOS * */ @@ -28,13 +28,13 @@ #define NET_IF_H /* - * Send uip_len bytes from uip_buf to the network interface selected by the - * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h). + * Send uip_len bytes from uip_buf to the network interface selected by the + * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h). */ void vNetifTx( void ); /* - * Receive bytes from the network interface selected by the + * Receive bytes from the network interface selected by the * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h). The * bytes are placed in uip_buf. The number of bytes copied into uip_buf is * returned. @@ -42,9 +42,9 @@ void vNetifTx( void ); UBaseType_t uxNetifRx( void ); /* - * Prepare a packet capture session. This will print out all the network - * interfaces available, and the one actually used is set by the - * configNETWORK_INTERFACE_TO_USE constant that is defined in + * Prepare a packet capture session. This will print out all the network + * interfaces available, and the one actually used is set by the + * configNETWORK_INTERFACE_TO_USE constant that is defined in * FreeRTOSConfig.h. */ BaseType_t xNetifInit( void ); diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap-bpf.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap-bpf.h index 5fe129dbb..2657827e0 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap-bpf.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap-bpf.h @@ -4,7 +4,7 @@ * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap-stdinc.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap-stdinc.h index 417604177..9cde17fb3 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap-stdinc.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap-stdinc.h @@ -31,20 +31,20 @@ * @(#) $Header: /tcpdump/master/libpcap/pcap-stdinc.h,v 1.10.2.1 2008-10-06 15:38:39 gianluca Exp $ (LBL) */ -#define SIZEOF_CHAR 1 -#define SIZEOF_SHORT 2 -#define SIZEOF_INT 4 +#define SIZEOF_CHAR 1 +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 #ifndef _MSC_EXTENSIONS -#define SIZEOF_LONG_LONG 8 + #define SIZEOF_LONG_LONG 8 #endif /* - * Avoids a compiler warning in case this was already defined + * Avoids a compiler warning in case this was already defined * (someone defined _WINSOCKAPI_ when including 'windows.h', in order * to prevent it from including 'winsock.h') */ #ifdef _WINSOCKAPI_ -#undef _WINSOCKAPI_ + #undef _WINSOCKAPI_ #endif #include @@ -55,39 +55,39 @@ #include #ifndef __MINGW32__ -#include "IP6_misc.h" + #include "IP6_misc.h" #endif -#define caddr_t char* +#define caddr_t char * #if _MSC_VER < 1500 -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define strdup _strdup + #define snprintf _snprintf + #define vsnprintf _vsnprintf + #define strdup _strdup #endif -#define inline __inline +#define inline __inline #ifdef __MINGW32__ -#include + #include #else /*__MINGW32__*/ /* MSVC compiler */ -#ifndef _UINTPTR_T_DEFINED -#ifdef _WIN64 -typedef unsigned __int64 uintptr_t; -#else -typedef _W64 unsigned int uintptr_t; -#endif -#define _UINTPTR_T_DEFINED -#endif + #ifndef _UINTPTR_T_DEFINED + #ifdef _WIN64 + typedef unsigned __int64 uintptr_t; + #else + typedef _W64 unsigned int uintptr_t; + #endif + #define _UINTPTR_T_DEFINED + #endif -#ifndef _INTPTR_T_DEFINED -#ifdef _WIN64 -typedef __int64 intptr_t; -#else -typedef _W64 int intptr_t; -#endif -#define _INTPTR_T_DEFINED -#endif + #ifndef _INTPTR_T_DEFINED + #ifdef _WIN64 + typedef __int64 intptr_t; + #else + typedef _W64 int intptr_t; + #endif + #define _INTPTR_T_DEFINED + #endif #endif /*__MINGW32__*/ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/bluetooth.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/bluetooth.h index 7bf65df03..05332a3a5 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/bluetooth.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/bluetooth.h @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,7 +32,7 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/bluetooth.h,v 1.1 2007/09/22 02:10:17 guy Exp $ */ - + #ifndef _PCAP_BLUETOOTH_STRUCTS_H__ #define _PCAP_BLUETOOTH_STRUCTS_H__ @@ -40,8 +40,9 @@ * Header prepended libpcap to each bluetooth h:4 frame. * fields are in network byte order */ -typedef struct _pcap_bluetooth_h4_header { - u_int32_t direction; /* if first bit is set direction is incoming */ +typedef struct _pcap_bluetooth_h4_header +{ + u_int32_t direction; /* if first bit is set direction is incoming */ } pcap_bluetooth_h4_header; diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/bpf.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/bpf.h index 9f4ca33e3..d53a87b2f 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/bpf.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/bpf.h @@ -4,7 +4,7 @@ * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without @@ -53,45 +53,46 @@ #ifndef BPF_MAJOR_VERSION -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* BSD style release date */ -#define BPF_RELEASE 199606 + #define BPF_RELEASE 199606 -#ifdef MSDOS /* must be 32-bit */ -typedef long bpf_int32; -typedef unsigned long bpf_u_int32; -#else -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #ifdef MSDOS /* must be 32-bit */ + typedef long bpf_int32; + typedef unsigned long bpf_u_int32; + #else + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif /* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + #ifndef __NetBSD__ + #define BPF_ALIGNMENT sizeof( bpf_int32 ) + #else + #define BPF_ALIGNMENT sizeof( long ) + #endif + #define BPF_WORDALIGN( x ) ( ( ( x ) + ( BPF_ALIGNMENT - 1 ) ) & ~( BPF_ALIGNMENT - 1 ) ) -#define BPF_MAXBUFSIZE 0x8000 -#define BPF_MINBUFSIZE 32 + #define BPF_MAXBUFSIZE 0x8000 + #define BPF_MINBUFSIZE 32 /* * Structure for "pcap_compile()", "pcap_setfilter()", etc.. */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - + struct bpf_program + { + u_int bf_len; + struct bpf_insn * bf_insns; + }; + /* - * Struct return by BIOCVERSION. This represents the version number of + * Struct return by BIOCVERSION. This represents the version number of * the filter language described by the instruction encodings below. * bpf understands a program iff kernel_major == filter_major && * kernel_minor >= filter_minor, that is, if the value returned by the @@ -101,13 +102,14 @@ struct bpf_program { * may be accepted haphazardly. * It has nothing to do with the source code version. */ -struct bpf_version { - u_short bv_major; - u_short bv_minor; -}; + struct bpf_version + { + u_short bv_major; + u_short bv_minor; + }; /* Current version number of filter architecture. */ -#define BPF_MAJOR_VERSION 1 -#define BPF_MINOR_VERSION 1 + #define BPF_MAJOR_VERSION 1 + #define BPF_MINOR_VERSION 1 /* * Data-link level type codes. @@ -125,17 +127,17 @@ struct bpf_version { * These are the types that are the same on all platforms, and that * have been defined by for ages. */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* 802.5 Token Ring */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ + #define DLT_NULL 0 /* BSD loopback encapsulation */ + #define DLT_EN10MB 1 /* Ethernet (10Mb) */ + #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ + #define DLT_AX25 3 /* Amateur Radio AX.25 */ + #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ + #define DLT_CHAOS 5 /* Chaos */ + #define DLT_IEEE802 6 /* 802.5 Token Ring */ + #define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ + #define DLT_SLIP 8 /* Serial Line IP */ + #define DLT_PPP 9 /* Point-to-point Protocol */ + #define DLT_FDDI 10 /* FDDI */ /* * These are types that are different on some platforms, and that @@ -146,13 +148,13 @@ struct bpf_version { * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, * but I don't know what the right #define is for BSD/OS. */ -#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + #define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif + #ifdef __OpenBSD__ + #define DLT_RAW 14 /* raw IP */ + #else + #define DLT_RAW 12 /* raw IP */ + #endif /* * Given that the only OS that currently generates BSD/OS SLIP or PPP @@ -160,15 +162,15 @@ struct bpf_version { * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they * didn't. So it goes. */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif + #if defined( __NetBSD__ ) || defined( __FreeBSD__ ) + #ifndef DLT_SLIP_BSDOS + #define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ + #endif + #else + #define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ + #endif /* * 17 is used for DLT_OLD_PFLOG in OpenBSD; @@ -176,21 +178,21 @@ struct bpf_version { * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. */ -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + #define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ /* * Apparently Redback uses this for its SmartEdge 400/800. I hope * nobody else decided to use it, too. */ -#define DLT_REDBACK_SMARTEDGE 32 + #define DLT_REDBACK_SMARTEDGE 32 /* * These values are defined by NetBSD; other platforms should refrain from * using them for other purposes, so that NetBSD savefiles with link * types of 50 or 51 can be read as this type on all platforms. */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + #define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ + #define DLT_PPP_ETHER 51 /* PPP over Ethernet */ /* * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses @@ -199,7 +201,7 @@ struct bpf_version { * Ethernet type, and 36 bytes that appear to be 0 in at least one capture * I've seen. */ -#define DLT_SYMANTEC_FIREWALL 99 + #define DLT_SYMANTEC_FIREWALL 99 /* * Values between 100 and 103 are used in capture file headers as @@ -221,10 +223,10 @@ struct bpf_version { * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, * for source compatibility with programs written for libpcap 0.5. */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC + #define DLT_C_HDLC 104 /* Cisco HDLC */ + #define DLT_CHDLC DLT_C_HDLC -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + #define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ /* * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, @@ -239,7 +241,7 @@ struct bpf_version { * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header * (DLCI, etc.). */ -#define DLT_FRELAY 107 + #define DLT_FRELAY 107 /* * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except @@ -248,22 +250,22 @@ struct bpf_version { * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so * we don't use 12 for it in OSes other than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_LOOP 12 -#else -#define DLT_LOOP 108 -#endif + #ifdef __OpenBSD__ + #define DLT_LOOP 12 + #else + #define DLT_LOOP 108 + #endif /* * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other * than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_ENC 13 -#else -#define DLT_ENC 109 -#endif + #ifdef __OpenBSD__ + #define DLT_ENC 13 + #else + #define DLT_ENC 109 + #endif /* * Values between 110 and 112 are reserved for use in capture file headers @@ -275,22 +277,22 @@ struct bpf_version { /* * This is for Linux cooked sockets. */ -#define DLT_LINUX_SLL 113 + #define DLT_LINUX_SLL 113 /* * Apple LocalTalk hardware. */ -#define DLT_LTALK 114 + #define DLT_LTALK 114 /* * Acorn Econet. */ -#define DLT_ECONET 115 + #define DLT_ECONET 115 /* * Reserved for use with OpenBSD ipfilter. */ -#define DLT_IPFILTER 116 + #define DLT_IPFILTER 116 /* * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 @@ -298,34 +300,34 @@ struct bpf_version { * * XXX: is there a conflict with DLT_PFSYNC 18 as well? */ -#ifdef __OpenBSD__ -#define DLT_OLD_PFLOG 17 -#define DLT_PFSYNC 18 -#endif -#define DLT_PFLOG 117 + #ifdef __OpenBSD__ + #define DLT_OLD_PFLOG 17 + #define DLT_PFSYNC 18 + #endif + #define DLT_PFLOG 117 /* * Registered for Cisco-internal use. */ -#define DLT_CISCO_IOS 118 + #define DLT_CISCO_IOS 118 /* * For 802.11 cards using the Prism II chips, with a link-layer * header including Prism monitor mode information plus an 802.11 * header. */ -#define DLT_PRISM_HEADER 119 + #define DLT_PRISM_HEADER 119 /* * Reserved for Aironet 802.11 cards, with an Aironet link-layer header * (see Doug Ambrisko's FreeBSD patches). */ -#define DLT_AIRONET_HEADER 120 + #define DLT_AIRONET_HEADER 120 /* * Reserved for Siemens HiPath HDLC. */ -#define DLT_HHDLC 121 + #define DLT_HHDLC 121 /* * This is for RFC 2625 IP-over-Fibre Channel. @@ -335,7 +337,7 @@ struct bpf_version { * where the link-layer header starts with an RFC 2625 Network_Header * field. */ -#define DLT_IP_OVER_FC 122 + #define DLT_IP_OVER_FC 122 /* * This is for Full Frontal ATM on Solaris with SunATM, with a @@ -351,22 +353,22 @@ struct bpf_version { * and the like don't have to infer the presence or absence of a * pseudo-header and the form of the pseudo-header. */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ + #define DLT_SUNATM 123 /* Solaris+SunATM */ -/* +/* * Reserved as per request from Kent Dahlgren * for private use. */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + #define DLT_RIO 124 /* RapidIO */ + #define DLT_PCI_EXP 125 /* PCI Express */ + #define DLT_AURORA 126 /* Xilinx Aurora link layer */ /* * Header for 802.11 plus a number of bits of link-layer information * including radio information, used by some recent BSD drivers as * well as the madwifi Atheros driver for Linux. */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + #define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ /* * Reserved for the TZSP encapsulation, as per request from @@ -376,7 +378,7 @@ struct bpf_version { * with the packet, e.g. signal strength and channel * for 802.11 packets. */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + #define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ /* * BSD's ARCNET headers have the source host, destination host, @@ -389,7 +391,7 @@ struct bpf_version { * * We therefore have to have separate DLT_ values for them. */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ + #define DLT_ARCNET_LINUX 129 /* ARCNET */ /* * Juniper-private data link types, as per request from @@ -397,14 +399,14 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 + #define DLT_JUNIPER_MLPPP 130 + #define DLT_JUNIPER_MLFR 131 + #define DLT_JUNIPER_ES 132 + #define DLT_JUNIPER_GGSN 133 + #define DLT_JUNIPER_MFR 134 + #define DLT_JUNIPER_ATM2 135 + #define DLT_JUNIPER_SERVICES 136 + #define DLT_JUNIPER_ATM1 137 /* * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund @@ -421,21 +423,21 @@ struct bpf_version { * with "firewire_type" being an Ethernet type value, rather than, * for example, raw GASP frames being handed up. */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 + #define DLT_APPLE_IP_OVER_IEEE1394 138 /* * Various SS7 encapsulations, as per a request from Jeff Morriss * and subsequent discussions. */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + #define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ + #define DLT_MTP2 140 /* MTP2, without pseudo-header */ + #define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ + #define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ /* * DOCSIS MAC frames. */ -#define DLT_DOCSIS 143 + #define DLT_DOCSIS 143 /* * Linux-IrDA packets. Protocol defined at http://www.irda.org. @@ -446,19 +448,19 @@ struct bpf_version { * interface (irdaX), but not on a raw serial port. * Note the capture is done in "Linux-cooked" mode, so each packet include * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or + * decoding is dependant on the direction of the packet (incoming or * outgoing). * When/if other platform implement IrDA capture, we may revisit the * issue and define a real DLT_IRDA... * Jean II */ -#define DLT_LINUX_IRDA 144 + #define DLT_LINUX_IRDA 144 /* * Reserved for IBM SP switch and IBM Next Federation switch. */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 + #define DLT_IBM_SP 145 + #define DLT_IBM_SN 146 /* * Reserved for private use. If you have some link-layer header type @@ -485,22 +487,22 @@ struct bpf_version { * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, * as per the comment above, and use the type you're given. */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 + #define DLT_USER0 147 + #define DLT_USER1 148 + #define DLT_USER2 149 + #define DLT_USER3 150 + #define DLT_USER4 151 + #define DLT_USER5 152 + #define DLT_USER6 153 + #define DLT_USER7 154 + #define DLT_USER8 155 + #define DLT_USER9 156 + #define DLT_USER10 157 + #define DLT_USER11 158 + #define DLT_USER12 159 + #define DLT_USER13 160 + #define DLT_USER14 161 + #define DLT_USER15 162 /* * For future use with 802.11 captures - defined by AbsoluteValue @@ -512,7 +514,7 @@ struct bpf_version { * but it might be used by some non-AVS drivers now or in the * future. */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + #define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ /* * Juniper-private data link type, as per request from @@ -520,12 +522,12 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MONITOR 164 + #define DLT_JUNIPER_MONITOR 164 /* * Reserved for BACnet MS/TP. */ -#define DLT_BACNET_MS_TP 165 + #define DLT_BACNET_MS_TP 165 /* * Another PPP variant as per request from Karsten Keil . @@ -538,17 +540,17 @@ struct bpf_version { * input packets such as port scans, packets from old lost connections, * etc. to force the connection to stay up). * - * The first byte of the PPP header (0xff03) is modified to accomodate + * The first byte of the PPP header (0xff03) is modified to accommodate * the direction - 0x00 = IN, 0x01 = OUT. */ -#define DLT_PPP_PPPD 166 + #define DLT_PPP_PPPD 166 /* * Names for backwards compatibility with older versions of some PPP * software; new software should use DLT_PPP_PPPD. */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + #define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD + #define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD /* * Juniper-private data link type, as per request from @@ -556,26 +558,26 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, cookies, etc.. */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 + #define DLT_JUNIPER_PPPOE 167 + #define DLT_JUNIPER_PPPOE_ATM 168 -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + #define DLT_GPRS_LLC 169 /* GPRS LLC */ + #define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ + #define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ /* * Requested by Oolan Zimmer for use in Gcom's T1/E1 line * monitoring equipment. */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 + #define DLT_GCOM_T1E1 172 + #define DLT_GCOM_SERIAL 173 /* * Juniper-private data link type, as per request from * Hannes Gredler . The DLT_ is used * for internal communication to Physical Interface Cards (PIC) */ -#define DLT_JUNIPER_PIC_PEER 174 + #define DLT_JUNIPER_PIC_PEER 174 /* * Link types requested by Gregor Maier of Endace @@ -583,8 +585,8 @@ struct bpf_version { * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of * the link-layer header. */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ + #define DLT_ERF_ETH 175 /* Ethernet */ + #define DLT_ERF_POS 176 /* Packet-over-SONET */ /* * Requested by Daniele Orlandi for raw LAPD @@ -592,32 +594,32 @@ struct bpf_version { * includes additional information before the LAPD header, so it's * not necessarily a generic LAPD header. */ -#define DLT_LINUX_LAPD 177 + #define DLT_LINUX_LAPD 177 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ are used for prepending meta-information * like interface index, interface name * before standard Ethernet, PPP, Frelay & C-HDLC Frames */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 + #define DLT_JUNIPER_ETHER 178 + #define DLT_JUNIPER_PPP 179 + #define DLT_JUNIPER_FRELAY 180 + #define DLT_JUNIPER_CHDLC 181 /* * Multi Link Frame Relay (FRF.16) */ -#define DLT_MFR 182 + #define DLT_MFR 182 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * voice Adapter Card (PIC) */ -#define DLT_JUNIPER_VP 183 + #define DLT_JUNIPER_VP 183 /* * Arinc 429 frames. @@ -626,38 +628,38 @@ struct bpf_version { * More documentation on Arinc 429 can be found at * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf */ -#define DLT_A429 184 + #define DLT_A429 184 /* * Arinc 653 Interpartition Communication messages. * DLT_ requested by Gianluca Varenni . * Please refer to the A653-1 standard for more information. */ -#define DLT_A653_ICM 185 + #define DLT_A653_ICM 185 /* * USB packets, beginning with a USB setup header; requested by * Paolo Abeni . */ -#define DLT_USB 186 + #define DLT_USB 186 /* * Bluetooth HCI UART transport layer (part H:4); requested by * Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4 187 + #define DLT_BLUETOOTH_HCI_H4 187 /* * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz * . */ -#define DLT_IEEE802_16_MAC_CPS 188 + #define DLT_IEEE802_16_MAC_CPS 188 /* * USB packets, beginning with a Linux USB header; requested by * Paolo Abeni . */ -#define DLT_USB_LINUX 189 + #define DLT_USB_LINUX 189 /* * Controller Area Network (CAN) v. 2.0B packets. @@ -666,79 +668,79 @@ struct bpf_version { * More documentation on the CAN v2.0B frames can be found at * http://www.can-cia.org/downloads/?269 */ -#define DLT_CAN20B 190 + #define DLT_CAN20B 190 /* * IEEE 802.15.4, with address fields padded, as is done by Linux * drivers; requested by Juergen Schimmer. */ -#define DLT_IEEE802_15_4_LINUX 191 + #define DLT_IEEE802_15_4_LINUX 191 /* * Per Packet Information encapsulated packets. * DLT_ requested by Gianluca Varenni . */ -#define DLT_PPI 192 + #define DLT_PPI 192 /* * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; * requested by Charles Clancy. */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + #define DLT_IEEE802_16_MAC_CPS_RADIO 193 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * integrated service module (ISM). */ -#define DLT_JUNIPER_ISM 194 + #define DLT_JUNIPER_ISM 194 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no * nothing); requested by Mikko Saarnivala . */ -#define DLT_IEEE802_15_4 195 + #define DLT_IEEE802_15_4 195 /* * Various link-layer types, with a pseudo-header, for SITA * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). */ -#define DLT_SITA 196 + #define DLT_SITA 196 /* * Various link-layer types, with a pseudo-header, for Endace DAG cards; * encapsulates Endace ERF records. Requested by Stephen Donnelly * . */ -#define DLT_ERF 197 + #define DLT_ERF 197 /* * Special header prepended to Ethernet packets when capturing from a * u10 Networks board. Requested by Phil Mulholland * . */ -#define DLT_RAIF1 198 + #define DLT_RAIF1 198 /* * IPMB packet for IPMI, beginning with the I2C slave address, followed * by the netFn and LUN, etc.. Requested by Chanthy Toeung * . */ -#define DLT_IPMB 199 + #define DLT_IPMB 199 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for capturing data on a secure tunnel interface. */ -#define DLT_JUNIPER_ST 200 + #define DLT_JUNIPER_ST 200 /* * Bluetooth HCI UART transport layer (part H:4), with pseudo-header * that includes direction information; requested by Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + #define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 /* * AX.25 packet with a 1-byte KISS header; see @@ -747,14 +749,14 @@ struct bpf_version { * * as per Richard Stearn . */ -#define DLT_AX25_KISS 202 + #define DLT_AX25_KISS 202 /* * LAPD packets from an ISDN channel, starting with the address field, * with no pseudo-header. * Requested by Varuna De Silva . */ -#define DLT_LAPD 203 + #define DLT_LAPD 203 /* * Variants of various link-layer headers, with a one-byte direction @@ -762,10 +764,10 @@ struct bpf_version { * non-zero (any non-zero value) means "sent by this host" - as per * Will Barker . */ -#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ -#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ -#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ -#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + #define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ + #define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ + #define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ + #define DLT_LAPB_WITH_DIR 207 /* LAPB */ /* * 208 is reserved for an as-yet-unspecified proprietary link-layer @@ -776,39 +778,39 @@ struct bpf_version { * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman * . */ -#define DLT_IPMB_LINUX 209 + #define DLT_IPMB_LINUX 209 /* * FlexRay automotive bus - http://www.flexray.com/ - as requested * by Hannes Kaelber . */ -#define DLT_FLEXRAY 210 + #define DLT_FLEXRAY 210 /* * Media Oriented Systems Transport (MOST) bus for multimedia * transport - http://www.mostcooperation.com/ - as requested * by Hannes Kaelber . */ -#define DLT_MOST 211 + #define DLT_MOST 211 /* * Local Interconnect Network (LIN) bus for vehicle networks - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber * . */ -#define DLT_LIN 212 + #define DLT_LIN 212 /* * X2E-private data link type used for serial line capture, * as requested by Hannes Kaelber . */ -#define DLT_X2E_SERIAL 213 + #define DLT_X2E_SERIAL 213 /* * X2E-private data link type used for the Xoraya data logger * family, as requested by Hannes Kaelber . */ -#define DLT_X2E_XORAYA 214 + #define DLT_X2E_XORAYA 214 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no @@ -819,7 +821,7 @@ struct bpf_version { * * Requested by Max Filippov . */ -#define DLT_IEEE802_15_4_NONASK_PHY 215 + #define DLT_IEEE802_15_4_NONASK_PHY 215 /* @@ -827,7 +829,7 @@ struct bpf_version { * a member of that class. A class value of 0 indicates a regular * DLT_/LINKTYPE_ value. */ -#define DLT_CLASS(x) ((x) & 0x03ff0000) + #define DLT_CLASS( x ) ( ( x ) & 0x03ff0000 ) /* * NetBSD-specific generic "raw" link type. The class value indicates @@ -836,99 +838,104 @@ struct bpf_version { * do not assume that they correspond to AF_ values for your operating * system. */ -#define DLT_CLASS_NETBSD_RAWAF 0x02240000 -#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) -#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) -#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + #define DLT_CLASS_NETBSD_RAWAF 0x02240000 + #define DLT_NETBSD_RAWAF( af ) ( DLT_CLASS_NETBSD_RAWAF | ( af ) ) + #define DLT_NETBSD_RAWAF_AF( x ) ( ( x ) & 0x0000ffff ) + #define DLT_IS_NETBSD_RAWAF( x ) ( DLT_CLASS( x ) == DLT_CLASS_NETBSD_RAWAF ) /* * The instruction encodings. */ /* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 + #define BPF_CLASS( code ) ( ( code ) & 0x07 ) + #define BPF_LD 0x00 + #define BPF_LDX 0x01 + #define BPF_ST 0x02 + #define BPF_STX 0x03 + #define BPF_ALU 0x04 + #define BPF_JMP 0x05 + #define BPF_RET 0x06 + #define BPF_MISC 0x07 /* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 + #define BPF_SIZE( code ) ( ( code ) & 0x18 ) + #define BPF_W 0x00 + #define BPF_H 0x08 + #define BPF_B 0x10 + #define BPF_MODE( code ) ( ( code ) & 0xe0 ) + #define BPF_IMM 0x00 + #define BPF_ABS 0x20 + #define BPF_IND 0x40 + #define BPF_MEM 0x60 + #define BPF_LEN 0x80 + #define BPF_MSH 0xa0 /* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 + #define BPF_OP( code ) ( ( code ) & 0xf0 ) + #define BPF_ADD 0x00 + #define BPF_SUB 0x10 + #define BPF_MUL 0x20 + #define BPF_DIV 0x30 + #define BPF_OR 0x40 + #define BPF_AND 0x50 + #define BPF_LSH 0x60 + #define BPF_RSH 0x70 + #define BPF_NEG 0x80 + #define BPF_JA 0x00 + #define BPF_JEQ 0x10 + #define BPF_JGT 0x20 + #define BPF_JGE 0x30 + #define BPF_JSET 0x40 + #define BPF_SRC( code ) ( ( code ) & 0x08 ) + #define BPF_K 0x00 + #define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 + #define BPF_RVAL( code ) ( ( code ) & 0x18 ) + #define BPF_A 0x10 /* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 + #define BPF_MISCOP( code ) ( ( code ) & 0xf8 ) + #define BPF_TAX 0x00 + #define BPF_TXA 0x80 /* * The instruction data structure. */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_u_int32 k; -}; + struct bpf_insn + { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; + }; /* * Macros for insn array initializers. */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + #define BPF_STMT( code, k ) { ( u_short ) ( code ), 0, 0, k } + #define BPF_JUMP( code, k, jt, jf ) { ( u_short ) ( code ), jt, jf, k } -#if __STDC__ || defined(__cplusplus) -extern int bpf_validate(const struct bpf_insn *, int); -extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -#else -extern int bpf_validate(); -extern u_int bpf_filter(); -#endif + #if __STDC__ || defined( __cplusplus ) + extern int bpf_validate( const struct bpf_insn *, + int ); + extern u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + #else + extern int bpf_validate(); + extern u_int bpf_filter(); + #endif /* * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). */ -#define BPF_MEMWORDS 16 + #define BPF_MEMWORDS 16 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef BPF_MAJOR_VERSION */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/namedb.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/namedb.h index 9002c7509..27bcaa5cc 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/namedb.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/namedb.h @@ -34,11 +34,11 @@ */ #ifndef lib_pcap_namedb_h -#define lib_pcap_namedb_h + #define lib_pcap_namedb_h -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* * As returned by the pcap_next_etherent() @@ -47,43 +47,52 @@ extern "C" { * on systems that don't have support for /etc/ethers, we * export these hooks since they'll */ -struct pcap_etherent { - u_char addr[6]; - char name[122]; -}; -#ifndef PCAP_ETHERS_FILE -#define PCAP_ETHERS_FILE "/etc/ethers" -#endif -struct pcap_etherent *pcap_next_etherent(FILE *); -u_char *pcap_ether_hostton(const char*); -u_char *pcap_ether_aton(const char *); + struct pcap_etherent + { + u_char addr[ 6 ]; + char name[ 122 ]; + }; + #ifndef PCAP_ETHERS_FILE + #define PCAP_ETHERS_FILE "/etc/ethers" + #endif + struct pcap_etherent * pcap_next_etherent( FILE * ); + u_char * pcap_ether_hostton( const char * ); + u_char * pcap_ether_aton( const char * ); -bpf_u_int32 **pcap_nametoaddr(const char *); -#ifdef INET6 -struct addrinfo *pcap_nametoaddrinfo(const char *); -#endif -bpf_u_int32 pcap_nametonetaddr(const char *); + bpf_u_int32 ** pcap_nametoaddr( const char * ); + #ifdef INET6 + struct addrinfo * pcap_nametoaddrinfo( const char * ); + #endif + bpf_u_int32 pcap_nametonetaddr( const char * ); + + int pcap_nametoport( const char *, + int *, + int * ); + int pcap_nametoportrange( const char *, + int *, + int *, + int * ); + int pcap_nametoproto( const char * ); + int pcap_nametoeproto( const char * ); + int pcap_nametollc( const char * ); -int pcap_nametoport(const char *, int *, int *); -int pcap_nametoportrange(const char *, int *, int *, int *); -int pcap_nametoproto(const char *); -int pcap_nametoeproto(const char *); -int pcap_nametollc(const char *); /* * If a protocol is unknown, PROTO_UNDEF is returned. * Also, pcap_nametoport() returns the protocol along with the port number. * If there are ambiguous entried in /etc/services (i.e. domain * can be either tcp or udp) PROTO_UNDEF is returned. */ -#define PROTO_UNDEF -1 + #define PROTO_UNDEF -1 /* XXX move these to pcap-int.h? */ -int __pcap_atodn(const char *, bpf_u_int32 *); -int __pcap_atoin(const char *, bpf_u_int32 *); -u_short __pcap_nametodnaddr(const char *); + int __pcap_atodn( const char *, + bpf_u_int32 * ); + int __pcap_atoin( const char *, + bpf_u_int32 * ); + u_short __pcap_nametodnaddr( const char * ); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_namedb_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/pcap.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/pcap.h index ad8fc40ac..20113a9e7 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/pcap.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/pcap.h @@ -1,4 +1,5 @@ /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ + /* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. @@ -35,59 +36,59 @@ */ #ifndef lib_pcap_pcap_h -#define lib_pcap_pcap_h + #define lib_pcap_pcap_h -#if defined(WIN32) - #include -#elif defined(MSDOS) - #include - #include /* u_int, u_char etc. */ -#else /* UN*X */ - #include - #include -#endif /* WIN32/MSDOS/UN*X */ + #if defined( WIN32 ) + #include + #elif defined( MSDOS ) + #include + #include /* u_int, u_char etc. */ + #else /* UN*X */ + #include + #include + #endif /* WIN32/MSDOS/UN*X */ -#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include -#endif + #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H + #include + #endif -#include + #include -#ifdef HAVE_REMOTE - // We have to define the SOCKET here, although it has been defined in sockutils.h - // This is to avoid the distribution of the 'sockutils.h' file around - // (for example in the WinPcap developer's pack) - #ifndef SOCKET - #ifdef WIN32 - #define SOCKET unsigned int - #else - #define SOCKET int - #endif - #endif -#endif + #ifdef HAVE_REMOTE + /* We have to define the SOCKET here, although it has been defined in sockutils.h */ + /* This is to avoid the distribution of the 'sockutils.h' file around */ + /* (for example in the WinPcap developer's pack) */ + #ifndef SOCKET + #ifdef WIN32 + #define SOCKET unsigned int + #else + #define SOCKET int + #endif + #endif + #endif /* ifdef HAVE_REMOTE */ -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 + #define PCAP_VERSION_MAJOR 2 + #define PCAP_VERSION_MINOR 4 -#define PCAP_ERRBUF_SIZE 256 + #define PCAP_ERRBUF_SIZE 256 /* * Compatibility for systems that have a bpf.h that * predates the bpf typedefs for 64-bit support. */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #if BPF_RELEASE - 0 < 199406 + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; + typedef struct pcap pcap_t; + typedef struct pcap_dumper pcap_dumper_t; + typedef struct pcap_if pcap_if_t; + typedef struct pcap_addr pcap_addr_t; /* * The first record in the file contains saved values for some @@ -126,31 +127,33 @@ typedef struct pcap_addr pcap_addr_t; * so that future versions of libpcap and programs that use it (such as * tcpdump) will be able to read your new capture file format. */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; + struct pcap_file_header + { + bpf_u_int32 magic; + u_short version_major; + u_short version_minor; + bpf_int32 thiszone; /* gmt to local correction */ + bpf_u_int32 sigfigs; /* accuracy of timestamps */ + bpf_u_int32 snaplen; /* max length saved portion of each pkt */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ + }; /* * Macros for the value returned by pcap_datalink_ext(). - * + * * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro * gives the FCS length of packets in the capture. */ -#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) -#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) -#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) + #define LT_FCS_LENGTH_PRESENT( x ) ( ( x ) & 0x04000000 ) + #define LT_FCS_LENGTH( x ) ( ( ( x ) & 0xF0000000 ) >> 28 ) + #define LT_FCS_DATALINK_EXT( x ) ( ( ( ( x ) & 0xF ) << 28 ) | 0x04000000 ) -typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT -} pcap_direction_t; + typedef enum + { + PCAP_D_INOUT = 0, + PCAP_D_IN, + PCAP_D_OUT + } pcap_direction_t; /* * Generic per-packet information, as supplied by libpcap. @@ -164,85 +167,92 @@ typedef enum { * should supply the appropriate version of "struct timeval", even if * that's not what the underlying packet capture mechanism supplies. */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; + struct pcap_pkthdr + { + struct timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ + }; /* * As returned by the pcap_stats() */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface XXX not yet supported */ -#ifdef HAVE_REMOTE - u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ - u_int ps_sent; /* number of packets sent by the server on the network */ - u_int ps_netdrop; /* number of packets lost on the network */ -#endif /* HAVE_REMOTE */ -}; + struct pcap_stat + { + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface XXX not yet supported */ + #ifdef HAVE_REMOTE + u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ + u_int ps_sent; /* number of packets sent by the server on the network */ + u_int ps_netdrop; /* number of packets lost on the network */ + #endif /* HAVE_REMOTE */ + }; + + #ifdef MSDOS -#ifdef MSDOS /* * As returned by the pcap_stats_ex() */ -struct pcap_stat_ex { - u_long rx_packets; /* total packets received */ - u_long tx_packets; /* total packets transmitted */ - u_long rx_bytes; /* total bytes received */ - u_long tx_bytes; /* total bytes transmitted */ - u_long rx_errors; /* bad packets received */ - u_long tx_errors; /* packet transmit problems */ - u_long rx_dropped; /* no space in Rx buffers */ - u_long tx_dropped; /* no space available for Tx */ - u_long multicast; /* multicast packets received */ - u_long collisions; + struct pcap_stat_ex + { + u_long rx_packets; /* total packets received */ + u_long tx_packets; /* total packets transmitted */ + u_long rx_bytes; /* total bytes received */ + u_long tx_bytes; /* total bytes transmitted */ + u_long rx_errors; /* bad packets received */ + u_long tx_errors; /* packet transmit problems */ + u_long rx_dropped; /* no space in Rx buffers */ + u_long tx_dropped; /* no space available for Tx */ + u_long multicast; /* multicast packets received */ + u_long collisions; - /* detailed rx_errors: */ - u_long rx_length_errors; - u_long rx_over_errors; /* receiver ring buff overflow */ - u_long rx_crc_errors; /* recv'd pkt with crc error */ - u_long rx_frame_errors; /* recv'd frame alignment error */ - u_long rx_fifo_errors; /* recv'r fifo overrun */ - u_long rx_missed_errors; /* recv'r missed packet */ + /* detailed rx_errors: */ + u_long rx_length_errors; + u_long rx_over_errors; /* receiver ring buff overflow */ + u_long rx_crc_errors; /* recv'd pkt with crc error */ + u_long rx_frame_errors; /* recv'd frame alignment error */ + u_long rx_fifo_errors; /* recv'r fifo overrun */ + u_long rx_missed_errors; /* recv'r missed packet */ - /* detailed tx_errors */ - u_long tx_aborted_errors; - u_long tx_carrier_errors; - u_long tx_fifo_errors; - u_long tx_heartbeat_errors; - u_long tx_window_errors; - }; -#endif + /* detailed tx_errors */ + u_long tx_aborted_errors; + u_long tx_carrier_errors; + u_long tx_fifo_errors; + u_long tx_heartbeat_errors; + u_long tx_window_errors; + }; + #endif /* ifdef MSDOS */ /* * Item in a list of interfaces. */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; + struct pcap_if + { + struct pcap_if * next; + char * name; /* name to hand to "pcap_open_live()" */ + char * description; /* textual description of interface, or NULL */ + struct pcap_addr * addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ + }; -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ + #define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ /* * Representation of an interface address. */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; + struct pcap_addr + { + struct pcap_addr * next; + struct sockaddr * addr; /* address */ + struct sockaddr * netmask; /* netmask for that address */ + struct sockaddr * broadaddr; /* broadcast address for that address */ + struct sockaddr * dstaddr; /* P2P destination address for that address */ + }; -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); + typedef void (* pcap_handler)( u_char *, + const struct pcap_pkthdr *, + const u_char * ); /* * Error codes for the pcap API. @@ -250,158 +260,222 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, * failure of a call that returns these codes by checking for a * negative value. */ -#define PCAP_ERROR -1 /* generic error code */ -#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ -#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ -#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ -#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ -#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ -#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ -#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ -#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ + #define PCAP_ERROR -1 /* generic error code */ + #define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ + #define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ + #define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ + #define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ + #define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ + #define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ + #define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ + #define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ /* * Warning codes for the pcap API. * These will all be positive and non-zero, so they won't look like * errors. */ -#define PCAP_WARNING 1 /* generic warning code */ -#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ + #define PCAP_WARNING 1 /* generic warning code */ + #define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ -char *pcap_lookupdev(char *); -int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); + char * pcap_lookupdev( char * ); + int pcap_lookupnet( const char *, + bpf_u_int32 *, + bpf_u_int32 *, + char * ); -pcap_t *pcap_create(const char *, char *); -int pcap_set_snaplen(pcap_t *, int); -int pcap_set_promisc(pcap_t *, int); -int pcap_can_set_rfmon(pcap_t *); -int pcap_set_rfmon(pcap_t *, int); -int pcap_set_timeout(pcap_t *, int); -int pcap_set_buffer_size(pcap_t *, int); -int pcap_activate(pcap_t *); + pcap_t * pcap_create( const char *, + char * ); + int pcap_set_snaplen( pcap_t *, + int ); + int pcap_set_promisc( pcap_t *, + int ); + int pcap_can_set_rfmon( pcap_t * ); + int pcap_set_rfmon( pcap_t *, + int ); + int pcap_set_timeout( pcap_t *, + int ); + int pcap_set_buffer_size( pcap_t *, + int ); + int pcap_activate( pcap_t * ); -pcap_t *pcap_open_live(const char *, int, int, int, char *); -pcap_t *pcap_open_dead(int, int); -pcap_t *pcap_open_offline(const char *, char *); -#if defined(WIN32) -pcap_t *pcap_hopen_offline(intptr_t, char *); -#if !defined(LIBPCAP_EXPORTS) -#define pcap_fopen_offline(f,b) \ - pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) -#else /*LIBPCAP_EXPORTS*/ -static pcap_t *pcap_fopen_offline(FILE *, char *); -#endif -#else /*WIN32*/ -pcap_t *pcap_fopen_offline(FILE *, char *); -#endif /*WIN32*/ + pcap_t * pcap_open_live( const char *, + int, + int, + int, + char * ); + pcap_t * pcap_open_dead( int, + int ); + pcap_t * pcap_open_offline( const char *, + char * ); + #if defined( WIN32 ) + pcap_t * pcap_hopen_offline( intptr_t, + char * ); + #if !defined( LIBPCAP_EXPORTS ) + #define pcap_fopen_offline( f, b ) \ + pcap_hopen_offline( _get_osfhandle( _fileno( f ) ), b ) + #else /*LIBPCAP_EXPORTS*/ + static pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif + #else /*WIN32*/ + pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif /*WIN32*/ -void pcap_close(pcap_t *); -int pcap_loop(pcap_t *, int, pcap_handler, u_char *); -int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); -const u_char* - pcap_next(pcap_t *, struct pcap_pkthdr *); -int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); -void pcap_breakloop(pcap_t *); -int pcap_stats(pcap_t *, struct pcap_stat *); -int pcap_setfilter(pcap_t *, struct bpf_program *); -int pcap_setdirection(pcap_t *, pcap_direction_t); -int pcap_getnonblock(pcap_t *, char *); -int pcap_setnonblock(pcap_t *, int, char *); -int pcap_inject(pcap_t *, const void *, size_t); -int pcap_sendpacket(pcap_t *, const u_char *, int); -const char *pcap_statustostr(int); -const char *pcap_strerror(int); -char *pcap_geterr(pcap_t *); -void pcap_perror(pcap_t *, char *); -int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32); -int pcap_compile_nopcap(int, int, struct bpf_program *, - const char *, int, bpf_u_int32); -void pcap_freecode(struct bpf_program *); -int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *, - const u_char *); -int pcap_datalink(pcap_t *); -int pcap_datalink_ext(pcap_t *); -int pcap_list_datalinks(pcap_t *, int **); -int pcap_set_datalink(pcap_t *, int); -void pcap_free_datalinks(int *); -int pcap_datalink_name_to_val(const char *); -const char *pcap_datalink_val_to_name(int); -const char *pcap_datalink_val_to_description(int); -int pcap_snapshot(pcap_t *); -int pcap_is_swapped(pcap_t *); -int pcap_major_version(pcap_t *); -int pcap_minor_version(pcap_t *); + void pcap_close( pcap_t * ); + int pcap_loop( pcap_t *, + int, + pcap_handler, + u_char * ); + int pcap_dispatch( pcap_t *, + int, + pcap_handler, + u_char * ); + const u_char * pcap_next( pcap_t *, + struct pcap_pkthdr * ); + int pcap_next_ex( pcap_t *, + struct pcap_pkthdr **, + const u_char ** ); + void pcap_breakloop( pcap_t * ); + int pcap_stats( pcap_t *, + struct pcap_stat * ); + int pcap_setfilter( pcap_t *, + struct bpf_program * ); + int pcap_setdirection( pcap_t *, + pcap_direction_t ); + int pcap_getnonblock( pcap_t *, + char * ); + int pcap_setnonblock( pcap_t *, + int, + char * ); + int pcap_inject( pcap_t *, + const void *, + size_t ); + int pcap_sendpacket( pcap_t *, + const u_char *, + int ); + const char * pcap_statustostr( int ); + const char * pcap_strerror( int ); + char * pcap_geterr( pcap_t * ); + void pcap_perror( pcap_t *, + char * ); + int pcap_compile( pcap_t *, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + int pcap_compile_nopcap( int, + int, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + void pcap_freecode( struct bpf_program * ); + int pcap_offline_filter( struct bpf_program *, + const struct pcap_pkthdr *, + const u_char * ); + int pcap_datalink( pcap_t * ); + int pcap_datalink_ext( pcap_t * ); + int pcap_list_datalinks( pcap_t *, + int ** ); + int pcap_set_datalink( pcap_t *, + int ); + void pcap_free_datalinks( int * ); + int pcap_datalink_name_to_val( const char * ); + const char * pcap_datalink_val_to_name( int ); + const char * pcap_datalink_val_to_description( int ); + int pcap_snapshot( pcap_t * ); + int pcap_is_swapped( pcap_t * ); + int pcap_major_version( pcap_t * ); + int pcap_minor_version( pcap_t * ); /* XXX */ -FILE *pcap_file(pcap_t *); -int pcap_fileno(pcap_t *); + FILE * pcap_file( pcap_t * ); + int pcap_fileno( pcap_t * ); -pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); -pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); -FILE *pcap_dump_file(pcap_dumper_t *); -long pcap_dump_ftell(pcap_dumper_t *); -int pcap_dump_flush(pcap_dumper_t *); -void pcap_dump_close(pcap_dumper_t *); -void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); + pcap_dumper_t * pcap_dump_open( pcap_t *, + const char * ); + pcap_dumper_t * pcap_dump_fopen( pcap_t *, + FILE * fp ); + FILE * pcap_dump_file( pcap_dumper_t * ); + long pcap_dump_ftell( pcap_dumper_t * ); + int pcap_dump_flush( pcap_dumper_t * ); + void pcap_dump_close( pcap_dumper_t * ); + void pcap_dump( u_char *, + const struct pcap_pkthdr *, + const u_char * ); -int pcap_findalldevs(pcap_if_t **, char *); -void pcap_freealldevs(pcap_if_t *); + int pcap_findalldevs( pcap_if_t **, + char * ); + void pcap_freealldevs( pcap_if_t * ); -const char *pcap_lib_version(void); + const char * pcap_lib_version( void ); /* XXX this guy lives in the bpf tree */ -u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -int bpf_validate(const struct bpf_insn *f, int len); -char *bpf_image(const struct bpf_insn *, int); -void bpf_dump(const struct bpf_program *, int); + u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + int bpf_validate( const struct bpf_insn * f, + int len ); + char * bpf_image( const struct bpf_insn *, + int ); + void bpf_dump( const struct bpf_program *, + int ); -#if defined(WIN32) + #if defined( WIN32 ) /* * Win32 definitions */ -int pcap_setbuff(pcap_t *p, int dim); -int pcap_setmode(pcap_t *p, int mode); -int pcap_setmintocopy(pcap_t *p, int size); + int pcap_setbuff( pcap_t * p, + int dim ); + int pcap_setmode( pcap_t * p, + int mode ); + int pcap_setmintocopy( pcap_t * p, + int size ); -#ifdef WPCAP + #ifdef WPCAP /* Include file with the wpcap-specific extensions */ -#include -#endif /* WPCAP */ + #include + #endif /* WPCAP */ -#define MODE_CAPT 0 -#define MODE_STAT 1 -#define MODE_MON 2 + #define MODE_CAPT 0 + #define MODE_STAT 1 + #define MODE_MON 2 -#elif defined(MSDOS) + #elif defined( MSDOS ) /* * MS-DOS definitions */ -int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); -void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); -u_long pcap_mac_packets (void); + int pcap_stats_ex( pcap_t *, + struct pcap_stat_ex * ); + void pcap_set_wait( pcap_t * p, + void ( * yield )( void ), + int wait ); + u_long pcap_mac_packets( void ); -#else /* UN*X */ + #else /* UN*X */ /* * UN*X definitions */ -int pcap_get_selectable_fd(pcap_t *); + int pcap_get_selectable_fd( pcap_t * ); -#endif /* WIN32/MSDOS/UN*X */ + #endif /* WIN32/MSDOS/UN*X */ -#ifdef HAVE_REMOTE + #ifdef HAVE_REMOTE /* Includes most of the public stuff that is needed for the remote capture */ -#include -#endif /* HAVE_REMOTE */ + #include + #endif /* HAVE_REMOTE */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_pcap_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/sll.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/sll.h index e9d5452af..e5052236a 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/sll.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/sll.h @@ -79,15 +79,16 @@ /* * A DLT_LINUX_SLL fake link-layer header. */ -#define SLL_HDR_LEN 16 /* total header length */ -#define SLL_ADDRLEN 8 /* length of address field */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ -struct sll_header { - u_int16_t sll_pkttype; /* packet type */ - u_int16_t sll_hatype; /* link-layer address type */ - u_int16_t sll_halen; /* link-layer address length */ - u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ - u_int16_t sll_protocol; /* protocol */ +struct sll_header +{ + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[ SLL_ADDRLEN ]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ }; /* @@ -96,11 +97,11 @@ struct sll_header { * available even on systems other than Linux, and so that they * don't change even if the PACKET_ values change. */ -#define LINUX_SLL_HOST 0 -#define LINUX_SLL_BROADCAST 1 -#define LINUX_SLL_MULTICAST 2 -#define LINUX_SLL_OTHERHOST 3 -#define LINUX_SLL_OUTGOING 4 +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 /* * The LINUX_SLL_ values for "sll_protocol"; these correspond to the @@ -123,7 +124,7 @@ struct sll_header { * in the Linux "if_ether.h" will, I suspect, actually show up in * captures.) */ -#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ -#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ -#endif +#endif /* ifndef lib_pcap_sll_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/usb.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/usb.h index adcd19c05..44a3c9557 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/usb.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/usb.h @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,36 +32,37 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $ */ - + #ifndef _PCAP_USB_STRUCTS_H__ #define _PCAP_USB_STRUCTS_H__ -/* +/* * possible transfer mode */ -#define URB_TRANSFER_IN 0x80 -#define URB_ISOCHRONOUS 0x0 -#define URB_INTERRUPT 0x1 -#define URB_CONTROL 0x2 -#define URB_BULK 0x3 +#define URB_TRANSFER_IN 0x80 +#define URB_ISOCHRONOUS 0x0 +#define URB_INTERRUPT 0x1 +#define URB_CONTROL 0x2 +#define URB_BULK 0x3 /* * possible event type */ -#define URB_SUBMIT 'S' -#define URB_COMPLETE 'C' -#define URB_ERROR 'E' +#define URB_SUBMIT 'S' +#define URB_COMPLETE 'C' +#define URB_ERROR 'E' /* * USB setup header as defined in USB specification. * Appears at the front of each packet in DLT_USB captures. */ -typedef struct _usb_setup { - u_int8_t bmRequestType; - u_int8_t bRequest; - u_int16_t wValue; - u_int16_t wIndex; - u_int16_t wLength; +typedef struct _usb_setup +{ + u_int8_t bmRequestType; + u_int8_t bRequest; + u_int16_t wValue; + u_int16_t wIndex; + u_int16_t wLength; } pcap_usb_setup; @@ -69,22 +70,23 @@ typedef struct _usb_setup { * Header prepended by linux kernel to each event. * Appears at the front of each packet in DLT_USB_LINUX captures. */ -typedef struct _usb_header { - u_int64_t id; - u_int8_t event_type; - u_int8_t transfer_type; - u_int8_t endpoint_number; - u_int8_t device_address; - u_int16_t bus_id; - char setup_flag;/*if !=0 the urb setup header is not present*/ - char data_flag; /*if !=0 no urb data is present*/ - int64_t ts_sec; - int32_t ts_usec; - int32_t status; - u_int32_t urb_len; - u_int32_t data_len; /* amount of urb data really present in this event*/ - pcap_usb_setup setup; +typedef struct _usb_header +{ + u_int64_t id; + u_int8_t event_type; + u_int8_t transfer_type; + u_int8_t endpoint_number; + u_int8_t device_address; + u_int16_t bus_id; + char setup_flag; /*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + u_int32_t urb_len; + u_int32_t data_len; /* amount of urb data really present in this event*/ + pcap_usb_setup setup; } pcap_usb_header; -#endif +#endif /* ifndef _PCAP_USB_STRUCTS_H__ */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/vlan.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/vlan.h index b0cb7949b..e9be8bd16 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/vlan.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/pcap/vlan.h @@ -36,11 +36,12 @@ #ifndef lib_pcap_vlan_h #define lib_pcap_vlan_h -struct vlan_tag { - u_int16_t vlan_tpid; /* ETH_P_8021Q */ - u_int16_t vlan_tci; /* VLAN TCI */ +struct vlan_tag +{ + u_int16_t vlan_tpid; /* ETH_P_8021Q */ + u_int16_t vlan_tci; /* VLAN TCI */ }; -#define VLAN_TAG_LEN 4 +#define VLAN_TAG_LEN 4 -#endif +#endif /* ifndef lib_pcap_vlan_h */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/remote-ext.h b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/remote-ext.h index 35a2fff6c..42d1fe6e9 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/remote-ext.h +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/WinPCap/remote-ext.h @@ -2,443 +2,471 @@ * Copyright (c) 2002 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions * are met: - * - * 1. Redistributions of source code must retain the above copyright + * + * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * */ #ifndef __REMOTE_EXT_H__ -#define __REMOTE_EXT_H__ + #define __REMOTE_EXT_H__ -#ifndef HAVE_REMOTE -#error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h -#endif + #ifndef HAVE_REMOTE + #error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h + #endif -// Definition for Microsoft Visual Studio -#if _MSC_VER > 1000 -#pragma once -#endif +/* Definition for Microsoft Visual Studio */ + #if _MSC_VER > 1000 + #pragma once + #endif -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /*! - \file remote-ext.h - - The goal of this file it to include most of the new definitions that should be - placed into the pcap.h file. - - It includes all new definitions (structures and functions like pcap_open(). - Some of the functions are not really a remote feature, but, right now, - they are placed here. -*/ + * \file remote-ext.h + * + * The goal of this file it to include most of the new definitions that should be + * placed into the pcap.h file. + * + * It includes all new definitions (structures and functions like pcap_open(). + * Some of the functions are not really a remote feature, but, right now, + * they are placed here. + */ -// All this stuff is public +/* All this stuff is public */ + /*! \addtogroup remote_struct - \{ -*/ - + \{ + */ /*! - \brief Defines the maximum buffer size in which address, port, interface names are kept. - - In case the adapter name or such is larger than this value, it is truncated. - This is not used by the user; however it must be aware that an hostname / interface - name longer than this value will be truncated. -*/ -#define PCAP_BUF_SIZE 1024 + * \brief Defines the maximum buffer size in which address, port, interface names are kept. + * + * In case the adapter name or such is larger than this value, it is truncated. + * This is not used by the user; however it must be aware that an hostname / interface + * name longer than this value will be truncated. + */ + #define PCAP_BUF_SIZE 1024 /*! \addtogroup remote_source_ID - \{ -*/ + \{ + */ /*! - \brief Internal representation of the type of source in use (file, - remote/local interface). - - This indicates a file, i.e. the user want to open a capture from a local file. -*/ -#define PCAP_SRC_FILE 2 -/*! - \brief Internal representation of the type of source in use (file, - remote/local interface). - - This indicates a local interface, i.e. the user want to open a capture from - a local interface. This does not involve the RPCAP protocol. -*/ -#define PCAP_SRC_IFLOCAL 3 -/*! - \brief Internal representation of the type of source in use (file, - remote/local interface). - - This indicates a remote interface, i.e. the user want to open a capture from - an interface on a remote host. This does involve the RPCAP protocol. -*/ -#define PCAP_SRC_IFREMOTE 4 + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a file, i.e. the user want to open a capture from a local file. + */ + #define PCAP_SRC_FILE 2 /*! - \} -*/ + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a local interface, i.e. the user want to open a capture from + * a local interface. This does not involve the RPCAP protocol. + */ + #define PCAP_SRC_IFLOCAL 3 + +/*! + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a remote interface, i.e. the user want to open a capture from + * an interface on a remote host. This does involve the RPCAP protocol. + */ + #define PCAP_SRC_IFREMOTE 4 + +/*! + \} + */ /*! \addtogroup remote_source_string - - The formats allowed by the pcap_open() are the following: - - file://path_and_filename [opens a local file] - - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] - - rpcap://host/devicename [opens the selected device available on a remote host] - - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] - - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] - - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] - - The formats allowed by the pcap_findalldevs_ex() are the following: - - file://folder/ [lists all the files in the given folder] - - rpcap:// [lists all local adapters] - - rpcap://host:port/ [lists the devices available on a remote host] - - Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since - IPv6 is fully supported, these are the allowed formats: - - - host (literal): e.g. host.foo.bar - - host (numeric IPv4): e.g. 10.11.12.13 - - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] - - host (numeric IPv6): e.g. [1:2:3::4] - - port: can be either numeric (e.g. '80') or literal (e.g. 'http') - - Here you find some allowed examples: - - rpcap://host.foo.bar/devicename [everything literal, no port number] - - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] - - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] - - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] - - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] - - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] - - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] - - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] - - \{ -*/ + * + * The formats allowed by the pcap_open() are the following: + * - file://path_and_filename [opens a local file] + * - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] + * - rpcap://host/devicename [opens the selected device available on a remote host] + * - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] + * - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] + * - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] + * + * The formats allowed by the pcap_findalldevs_ex() are the following: + * - file://folder/ [lists all the files in the given folder] + * - rpcap:// [lists all local adapters] + * - rpcap://host:port/ [lists the devices available on a remote host] + * + * Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since + * IPv6 is fully supported, these are the allowed formats: + * + * - host (literal): e.g. host.foo.bar + * - host (numeric IPv4): e.g. 10.11.12.13 + * - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] + * - host (numeric IPv6): e.g. [1:2:3::4] + * - port: can be either numeric (e.g. '80') or literal (e.g. 'http') + * + * Here you find some allowed examples: + * - rpcap://host.foo.bar/devicename [everything literal, no port number] + * - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] + * - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] + * - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] + * - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] + * - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] + * - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] + * - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] + * + \{ + */ /*! - \brief String that will be used to determine the type of source in use (file, - remote/local interface). - - This string will be prepended to the interface name in order to create a string - that contains all the information required to open the source. - - This string indicates that the user wants to open a capture from a local file. -*/ -#define PCAP_SRC_FILE_STRING "file://" -/*! - \brief String that will be used to determine the type of source in use (file, - remote/local interface). - - This string will be prepended to the interface name in order to create a string - that contains all the information required to open the source. - - This string indicates that the user wants to open a capture from a network interface. - This string does not necessarily involve the use of the RPCAP protocol. If the - interface required resides on the local host, the RPCAP protocol is not involved - and the local functions are used. -*/ -#define PCAP_SRC_IF_STRING "rpcap://" + * \brief String that will be used to determine the type of source in use (file, + * remote/local interface). + * + * This string will be prepended to the interface name in order to create a string + * that contains all the information required to open the source. + * + * This string indicates that the user wants to open a capture from a local file. + */ + #define PCAP_SRC_FILE_STRING "file://" /*! - \} -*/ - + * \brief String that will be used to determine the type of source in use (file, + * remote/local interface). + * + * This string will be prepended to the interface name in order to create a string + * that contains all the information required to open the source. + * + * This string indicates that the user wants to open a capture from a network interface. + * This string does not necessarily involve the use of the RPCAP protocol. If the + * interface required resides on the local host, the RPCAP protocol is not involved + * and the local functions are used. + */ + #define PCAP_SRC_IF_STRING "rpcap://" +/*! + \} + */ /*! - \addtogroup remote_open_flags - \{ -*/ + * \addtogroup remote_open_flags + \{ + */ /*! - \brief Defines if the adapter has to go in promiscuous mode. - - It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise. - Note that even if this parameter is false, the interface could well be in promiscuous - mode for some other reason (for example because another capture process with - promiscuous mode enabled is currently using that interface). - On on Linux systems with 2.2 or later kernels (that have the "any" device), this - flag does not work on the "any" device; if an argument of "any" is supplied, - the 'promisc' flag is ignored. -*/ -#define PCAP_OPENFLAG_PROMISCUOUS 1 + * \brief Defines if the adapter has to go in promiscuous mode. + * + * It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise. + * Note that even if this parameter is false, the interface could well be in promiscuous + * mode for some other reason (for example because another capture process with + * promiscuous mode enabled is currently using that interface). + * On on Linux systems with 2.2 or later kernels (that have the "any" device), this + * flag does not work on the "any" device; if an argument of "any" is supplied, + * the 'promisc' flag is ignored. + */ + #define PCAP_OPENFLAG_PROMISCUOUS 1 /*! - \brief Defines if the data trasfer (in case of a remote - capture) has to be done with UDP protocol. - - If it is '1' if you want a UDP data connection, '0' if you want - a TCP data connection; control connection is always TCP-based. - A UDP connection is much lighter, but it does not guarantee that all - the captured packets arrive to the client workstation. Moreover, - it could be harmful in case of network congestion. - This flag is meaningless if the source is not a remote interface. - In that case, it is simply ignored. -*/ -#define PCAP_OPENFLAG_DATATX_UDP 2 + * \brief Defines if the data transfer (in case of a remote + * capture) has to be done with UDP protocol. + * + * If it is '1' if you want a UDP data connection, '0' if you want + * a TCP data connection; control connection is always TCP-based. + * A UDP connection is much lighter, but it does not guarantee that all + * the captured packets arrive to the client workstation. Moreover, + * it could be harmful in case of network congestion. + * This flag is meaningless if the source is not a remote interface. + * In that case, it is simply ignored. + */ + #define PCAP_OPENFLAG_DATATX_UDP 2 /*! - \brief Defines if the remote probe will capture its own generated traffic. - - In case the remote probe uses the same interface to capture traffic and to send - data back to the caller, the captured traffic includes the RPCAP traffic as well. - If this flag is turned on, the RPCAP traffic is excluded from the capture, so that - the trace returned back to the collector is does not include this traffic. -*/ -#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 + * \brief Defines if the remote probe will capture its own generated traffic. + * + * In case the remote probe uses the same interface to capture traffic and to send + * data back to the caller, the captured traffic includes the RPCAP traffic as well. + * If this flag is turned on, the RPCAP traffic is excluded from the capture, so that + * the trace returned back to the collector is does not include this traffic. + */ + #define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 /*! - \brief Defines if the local adapter will capture its own generated traffic. - - This flag tells the underlying capture driver to drop the packets that were sent by itself. - This is usefult when building applications like bridges, that should ignore the traffic - they just sent. -*/ -#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 + * \brief Defines if the local adapter will capture its own generated traffic. + * + * This flag tells the underlying capture driver to drop the packets that were sent by itself. + * This is useful when building applications like bridges, that should ignore the traffic + * they just sent. + */ + #define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 /*! - \brief This flag configures the adapter for maximum responsiveness. - - In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before - copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, - i.e. better performance, which is good for applications like sniffers. If the user sets the - PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application - is ready to receive them. This is suggested for real time applications (like, for example, a bridge) - that need the best responsiveness.*/ -#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 + * \brief This flag configures the adapter for maximum responsiveness. + * + * In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before + * copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, + * i.e. better performance, which is good for applications like sniffers. If the user sets the + * PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application + * is ready to receive them. This is suggested for real time applications (like, for example, a bridge) + * that need the best responsiveness.*/ + #define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 /*! - \} -*/ + \} + */ /*! - \addtogroup remote_samp_methods - \{ -*/ + * \addtogroup remote_samp_methods + \{ + */ /*! - \brief No sampling has to be done on the current capture. - - In this case, no sampling algorithms are applied to the current capture. -*/ -#define PCAP_SAMP_NOSAMP 0 + * \brief No sampling has to be done on the current capture. + * + * In this case, no sampling algorithms are applied to the current capture. + */ + #define PCAP_SAMP_NOSAMP 0 /*! - \brief It defines that only 1 out of N packets must be returned to the user. - - In this case, the 'value' field of the 'pcap_samp' structure indicates the - number of packets (minus 1) that must be discarded before one packet got accepted. - In other words, if 'value = 10', the first packet is returned to the caller, while - the following 9 are discarded. -*/ -#define PCAP_SAMP_1_EVERY_N 1 + * \brief It defines that only 1 out of N packets must be returned to the user. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates the + * number of packets (minus 1) that must be discarded before one packet got accepted. + * In other words, if 'value = 10', the first packet is returned to the caller, while + * the following 9 are discarded. + */ + #define PCAP_SAMP_1_EVERY_N 1 /*! - \brief It defines that we have to return 1 packet every N milliseconds. - - In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting - time' in milliseconds before one packet got accepted. - In other words, if 'value = 10', the first packet is returned to the caller; the next - returned one will be the first packet that arrives when 10ms have elapsed. -*/ -#define PCAP_SAMP_FIRST_AFTER_N_MS 2 + * \brief It defines that we have to return 1 packet every N milliseconds. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting + * time' in milliseconds before one packet got accepted. + * In other words, if 'value = 10', the first packet is returned to the caller; the next + * returned one will be the first packet that arrives when 10ms have elapsed. + */ + #define PCAP_SAMP_FIRST_AFTER_N_MS 2 /*! - \} -*/ + \} + */ /*! - \addtogroup remote_auth_methods - \{ -*/ + * \addtogroup remote_auth_methods + \{ + */ /*! - \brief It defines the NULL authentication. - - This value has to be used within the 'type' member of the pcap_rmtauth structure. - The 'NULL' authentication has to be equal to 'zero', so that old applications - can just put every field of struct pcap_rmtauth to zero, and it does work. -*/ -#define RPCAP_RMTAUTH_NULL 0 -/*! - \brief It defines the username/password authentication. - - With this type of authentication, the RPCAP protocol will use the username/ - password provided to authenticate the user on the remote machine. If the - authentication is successful (and the user has the right to open network devices) - the RPCAP connection will continue; otherwise it will be dropped. - - This value has to be used within the 'type' member of the pcap_rmtauth structure. -*/ -#define RPCAP_RMTAUTH_PWD 1 + * \brief It defines the NULL authentication. + * + * This value has to be used within the 'type' member of the pcap_rmtauth structure. + * The 'NULL' authentication has to be equal to 'zero', so that old applications + * can just put every field of struct pcap_rmtauth to zero, and it does work. + */ + #define RPCAP_RMTAUTH_NULL 0 /*! - \} -*/ + * \brief It defines the username/password authentication. + * + * With this type of authentication, the RPCAP protocol will use the username/ + * password provided to authenticate the user on the remote machine. If the + * authentication is successful (and the user has the right to open network devices) + * the RPCAP connection will continue; otherwise it will be dropped. + * + * This value has to be used within the 'type' member of the pcap_rmtauth structure. + */ + #define RPCAP_RMTAUTH_PWD 1 +/*! + \} + */ /*! + * + * \brief This structure keeps the information needed to authenticate + * the user on a remote machine. + * + * The remote machine can either grant or refuse the access according + * to the information provided. + * In case the NULL authentication is required, both 'username' and + * 'password' can be NULL pointers. + * + * This structure is meaningless if the source is not a remote interface; + * in that case, the functions which requires such a structure can accept + * a NULL pointer as well. + */ + struct pcap_rmtauth + { + /*! + * \brief Type of the authentication required. + * + * In order to provide maximum flexibility, we can support different types + * of authentication based on the value of this 'type' variable. The currently + * supported authentication methods are defined into the + * \link remote_auth_methods Remote Authentication Methods Section\endlink. + * + */ + int type; - \brief This structure keeps the information needed to autheticate - the user on a remote machine. - - The remote machine can either grant or refuse the access according - to the information provided. - In case the NULL authentication is required, both 'username' and - 'password' can be NULL pointers. - - This structure is meaningless if the source is not a remote interface; - in that case, the functions which requires such a structure can accept - a NULL pointer as well. -*/ -struct pcap_rmtauth -{ - /*! - \brief Type of the authentication required. + /*! + * \brief Zero-terminated string containing the username that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char * username; - In order to provide maximum flexibility, we can support different types - of authentication based on the value of this 'type' variable. The currently - supported authentication methods are defined into the - \link remote_auth_methods Remote Authentication Methods Section\endlink. - - */ - int type; - /*! - \brief Zero-terminated string containing the username that has to be - used on the remote machine for authentication. - - This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication - and it can be NULL. - */ - char *username; - /*! - \brief Zero-terminated string containing the password that has to be - used on the remote machine for authentication. - - This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication - and it can be NULL. - */ - char *password; -}; + /*! + * \brief Zero-terminated string containing the password that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char * password; + }; /*! - \brief This structure defines the information related to sampling. + * \brief This structure defines the information related to sampling. + * + * In case the sampling is requested, the capturing device should read + * only a subset of the packets coming from the source. The returned packets depend + * on the sampling parameters. + * + * \warning The sampling process is applied after the filtering process. + * In other words, packets are filtered first, then the sampling process selects a + * subset of the 'filtered' packets and it returns them to the caller. + */ + struct pcap_samp + { + /*! + * Method used for sampling. Currently, the supported methods are listed in the + * \link remote_samp_methods Sampling Methods Section\endlink. + */ + int method; - In case the sampling is requested, the capturing device should read - only a subset of the packets coming from the source. The returned packets depend - on the sampling parameters. - - \warning The sampling process is applied after the filtering process. - In other words, packets are filtered first, then the sampling process selects a - subset of the 'filtered' packets and it returns them to the caller. -*/ -struct pcap_samp -{ - /*! - Method used for sampling. Currently, the supported methods are listed in the - \link remote_samp_methods Sampling Methods Section\endlink. - */ - int method; - - /*! - This value depends on the sampling method defined. For its meaning, please check - at the \link remote_samp_methods Sampling Methods Section\endlink. - */ - int value; -}; + /*! + * This value depends on the sampling method defined. For its meaning, please check + * at the \link remote_samp_methods Sampling Methods Section\endlink. + */ + int value; + }; - -//! Maximum lenght of an host name (needed for the RPCAP active mode) -#define RPCAP_HOSTLIST_SIZE 1024 +/*! Maximum length of an host name (needed for the RPCAP active mode) */ + #define RPCAP_HOSTLIST_SIZE 1024 /*! - \} -*/ // end of public documentation + \} + *//* end of public documentation */ -// Exported functions +/* Exported functions */ /** \name New WinPcap functions - - This section lists the new functions that are able to help considerably in writing - WinPcap programs because of their easiness of use. + * + * This section lists the new functions that are able to help considerably in writing + * WinPcap programs because of their easiness of use. */ -//\{ -pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf); -int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf); -int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf); -int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf); -struct pcap_samp *pcap_setsampling(pcap_t *p); +/*\{ */ + pcap_t * pcap_open( const char * source, + int snaplen, + int flags, + int read_timeout, + struct pcap_rmtauth * auth, + char * errbuf ); + int pcap_createsrcstr( char * source, + int type, + const char * host, + const char * port, + const char * name, + char * errbuf ); + int pcap_parsesrcstr( const char * source, + int * type, + char * host, + char * port, + char * name, + char * errbuf ); + int pcap_findalldevs_ex( char * source, + struct pcap_rmtauth * auth, + pcap_if_t ** alldevs, + char * errbuf ); + struct pcap_samp * pcap_setsampling( pcap_t * p ); -//\} -// End of new winpcap functions +/*\} */ +/* End of new winpcap functions */ /** \name Remote Capture functions */ -//\{ -SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf); -int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf); -int pcap_remoteact_close(const char *host, char *errbuf); -void pcap_remoteact_cleanup(); -//\} -// End of remote capture functions +/*\{ */ + SOCKET pcap_remoteact_accept( const char * address, + const char * port, + const char * hostlist, + char * connectinghost, + struct pcap_rmtauth * auth, + char * errbuf ); + int pcap_remoteact_list( char * hostlist, + char sep, + int size, + char * errbuf ); + int pcap_remoteact_close( const char * host, + char * errbuf ); + void pcap_remoteact_cleanup(); +/*\} */ +/* End of remote capture functions */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif - +#endif /* ifndef __REMOTE_EXT_H__ */ diff --git a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/main.c b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/main.c index 9930edad9..950b8a275 100644 --- a/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/main.c +++ b/FreeRTOS-Plus/Test/FreeRTOS-Plus-TCP/Integration/Full-TCP-Suite/main.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -23,6 +23,7 @@ * https://github.com/FreeRTOS * */ + /** * @file main.c * @brief Implements the main function. @@ -162,7 +163,7 @@ int main( void ) #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, - struct xNetworkEndPoint * pxEndPoint ) + struct xNetworkEndPoint * pxEndPoint ) #else void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ @@ -214,7 +215,7 @@ static LONG CALLBACK prvExceptionHandler( _In_ PEXCEPTION_POINTERS ExceptionInfo #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, - const char * pcName ) + const char * pcName ) #else BaseType_t xApplicationDNSQueryHook( const char * pcName ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/Packet32.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/Packet32.h index 64be055d9..f6b7b27aa 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/Packet32.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/Packet32.h @@ -12,9 +12,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino, CACE Technologies - * nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,7 +32,7 @@ */ /** @ingroup packetapi - * @{ + * @{ */ /** @defgroup packet32h Packet.dll definitions and data structures @@ -43,317 +43,356 @@ */ #ifndef __PACKET32 -#define __PACKET32 + #define __PACKET32 -#include + #include -#ifdef HAVE_AIRPCAP_API -#include -#else -#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) -#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ -typedef struct _AirpcapHandle *PAirpcapHandle; -#endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */ -#endif /* HAVE_AIRPCAP_API */ + #ifdef HAVE_AIRPCAP_API + #include + #else + #if !defined( AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ ) + #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ + typedef struct _AirpcapHandle * PAirpcapHandle; + #endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */ + #endif /* HAVE_AIRPCAP_API */ -#ifdef HAVE_DAG_API -#include -#endif /* HAVE_DAG_API */ + #ifdef HAVE_DAG_API + #include + #endif /* HAVE_DAG_API */ -// Working modes -#define PACKET_MODE_CAPT 0x0 ///< Capture mode -#define PACKET_MODE_STAT 0x1 ///< Statistical mode -#define PACKET_MODE_MON 0x2 ///< Monitoring mode -#define PACKET_MODE_DUMP 0x10 ///< Dump mode -#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode +/* Working modes */ + #define PACKET_MODE_CAPT 0x0 /*/< Capture mode */ + #define PACKET_MODE_STAT 0x1 /*/< Statistical mode */ + #define PACKET_MODE_MON 0x2 /*/< Monitoring mode */ + #define PACKET_MODE_DUMP 0x10 /*/< Dump mode */ + #define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT /*/< Statistical dump Mode */ -/// Alignment macro. Defines the alignment size. -#define Packet_ALIGNMENT sizeof(int) -/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. -#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) +/*/ Alignment macro. Defines the alignment size. */ + #define Packet_ALIGNMENT sizeof( int ) +/*/ Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. */ + #define Packet_WORDALIGN( x ) ( ( ( x ) + ( Packet_ALIGNMENT - 1 ) ) & ~( Packet_ALIGNMENT - 1 ) ) -#define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent -#define NdisMediumPpi -6 ///< Custom linktype: NDIS doesn't provide an equivalent + #define NdisMediumNull -1 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumCHDLC -2 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumPPPSerial -3 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumBare80211 -4 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumRadio80211 -5 /*/< Custom linktype: NDIS doesn't provide an equivalent */ + #define NdisMediumPpi -6 /*/< Custom linktype: NDIS doesn't provide an equivalent */ -// Loopback behaviour definitions -#define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver -#define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver +/* Loopback behaviour definitions */ + #define NPF_DISABLE_LOOPBACK 1 /*/< Drop the packets sent by the NPF driver */ + #define NPF_ENABLE_LOOPBACK 2 /*/< Capture the packets sent by the NPF driver */ /*! - \brief Network type structure. - - This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. -*/ -typedef struct NetType -{ - UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information) - ULONGLONG LinkSpeed; ///< The speed of the network in bits per second -}NetType; + * \brief Network type structure. + * + * This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. + */ + typedef struct NetType + { + UINT LinkType; /*/< The MAC of the current network adapter (see function PacketGetNetType() for more information) */ + ULONGLONG LinkSpeed; /*/< The speed of the network in bits per second */ + } NetType; -//some definitions stolen from libpcap +/*some definitions stolen from libpcap */ -#ifndef BPF_MAJOR_VERSION + #ifndef BPF_MAJOR_VERSION /*! - \brief A BPF pseudo-assembly program. - - The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. -*/ -struct bpf_program -{ - UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. - struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program. -}; + * \brief A BPF pseudo-assembly program. + * + * The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. + */ + struct bpf_program + { + UINT bf_len; /*/< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. */ + struct bpf_insn * bf_insns; /*/< A pointer to the first instruction of the program. */ + }; /*! - \brief A single BPF pseudo-instruction. - - bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. -*/ -struct bpf_insn -{ - USHORT code; ///< Instruction type and addressing mode. - UCHAR jt; ///< Jump if true - UCHAR jf; ///< Jump if false - int k; ///< Generic field used for various purposes. -}; + * \brief A single BPF pseudo-instruction. + * + * bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. + */ + struct bpf_insn + { + USHORT code; /*/< Instruction type and addressing mode. */ + UCHAR jt; /*/< Jump if true */ + UCHAR jf; /*/< Jump if false */ + int k; /*/< Generic field used for various purposes. */ + }; /*! - \brief Structure that contains a couple of statistics values on the current capture. - - It is used by packet.dll to return statistics about a capture session. -*/ -struct bpf_stat -{ - UINT bs_recv; ///< Number of packets that the driver received from the network adapter - ///< from the beginning of the current capture. This value includes the packets - ///< lost by the driver. - UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture. - ///< Basically, a packet is lost when the the buffer of the driver is full. - ///< In this situation the packet cannot be stored and the driver rejects it. - UINT ps_ifdrop; ///< drops by interface. XXX not yet supported - UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and - ///< thus reach the application. -}; + * \brief Structure that contains a couple of statistics values on the current capture. + * + * It is used by packet.dll to return statistics about a capture session. + */ + struct bpf_stat + { + UINT bs_recv; /*/< Number of packets that the driver received from the network adapter */ + /*/< from the beginning of the current capture. This value includes the packets */ + /*/< lost by the driver. */ + UINT bs_drop; /*/< number of packets that the driver lost from the beginning of a capture. */ + /*/< Basically, a packet is lost when the the buffer of the driver is full. */ + /*/< In this situation the packet cannot be stored and the driver rejects it. */ + UINT ps_ifdrop; /*/< drops by interface. XXX not yet supported */ + UINT bs_capt; /*/< number of packets that pass the filter, find place in the kernel buffer and */ + /*/< thus reach the application. */ + }; /*! - \brief Packet header. - - This structure defines the header associated with every packet delivered to the application. -*/ -struct bpf_hdr -{ - struct timeval bh_tstamp; ///< The timestamp associated with the captured packet. - ///< It is stored in a TimeVal structure. - UINT bh_caplen; ///< Length of captured portion. The captured portion can be different - ///< from the original packet, because it is possible (with a proper filter) - ///< to instruct the driver to capture only a portion of the packets. - UINT bh_datalen; ///< Original length of packet - USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases, - ///< a padding could be added between the end of this structure and the packet - ///< data for performance reasons. This filed can be used to retrieve the actual data - ///< of the packet. -}; + * \brief Packet header. + * + * This structure defines the header associated with every packet delivered to the application. + */ + struct bpf_hdr + { + struct timeval bh_tstamp; /*/< The timestamp associated with the captured packet. */ + /*/< It is stored in a TimeVal structure. */ + UINT bh_caplen; /*/< Length of captured portion. The captured portion can be different */ + /*/< from the original packet, because it is possible (with a proper filter) */ + /*/< to instruct the driver to capture only a portion of the packets. */ + UINT bh_datalen; /*/< Original length of packet */ + USHORT bh_hdrlen; /*/< Length of bpf header (this struct plus alignment padding). In some cases, */ + /*/< a padding could be added between the end of this structure and the packet */ + /*/< data for performance reasons. This filed can be used to retrieve the actual data */ + /*/< of the packet. */ + }; /*! - \brief Dump packet header. - - This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). - It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a - packet in a dump file. This makes straightforward sending WinPcap dump files to the network. -*/ -struct dump_bpf_hdr{ - struct timeval ts; ///< Time stamp of the packet - UINT caplen; ///< Length of captured portion. The captured portion can smaller than the - ///< the original packet, because it is possible (with a proper filter) to - ///< instruct the driver to capture only a portion of the packets. - UINT len; ///< Length of the original packet (off wire). -}; + * \brief Dump packet header. + * + * This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). + * It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a + * packet in a dump file. This makes straightforward sending WinPcap dump files to the network. + */ + struct dump_bpf_hdr + { + struct timeval ts; /*/< Time stamp of the packet */ + UINT caplen; /*/< Length of captured portion. The captured portion can smaller than the */ + /*/< the original packet, because it is possible (with a proper filter) to */ + /*/< instruct the driver to capture only a portion of the packets. */ + UINT len; /*/< Length of the original packet (off wire). */ + }; -#endif + #endif /* ifndef BPF_MAJOR_VERSION */ -struct bpf_stat; + struct bpf_stat; -#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices -#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links -#define NMAX_PACKET 65535 + #define DOSNAMEPREFIX TEXT( "Packet_" ) /*/< Prefix added to the adapters device names to create the WinPcap devices */ + #define MAX_LINK_NAME_LENGTH 64 /*< Maximum length of the devices symbolic links */ + #define NMAX_PACKET 65535 /*! - \brief Addresses of a network adapter. - - This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with - an adapter. -*/ -typedef struct npf_if_addr { - struct sockaddr_storage IPAddress; ///< IP address. - struct sockaddr_storage SubnetMask; ///< Netmask for that address. - struct sockaddr_storage Broadcast; ///< Broadcast address. -}npf_if_addr; + * \brief Addresses of a network adapter. + * + * This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with + * an adapter. + */ + typedef struct npf_if_addr + { + struct sockaddr_storage IPAddress; /*/< IP address. */ + struct sockaddr_storage SubnetMask; /*/< Netmask for that address. */ + struct sockaddr_storage Broadcast; /*/< Broadcast address. */ + } npf_if_addr; -#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API. -#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API. -#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. -#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. + #define ADAPTER_NAME_LENGTH 256 + 12 /*/< Maximum length for the name of an adapter. The value is the same used by the IP Helper API. */ + #define ADAPTER_DESC_LENGTH 128 /*/< Maximum length for the description of an adapter. The value is the same used by the IP Helper API. */ + #define MAX_MAC_ADDR_LENGTH 8 /*/< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. */ + #define MAX_NETWORK_ADDRESSES 16 /*/< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. */ -typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API -typedef WAN_ADAPTER *PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API + typedef struct WAN_ADAPTER_INT WAN_ADAPTER; /*/< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API */ + typedef WAN_ADAPTER * PWAN_ADAPTER; /*/< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API */ -#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter -#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET -#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card -#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file -#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones. -#define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card -#define INFO_FLAG_NPFIM_DEVICE 32 + #define INFO_FLAG_NDIS_ADAPTER 0 /*/< Flag for ADAPTER_INFO: this is a traditional ndis adapter */ + #define INFO_FLAG_NDISWAN_ADAPTER 1 /*/< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET */ + #define INFO_FLAG_DAG_CARD 2 /*/< Flag for ADAPTER_INFO: this is a DAG card */ + #define INFO_FLAG_DAG_FILE 6 /*/< Flag for ADAPTER_INFO: this is a DAG file */ + #define INFO_FLAG_DONT_EXPORT 8 /*/< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones. */ + #define INFO_FLAG_AIRPCAP_CARD 16 /*/< Flag for ADAPTER_INFO: this is an airpcap card */ + #define INFO_FLAG_NPFIM_DEVICE 32 /*! - \brief Describes an opened network adapter. + * \brief Describes an opened network adapter. + * + * This structure is the most important for the functioning of packet.dll, but the great part of its fields + * should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters + */ + typedef struct _ADAPTER + { + HANDLE hFile; /*/< \internal Handle to an open instance of the NPF driver. */ + CHAR SymbolicLink[ MAX_LINK_NAME_LENGTH ]; /*/< \internal A string containing the name of the network adapter currently opened. */ + int NumWrites; /*/< \internal Number of times a packets written on this adapter will be repeated */ + /*/< on the wire. */ + HANDLE ReadEvent; /*/< A notification event associated with the read calls on the adapter. */ + /*/< It can be passed to standard Win32 functions (like WaitForSingleObject */ + /*/< or WaitForMultipleObjects) to wait until the driver's buffer contains some */ + /*/< data. It is particularly useful in GUI applications that need to wait */ + /*/< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() */ + /*/< function can be used to define the minimum amount of data in the kernel buffer */ + /*/< that will cause the event to be signalled. */ - This structure is the most important for the functioning of packet.dll, but the great part of its fields - should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters -*/ -typedef struct _ADAPTER { - HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver. - CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened. - int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated - ///< on the wire. - HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter. - ///< It can be passed to standard Win32 functions (like WaitForSingleObject - ///< or WaitForMultipleObjects) to wait until the driver's buffer contains some - ///< data. It is particularly useful in GUI applications that need to wait - ///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() - ///< function can be used to define the minimum amount of data in the kernel buffer - ///< that will cause the event to be signalled. - - UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and - ///< ReadEvent will be signaled, also if no packets were captured - CHAR Name[ADAPTER_NAME_LENGTH]; - PWAN_ADAPTER pWanAdapter; - UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. + UINT ReadTimeOut; /*/< \internal The amount of time after which a read on the driver will be released and */ + /*/< ReadEvent will be signaled, also if no packets were captured */ + CHAR Name[ ADAPTER_NAME_LENGTH ]; + PWAN_ADAPTER pWanAdapter; + UINT Flags; /*/< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. */ -#ifdef HAVE_AIRPCAP_API - PAirpcapHandle AirpcapAd; -#endif // HAVE_AIRPCAP_API + #ifdef HAVE_AIRPCAP_API + PAirpcapHandle AirpcapAd; + #endif // HAVE_AIRPCAP_API -#ifdef HAVE_NPFIM_API - void* NpfImHandle; -#endif // HAVE_NPFIM_API + #ifdef HAVE_NPFIM_API + void * NpfImHandle; + #endif // HAVE_NPFIM_API -#ifdef HAVE_DAG_API - dagc_t *pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter - PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card - struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure - unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry - DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps). -#endif // HAVE_DAG_API -} ADAPTER, *LPADAPTER; + #ifdef HAVE_DAG_API + dagc_t * pDagCard; /*/< Pointer to the dagc API adapter descriptor for this adapter */ + PCHAR DagBuffer; /*/< Pointer to the buffer with the packets that is received from the DAG card */ + struct timeval DagReadTimeout; /*/< Read timeout. The dagc API requires a timeval structure */ + unsigned DagFcsLen; /*/< Length of the frame check sequence attached to any packet by the card. Obtained from the registry */ + DWORD DagFastProcess; /*/< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps). */ + #endif // HAVE_DAG_API + } ADAPTER, * LPADAPTER; /*! - \brief Structure that contains a group of packets coming from the driver. - - This structure defines the header associated with every packet delivered to the application. -*/ -typedef struct _PACKET { - HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications. - OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications. - PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for - ///< details about the organization of the data in this buffer - UINT Length; ///< Length of the buffer - DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data - ///< received by the last call to PacketReceivePacket() - BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications. -} PACKET, *LPPACKET; + * \brief Structure that contains a group of packets coming from the driver. + * + * This structure defines the header associated with every packet delivered to the application. + */ + typedef struct _PACKET + { + HANDLE hEvent; /*/< \deprecated Still present for compatibility with old applications. */ + OVERLAPPED OverLapped; /*/< \deprecated Still present for compatibility with old applications. */ + PVOID Buffer; /*/< Buffer with containing the packets. See the PacketReceivePacket() for */ + /*/< details about the organization of the data in this buffer */ + UINT Length; /*/< Length of the buffer */ + DWORD ulBytesReceived; /*/< Number of valid bytes present in the buffer, i.e. amount of data */ + /*/< received by the last call to PacketReceivePacket() */ + BOOLEAN bIoComplete; /*/< \deprecated Still present for compatibility with old applications. */ + } PACKET, * LPPACKET; /*! - \brief Structure containing an OID request. + * \brief Structure containing an OID request. + * + * It is used by the PacketRequest() function to send an OID to the interface card driver. + * It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, + * the list of the multicast groups defined on it, and so on. + */ + struct _PACKET_OID_DATA + { + ULONG Oid; /*/< OID code. See the Microsoft DDK documentation or the file ntddndis.h */ + /*/< for a complete list of valid codes. */ + ULONG Length; /*/< Length of the data field */ + UCHAR Data[ 1 ]; /*/< variable-length field that contains the information passed to or received */ + /*/< from the adapter. */ + }; + typedef struct _PACKET_OID_DATA PACKET_OID_DATA, * PPACKET_OID_DATA; - It is used by the PacketRequest() function to send an OID to the interface card driver. - It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, - the list of the multicast groups defined on it, and so on. -*/ -struct _PACKET_OID_DATA { - ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h - ///< for a complete list of valid codes. - ULONG Length; ///< Length of the data field - UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received - ///< from the adapter. -}; -typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; - -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /** * @} */ /* -BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, - CHAR *Value, - UINT *pValueLen, - CHAR *DefaultVal); + * BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, + * CHAR *Value, + * UINT *pValueLen, + * CHAR *DefaultVal); + * + * BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, + * WCHAR *Value, + * UINT *pValueLen, + * WCHAR *DefaultVal); + */ -BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, - WCHAR *Value, - UINT *pValueLen, - WCHAR *DefaultVal); -*/ - -//--------------------------------------------------------------------------- -// EXPORTED FUNCTIONS -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- */ +/* EXPORTED FUNCTIONS */ +/*--------------------------------------------------------------------------- */ -PCHAR PacketGetVersion(); -PCHAR PacketGetDriverVersion(); -BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes); -BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites); -BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode); -BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout); -BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp); -BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior); -INT PacketSetSnapLen(LPADAPTER AdapterObject,int snaplen); -BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s); -BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s); -BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim); -BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type); -LPADAPTER PacketOpenAdapter(PCHAR AdapterName); -BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync); -INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync); -LPPACKET PacketAllocatePacket(void); -VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length); -VOID PacketFreePacket(LPPACKET lpPacket); -BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync); -BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter); -BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize); -BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries); -BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData); -HANDLE PacketGetReadEvent(LPADAPTER AdapterObject); -BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len); -BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks); -BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync); -BOOL PacketStopDriver(); -VOID PacketCloseAdapter(LPADAPTER lpAdapter); -BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength); -BOOLEAN PacketStartOemEx(PCHAR errorString, UINT errorStringLength, ULONG flags); -PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject); + PCHAR PacketGetVersion(); + PCHAR PacketGetDriverVersion(); + BOOLEAN PacketSetMinToCopy( LPADAPTER AdapterObject, + int nbytes ); + BOOLEAN PacketSetNumWrites( LPADAPTER AdapterObject, + int nwrites ); + BOOLEAN PacketSetMode( LPADAPTER AdapterObject, + int mode ); + BOOLEAN PacketSetReadTimeout( LPADAPTER AdapterObject, + int timeout ); + BOOLEAN PacketSetBpf( LPADAPTER AdapterObject, + struct bpf_program * fp ); + BOOLEAN PacketSetLoopbackBehavior( LPADAPTER AdapterObject, + UINT LoopbackBehavior ); + INT PacketSetSnapLen( LPADAPTER AdapterObject, + int snaplen ); + BOOLEAN PacketGetStats( LPADAPTER AdapterObject, + struct bpf_stat * s ); + BOOLEAN PacketGetStatsEx( LPADAPTER AdapterObject, + struct bpf_stat * s ); + BOOLEAN PacketSetBuff( LPADAPTER AdapterObject, + int dim ); + BOOLEAN PacketGetNetType( LPADAPTER AdapterObject, + NetType * type ); + LPADAPTER PacketOpenAdapter( PCHAR AdapterName ); + BOOLEAN PacketSendPacket( LPADAPTER AdapterObject, + LPPACKET pPacket, + BOOLEAN Sync ); + INT PacketSendPackets( LPADAPTER AdapterObject, + PVOID PacketBuff, + ULONG Size, + BOOLEAN Sync ); + LPPACKET PacketAllocatePacket( void ); + VOID PacketInitPacket( LPPACKET lpPacket, + PVOID Buffer, + UINT Length ); + VOID PacketFreePacket( LPPACKET lpPacket ); + BOOLEAN PacketReceivePacket( LPADAPTER AdapterObject, + LPPACKET lpPacket, + BOOLEAN Sync ); + BOOLEAN PacketSetHwFilter( LPADAPTER AdapterObject, + ULONG Filter ); + BOOLEAN PacketGetAdapterNames( PTSTR pStr, + PULONG BufferSize ); + BOOLEAN PacketGetNetInfoEx( PCHAR AdapterName, + npf_if_addr * buffer, + PLONG NEntries ); + BOOLEAN PacketRequest( LPADAPTER AdapterObject, + BOOLEAN Set, + PPACKET_OID_DATA OidData ); + HANDLE PacketGetReadEvent( LPADAPTER AdapterObject ); + BOOLEAN PacketSetDumpName( LPADAPTER AdapterObject, + void * name, + int len ); + BOOLEAN PacketSetDumpLimits( LPADAPTER AdapterObject, + UINT maxfilesize, + UINT maxnpacks ); + BOOLEAN PacketIsDumpEnded( LPADAPTER AdapterObject, + BOOLEAN sync ); + BOOL PacketStopDriver(); + VOID PacketCloseAdapter( LPADAPTER lpAdapter ); + BOOLEAN PacketStartOem( PCHAR errorString, + UINT errorStringLength ); + BOOLEAN PacketStartOemEx( PCHAR errorString, + UINT errorStringLength, + ULONG flags ); + PAirpcapHandle PacketGetAirPcapHandle( LPADAPTER AdapterObject ); -// -// Used by PacketStartOemEx -// -#define PACKET_START_OEM_NO_NETMON 0x00000001 +/* */ +/* Used by PacketStartOemEx */ +/* */ + #define PACKET_START_OEM_NO_NETMON 0x00000001 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif //__PACKET32 diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/Win32-Extensions.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/Win32-Extensions.h index ad3be25cf..76722c875 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/Win32-Extensions.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/Win32-Extensions.h @@ -12,9 +12,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino, CACE Technologies - * nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,82 +32,95 @@ */ #ifndef __WIN32_EXTENSIONS_H__ -#define __WIN32_EXTENSIONS_H__ + #define __WIN32_EXTENSIONS_H__ -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* Definitions */ /*! - \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). -*/ -struct pcap_send_queue -{ - u_int maxlen; ///< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. - u_int len; ///< Current size of the queue, in bytes. - char *buffer; ///< Buffer containing the packets to be sent. -}; + * \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). + */ + struct pcap_send_queue + { + u_int maxlen; /*/< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. */ + u_int len; /*/< Current size of the queue, in bytes. */ + char * buffer; /*/< Buffer containing the packets to be sent. */ + }; -typedef struct pcap_send_queue pcap_send_queue; + typedef struct pcap_send_queue pcap_send_queue; /*! - \brief This typedef is a support for the pcap_get_airpcap_handle() function -*/ -#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) -#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ -typedef struct _AirpcapHandle *PAirpcapHandle; -#endif + * \brief This typedef is a support for the pcap_get_airpcap_handle() function + */ + #if !defined( AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ ) + #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ + typedef struct _AirpcapHandle * PAirpcapHandle; + #endif -#define BPF_MEM_EX_IMM 0xc0 -#define BPF_MEM_EX_IND 0xe0 + #define BPF_MEM_EX_IMM 0xc0 + #define BPF_MEM_EX_IND 0xe0 /*used for ST*/ -#define BPF_MEM_EX 0xc0 -#define BPF_TME 0x08 + #define BPF_MEM_EX 0xc0 + #define BPF_TME 0x08 -#define BPF_LOOKUP 0x90 -#define BPF_EXECUTE 0xa0 -#define BPF_INIT 0xb0 -#define BPF_VALIDATE 0xc0 -#define BPF_SET_ACTIVE 0xd0 -#define BPF_RESET 0xe0 -#define BPF_SET_MEMORY 0x80 -#define BPF_GET_REGISTER_VALUE 0x70 -#define BPF_SET_REGISTER_VALUE 0x60 -#define BPF_SET_WORKING 0x50 -#define BPF_SET_ACTIVE_READ 0x40 -#define BPF_SET_AUTODELETION 0x30 -#define BPF_SEPARATION 0xff + #define BPF_LOOKUP 0x90 + #define BPF_EXECUTE 0xa0 + #define BPF_INIT 0xb0 + #define BPF_VALIDATE 0xc0 + #define BPF_SET_ACTIVE 0xd0 + #define BPF_RESET 0xe0 + #define BPF_SET_MEMORY 0x80 + #define BPF_GET_REGISTER_VALUE 0x70 + #define BPF_SET_REGISTER_VALUE 0x60 + #define BPF_SET_WORKING 0x50 + #define BPF_SET_ACTIVE_READ 0x40 + #define BPF_SET_AUTODELETION 0x30 + #define BPF_SEPARATION 0xff /* Prototypes */ -pcap_send_queue* pcap_sendqueue_alloc(u_int memsize); + pcap_send_queue * pcap_sendqueue_alloc( u_int memsize ); -void pcap_sendqueue_destroy(pcap_send_queue* queue); + void pcap_sendqueue_destroy( pcap_send_queue * queue ); -int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); + int pcap_sendqueue_queue( pcap_send_queue * queue, + const struct pcap_pkthdr * pkt_header, + const u_char * pkt_data ); -u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync); + u_int pcap_sendqueue_transmit( pcap_t * p, + pcap_send_queue * queue, + int sync ); -HANDLE pcap_getevent(pcap_t *p); + HANDLE pcap_getevent( pcap_t * p ); -struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size); + struct pcap_stat * pcap_stats_ex( pcap_t * p, + int * pcap_stat_size ); -int pcap_setuserbuffer(pcap_t *p, int size); + int pcap_setuserbuffer( pcap_t * p, + int size ); -int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks); + int pcap_live_dump( pcap_t * p, + char * filename, + int maxsize, + int maxpacks ); -int pcap_live_dump_ended(pcap_t *p, int sync); + int pcap_live_dump_ended( pcap_t * p, + int sync ); -int pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data); + int pcap_offline_filter( struct bpf_program * prog, + const struct pcap_pkthdr * header, + const u_char * pkt_data ); -int pcap_start_oem(char* err_str, int flags); + int pcap_start_oem( char * err_str, + int flags ); -PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); + PAirpcapHandle pcap_get_airpcap_handle( pcap_t * p ); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif #endif //__WIN32_EXTENSIONS_H__ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/bittypes.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/bittypes.h index 558a0b5c0..868c73fcd 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/bittypes.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/bittypes.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,107 +31,107 @@ #ifndef HAVE_U_INT8_T -#if SIZEOF_CHAR == 1 -typedef unsigned char u_int8_t; -typedef signed char int8_t; -#elif SIZEOF_INT == 1 -typedef unsigned int u_int8_t; -typedef signed int int8_t; -#else /* XXX */ -#error "there's no appropriate type for u_int8_t" -#endif -#define HAVE_U_INT8_T 1 -#define HAVE_INT8_T 1 + #if SIZEOF_CHAR == 1 + typedef unsigned char u_int8_t; + typedef signed char int8_t; + #elif SIZEOF_INT == 1 + typedef unsigned int u_int8_t; + typedef signed int int8_t; + #else /* XXX */ + #error "there's no appropriate type for u_int8_t" + #endif + #define HAVE_U_INT8_T 1 + #define HAVE_INT8_T 1 #endif /* HAVE_U_INT8_T */ -#ifndef HAVE_U_INT16_T +#ifndef HAVE_U_INT16_T -#if SIZEOF_SHORT == 2 -typedef unsigned short u_int16_t; -typedef signed short int16_t; -#elif SIZEOF_INT == 2 -typedef unsigned int u_int16_t; -typedef signed int int16_t; -#elif SIZEOF_CHAR == 2 -typedef unsigned char u_int16_t; -typedef signed char int16_t; -#else /* XXX */ -#error "there's no appropriate type for u_int16_t" -#endif -#define HAVE_U_INT16_T 1 -#define HAVE_INT16_T 1 + #if SIZEOF_SHORT == 2 + typedef unsigned short u_int16_t; + typedef signed short int16_t; + #elif SIZEOF_INT == 2 + typedef unsigned int u_int16_t; + typedef signed int int16_t; + #elif SIZEOF_CHAR == 2 + typedef unsigned char u_int16_t; + typedef signed char int16_t; + #else /* XXX */ + #error "there's no appropriate type for u_int16_t" + #endif /* if SIZEOF_SHORT == 2 */ + #define HAVE_U_INT16_T 1 + #define HAVE_INT16_T 1 #endif /* HAVE_U_INT16_T */ #ifndef HAVE_U_INT32_T -#if SIZEOF_INT == 4 -typedef unsigned int u_int32_t; -typedef signed int int32_t; -#elif SIZEOF_LONG == 4 -typedef unsigned long u_int32_t; -typedef signed long int32_t; -#elif SIZEOF_SHORT == 4 -typedef unsigned short u_int32_t; -typedef signed short int32_t; -#else /* XXX */ -#error "there's no appropriate type for u_int32_t" -#endif -#define HAVE_U_INT32_T 1 -#define HAVE_INT32_T 1 + #if SIZEOF_INT == 4 + typedef unsigned int u_int32_t; + typedef signed int int32_t; + #elif SIZEOF_LONG == 4 + typedef unsigned long u_int32_t; + typedef signed long int32_t; + #elif SIZEOF_SHORT == 4 + typedef unsigned short u_int32_t; + typedef signed short int32_t; + #else /* XXX */ + #error "there's no appropriate type for u_int32_t" + #endif /* if SIZEOF_INT == 4 */ + #define HAVE_U_INT32_T 1 + #define HAVE_INT32_T 1 #endif /* HAVE_U_INT32_T */ #ifndef HAVE_U_INT64_T -#if SIZEOF_LONG_LONG == 8 -typedef unsigned long long u_int64_t; -typedef long long int64_t; -#elif defined(_MSC_EXTENSIONS) -typedef unsigned _int64 u_int64_t; -typedef _int64 int64_t; -#elif SIZEOF_INT == 8 -typedef unsigned int u_int64_t; -#elif SIZEOF_LONG == 8 -typedef unsigned long u_int64_t; -#elif SIZEOF_SHORT == 8 -typedef unsigned short u_int64_t; -#else /* XXX */ -#error "there's no appropriate type for u_int64_t" -#endif + #if SIZEOF_LONG_LONG == 8 + typedef unsigned long long u_int64_t; + typedef long long int64_t; + #elif defined( _MSC_EXTENSIONS ) + typedef unsigned _int64 u_int64_t; + typedef _int64 int64_t; + #elif SIZEOF_INT == 8 + typedef unsigned int u_int64_t; + #elif SIZEOF_LONG == 8 + typedef unsigned long u_int64_t; + #elif SIZEOF_SHORT == 8 + typedef unsigned short u_int64_t; + #else /* XXX */ + #error "there's no appropriate type for u_int64_t" + #endif /* if SIZEOF_LONG_LONG == 8 */ #endif /* HAVE_U_INT64_T */ #ifndef PRId64 -#ifdef _MSC_EXTENSIONS -#define PRId64 "I64d" -#else /* _MSC_EXTENSIONS */ -#define PRId64 "lld" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRId64 "I64d" + #else /* _MSC_EXTENSIONS */ + #define PRId64 "lld" + #endif /* _MSC_EXTENSIONS */ #endif /* PRId64 */ #ifndef PRIo64 -#ifdef _MSC_EXTENSIONS -#define PRIo64 "I64o" -#else /* _MSC_EXTENSIONS */ -#define PRIo64 "llo" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRIo64 "I64o" + #else /* _MSC_EXTENSIONS */ + #define PRIo64 "llo" + #endif /* _MSC_EXTENSIONS */ #endif /* PRIo64 */ #ifndef PRIx64 -#ifdef _MSC_EXTENSIONS -#define PRIx64 "I64x" -#else /* _MSC_EXTENSIONS */ -#define PRIx64 "llx" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRIx64 "I64x" + #else /* _MSC_EXTENSIONS */ + #define PRIx64 "llx" + #endif /* _MSC_EXTENSIONS */ #endif /* PRIx64 */ #ifndef PRIu64 -#ifdef _MSC_EXTENSIONS -#define PRIu64 "I64u" -#else /* _MSC_EXTENSIONS */ -#define PRIu64 "llu" -#endif /* _MSC_EXTENSIONS */ + #ifdef _MSC_EXTENSIONS + #define PRIu64 "I64u" + #else /* _MSC_EXTENSIONS */ + #define PRIu64 "llu" + #endif /* _MSC_EXTENSIONS */ #endif /* PRIu64 */ #endif /* _BITTYPES_H */ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/ip6_misc.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/ip6_misc.h index 562fa6184..1b2e4337b 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/ip6_misc.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/ip6_misc.h @@ -30,134 +30,136 @@ #include #ifndef __MINGW32__ -#define IN_MULTICAST(a) IN_CLASSD(a) + #define IN_MULTICAST( a ) IN_CLASSD( a ) #endif -#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xf0000000) == 0xf0000000) +#define IN_EXPERIMENTAL( a ) ( ( ( ( u_int32_t ) ( a ) ) & 0xf0000000 ) == 0xf0000000 ) -#define IN_LOOPBACKNET 127 +#define IN_LOOPBACKNET 127 -#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) +#if defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) /* IPv6 address */ -struct in6_addr - { - union - { - u_int8_t u6_addr8[16]; - u_int16_t u6_addr16[8]; - u_int32_t u6_addr32[4]; - } in6_u; -#define s6_addr in6_u.u6_addr8 -#define s6_addr16 in6_u.u6_addr16 -#define s6_addr32 in6_u.u6_addr32 -#define s6_addr64 in6_u.u6_addr64 - }; + struct in6_addr + { + union + { + u_int8_t u6_addr8[ 16 ]; + u_int16_t u6_addr16[ 8 ]; + u_int32_t u6_addr32[ 4 ]; + } + in6_u; + #define s6_addr in6_u.u6_addr8 + #define s6_addr16 in6_u.u6_addr16 + #define s6_addr32 in6_u.u6_addr32 + #define s6_addr64 in6_u.u6_addr64 + }; -#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } + #define IN6ADDR_ANY_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + #define IN6ADDR_LOOPBACK_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } #endif /* __MINGW32__ */ -#if (defined _MSC_VER) || (defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)) -typedef unsigned short sa_family_t; +#if ( defined _MSC_VER ) || ( defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) ) + typedef unsigned short sa_family_t; #endif -#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) +#if defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) -#define __SOCKADDR_COMMON(sa_prefix) \ - sa_family_t sa_prefix##family + #define __SOCKADDR_COMMON( sa_prefix ) \ + sa_family_t sa_prefix ## family /* Ditto, for IPv6. */ -struct sockaddr_in6 - { - __SOCKADDR_COMMON (sin6_); - u_int16_t sin6_port; /* Transport layer port # */ - u_int32_t sin6_flowinfo; /* IPv6 flow information */ - struct in6_addr sin6_addr; /* IPv6 address */ - }; + struct sockaddr_in6 + { + __SOCKADDR_COMMON( sin6_ ); + u_int16_t sin6_port; /* Transport layer port # */ + u_int32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + }; -#define IN6_IS_ADDR_V4MAPPED(a) \ - ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ - (((u_int32_t *) (a))[2] == htonl (0xffff))) + #define IN6_IS_ADDR_V4MAPPED( a ) \ + ( ( ( ( u_int32_t * ) ( a ) )[ 0 ] == 0 ) && ( ( ( u_int32_t * ) ( a ) )[ 1 ] == 0 ) && \ + ( ( ( u_int32_t * ) ( a ) )[ 2 ] == htonl( 0xffff ) ) ) -#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff) + #define IN6_IS_ADDR_MULTICAST( a ) ( ( ( u_int8_t * ) ( a ) )[ 0 ] == 0xff ) -#define IN6_IS_ADDR_LINKLOCAL(a) \ - ((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000)) + #define IN6_IS_ADDR_LINKLOCAL( a ) \ + ( ( ( ( u_int32_t * ) ( a ) )[ 0 ] & htonl( 0xffc00000 ) ) == htonl( 0xfe800000 ) ) -#define IN6_IS_ADDR_LOOPBACK(a) \ - (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ - ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) + #define IN6_IS_ADDR_LOOPBACK( a ) \ + ( ( ( u_int32_t * ) ( a ) )[ 0 ] == 0 && ( ( u_int32_t * ) ( a ) )[ 1 ] == 0 && \ + ( ( u_int32_t * ) ( a ) )[ 2 ] == 0 && ( ( u_int32_t * ) ( a ) )[ 3 ] == htonl( 1 ) ) #endif /* __MINGW32__ */ -#define ip6_vfc ip6_ctlun.ip6_un2_vfc -#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow -#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen -#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt -#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim -#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim +#define ip6_vfc ip6_ctlun.ip6_un2_vfc +#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow +#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen +#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt +#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim +#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim #define nd_rd_type nd_rd_hdr.icmp6_type #define nd_rd_code nd_rd_hdr.icmp6_code #define nd_rd_cksum nd_rd_hdr.icmp6_cksum -#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] +#define nd_rd_reserved nd_rd_hdr.icmp6_data32[ 0 ] /* * IPV6 extension headers */ -#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ -#define IPPROTO_IPV6 41 /* IPv6 header. */ -#define IPPROTO_ROUTING 43 /* IPv6 routing header */ -#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ -#define IPPROTO_ESP 50 /* encapsulating security payload */ -#define IPPROTO_AH 51 /* authentication header */ -#define IPPROTO_ICMPV6 58 /* ICMPv6 */ -#define IPPROTO_NONE 59 /* IPv6 no next header */ -#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ -#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */ +#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ +#define IPPROTO_IPV6 41 /* IPv6 header. */ +#define IPPROTO_ROUTING 43 /* IPv6 routing header */ +#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ +#define IPPROTO_ESP 50 /* encapsulating security payload */ +#define IPPROTO_AH 51 /* authentication header */ +#define IPPROTO_ICMPV6 58 /* ICMPv6 */ +#define IPPROTO_NONE 59 /* IPv6 no next header */ +#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ +#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */ -#define IPV6_RTHDR_TYPE_0 0 +#define IPV6_RTHDR_TYPE_0 0 /* Option types and related macros */ -#define IP6OPT_PAD1 0x00 /* 00 0 00000 */ -#define IP6OPT_PADN 0x01 /* 00 0 00001 */ -#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ -#define IP6OPT_JUMBO_LEN 6 -#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ +#define IP6OPT_PAD1 0x00 /* 00 0 00000 */ +#define IP6OPT_PADN 0x01 /* 00 0 00001 */ +#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ +#define IP6OPT_JUMBO_LEN 6 +#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ -#define IP6OPT_RTALERT_LEN 4 -#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ -#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ -#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ -#define IP6OPT_MINLEN 2 +#define IP6OPT_RTALERT_LEN 4 +#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ +#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ +#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ +#define IP6OPT_MINLEN 2 -#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ -#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ -#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ -#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ -#define IP6OPT_EID 0x8a /* 10 0 01010 */ +#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ +#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ +#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ +#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ +#define IP6OPT_EID 0x8a /* 10 0 01010 */ -#define IP6OPT_TYPE(o) ((o) & 0xC0) -#define IP6OPT_TYPE_SKIP 0x00 -#define IP6OPT_TYPE_DISCARD 0x40 -#define IP6OPT_TYPE_FORCEICMP 0x80 -#define IP6OPT_TYPE_ICMP 0xC0 +#define IP6OPT_TYPE( o ) ( ( o ) & 0xC0 ) +#define IP6OPT_TYPE_SKIP 0x00 +#define IP6OPT_TYPE_DISCARD 0x40 +#define IP6OPT_TYPE_FORCEICMP 0x80 +#define IP6OPT_TYPE_ICMP 0xC0 -#define IP6OPT_MUTABLE 0x20 +#define IP6OPT_MUTABLE 0x20 -#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) -#ifndef EAI_ADDRFAMILY -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -#endif +#if defined( __MINGW32__ ) && defined( DEFINE_ADDITIONAL_IPV6_STUFF ) + #ifndef EAI_ADDRFAMILY + struct addrinfo + { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char * ai_canonname; /* canonical name for hostname */ + struct sockaddr * ai_addr; /* binary address */ + struct addrinfo * ai_next; /* next structure in linked list */ + }; + #endif /* ifndef EAI_ADDRFAMILY */ #endif /* __MINGW32__ */ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap-bpf.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap-bpf.h index 5fe129dbb..2657827e0 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap-bpf.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap-bpf.h @@ -4,7 +4,7 @@ * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap-stdinc.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap-stdinc.h index 6ccfd95c2..7a04bc85d 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap-stdinc.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap-stdinc.h @@ -31,20 +31,20 @@ * @(#) $Header: /tcpdump/master/libpcap/pcap-stdinc.h,v 1.10.2.1 2008-10-06 15:38:39 gianluca Exp $ (LBL) */ -#define SIZEOF_CHAR 1 -#define SIZEOF_SHORT 2 -#define SIZEOF_INT 4 +#define SIZEOF_CHAR 1 +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 #ifndef _MSC_EXTENSIONS -#define SIZEOF_LONG_LONG 8 + #define SIZEOF_LONG_LONG 8 #endif /* - * Avoids a compiler warning in case this was already defined + * Avoids a compiler warning in case this was already defined * (someone defined _WINSOCKAPI_ when including 'windows.h', in order * to prevent it from including 'winsock.h') */ #ifdef _WINSOCKAPI_ -#undef _WINSOCKAPI_ + #undef _WINSOCKAPI_ #endif #include @@ -55,39 +55,39 @@ #include #ifndef __MINGW32__ -#include "ip6_misc.h" + #include "ip6_misc.h" #endif -#define caddr_t char* +#define caddr_t char * #if _MSC_VER < 1500 -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define strdup _strdup + #define snprintf _snprintf + #define vsnprintf _vsnprintf + #define strdup _strdup #endif -#define inline __inline +#define inline __inline #ifdef __MINGW32__ -#include + #include #else /*__MINGW32__*/ /* MSVC compiler */ -#ifndef _UINTPTR_T_DEFINED -#ifdef _WIN64 -typedef unsigned __int64 uintptr_t; -#else -typedef _W64 unsigned int uintptr_t; -#endif -#define _UINTPTR_T_DEFINED -#endif + #ifndef _UINTPTR_T_DEFINED + #ifdef _WIN64 + typedef unsigned __int64 uintptr_t; + #else + typedef _W64 unsigned int uintptr_t; + #endif + #define _UINTPTR_T_DEFINED + #endif -#ifndef _INTPTR_T_DEFINED -#ifdef _WIN64 -typedef __int64 intptr_t; -#else -typedef _W64 int intptr_t; -#endif -#define _INTPTR_T_DEFINED -#endif + #ifndef _INTPTR_T_DEFINED + #ifdef _WIN64 + typedef __int64 intptr_t; + #else + typedef _W64 int intptr_t; + #endif + #define _INTPTR_T_DEFINED + #endif #endif /*__MINGW32__*/ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/bluetooth.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/bluetooth.h index 7bf65df03..05332a3a5 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/bluetooth.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/bluetooth.h @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,7 +32,7 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/bluetooth.h,v 1.1 2007/09/22 02:10:17 guy Exp $ */ - + #ifndef _PCAP_BLUETOOTH_STRUCTS_H__ #define _PCAP_BLUETOOTH_STRUCTS_H__ @@ -40,8 +40,9 @@ * Header prepended libpcap to each bluetooth h:4 frame. * fields are in network byte order */ -typedef struct _pcap_bluetooth_h4_header { - u_int32_t direction; /* if first bit is set direction is incoming */ +typedef struct _pcap_bluetooth_h4_header +{ + u_int32_t direction; /* if first bit is set direction is incoming */ } pcap_bluetooth_h4_header; diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/bpf.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/bpf.h index 9f4ca33e3..d53a87b2f 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/bpf.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/bpf.h @@ -4,7 +4,7 @@ * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without @@ -53,45 +53,46 @@ #ifndef BPF_MAJOR_VERSION -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* BSD style release date */ -#define BPF_RELEASE 199606 + #define BPF_RELEASE 199606 -#ifdef MSDOS /* must be 32-bit */ -typedef long bpf_int32; -typedef unsigned long bpf_u_int32; -#else -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #ifdef MSDOS /* must be 32-bit */ + typedef long bpf_int32; + typedef unsigned long bpf_u_int32; + #else + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif /* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + #ifndef __NetBSD__ + #define BPF_ALIGNMENT sizeof( bpf_int32 ) + #else + #define BPF_ALIGNMENT sizeof( long ) + #endif + #define BPF_WORDALIGN( x ) ( ( ( x ) + ( BPF_ALIGNMENT - 1 ) ) & ~( BPF_ALIGNMENT - 1 ) ) -#define BPF_MAXBUFSIZE 0x8000 -#define BPF_MINBUFSIZE 32 + #define BPF_MAXBUFSIZE 0x8000 + #define BPF_MINBUFSIZE 32 /* * Structure for "pcap_compile()", "pcap_setfilter()", etc.. */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - + struct bpf_program + { + u_int bf_len; + struct bpf_insn * bf_insns; + }; + /* - * Struct return by BIOCVERSION. This represents the version number of + * Struct return by BIOCVERSION. This represents the version number of * the filter language described by the instruction encodings below. * bpf understands a program iff kernel_major == filter_major && * kernel_minor >= filter_minor, that is, if the value returned by the @@ -101,13 +102,14 @@ struct bpf_program { * may be accepted haphazardly. * It has nothing to do with the source code version. */ -struct bpf_version { - u_short bv_major; - u_short bv_minor; -}; + struct bpf_version + { + u_short bv_major; + u_short bv_minor; + }; /* Current version number of filter architecture. */ -#define BPF_MAJOR_VERSION 1 -#define BPF_MINOR_VERSION 1 + #define BPF_MAJOR_VERSION 1 + #define BPF_MINOR_VERSION 1 /* * Data-link level type codes. @@ -125,17 +127,17 @@ struct bpf_version { * These are the types that are the same on all platforms, and that * have been defined by for ages. */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* 802.5 Token Ring */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ + #define DLT_NULL 0 /* BSD loopback encapsulation */ + #define DLT_EN10MB 1 /* Ethernet (10Mb) */ + #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ + #define DLT_AX25 3 /* Amateur Radio AX.25 */ + #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ + #define DLT_CHAOS 5 /* Chaos */ + #define DLT_IEEE802 6 /* 802.5 Token Ring */ + #define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ + #define DLT_SLIP 8 /* Serial Line IP */ + #define DLT_PPP 9 /* Point-to-point Protocol */ + #define DLT_FDDI 10 /* FDDI */ /* * These are types that are different on some platforms, and that @@ -146,13 +148,13 @@ struct bpf_version { * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, * but I don't know what the right #define is for BSD/OS. */ -#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + #define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif + #ifdef __OpenBSD__ + #define DLT_RAW 14 /* raw IP */ + #else + #define DLT_RAW 12 /* raw IP */ + #endif /* * Given that the only OS that currently generates BSD/OS SLIP or PPP @@ -160,15 +162,15 @@ struct bpf_version { * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they * didn't. So it goes. */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif + #if defined( __NetBSD__ ) || defined( __FreeBSD__ ) + #ifndef DLT_SLIP_BSDOS + #define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ + #endif + #else + #define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ + #define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ + #endif /* * 17 is used for DLT_OLD_PFLOG in OpenBSD; @@ -176,21 +178,21 @@ struct bpf_version { * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. */ -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + #define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ /* * Apparently Redback uses this for its SmartEdge 400/800. I hope * nobody else decided to use it, too. */ -#define DLT_REDBACK_SMARTEDGE 32 + #define DLT_REDBACK_SMARTEDGE 32 /* * These values are defined by NetBSD; other platforms should refrain from * using them for other purposes, so that NetBSD savefiles with link * types of 50 or 51 can be read as this type on all platforms. */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + #define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ + #define DLT_PPP_ETHER 51 /* PPP over Ethernet */ /* * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses @@ -199,7 +201,7 @@ struct bpf_version { * Ethernet type, and 36 bytes that appear to be 0 in at least one capture * I've seen. */ -#define DLT_SYMANTEC_FIREWALL 99 + #define DLT_SYMANTEC_FIREWALL 99 /* * Values between 100 and 103 are used in capture file headers as @@ -221,10 +223,10 @@ struct bpf_version { * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, * for source compatibility with programs written for libpcap 0.5. */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC + #define DLT_C_HDLC 104 /* Cisco HDLC */ + #define DLT_CHDLC DLT_C_HDLC -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + #define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ /* * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, @@ -239,7 +241,7 @@ struct bpf_version { * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header * (DLCI, etc.). */ -#define DLT_FRELAY 107 + #define DLT_FRELAY 107 /* * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except @@ -248,22 +250,22 @@ struct bpf_version { * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so * we don't use 12 for it in OSes other than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_LOOP 12 -#else -#define DLT_LOOP 108 -#endif + #ifdef __OpenBSD__ + #define DLT_LOOP 12 + #else + #define DLT_LOOP 108 + #endif /* * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other * than OpenBSD. */ -#ifdef __OpenBSD__ -#define DLT_ENC 13 -#else -#define DLT_ENC 109 -#endif + #ifdef __OpenBSD__ + #define DLT_ENC 13 + #else + #define DLT_ENC 109 + #endif /* * Values between 110 and 112 are reserved for use in capture file headers @@ -275,22 +277,22 @@ struct bpf_version { /* * This is for Linux cooked sockets. */ -#define DLT_LINUX_SLL 113 + #define DLT_LINUX_SLL 113 /* * Apple LocalTalk hardware. */ -#define DLT_LTALK 114 + #define DLT_LTALK 114 /* * Acorn Econet. */ -#define DLT_ECONET 115 + #define DLT_ECONET 115 /* * Reserved for use with OpenBSD ipfilter. */ -#define DLT_IPFILTER 116 + #define DLT_IPFILTER 116 /* * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 @@ -298,34 +300,34 @@ struct bpf_version { * * XXX: is there a conflict with DLT_PFSYNC 18 as well? */ -#ifdef __OpenBSD__ -#define DLT_OLD_PFLOG 17 -#define DLT_PFSYNC 18 -#endif -#define DLT_PFLOG 117 + #ifdef __OpenBSD__ + #define DLT_OLD_PFLOG 17 + #define DLT_PFSYNC 18 + #endif + #define DLT_PFLOG 117 /* * Registered for Cisco-internal use. */ -#define DLT_CISCO_IOS 118 + #define DLT_CISCO_IOS 118 /* * For 802.11 cards using the Prism II chips, with a link-layer * header including Prism monitor mode information plus an 802.11 * header. */ -#define DLT_PRISM_HEADER 119 + #define DLT_PRISM_HEADER 119 /* * Reserved for Aironet 802.11 cards, with an Aironet link-layer header * (see Doug Ambrisko's FreeBSD patches). */ -#define DLT_AIRONET_HEADER 120 + #define DLT_AIRONET_HEADER 120 /* * Reserved for Siemens HiPath HDLC. */ -#define DLT_HHDLC 121 + #define DLT_HHDLC 121 /* * This is for RFC 2625 IP-over-Fibre Channel. @@ -335,7 +337,7 @@ struct bpf_version { * where the link-layer header starts with an RFC 2625 Network_Header * field. */ -#define DLT_IP_OVER_FC 122 + #define DLT_IP_OVER_FC 122 /* * This is for Full Frontal ATM on Solaris with SunATM, with a @@ -351,22 +353,22 @@ struct bpf_version { * and the like don't have to infer the presence or absence of a * pseudo-header and the form of the pseudo-header. */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ + #define DLT_SUNATM 123 /* Solaris+SunATM */ -/* +/* * Reserved as per request from Kent Dahlgren * for private use. */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + #define DLT_RIO 124 /* RapidIO */ + #define DLT_PCI_EXP 125 /* PCI Express */ + #define DLT_AURORA 126 /* Xilinx Aurora link layer */ /* * Header for 802.11 plus a number of bits of link-layer information * including radio information, used by some recent BSD drivers as * well as the madwifi Atheros driver for Linux. */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + #define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ /* * Reserved for the TZSP encapsulation, as per request from @@ -376,7 +378,7 @@ struct bpf_version { * with the packet, e.g. signal strength and channel * for 802.11 packets. */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + #define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ /* * BSD's ARCNET headers have the source host, destination host, @@ -389,7 +391,7 @@ struct bpf_version { * * We therefore have to have separate DLT_ values for them. */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ + #define DLT_ARCNET_LINUX 129 /* ARCNET */ /* * Juniper-private data link types, as per request from @@ -397,14 +399,14 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 + #define DLT_JUNIPER_MLPPP 130 + #define DLT_JUNIPER_MLFR 131 + #define DLT_JUNIPER_ES 132 + #define DLT_JUNIPER_GGSN 133 + #define DLT_JUNIPER_MFR 134 + #define DLT_JUNIPER_ATM2 135 + #define DLT_JUNIPER_SERVICES 136 + #define DLT_JUNIPER_ATM1 137 /* * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund @@ -421,21 +423,21 @@ struct bpf_version { * with "firewire_type" being an Ethernet type value, rather than, * for example, raw GASP frames being handed up. */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 + #define DLT_APPLE_IP_OVER_IEEE1394 138 /* * Various SS7 encapsulations, as per a request from Jeff Morriss * and subsequent discussions. */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + #define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ + #define DLT_MTP2 140 /* MTP2, without pseudo-header */ + #define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ + #define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ /* * DOCSIS MAC frames. */ -#define DLT_DOCSIS 143 + #define DLT_DOCSIS 143 /* * Linux-IrDA packets. Protocol defined at http://www.irda.org. @@ -446,19 +448,19 @@ struct bpf_version { * interface (irdaX), but not on a raw serial port. * Note the capture is done in "Linux-cooked" mode, so each packet include * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or + * decoding is dependant on the direction of the packet (incoming or * outgoing). * When/if other platform implement IrDA capture, we may revisit the * issue and define a real DLT_IRDA... * Jean II */ -#define DLT_LINUX_IRDA 144 + #define DLT_LINUX_IRDA 144 /* * Reserved for IBM SP switch and IBM Next Federation switch. */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 + #define DLT_IBM_SP 145 + #define DLT_IBM_SN 146 /* * Reserved for private use. If you have some link-layer header type @@ -485,22 +487,22 @@ struct bpf_version { * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, * as per the comment above, and use the type you're given. */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 + #define DLT_USER0 147 + #define DLT_USER1 148 + #define DLT_USER2 149 + #define DLT_USER3 150 + #define DLT_USER4 151 + #define DLT_USER5 152 + #define DLT_USER6 153 + #define DLT_USER7 154 + #define DLT_USER8 155 + #define DLT_USER9 156 + #define DLT_USER10 157 + #define DLT_USER11 158 + #define DLT_USER12 159 + #define DLT_USER13 160 + #define DLT_USER14 161 + #define DLT_USER15 162 /* * For future use with 802.11 captures - defined by AbsoluteValue @@ -512,7 +514,7 @@ struct bpf_version { * but it might be used by some non-AVS drivers now or in the * future. */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + #define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ /* * Juniper-private data link type, as per request from @@ -520,12 +522,12 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ -#define DLT_JUNIPER_MONITOR 164 + #define DLT_JUNIPER_MONITOR 164 /* * Reserved for BACnet MS/TP. */ -#define DLT_BACNET_MS_TP 165 + #define DLT_BACNET_MS_TP 165 /* * Another PPP variant as per request from Karsten Keil . @@ -538,17 +540,17 @@ struct bpf_version { * input packets such as port scans, packets from old lost connections, * etc. to force the connection to stay up). * - * The first byte of the PPP header (0xff03) is modified to accomodate + * The first byte of the PPP header (0xff03) is modified to accommodate * the direction - 0x00 = IN, 0x01 = OUT. */ -#define DLT_PPP_PPPD 166 + #define DLT_PPP_PPPD 166 /* * Names for backwards compatibility with older versions of some PPP * software; new software should use DLT_PPP_PPPD. */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + #define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD + #define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD /* * Juniper-private data link type, as per request from @@ -556,26 +558,26 @@ struct bpf_version { * for passing on chassis-internal metainformation such as * QOS profiles, cookies, etc.. */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 + #define DLT_JUNIPER_PPPOE 167 + #define DLT_JUNIPER_PPPOE_ATM 168 -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + #define DLT_GPRS_LLC 169 /* GPRS LLC */ + #define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ + #define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ /* * Requested by Oolan Zimmer for use in Gcom's T1/E1 line * monitoring equipment. */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 + #define DLT_GCOM_T1E1 172 + #define DLT_GCOM_SERIAL 173 /* * Juniper-private data link type, as per request from * Hannes Gredler . The DLT_ is used * for internal communication to Physical Interface Cards (PIC) */ -#define DLT_JUNIPER_PIC_PEER 174 + #define DLT_JUNIPER_PIC_PEER 174 /* * Link types requested by Gregor Maier of Endace @@ -583,8 +585,8 @@ struct bpf_version { * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of * the link-layer header. */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ + #define DLT_ERF_ETH 175 /* Ethernet */ + #define DLT_ERF_POS 176 /* Packet-over-SONET */ /* * Requested by Daniele Orlandi for raw LAPD @@ -592,32 +594,32 @@ struct bpf_version { * includes additional information before the LAPD header, so it's * not necessarily a generic LAPD header. */ -#define DLT_LINUX_LAPD 177 + #define DLT_LINUX_LAPD 177 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ are used for prepending meta-information * like interface index, interface name * before standard Ethernet, PPP, Frelay & C-HDLC Frames */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 + #define DLT_JUNIPER_ETHER 178 + #define DLT_JUNIPER_PPP 179 + #define DLT_JUNIPER_FRELAY 180 + #define DLT_JUNIPER_CHDLC 181 /* * Multi Link Frame Relay (FRF.16) */ -#define DLT_MFR 182 + #define DLT_MFR 182 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * voice Adapter Card (PIC) */ -#define DLT_JUNIPER_VP 183 + #define DLT_JUNIPER_VP 183 /* * Arinc 429 frames. @@ -626,38 +628,38 @@ struct bpf_version { * More documentation on Arinc 429 can be found at * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf */ -#define DLT_A429 184 + #define DLT_A429 184 /* * Arinc 653 Interpartition Communication messages. * DLT_ requested by Gianluca Varenni . * Please refer to the A653-1 standard for more information. */ -#define DLT_A653_ICM 185 + #define DLT_A653_ICM 185 /* * USB packets, beginning with a USB setup header; requested by * Paolo Abeni . */ -#define DLT_USB 186 + #define DLT_USB 186 /* * Bluetooth HCI UART transport layer (part H:4); requested by * Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4 187 + #define DLT_BLUETOOTH_HCI_H4 187 /* * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz * . */ -#define DLT_IEEE802_16_MAC_CPS 188 + #define DLT_IEEE802_16_MAC_CPS 188 /* * USB packets, beginning with a Linux USB header; requested by * Paolo Abeni . */ -#define DLT_USB_LINUX 189 + #define DLT_USB_LINUX 189 /* * Controller Area Network (CAN) v. 2.0B packets. @@ -666,79 +668,79 @@ struct bpf_version { * More documentation on the CAN v2.0B frames can be found at * http://www.can-cia.org/downloads/?269 */ -#define DLT_CAN20B 190 + #define DLT_CAN20B 190 /* * IEEE 802.15.4, with address fields padded, as is done by Linux * drivers; requested by Juergen Schimmer. */ -#define DLT_IEEE802_15_4_LINUX 191 + #define DLT_IEEE802_15_4_LINUX 191 /* * Per Packet Information encapsulated packets. * DLT_ requested by Gianluca Varenni . */ -#define DLT_PPI 192 + #define DLT_PPI 192 /* * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; * requested by Charles Clancy. */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + #define DLT_IEEE802_16_MAC_CPS_RADIO 193 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for internal communication with a * integrated service module (ISM). */ -#define DLT_JUNIPER_ISM 194 + #define DLT_JUNIPER_ISM 194 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no * nothing); requested by Mikko Saarnivala . */ -#define DLT_IEEE802_15_4 195 + #define DLT_IEEE802_15_4 195 /* * Various link-layer types, with a pseudo-header, for SITA * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). */ -#define DLT_SITA 196 + #define DLT_SITA 196 /* * Various link-layer types, with a pseudo-header, for Endace DAG cards; * encapsulates Endace ERF records. Requested by Stephen Donnelly * . */ -#define DLT_ERF 197 + #define DLT_ERF 197 /* * Special header prepended to Ethernet packets when capturing from a * u10 Networks board. Requested by Phil Mulholland * . */ -#define DLT_RAIF1 198 + #define DLT_RAIF1 198 /* * IPMB packet for IPMI, beginning with the I2C slave address, followed * by the netFn and LUN, etc.. Requested by Chanthy Toeung * . */ -#define DLT_IPMB 199 + #define DLT_IPMB 199 /* * Juniper-private data link type, as per request from - * Hannes Gredler . + * Hannes Gredler . * The DLT_ is used for capturing data on a secure tunnel interface. */ -#define DLT_JUNIPER_ST 200 + #define DLT_JUNIPER_ST 200 /* * Bluetooth HCI UART transport layer (part H:4), with pseudo-header * that includes direction information; requested by Paolo Abeni. */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + #define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 /* * AX.25 packet with a 1-byte KISS header; see @@ -747,14 +749,14 @@ struct bpf_version { * * as per Richard Stearn . */ -#define DLT_AX25_KISS 202 + #define DLT_AX25_KISS 202 /* * LAPD packets from an ISDN channel, starting with the address field, * with no pseudo-header. * Requested by Varuna De Silva . */ -#define DLT_LAPD 203 + #define DLT_LAPD 203 /* * Variants of various link-layer headers, with a one-byte direction @@ -762,10 +764,10 @@ struct bpf_version { * non-zero (any non-zero value) means "sent by this host" - as per * Will Barker . */ -#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ -#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ -#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ -#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + #define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ + #define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ + #define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ + #define DLT_LAPB_WITH_DIR 207 /* LAPB */ /* * 208 is reserved for an as-yet-unspecified proprietary link-layer @@ -776,39 +778,39 @@ struct bpf_version { * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman * . */ -#define DLT_IPMB_LINUX 209 + #define DLT_IPMB_LINUX 209 /* * FlexRay automotive bus - http://www.flexray.com/ - as requested * by Hannes Kaelber . */ -#define DLT_FLEXRAY 210 + #define DLT_FLEXRAY 210 /* * Media Oriented Systems Transport (MOST) bus for multimedia * transport - http://www.mostcooperation.com/ - as requested * by Hannes Kaelber . */ -#define DLT_MOST 211 + #define DLT_MOST 211 /* * Local Interconnect Network (LIN) bus for vehicle networks - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber * . */ -#define DLT_LIN 212 + #define DLT_LIN 212 /* * X2E-private data link type used for serial line capture, * as requested by Hannes Kaelber . */ -#define DLT_X2E_SERIAL 213 + #define DLT_X2E_SERIAL 213 /* * X2E-private data link type used for the Xoraya data logger * family, as requested by Hannes Kaelber . */ -#define DLT_X2E_XORAYA 214 + #define DLT_X2E_XORAYA 214 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no @@ -819,7 +821,7 @@ struct bpf_version { * * Requested by Max Filippov . */ -#define DLT_IEEE802_15_4_NONASK_PHY 215 + #define DLT_IEEE802_15_4_NONASK_PHY 215 /* @@ -827,7 +829,7 @@ struct bpf_version { * a member of that class. A class value of 0 indicates a regular * DLT_/LINKTYPE_ value. */ -#define DLT_CLASS(x) ((x) & 0x03ff0000) + #define DLT_CLASS( x ) ( ( x ) & 0x03ff0000 ) /* * NetBSD-specific generic "raw" link type. The class value indicates @@ -836,99 +838,104 @@ struct bpf_version { * do not assume that they correspond to AF_ values for your operating * system. */ -#define DLT_CLASS_NETBSD_RAWAF 0x02240000 -#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) -#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) -#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + #define DLT_CLASS_NETBSD_RAWAF 0x02240000 + #define DLT_NETBSD_RAWAF( af ) ( DLT_CLASS_NETBSD_RAWAF | ( af ) ) + #define DLT_NETBSD_RAWAF_AF( x ) ( ( x ) & 0x0000ffff ) + #define DLT_IS_NETBSD_RAWAF( x ) ( DLT_CLASS( x ) == DLT_CLASS_NETBSD_RAWAF ) /* * The instruction encodings. */ /* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 + #define BPF_CLASS( code ) ( ( code ) & 0x07 ) + #define BPF_LD 0x00 + #define BPF_LDX 0x01 + #define BPF_ST 0x02 + #define BPF_STX 0x03 + #define BPF_ALU 0x04 + #define BPF_JMP 0x05 + #define BPF_RET 0x06 + #define BPF_MISC 0x07 /* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 + #define BPF_SIZE( code ) ( ( code ) & 0x18 ) + #define BPF_W 0x00 + #define BPF_H 0x08 + #define BPF_B 0x10 + #define BPF_MODE( code ) ( ( code ) & 0xe0 ) + #define BPF_IMM 0x00 + #define BPF_ABS 0x20 + #define BPF_IND 0x40 + #define BPF_MEM 0x60 + #define BPF_LEN 0x80 + #define BPF_MSH 0xa0 /* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 + #define BPF_OP( code ) ( ( code ) & 0xf0 ) + #define BPF_ADD 0x00 + #define BPF_SUB 0x10 + #define BPF_MUL 0x20 + #define BPF_DIV 0x30 + #define BPF_OR 0x40 + #define BPF_AND 0x50 + #define BPF_LSH 0x60 + #define BPF_RSH 0x70 + #define BPF_NEG 0x80 + #define BPF_JA 0x00 + #define BPF_JEQ 0x10 + #define BPF_JGT 0x20 + #define BPF_JGE 0x30 + #define BPF_JSET 0x40 + #define BPF_SRC( code ) ( ( code ) & 0x08 ) + #define BPF_K 0x00 + #define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 + #define BPF_RVAL( code ) ( ( code ) & 0x18 ) + #define BPF_A 0x10 /* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 + #define BPF_MISCOP( code ) ( ( code ) & 0xf8 ) + #define BPF_TAX 0x00 + #define BPF_TXA 0x80 /* * The instruction data structure. */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_u_int32 k; -}; + struct bpf_insn + { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; + }; /* * Macros for insn array initializers. */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + #define BPF_STMT( code, k ) { ( u_short ) ( code ), 0, 0, k } + #define BPF_JUMP( code, k, jt, jf ) { ( u_short ) ( code ), jt, jf, k } -#if __STDC__ || defined(__cplusplus) -extern int bpf_validate(const struct bpf_insn *, int); -extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -#else -extern int bpf_validate(); -extern u_int bpf_filter(); -#endif + #if __STDC__ || defined( __cplusplus ) + extern int bpf_validate( const struct bpf_insn *, + int ); + extern u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + #else + extern int bpf_validate(); + extern u_int bpf_filter(); + #endif /* * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). */ -#define BPF_MEMWORDS 16 + #define BPF_MEMWORDS 16 -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef BPF_MAJOR_VERSION */ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/namedb.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/namedb.h index 9002c7509..27bcaa5cc 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/namedb.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/namedb.h @@ -34,11 +34,11 @@ */ #ifndef lib_pcap_namedb_h -#define lib_pcap_namedb_h + #define lib_pcap_namedb_h -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* * As returned by the pcap_next_etherent() @@ -47,43 +47,52 @@ extern "C" { * on systems that don't have support for /etc/ethers, we * export these hooks since they'll */ -struct pcap_etherent { - u_char addr[6]; - char name[122]; -}; -#ifndef PCAP_ETHERS_FILE -#define PCAP_ETHERS_FILE "/etc/ethers" -#endif -struct pcap_etherent *pcap_next_etherent(FILE *); -u_char *pcap_ether_hostton(const char*); -u_char *pcap_ether_aton(const char *); + struct pcap_etherent + { + u_char addr[ 6 ]; + char name[ 122 ]; + }; + #ifndef PCAP_ETHERS_FILE + #define PCAP_ETHERS_FILE "/etc/ethers" + #endif + struct pcap_etherent * pcap_next_etherent( FILE * ); + u_char * pcap_ether_hostton( const char * ); + u_char * pcap_ether_aton( const char * ); -bpf_u_int32 **pcap_nametoaddr(const char *); -#ifdef INET6 -struct addrinfo *pcap_nametoaddrinfo(const char *); -#endif -bpf_u_int32 pcap_nametonetaddr(const char *); + bpf_u_int32 ** pcap_nametoaddr( const char * ); + #ifdef INET6 + struct addrinfo * pcap_nametoaddrinfo( const char * ); + #endif + bpf_u_int32 pcap_nametonetaddr( const char * ); + + int pcap_nametoport( const char *, + int *, + int * ); + int pcap_nametoportrange( const char *, + int *, + int *, + int * ); + int pcap_nametoproto( const char * ); + int pcap_nametoeproto( const char * ); + int pcap_nametollc( const char * ); -int pcap_nametoport(const char *, int *, int *); -int pcap_nametoportrange(const char *, int *, int *, int *); -int pcap_nametoproto(const char *); -int pcap_nametoeproto(const char *); -int pcap_nametollc(const char *); /* * If a protocol is unknown, PROTO_UNDEF is returned. * Also, pcap_nametoport() returns the protocol along with the port number. * If there are ambiguous entried in /etc/services (i.e. domain * can be either tcp or udp) PROTO_UNDEF is returned. */ -#define PROTO_UNDEF -1 + #define PROTO_UNDEF -1 /* XXX move these to pcap-int.h? */ -int __pcap_atodn(const char *, bpf_u_int32 *); -int __pcap_atoin(const char *, bpf_u_int32 *); -u_short __pcap_nametodnaddr(const char *); + int __pcap_atodn( const char *, + bpf_u_int32 * ); + int __pcap_atoin( const char *, + bpf_u_int32 * ); + u_short __pcap_nametodnaddr( const char * ); -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_namedb_h */ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/pcap.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/pcap.h index ad8fc40ac..20113a9e7 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/pcap.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/pcap.h @@ -1,4 +1,5 @@ /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ + /* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. @@ -35,59 +36,59 @@ */ #ifndef lib_pcap_pcap_h -#define lib_pcap_pcap_h + #define lib_pcap_pcap_h -#if defined(WIN32) - #include -#elif defined(MSDOS) - #include - #include /* u_int, u_char etc. */ -#else /* UN*X */ - #include - #include -#endif /* WIN32/MSDOS/UN*X */ + #if defined( WIN32 ) + #include + #elif defined( MSDOS ) + #include + #include /* u_int, u_char etc. */ + #else /* UN*X */ + #include + #include + #endif /* WIN32/MSDOS/UN*X */ -#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include -#endif + #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H + #include + #endif -#include + #include -#ifdef HAVE_REMOTE - // We have to define the SOCKET here, although it has been defined in sockutils.h - // This is to avoid the distribution of the 'sockutils.h' file around - // (for example in the WinPcap developer's pack) - #ifndef SOCKET - #ifdef WIN32 - #define SOCKET unsigned int - #else - #define SOCKET int - #endif - #endif -#endif + #ifdef HAVE_REMOTE + /* We have to define the SOCKET here, although it has been defined in sockutils.h */ + /* This is to avoid the distribution of the 'sockutils.h' file around */ + /* (for example in the WinPcap developer's pack) */ + #ifndef SOCKET + #ifdef WIN32 + #define SOCKET unsigned int + #else + #define SOCKET int + #endif + #endif + #endif /* ifdef HAVE_REMOTE */ -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 + #define PCAP_VERSION_MAJOR 2 + #define PCAP_VERSION_MINOR 4 -#define PCAP_ERRBUF_SIZE 256 + #define PCAP_ERRBUF_SIZE 256 /* * Compatibility for systems that have a bpf.h that * predates the bpf typedefs for 64-bit support. */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif + #if BPF_RELEASE - 0 < 199406 + typedef int bpf_int32; + typedef u_int bpf_u_int32; + #endif -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; + typedef struct pcap pcap_t; + typedef struct pcap_dumper pcap_dumper_t; + typedef struct pcap_if pcap_if_t; + typedef struct pcap_addr pcap_addr_t; /* * The first record in the file contains saved values for some @@ -126,31 +127,33 @@ typedef struct pcap_addr pcap_addr_t; * so that future versions of libpcap and programs that use it (such as * tcpdump) will be able to read your new capture file format. */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; + struct pcap_file_header + { + bpf_u_int32 magic; + u_short version_major; + u_short version_minor; + bpf_int32 thiszone; /* gmt to local correction */ + bpf_u_int32 sigfigs; /* accuracy of timestamps */ + bpf_u_int32 snaplen; /* max length saved portion of each pkt */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ + }; /* * Macros for the value returned by pcap_datalink_ext(). - * + * * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro * gives the FCS length of packets in the capture. */ -#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) -#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) -#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) + #define LT_FCS_LENGTH_PRESENT( x ) ( ( x ) & 0x04000000 ) + #define LT_FCS_LENGTH( x ) ( ( ( x ) & 0xF0000000 ) >> 28 ) + #define LT_FCS_DATALINK_EXT( x ) ( ( ( ( x ) & 0xF ) << 28 ) | 0x04000000 ) -typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT -} pcap_direction_t; + typedef enum + { + PCAP_D_INOUT = 0, + PCAP_D_IN, + PCAP_D_OUT + } pcap_direction_t; /* * Generic per-packet information, as supplied by libpcap. @@ -164,85 +167,92 @@ typedef enum { * should supply the appropriate version of "struct timeval", even if * that's not what the underlying packet capture mechanism supplies. */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; + struct pcap_pkthdr + { + struct timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ + }; /* * As returned by the pcap_stats() */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface XXX not yet supported */ -#ifdef HAVE_REMOTE - u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ - u_int ps_sent; /* number of packets sent by the server on the network */ - u_int ps_netdrop; /* number of packets lost on the network */ -#endif /* HAVE_REMOTE */ -}; + struct pcap_stat + { + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface XXX not yet supported */ + #ifdef HAVE_REMOTE + u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ + u_int ps_sent; /* number of packets sent by the server on the network */ + u_int ps_netdrop; /* number of packets lost on the network */ + #endif /* HAVE_REMOTE */ + }; + + #ifdef MSDOS -#ifdef MSDOS /* * As returned by the pcap_stats_ex() */ -struct pcap_stat_ex { - u_long rx_packets; /* total packets received */ - u_long tx_packets; /* total packets transmitted */ - u_long rx_bytes; /* total bytes received */ - u_long tx_bytes; /* total bytes transmitted */ - u_long rx_errors; /* bad packets received */ - u_long tx_errors; /* packet transmit problems */ - u_long rx_dropped; /* no space in Rx buffers */ - u_long tx_dropped; /* no space available for Tx */ - u_long multicast; /* multicast packets received */ - u_long collisions; + struct pcap_stat_ex + { + u_long rx_packets; /* total packets received */ + u_long tx_packets; /* total packets transmitted */ + u_long rx_bytes; /* total bytes received */ + u_long tx_bytes; /* total bytes transmitted */ + u_long rx_errors; /* bad packets received */ + u_long tx_errors; /* packet transmit problems */ + u_long rx_dropped; /* no space in Rx buffers */ + u_long tx_dropped; /* no space available for Tx */ + u_long multicast; /* multicast packets received */ + u_long collisions; - /* detailed rx_errors: */ - u_long rx_length_errors; - u_long rx_over_errors; /* receiver ring buff overflow */ - u_long rx_crc_errors; /* recv'd pkt with crc error */ - u_long rx_frame_errors; /* recv'd frame alignment error */ - u_long rx_fifo_errors; /* recv'r fifo overrun */ - u_long rx_missed_errors; /* recv'r missed packet */ + /* detailed rx_errors: */ + u_long rx_length_errors; + u_long rx_over_errors; /* receiver ring buff overflow */ + u_long rx_crc_errors; /* recv'd pkt with crc error */ + u_long rx_frame_errors; /* recv'd frame alignment error */ + u_long rx_fifo_errors; /* recv'r fifo overrun */ + u_long rx_missed_errors; /* recv'r missed packet */ - /* detailed tx_errors */ - u_long tx_aborted_errors; - u_long tx_carrier_errors; - u_long tx_fifo_errors; - u_long tx_heartbeat_errors; - u_long tx_window_errors; - }; -#endif + /* detailed tx_errors */ + u_long tx_aborted_errors; + u_long tx_carrier_errors; + u_long tx_fifo_errors; + u_long tx_heartbeat_errors; + u_long tx_window_errors; + }; + #endif /* ifdef MSDOS */ /* * Item in a list of interfaces. */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; + struct pcap_if + { + struct pcap_if * next; + char * name; /* name to hand to "pcap_open_live()" */ + char * description; /* textual description of interface, or NULL */ + struct pcap_addr * addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ + }; -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ + #define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ /* * Representation of an interface address. */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; + struct pcap_addr + { + struct pcap_addr * next; + struct sockaddr * addr; /* address */ + struct sockaddr * netmask; /* netmask for that address */ + struct sockaddr * broadaddr; /* broadcast address for that address */ + struct sockaddr * dstaddr; /* P2P destination address for that address */ + }; -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); + typedef void (* pcap_handler)( u_char *, + const struct pcap_pkthdr *, + const u_char * ); /* * Error codes for the pcap API. @@ -250,158 +260,222 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, * failure of a call that returns these codes by checking for a * negative value. */ -#define PCAP_ERROR -1 /* generic error code */ -#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ -#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ -#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ -#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ -#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ -#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ -#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ -#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ + #define PCAP_ERROR -1 /* generic error code */ + #define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ + #define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ + #define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ + #define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ + #define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ + #define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ + #define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ + #define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ /* * Warning codes for the pcap API. * These will all be positive and non-zero, so they won't look like * errors. */ -#define PCAP_WARNING 1 /* generic warning code */ -#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ + #define PCAP_WARNING 1 /* generic warning code */ + #define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ -char *pcap_lookupdev(char *); -int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); + char * pcap_lookupdev( char * ); + int pcap_lookupnet( const char *, + bpf_u_int32 *, + bpf_u_int32 *, + char * ); -pcap_t *pcap_create(const char *, char *); -int pcap_set_snaplen(pcap_t *, int); -int pcap_set_promisc(pcap_t *, int); -int pcap_can_set_rfmon(pcap_t *); -int pcap_set_rfmon(pcap_t *, int); -int pcap_set_timeout(pcap_t *, int); -int pcap_set_buffer_size(pcap_t *, int); -int pcap_activate(pcap_t *); + pcap_t * pcap_create( const char *, + char * ); + int pcap_set_snaplen( pcap_t *, + int ); + int pcap_set_promisc( pcap_t *, + int ); + int pcap_can_set_rfmon( pcap_t * ); + int pcap_set_rfmon( pcap_t *, + int ); + int pcap_set_timeout( pcap_t *, + int ); + int pcap_set_buffer_size( pcap_t *, + int ); + int pcap_activate( pcap_t * ); -pcap_t *pcap_open_live(const char *, int, int, int, char *); -pcap_t *pcap_open_dead(int, int); -pcap_t *pcap_open_offline(const char *, char *); -#if defined(WIN32) -pcap_t *pcap_hopen_offline(intptr_t, char *); -#if !defined(LIBPCAP_EXPORTS) -#define pcap_fopen_offline(f,b) \ - pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) -#else /*LIBPCAP_EXPORTS*/ -static pcap_t *pcap_fopen_offline(FILE *, char *); -#endif -#else /*WIN32*/ -pcap_t *pcap_fopen_offline(FILE *, char *); -#endif /*WIN32*/ + pcap_t * pcap_open_live( const char *, + int, + int, + int, + char * ); + pcap_t * pcap_open_dead( int, + int ); + pcap_t * pcap_open_offline( const char *, + char * ); + #if defined( WIN32 ) + pcap_t * pcap_hopen_offline( intptr_t, + char * ); + #if !defined( LIBPCAP_EXPORTS ) + #define pcap_fopen_offline( f, b ) \ + pcap_hopen_offline( _get_osfhandle( _fileno( f ) ), b ) + #else /*LIBPCAP_EXPORTS*/ + static pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif + #else /*WIN32*/ + pcap_t * pcap_fopen_offline( FILE *, + char * ); + #endif /*WIN32*/ -void pcap_close(pcap_t *); -int pcap_loop(pcap_t *, int, pcap_handler, u_char *); -int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); -const u_char* - pcap_next(pcap_t *, struct pcap_pkthdr *); -int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); -void pcap_breakloop(pcap_t *); -int pcap_stats(pcap_t *, struct pcap_stat *); -int pcap_setfilter(pcap_t *, struct bpf_program *); -int pcap_setdirection(pcap_t *, pcap_direction_t); -int pcap_getnonblock(pcap_t *, char *); -int pcap_setnonblock(pcap_t *, int, char *); -int pcap_inject(pcap_t *, const void *, size_t); -int pcap_sendpacket(pcap_t *, const u_char *, int); -const char *pcap_statustostr(int); -const char *pcap_strerror(int); -char *pcap_geterr(pcap_t *); -void pcap_perror(pcap_t *, char *); -int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32); -int pcap_compile_nopcap(int, int, struct bpf_program *, - const char *, int, bpf_u_int32); -void pcap_freecode(struct bpf_program *); -int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *, - const u_char *); -int pcap_datalink(pcap_t *); -int pcap_datalink_ext(pcap_t *); -int pcap_list_datalinks(pcap_t *, int **); -int pcap_set_datalink(pcap_t *, int); -void pcap_free_datalinks(int *); -int pcap_datalink_name_to_val(const char *); -const char *pcap_datalink_val_to_name(int); -const char *pcap_datalink_val_to_description(int); -int pcap_snapshot(pcap_t *); -int pcap_is_swapped(pcap_t *); -int pcap_major_version(pcap_t *); -int pcap_minor_version(pcap_t *); + void pcap_close( pcap_t * ); + int pcap_loop( pcap_t *, + int, + pcap_handler, + u_char * ); + int pcap_dispatch( pcap_t *, + int, + pcap_handler, + u_char * ); + const u_char * pcap_next( pcap_t *, + struct pcap_pkthdr * ); + int pcap_next_ex( pcap_t *, + struct pcap_pkthdr **, + const u_char ** ); + void pcap_breakloop( pcap_t * ); + int pcap_stats( pcap_t *, + struct pcap_stat * ); + int pcap_setfilter( pcap_t *, + struct bpf_program * ); + int pcap_setdirection( pcap_t *, + pcap_direction_t ); + int pcap_getnonblock( pcap_t *, + char * ); + int pcap_setnonblock( pcap_t *, + int, + char * ); + int pcap_inject( pcap_t *, + const void *, + size_t ); + int pcap_sendpacket( pcap_t *, + const u_char *, + int ); + const char * pcap_statustostr( int ); + const char * pcap_strerror( int ); + char * pcap_geterr( pcap_t * ); + void pcap_perror( pcap_t *, + char * ); + int pcap_compile( pcap_t *, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + int pcap_compile_nopcap( int, + int, + struct bpf_program *, + const char *, + int, + bpf_u_int32 ); + void pcap_freecode( struct bpf_program * ); + int pcap_offline_filter( struct bpf_program *, + const struct pcap_pkthdr *, + const u_char * ); + int pcap_datalink( pcap_t * ); + int pcap_datalink_ext( pcap_t * ); + int pcap_list_datalinks( pcap_t *, + int ** ); + int pcap_set_datalink( pcap_t *, + int ); + void pcap_free_datalinks( int * ); + int pcap_datalink_name_to_val( const char * ); + const char * pcap_datalink_val_to_name( int ); + const char * pcap_datalink_val_to_description( int ); + int pcap_snapshot( pcap_t * ); + int pcap_is_swapped( pcap_t * ); + int pcap_major_version( pcap_t * ); + int pcap_minor_version( pcap_t * ); /* XXX */ -FILE *pcap_file(pcap_t *); -int pcap_fileno(pcap_t *); + FILE * pcap_file( pcap_t * ); + int pcap_fileno( pcap_t * ); -pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); -pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); -FILE *pcap_dump_file(pcap_dumper_t *); -long pcap_dump_ftell(pcap_dumper_t *); -int pcap_dump_flush(pcap_dumper_t *); -void pcap_dump_close(pcap_dumper_t *); -void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); + pcap_dumper_t * pcap_dump_open( pcap_t *, + const char * ); + pcap_dumper_t * pcap_dump_fopen( pcap_t *, + FILE * fp ); + FILE * pcap_dump_file( pcap_dumper_t * ); + long pcap_dump_ftell( pcap_dumper_t * ); + int pcap_dump_flush( pcap_dumper_t * ); + void pcap_dump_close( pcap_dumper_t * ); + void pcap_dump( u_char *, + const struct pcap_pkthdr *, + const u_char * ); -int pcap_findalldevs(pcap_if_t **, char *); -void pcap_freealldevs(pcap_if_t *); + int pcap_findalldevs( pcap_if_t **, + char * ); + void pcap_freealldevs( pcap_if_t * ); -const char *pcap_lib_version(void); + const char * pcap_lib_version( void ); /* XXX this guy lives in the bpf tree */ -u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -int bpf_validate(const struct bpf_insn *f, int len); -char *bpf_image(const struct bpf_insn *, int); -void bpf_dump(const struct bpf_program *, int); + u_int bpf_filter( const struct bpf_insn *, + const u_char *, + u_int, + u_int ); + int bpf_validate( const struct bpf_insn * f, + int len ); + char * bpf_image( const struct bpf_insn *, + int ); + void bpf_dump( const struct bpf_program *, + int ); -#if defined(WIN32) + #if defined( WIN32 ) /* * Win32 definitions */ -int pcap_setbuff(pcap_t *p, int dim); -int pcap_setmode(pcap_t *p, int mode); -int pcap_setmintocopy(pcap_t *p, int size); + int pcap_setbuff( pcap_t * p, + int dim ); + int pcap_setmode( pcap_t * p, + int mode ); + int pcap_setmintocopy( pcap_t * p, + int size ); -#ifdef WPCAP + #ifdef WPCAP /* Include file with the wpcap-specific extensions */ -#include -#endif /* WPCAP */ + #include + #endif /* WPCAP */ -#define MODE_CAPT 0 -#define MODE_STAT 1 -#define MODE_MON 2 + #define MODE_CAPT 0 + #define MODE_STAT 1 + #define MODE_MON 2 -#elif defined(MSDOS) + #elif defined( MSDOS ) /* * MS-DOS definitions */ -int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); -void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); -u_long pcap_mac_packets (void); + int pcap_stats_ex( pcap_t *, + struct pcap_stat_ex * ); + void pcap_set_wait( pcap_t * p, + void ( * yield )( void ), + int wait ); + u_long pcap_mac_packets( void ); -#else /* UN*X */ + #else /* UN*X */ /* * UN*X definitions */ -int pcap_get_selectable_fd(pcap_t *); + int pcap_get_selectable_fd( pcap_t * ); -#endif /* WIN32/MSDOS/UN*X */ + #endif /* WIN32/MSDOS/UN*X */ -#ifdef HAVE_REMOTE + #ifdef HAVE_REMOTE /* Includes most of the public stuff that is needed for the remote capture */ -#include -#endif /* HAVE_REMOTE */ + #include + #endif /* HAVE_REMOTE */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif +#endif /* ifndef lib_pcap_pcap_h */ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/sll.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/sll.h index e9d5452af..e5052236a 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/sll.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/sll.h @@ -79,15 +79,16 @@ /* * A DLT_LINUX_SLL fake link-layer header. */ -#define SLL_HDR_LEN 16 /* total header length */ -#define SLL_ADDRLEN 8 /* length of address field */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ -struct sll_header { - u_int16_t sll_pkttype; /* packet type */ - u_int16_t sll_hatype; /* link-layer address type */ - u_int16_t sll_halen; /* link-layer address length */ - u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ - u_int16_t sll_protocol; /* protocol */ +struct sll_header +{ + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[ SLL_ADDRLEN ]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ }; /* @@ -96,11 +97,11 @@ struct sll_header { * available even on systems other than Linux, and so that they * don't change even if the PACKET_ values change. */ -#define LINUX_SLL_HOST 0 -#define LINUX_SLL_BROADCAST 1 -#define LINUX_SLL_MULTICAST 2 -#define LINUX_SLL_OTHERHOST 3 -#define LINUX_SLL_OUTGOING 4 +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 /* * The LINUX_SLL_ values for "sll_protocol"; these correspond to the @@ -123,7 +124,7 @@ struct sll_header { * in the Linux "if_ether.h" will, I suspect, actually show up in * captures.) */ -#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ -#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ -#endif +#endif /* ifndef lib_pcap_sll_h */ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/usb.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/usb.h index adcd19c05..44a3c9557 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/usb.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/usb.h @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,36 +32,37 @@ * * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $ */ - + #ifndef _PCAP_USB_STRUCTS_H__ #define _PCAP_USB_STRUCTS_H__ -/* +/* * possible transfer mode */ -#define URB_TRANSFER_IN 0x80 -#define URB_ISOCHRONOUS 0x0 -#define URB_INTERRUPT 0x1 -#define URB_CONTROL 0x2 -#define URB_BULK 0x3 +#define URB_TRANSFER_IN 0x80 +#define URB_ISOCHRONOUS 0x0 +#define URB_INTERRUPT 0x1 +#define URB_CONTROL 0x2 +#define URB_BULK 0x3 /* * possible event type */ -#define URB_SUBMIT 'S' -#define URB_COMPLETE 'C' -#define URB_ERROR 'E' +#define URB_SUBMIT 'S' +#define URB_COMPLETE 'C' +#define URB_ERROR 'E' /* * USB setup header as defined in USB specification. * Appears at the front of each packet in DLT_USB captures. */ -typedef struct _usb_setup { - u_int8_t bmRequestType; - u_int8_t bRequest; - u_int16_t wValue; - u_int16_t wIndex; - u_int16_t wLength; +typedef struct _usb_setup +{ + u_int8_t bmRequestType; + u_int8_t bRequest; + u_int16_t wValue; + u_int16_t wIndex; + u_int16_t wLength; } pcap_usb_setup; @@ -69,22 +70,23 @@ typedef struct _usb_setup { * Header prepended by linux kernel to each event. * Appears at the front of each packet in DLT_USB_LINUX captures. */ -typedef struct _usb_header { - u_int64_t id; - u_int8_t event_type; - u_int8_t transfer_type; - u_int8_t endpoint_number; - u_int8_t device_address; - u_int16_t bus_id; - char setup_flag;/*if !=0 the urb setup header is not present*/ - char data_flag; /*if !=0 no urb data is present*/ - int64_t ts_sec; - int32_t ts_usec; - int32_t status; - u_int32_t urb_len; - u_int32_t data_len; /* amount of urb data really present in this event*/ - pcap_usb_setup setup; +typedef struct _usb_header +{ + u_int64_t id; + u_int8_t event_type; + u_int8_t transfer_type; + u_int8_t endpoint_number; + u_int8_t device_address; + u_int16_t bus_id; + char setup_flag; /*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + u_int32_t urb_len; + u_int32_t data_len; /* amount of urb data really present in this event*/ + pcap_usb_setup setup; } pcap_usb_header; -#endif +#endif /* ifndef _PCAP_USB_STRUCTS_H__ */ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/vlan.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/vlan.h index b0cb7949b..e9be8bd16 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/vlan.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/pcap/vlan.h @@ -36,11 +36,12 @@ #ifndef lib_pcap_vlan_h #define lib_pcap_vlan_h -struct vlan_tag { - u_int16_t vlan_tpid; /* ETH_P_8021Q */ - u_int16_t vlan_tci; /* VLAN TCI */ +struct vlan_tag +{ + u_int16_t vlan_tpid; /* ETH_P_8021Q */ + u_int16_t vlan_tci; /* VLAN TCI */ }; -#define VLAN_TAG_LEN 4 +#define VLAN_TAG_LEN 4 -#endif +#endif /* ifndef lib_pcap_vlan_h */ diff --git a/FreeRTOS-Plus/ThirdParty/winpcap/include/remote-ext.h b/FreeRTOS-Plus/ThirdParty/winpcap/include/remote-ext.h index 35a2fff6c..42d1fe6e9 100644 --- a/FreeRTOS-Plus/ThirdParty/winpcap/include/remote-ext.h +++ b/FreeRTOS-Plus/ThirdParty/winpcap/include/remote-ext.h @@ -2,443 +2,471 @@ * Copyright (c) 2002 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions * are met: - * - * 1. Redistributions of source code must retain the above copyright + * + * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * */ #ifndef __REMOTE_EXT_H__ -#define __REMOTE_EXT_H__ + #define __REMOTE_EXT_H__ -#ifndef HAVE_REMOTE -#error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h -#endif + #ifndef HAVE_REMOTE + #error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h + #endif -// Definition for Microsoft Visual Studio -#if _MSC_VER > 1000 -#pragma once -#endif +/* Definition for Microsoft Visual Studio */ + #if _MSC_VER > 1000 + #pragma once + #endif -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /*! - \file remote-ext.h - - The goal of this file it to include most of the new definitions that should be - placed into the pcap.h file. - - It includes all new definitions (structures and functions like pcap_open(). - Some of the functions are not really a remote feature, but, right now, - they are placed here. -*/ + * \file remote-ext.h + * + * The goal of this file it to include most of the new definitions that should be + * placed into the pcap.h file. + * + * It includes all new definitions (structures and functions like pcap_open(). + * Some of the functions are not really a remote feature, but, right now, + * they are placed here. + */ -// All this stuff is public +/* All this stuff is public */ + /*! \addtogroup remote_struct - \{ -*/ - + \{ + */ /*! - \brief Defines the maximum buffer size in which address, port, interface names are kept. - - In case the adapter name or such is larger than this value, it is truncated. - This is not used by the user; however it must be aware that an hostname / interface - name longer than this value will be truncated. -*/ -#define PCAP_BUF_SIZE 1024 + * \brief Defines the maximum buffer size in which address, port, interface names are kept. + * + * In case the adapter name or such is larger than this value, it is truncated. + * This is not used by the user; however it must be aware that an hostname / interface + * name longer than this value will be truncated. + */ + #define PCAP_BUF_SIZE 1024 /*! \addtogroup remote_source_ID - \{ -*/ + \{ + */ /*! - \brief Internal representation of the type of source in use (file, - remote/local interface). - - This indicates a file, i.e. the user want to open a capture from a local file. -*/ -#define PCAP_SRC_FILE 2 -/*! - \brief Internal representation of the type of source in use (file, - remote/local interface). - - This indicates a local interface, i.e. the user want to open a capture from - a local interface. This does not involve the RPCAP protocol. -*/ -#define PCAP_SRC_IFLOCAL 3 -/*! - \brief Internal representation of the type of source in use (file, - remote/local interface). - - This indicates a remote interface, i.e. the user want to open a capture from - an interface on a remote host. This does involve the RPCAP protocol. -*/ -#define PCAP_SRC_IFREMOTE 4 + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a file, i.e. the user want to open a capture from a local file. + */ + #define PCAP_SRC_FILE 2 /*! - \} -*/ + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a local interface, i.e. the user want to open a capture from + * a local interface. This does not involve the RPCAP protocol. + */ + #define PCAP_SRC_IFLOCAL 3 + +/*! + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a remote interface, i.e. the user want to open a capture from + * an interface on a remote host. This does involve the RPCAP protocol. + */ + #define PCAP_SRC_IFREMOTE 4 + +/*! + \} + */ /*! \addtogroup remote_source_string - - The formats allowed by the pcap_open() are the following: - - file://path_and_filename [opens a local file] - - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] - - rpcap://host/devicename [opens the selected device available on a remote host] - - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] - - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] - - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] - - The formats allowed by the pcap_findalldevs_ex() are the following: - - file://folder/ [lists all the files in the given folder] - - rpcap:// [lists all local adapters] - - rpcap://host:port/ [lists the devices available on a remote host] - - Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since - IPv6 is fully supported, these are the allowed formats: - - - host (literal): e.g. host.foo.bar - - host (numeric IPv4): e.g. 10.11.12.13 - - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] - - host (numeric IPv6): e.g. [1:2:3::4] - - port: can be either numeric (e.g. '80') or literal (e.g. 'http') - - Here you find some allowed examples: - - rpcap://host.foo.bar/devicename [everything literal, no port number] - - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] - - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] - - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] - - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] - - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] - - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] - - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] - - \{ -*/ + * + * The formats allowed by the pcap_open() are the following: + * - file://path_and_filename [opens a local file] + * - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] + * - rpcap://host/devicename [opens the selected device available on a remote host] + * - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] + * - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] + * - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] + * + * The formats allowed by the pcap_findalldevs_ex() are the following: + * - file://folder/ [lists all the files in the given folder] + * - rpcap:// [lists all local adapters] + * - rpcap://host:port/ [lists the devices available on a remote host] + * + * Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since + * IPv6 is fully supported, these are the allowed formats: + * + * - host (literal): e.g. host.foo.bar + * - host (numeric IPv4): e.g. 10.11.12.13 + * - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] + * - host (numeric IPv6): e.g. [1:2:3::4] + * - port: can be either numeric (e.g. '80') or literal (e.g. 'http') + * + * Here you find some allowed examples: + * - rpcap://host.foo.bar/devicename [everything literal, no port number] + * - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] + * - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] + * - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] + * - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] + * - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] + * - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] + * - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] + * + \{ + */ /*! - \brief String that will be used to determine the type of source in use (file, - remote/local interface). - - This string will be prepended to the interface name in order to create a string - that contains all the information required to open the source. - - This string indicates that the user wants to open a capture from a local file. -*/ -#define PCAP_SRC_FILE_STRING "file://" -/*! - \brief String that will be used to determine the type of source in use (file, - remote/local interface). - - This string will be prepended to the interface name in order to create a string - that contains all the information required to open the source. - - This string indicates that the user wants to open a capture from a network interface. - This string does not necessarily involve the use of the RPCAP protocol. If the - interface required resides on the local host, the RPCAP protocol is not involved - and the local functions are used. -*/ -#define PCAP_SRC_IF_STRING "rpcap://" + * \brief String that will be used to determine the type of source in use (file, + * remote/local interface). + * + * This string will be prepended to the interface name in order to create a string + * that contains all the information required to open the source. + * + * This string indicates that the user wants to open a capture from a local file. + */ + #define PCAP_SRC_FILE_STRING "file://" /*! - \} -*/ - + * \brief String that will be used to determine the type of source in use (file, + * remote/local interface). + * + * This string will be prepended to the interface name in order to create a string + * that contains all the information required to open the source. + * + * This string indicates that the user wants to open a capture from a network interface. + * This string does not necessarily involve the use of the RPCAP protocol. If the + * interface required resides on the local host, the RPCAP protocol is not involved + * and the local functions are used. + */ + #define PCAP_SRC_IF_STRING "rpcap://" +/*! + \} + */ /*! - \addtogroup remote_open_flags - \{ -*/ + * \addtogroup remote_open_flags + \{ + */ /*! - \brief Defines if the adapter has to go in promiscuous mode. - - It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise. - Note that even if this parameter is false, the interface could well be in promiscuous - mode for some other reason (for example because another capture process with - promiscuous mode enabled is currently using that interface). - On on Linux systems with 2.2 or later kernels (that have the "any" device), this - flag does not work on the "any" device; if an argument of "any" is supplied, - the 'promisc' flag is ignored. -*/ -#define PCAP_OPENFLAG_PROMISCUOUS 1 + * \brief Defines if the adapter has to go in promiscuous mode. + * + * It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise. + * Note that even if this parameter is false, the interface could well be in promiscuous + * mode for some other reason (for example because another capture process with + * promiscuous mode enabled is currently using that interface). + * On on Linux systems with 2.2 or later kernels (that have the "any" device), this + * flag does not work on the "any" device; if an argument of "any" is supplied, + * the 'promisc' flag is ignored. + */ + #define PCAP_OPENFLAG_PROMISCUOUS 1 /*! - \brief Defines if the data trasfer (in case of a remote - capture) has to be done with UDP protocol. - - If it is '1' if you want a UDP data connection, '0' if you want - a TCP data connection; control connection is always TCP-based. - A UDP connection is much lighter, but it does not guarantee that all - the captured packets arrive to the client workstation. Moreover, - it could be harmful in case of network congestion. - This flag is meaningless if the source is not a remote interface. - In that case, it is simply ignored. -*/ -#define PCAP_OPENFLAG_DATATX_UDP 2 + * \brief Defines if the data transfer (in case of a remote + * capture) has to be done with UDP protocol. + * + * If it is '1' if you want a UDP data connection, '0' if you want + * a TCP data connection; control connection is always TCP-based. + * A UDP connection is much lighter, but it does not guarantee that all + * the captured packets arrive to the client workstation. Moreover, + * it could be harmful in case of network congestion. + * This flag is meaningless if the source is not a remote interface. + * In that case, it is simply ignored. + */ + #define PCAP_OPENFLAG_DATATX_UDP 2 /*! - \brief Defines if the remote probe will capture its own generated traffic. - - In case the remote probe uses the same interface to capture traffic and to send - data back to the caller, the captured traffic includes the RPCAP traffic as well. - If this flag is turned on, the RPCAP traffic is excluded from the capture, so that - the trace returned back to the collector is does not include this traffic. -*/ -#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 + * \brief Defines if the remote probe will capture its own generated traffic. + * + * In case the remote probe uses the same interface to capture traffic and to send + * data back to the caller, the captured traffic includes the RPCAP traffic as well. + * If this flag is turned on, the RPCAP traffic is excluded from the capture, so that + * the trace returned back to the collector is does not include this traffic. + */ + #define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 /*! - \brief Defines if the local adapter will capture its own generated traffic. - - This flag tells the underlying capture driver to drop the packets that were sent by itself. - This is usefult when building applications like bridges, that should ignore the traffic - they just sent. -*/ -#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 + * \brief Defines if the local adapter will capture its own generated traffic. + * + * This flag tells the underlying capture driver to drop the packets that were sent by itself. + * This is useful when building applications like bridges, that should ignore the traffic + * they just sent. + */ + #define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 /*! - \brief This flag configures the adapter for maximum responsiveness. - - In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before - copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, - i.e. better performance, which is good for applications like sniffers. If the user sets the - PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application - is ready to receive them. This is suggested for real time applications (like, for example, a bridge) - that need the best responsiveness.*/ -#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 + * \brief This flag configures the adapter for maximum responsiveness. + * + * In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before + * copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, + * i.e. better performance, which is good for applications like sniffers. If the user sets the + * PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application + * is ready to receive them. This is suggested for real time applications (like, for example, a bridge) + * that need the best responsiveness.*/ + #define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 /*! - \} -*/ + \} + */ /*! - \addtogroup remote_samp_methods - \{ -*/ + * \addtogroup remote_samp_methods + \{ + */ /*! - \brief No sampling has to be done on the current capture. - - In this case, no sampling algorithms are applied to the current capture. -*/ -#define PCAP_SAMP_NOSAMP 0 + * \brief No sampling has to be done on the current capture. + * + * In this case, no sampling algorithms are applied to the current capture. + */ + #define PCAP_SAMP_NOSAMP 0 /*! - \brief It defines that only 1 out of N packets must be returned to the user. - - In this case, the 'value' field of the 'pcap_samp' structure indicates the - number of packets (minus 1) that must be discarded before one packet got accepted. - In other words, if 'value = 10', the first packet is returned to the caller, while - the following 9 are discarded. -*/ -#define PCAP_SAMP_1_EVERY_N 1 + * \brief It defines that only 1 out of N packets must be returned to the user. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates the + * number of packets (minus 1) that must be discarded before one packet got accepted. + * In other words, if 'value = 10', the first packet is returned to the caller, while + * the following 9 are discarded. + */ + #define PCAP_SAMP_1_EVERY_N 1 /*! - \brief It defines that we have to return 1 packet every N milliseconds. - - In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting - time' in milliseconds before one packet got accepted. - In other words, if 'value = 10', the first packet is returned to the caller; the next - returned one will be the first packet that arrives when 10ms have elapsed. -*/ -#define PCAP_SAMP_FIRST_AFTER_N_MS 2 + * \brief It defines that we have to return 1 packet every N milliseconds. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting + * time' in milliseconds before one packet got accepted. + * In other words, if 'value = 10', the first packet is returned to the caller; the next + * returned one will be the first packet that arrives when 10ms have elapsed. + */ + #define PCAP_SAMP_FIRST_AFTER_N_MS 2 /*! - \} -*/ + \} + */ /*! - \addtogroup remote_auth_methods - \{ -*/ + * \addtogroup remote_auth_methods + \{ + */ /*! - \brief It defines the NULL authentication. - - This value has to be used within the 'type' member of the pcap_rmtauth structure. - The 'NULL' authentication has to be equal to 'zero', so that old applications - can just put every field of struct pcap_rmtauth to zero, and it does work. -*/ -#define RPCAP_RMTAUTH_NULL 0 -/*! - \brief It defines the username/password authentication. - - With this type of authentication, the RPCAP protocol will use the username/ - password provided to authenticate the user on the remote machine. If the - authentication is successful (and the user has the right to open network devices) - the RPCAP connection will continue; otherwise it will be dropped. - - This value has to be used within the 'type' member of the pcap_rmtauth structure. -*/ -#define RPCAP_RMTAUTH_PWD 1 + * \brief It defines the NULL authentication. + * + * This value has to be used within the 'type' member of the pcap_rmtauth structure. + * The 'NULL' authentication has to be equal to 'zero', so that old applications + * can just put every field of struct pcap_rmtauth to zero, and it does work. + */ + #define RPCAP_RMTAUTH_NULL 0 /*! - \} -*/ + * \brief It defines the username/password authentication. + * + * With this type of authentication, the RPCAP protocol will use the username/ + * password provided to authenticate the user on the remote machine. If the + * authentication is successful (and the user has the right to open network devices) + * the RPCAP connection will continue; otherwise it will be dropped. + * + * This value has to be used within the 'type' member of the pcap_rmtauth structure. + */ + #define RPCAP_RMTAUTH_PWD 1 +/*! + \} + */ /*! + * + * \brief This structure keeps the information needed to authenticate + * the user on a remote machine. + * + * The remote machine can either grant or refuse the access according + * to the information provided. + * In case the NULL authentication is required, both 'username' and + * 'password' can be NULL pointers. + * + * This structure is meaningless if the source is not a remote interface; + * in that case, the functions which requires such a structure can accept + * a NULL pointer as well. + */ + struct pcap_rmtauth + { + /*! + * \brief Type of the authentication required. + * + * In order to provide maximum flexibility, we can support different types + * of authentication based on the value of this 'type' variable. The currently + * supported authentication methods are defined into the + * \link remote_auth_methods Remote Authentication Methods Section\endlink. + * + */ + int type; - \brief This structure keeps the information needed to autheticate - the user on a remote machine. - - The remote machine can either grant or refuse the access according - to the information provided. - In case the NULL authentication is required, both 'username' and - 'password' can be NULL pointers. - - This structure is meaningless if the source is not a remote interface; - in that case, the functions which requires such a structure can accept - a NULL pointer as well. -*/ -struct pcap_rmtauth -{ - /*! - \brief Type of the authentication required. + /*! + * \brief Zero-terminated string containing the username that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char * username; - In order to provide maximum flexibility, we can support different types - of authentication based on the value of this 'type' variable. The currently - supported authentication methods are defined into the - \link remote_auth_methods Remote Authentication Methods Section\endlink. - - */ - int type; - /*! - \brief Zero-terminated string containing the username that has to be - used on the remote machine for authentication. - - This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication - and it can be NULL. - */ - char *username; - /*! - \brief Zero-terminated string containing the password that has to be - used on the remote machine for authentication. - - This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication - and it can be NULL. - */ - char *password; -}; + /*! + * \brief Zero-terminated string containing the password that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char * password; + }; /*! - \brief This structure defines the information related to sampling. + * \brief This structure defines the information related to sampling. + * + * In case the sampling is requested, the capturing device should read + * only a subset of the packets coming from the source. The returned packets depend + * on the sampling parameters. + * + * \warning The sampling process is applied after the filtering process. + * In other words, packets are filtered first, then the sampling process selects a + * subset of the 'filtered' packets and it returns them to the caller. + */ + struct pcap_samp + { + /*! + * Method used for sampling. Currently, the supported methods are listed in the + * \link remote_samp_methods Sampling Methods Section\endlink. + */ + int method; - In case the sampling is requested, the capturing device should read - only a subset of the packets coming from the source. The returned packets depend - on the sampling parameters. - - \warning The sampling process is applied after the filtering process. - In other words, packets are filtered first, then the sampling process selects a - subset of the 'filtered' packets and it returns them to the caller. -*/ -struct pcap_samp -{ - /*! - Method used for sampling. Currently, the supported methods are listed in the - \link remote_samp_methods Sampling Methods Section\endlink. - */ - int method; - - /*! - This value depends on the sampling method defined. For its meaning, please check - at the \link remote_samp_methods Sampling Methods Section\endlink. - */ - int value; -}; + /*! + * This value depends on the sampling method defined. For its meaning, please check + * at the \link remote_samp_methods Sampling Methods Section\endlink. + */ + int value; + }; - -//! Maximum lenght of an host name (needed for the RPCAP active mode) -#define RPCAP_HOSTLIST_SIZE 1024 +/*! Maximum length of an host name (needed for the RPCAP active mode) */ + #define RPCAP_HOSTLIST_SIZE 1024 /*! - \} -*/ // end of public documentation + \} + *//* end of public documentation */ -// Exported functions +/* Exported functions */ /** \name New WinPcap functions - - This section lists the new functions that are able to help considerably in writing - WinPcap programs because of their easiness of use. + * + * This section lists the new functions that are able to help considerably in writing + * WinPcap programs because of their easiness of use. */ -//\{ -pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf); -int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf); -int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf); -int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf); -struct pcap_samp *pcap_setsampling(pcap_t *p); +/*\{ */ + pcap_t * pcap_open( const char * source, + int snaplen, + int flags, + int read_timeout, + struct pcap_rmtauth * auth, + char * errbuf ); + int pcap_createsrcstr( char * source, + int type, + const char * host, + const char * port, + const char * name, + char * errbuf ); + int pcap_parsesrcstr( const char * source, + int * type, + char * host, + char * port, + char * name, + char * errbuf ); + int pcap_findalldevs_ex( char * source, + struct pcap_rmtauth * auth, + pcap_if_t ** alldevs, + char * errbuf ); + struct pcap_samp * pcap_setsampling( pcap_t * p ); -//\} -// End of new winpcap functions +/*\} */ +/* End of new winpcap functions */ /** \name Remote Capture functions */ -//\{ -SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf); -int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf); -int pcap_remoteact_close(const char *host, char *errbuf); -void pcap_remoteact_cleanup(); -//\} -// End of remote capture functions +/*\{ */ + SOCKET pcap_remoteact_accept( const char * address, + const char * port, + const char * hostlist, + char * connectinghost, + struct pcap_rmtauth * auth, + char * errbuf ); + int pcap_remoteact_list( char * hostlist, + char sep, + int size, + char * errbuf ); + int pcap_remoteact_close( const char * host, + char * errbuf ); + void pcap_remoteact_cleanup(); +/*\} */ +/* End of remote capture functions */ -#ifdef __cplusplus + #ifdef __cplusplus } -#endif + #endif -#endif - +#endif /* ifndef __REMOTE_EXT_H__ */ diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOS+TCP.vcxproj b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOS+TCP.vcxproj index 14245bb6b..eb370fbd3 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOS+TCP.vcxproj +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOS+TCP.vcxproj @@ -1,1893 +1,1893 @@ - - - - - Debug_with_Libslirp - Win32 - - - Debug_with_Libslirp - x64 - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 17.0 - {C90E6CC5-818B-4C97-8876-0986D989387C} - Win32Proj - 10.0 - FreeRTOS_TCP - - - - StaticLibrary - true - v142 - - - StaticLibrary - true - v142 - - - StaticLibrary - false - v142 - - - StaticLibrary - true - v142 - - - StaticLibrary - true - v142 - - - StaticLibrary - false - v142 - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) - true - build\$(ProjectName)\$(Platform)\$(Configuration)\ - build\$(ProjectName)\$(Platform)\$(Configuration)\ - $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);..\..\ThirdParty\winpcap\lib\x64 - $(IncludePath) - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) - - - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) - true - build\$(ProjectName)\$(Platform)\$(Configuration)\ - build\$(ProjectName)\$(Platform)\$(Configuration)\ - $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);..\..\ThirdParty\winpcap\lib\x64 - $(IncludePath) - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) - - - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) - true - build\$(ProjectName)\$(Platform)\$(Configuration)\ - build\$(ProjectName)\$(Platform)\$(Configuration)\ - $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);..\..\ThirdParty\winpcap\lib\x64 - $(IncludePath) - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) - - - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) - true - build\$(ProjectName)\$(Platform)\$(Configuration)\ - build\$(ProjectName)\$(Platform)\$(Configuration)\ - $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\..\ThirdParty\winpcap\lib\x86 - $(IncludePath) - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) - - - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) - true - build\$(ProjectName)\$(Platform)\$(Configuration)\ - build\$(ProjectName)\$(Platform)\$(Configuration)\ - $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\..\ThirdParty\winpcap\lib\x86 - $(IncludePath) - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) - - - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) - true - build\$(ProjectName)\$(Platform)\$(Configuration)\ - build\$(ProjectName)\$(Platform)\$(Configuration)\ - $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\..\ThirdParty\winpcap\lib\x86 - $(IncludePath) - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ - ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) - - - false - - - - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - Disabled - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) - - - MachineX86 - true - Windows - - - wpcap.lib;%(AdditionalDependencies) - - - - - BUILDING_LIBSLIRP;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - Disabled - ..\..\ThirdParty\glib;..\..\ThirdParty\glib\glib;..\..\ThirdParty\glib\build;..\..\ThirdParty\glib\build\glib;..\..\ThirdParty\glib\build\subprojects\pcre2-10.42;..\..\ThirdParty\glib\subprojects\proxy-libintl;..\..\ThirdParty\libslirp\src;..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) - - - MachineX86 - true - Windows - - - wpcap.lib;%(AdditionalDependencies) - - - - - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDLL - Level3 - ProgramDatabase - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) - - - MachineX86 - true - Windows - true - true - - - wpcap.lib;%(AdditionalDependencies) - - - - - - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) - - - wpcap.lib;%(AdditionalDependencies) - - - - - - BUILDING_LIBSLIRP;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ThirdParty\glib;..\..\ThirdParty\glib\glib;..\..\ThirdParty\glib\build\;..\..\ThirdParty\glib\build\glib;..\..\ThirdParty\glib\build\subprojects\pcre2-10.42;..\..\ThirdParty\glib\subprojects\proxy-libintl;..\..\ThirdParty\libslirp\src;..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) - - - wpcap.lib;%(AdditionalDependencies) - - - - - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) - - - wpcap.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - true - true - false - true - true - - - false - true - true - false - true - true - - - - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - false - true - true - true - true - false - - - true - true - - - - - - - ipconfigUSE_LIBSLIRP;BUILDING_LIBSLIRP;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ipconfigUSE_LIBSLIRP;BUILDING_LIBSLIRP;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - - - - {72c209c4-49a4-4942-a201-44706c9d77ec} - false - true - true - - - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - false - false - true - true - true - true - - - - - + + + + + Debug_with_Libslirp + Win32 + + + Debug_with_Libslirp + x64 + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {C90E6CC5-818B-4C97-8876-0986D989387C} + Win32Proj + 10.0 + FreeRTOS_TCP + + + + StaticLibrary + true + v142 + + + StaticLibrary + true + v142 + + + StaticLibrary + false + v142 + + + StaticLibrary + true + v142 + + + StaticLibrary + true + v142 + + + StaticLibrary + false + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) + true + build\$(ProjectName)\$(Platform)\$(Configuration)\ + build\$(ProjectName)\$(Platform)\$(Configuration)\ + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);..\..\ThirdParty\winpcap\lib\x64 + $(IncludePath) + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) + + + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) + true + build\$(ProjectName)\$(Platform)\$(Configuration)\ + build\$(ProjectName)\$(Platform)\$(Configuration)\ + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);..\..\ThirdParty\winpcap\lib\x64 + $(IncludePath) + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) + + + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) + true + build\$(ProjectName)\$(Platform)\$(Configuration)\ + build\$(ProjectName)\$(Platform)\$(Configuration)\ + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);..\..\ThirdParty\winpcap\lib\x64 + $(IncludePath) + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) + + + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) + true + build\$(ProjectName)\$(Platform)\$(Configuration)\ + build\$(ProjectName)\$(Platform)\$(Configuration)\ + $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\..\ThirdParty\winpcap\lib\x86 + $(IncludePath) + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) + + + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) + true + build\$(ProjectName)\$(Platform)\$(Configuration)\ + build\$(ProjectName)\$(Platform)\$(Configuration)\ + $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\..\ThirdParty\winpcap\lib\x86 + $(IncludePath) + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) + + + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\;$(PublicIncludeDirectories) + true + build\$(ProjectName)\$(Platform)\$(Configuration)\ + build\$(ProjectName)\$(Platform)\$(Configuration)\ + $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\..\ThirdParty\winpcap\lib\x86 + $(IncludePath) + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;.\ + ..\..\Source\FreeRTOS-Plus-TCP\source;..\..\Source\FreeRTOS-Plus-TCP\tools;$(SourcePath) + + + false + + + + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) + + + MachineX86 + true + Windows + + + wpcap.lib;%(AdditionalDependencies) + + + + + BUILDING_LIBSLIRP;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + ..\..\ThirdParty\glib;..\..\ThirdParty\glib\glib;..\..\ThirdParty\glib\build;..\..\ThirdParty\glib\build\glib;..\..\ThirdParty\glib\build\subprojects\pcre2-10.42;..\..\ThirdParty\glib\subprojects\proxy-libintl;..\..\ThirdParty\libslirp\src;..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) + + + MachineX86 + true + Windows + + + wpcap.lib;%(AdditionalDependencies) + + + + + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) + + + MachineX86 + true + Windows + true + true + + + wpcap.lib;%(AdditionalDependencies) + + + + + + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) + + + wpcap.lib;%(AdditionalDependencies) + + + + + + BUILDING_LIBSLIRP;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\ThirdParty\glib;..\..\ThirdParty\glib\glib;..\..\ThirdParty\glib\build\;..\..\ThirdParty\glib\build\glib;..\..\ThirdParty\glib\build\subprojects\pcre2-10.42;..\..\ThirdParty\glib\subprojects\proxy-libintl;..\..\ThirdParty\libslirp\src;..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) + + + wpcap.lib;%(AdditionalDependencies) + + + + + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\Source\FreeRTOS-Plus-TCP\source\include;..\..\Source\FreeRTOS-Plus-TCP\source\portable\Compiler\MSVC;..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;..\..\ThirdParty\winpcap\include;..\..\ThirdParty\winpcap\include\pcap;.\;%(AdditionalIncludeDirectories) + + + wpcap.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + true + true + false + true + true + + + false + true + true + false + true + true + + + + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + false + true + true + true + true + false + + + true + true + + + + + + + ipconfigUSE_LIBSLIRP;BUILDING_LIBSLIRP;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ipconfigUSE_LIBSLIRP;BUILDING_LIBSLIRP;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + + + + {72c209c4-49a4-4942-a201-44706c9d77ec} + false + true + true + + + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + false + false + true + true + true + true + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOS+TCP.vcxproj.filters b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOS+TCP.vcxproj.filters index 267b07137..e06353522 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOS+TCP.vcxproj.filters +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOS+TCP.vcxproj.filters @@ -1,942 +1,942 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {a3216426-70cf-4b4f-8b8f-423c8d0416cb} - - - {21d82bd5-24ba-4986-bf91-cc5eefe88952} - - - {6ceb2f4f-e7f3-4a8d-a60b-4c48157f091d} - - - {97a99563-c215-4975-9cb8-c6a29a30f03f} - h - - - {7a52d3bf-8fc9-4242-8636-e173ade0aa68} - - - {2968f486-aba8-47f5-a175-fe77e197a2c6} - - - {b2e06bcd-b665-4ef4-8eff-5203748463d1} - - - {af7dc417-59c0-4c2b-bb4b-cc9b84817e89} - - - {2f9d315d-e376-46c7-b896-052a57fa90c9} - - - {80f9d2cd-c700-4cc5-b0a4-e00ad25ad4b0} - - - {dd33c19f-f4e9-4a7e-bdf9-c2716cf554b9} - - - {e1a1fbf5-cbe9-4b8c-8cc0-b07325ec237a} - - - {c96ee908-213c-4a3b-bf42-eb90362fe673} - - - {0e5bd1c4-dcc1-4cfe-ade2-37c6b0137e5b} - - - {bf054a66-9772-4e3d-9f7d-2ad8b488c759} - - - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - Network Interface\tcp_utilities - - - Network Interface\tcp_utilities - - - Network Interface\tcp_utilities - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - source - - - Network Interface\winpcap - - - Network Interface\libslirp - - - Network Interface\libslirp - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface\libslirp\source - - - Network Interface - - - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - Network Interface\tcp_utilities\include - - - Network Interface\tcp_utilities\include - - - Network Interface\tcp_utilities\include - - - compiler_msvc - - - compiler_msvc - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - Network Interface\winpcap\include - - - - Network Interface\winpcap\include\pcap - - - Network Interface\winpcap\include\pcap - - - Network Interface\winpcap\include\pcap - - - Network Interface\winpcap\include\pcap - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\dependency\glib\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - Network Interface\libslirp\include - - - - - Network Interface\libslirp\dependency\glib\x86 - - - Network Interface\libslirp\dependency\glib\x86 - - - Network Interface\libslirp\dependency\glib\x86 - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {a3216426-70cf-4b4f-8b8f-423c8d0416cb} + + + {21d82bd5-24ba-4986-bf91-cc5eefe88952} + + + {6ceb2f4f-e7f3-4a8d-a60b-4c48157f091d} + + + {97a99563-c215-4975-9cb8-c6a29a30f03f} + h + + + {7a52d3bf-8fc9-4242-8636-e173ade0aa68} + + + {2968f486-aba8-47f5-a175-fe77e197a2c6} + + + {b2e06bcd-b665-4ef4-8eff-5203748463d1} + + + {af7dc417-59c0-4c2b-bb4b-cc9b84817e89} + + + {2f9d315d-e376-46c7-b896-052a57fa90c9} + + + {80f9d2cd-c700-4cc5-b0a4-e00ad25ad4b0} + + + {dd33c19f-f4e9-4a7e-bdf9-c2716cf554b9} + + + {e1a1fbf5-cbe9-4b8c-8cc0-b07325ec237a} + + + {c96ee908-213c-4a3b-bf42-eb90362fe673} + + + {0e5bd1c4-dcc1-4cfe-ade2-37c6b0137e5b} + + + {bf054a66-9772-4e3d-9f7d-2ad8b488c759} + + + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + Network Interface\tcp_utilities + + + Network Interface\tcp_utilities + + + Network Interface\tcp_utilities + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + source + + + Network Interface\winpcap + + + Network Interface\libslirp + + + Network Interface\libslirp + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface\libslirp\source + + + Network Interface + + + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + Network Interface\tcp_utilities\include + + + Network Interface\tcp_utilities\include + + + Network Interface\tcp_utilities\include + + + compiler_msvc + + + compiler_msvc + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + Network Interface\winpcap\include + + + + Network Interface\winpcap\include\pcap + + + Network Interface\winpcap\include\pcap + + + Network Interface\winpcap\include\pcap + + + Network Interface\winpcap\include\pcap + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\dependency\glib\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + Network Interface\libslirp\include + + + + + Network Interface\libslirp\dependency\glib\x86 + + + Network Interface\libslirp\dependency\glib\x86 + + + Network Interface\libslirp\dependency\glib\x86 + + \ No newline at end of file diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOSIPConfig.h b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOSIPConfig.h index 10ed0d5a8..bb372e016 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOSIPConfig.h +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/FreeRTOSIPConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -119,14 +119,14 @@ extern void vLoggingPrintf( const char * pcFormatString, * own random number generation method. For example, it might be possible to * generate a random number by sampling noise on an analogue input. */ extern UBaseType_t uxRand(); -#define ipconfigRAND32() uxRand() +#define ipconfigRAND32() uxRand() /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml */ -#define ipconfigUSE_NETWORK_EVENT_HOOK 1 +#define ipconfigUSE_NETWORK_EVENT_HOOK 1 /* Sockets have a send block time attribute. If FreeRTOS_sendto() is called but * a network buffer cannot be obtained then the calling task is held in the Blocked @@ -140,7 +140,7 @@ extern UBaseType_t uxRand(); * ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in * milliseconds can be converted to a time in ticks by dividing the time in * milliseconds by portTICK_PERIOD_MS. */ -#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000U / portTICK_PERIOD_MS ) +#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000U / portTICK_PERIOD_MS ) /* If ipconfigUSE_DHCP is 1 then FreeRTOS+TCP will attempt to retrieve an IP * address, netmask, DNS server address and gateway address from a DHCP server. If @@ -149,7 +149,7 @@ extern UBaseType_t uxRand(); * set to 1 if a valid configuration cannot be obtained from a DHCP server for any * reason. The static configuration used is that passed into the stack by the * FreeRTOS_IPInit() function call. */ -#define ipconfigUSE_DHCP 1 +#define ipconfigUSE_DHCP 1 /* When ipconfigUSE_DHCP is set to 1, DHCP requests will be sent out at * increasing time intervals until either a reply is received from a DHCP server @@ -158,7 +158,7 @@ extern UBaseType_t uxRand(); * static IP address passed as a parameter to FreeRTOS_IPInit() if the * re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without * a DHCP reply being received. */ -#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( 120000U / portTICK_PERIOD_MS ) +#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( 120000U / portTICK_PERIOD_MS ) /* The ARP cache is a table that maps IP addresses to MAC addresses. The IP * stack can only send a UDP message to a remove IP address if it knowns the MAC @@ -169,19 +169,19 @@ extern UBaseType_t uxRand(); * cache then the UDP message is replaced by a ARP message that solicits the * required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum * number of entries that can exist in the ARP table at any one time. */ -#define ipconfigARP_CACHE_ENTRIES 6 +#define ipconfigARP_CACHE_ENTRIES 6 /* ARP requests that do not result in an ARP response will be re-transmitted a * maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is * aborted. */ -#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 ) +#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 ) /* ipconfigMAX_ARP_AGE defines the maximum time between an entry in the ARP * table being created or refreshed and the entry being removed because it is stale. * New ARP requests are sent for ARP cache entries that are nearing their maximum * age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is * equal to 1500 seconds (or 25 minutes). */ -#define ipconfigMAX_ARP_AGE 150U +#define ipconfigMAX_ARP_AGE 150U /* Implementing FreeRTOS_inet_addr() necessitates the use of string handling * routines, which are relatively large. To save code space the full @@ -193,19 +193,19 @@ extern UBaseType_t uxRand(); * ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and * FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is * not set to 1 then only FreeRTOS_indet_addr_quick() is available. */ -#define ipconfigINCLUDE_FULL_INET_ADDR 1 +#define ipconfigINCLUDE_FULL_INET_ADDR 1 /* ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS defines the total number of network buffer that * are available to the IP stack. The total number of network buffers is limited * to ensure the total amount of RAM that can be consumed by the IP stack is capped * to a pre-determinable value. */ -#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60U +#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60U /* A FreeRTOS queue is used to send events from application tasks to the IP * stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can * be queued for processing at any one time. The event queue must be a minimum of * 5 greater than the total number of network buffers. */ -#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) +#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) /* The address of a socket is the combination of its IP address and its port * number. FreeRTOS_bind() is used to manually allocate a port number to a socket @@ -219,48 +219,48 @@ extern UBaseType_t uxRand(); * ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto() * on a socket that has not yet been bound will result in the send operation being * aborted. */ -#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 +#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 /* Defines the Time To Live (TTL) values used in outgoing UDP packets. */ -#define ipconfigUDP_TIME_TO_LIVE 128 -#define ipconfigTCP_TIME_TO_LIVE 128 /* also defined in FreeRTOSIPConfigDefaults.h */ +#define ipconfigUDP_TIME_TO_LIVE 128 +#define ipconfigTCP_TIME_TO_LIVE 128 /* also defined in FreeRTOSIPConfigDefaults.h */ /* USE_TCP: Use TCP and all its features */ -#define ipconfigUSE_TCP ( 1 ) +#define ipconfigUSE_TCP ( 1 ) /* Use the TCP socket wake context with a callback. */ -#define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK ( 1 ) +#define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK ( 1 ) /* USE_WIN: Let TCP use windowing mechanism. */ -#define ipconfigUSE_TCP_WIN ( 1 ) +#define ipconfigUSE_TCP_WIN ( 1 ) /* The MTU is the maximum number of bytes the payload of a network frame can * contain. For normal Ethernet V2 frames the maximum MTU is 1500. Setting a * lower value can save RAM, depending on the buffer management scheme used. If * ipconfigCAN_FRAGMENT_OUTGOING_PACKETS is 1 then (ipconfigNETWORK_MTU - 28) must * be divisible by 8. */ -#define ipconfigNETWORK_MTU 1500U +#define ipconfigNETWORK_MTU 1500U /* Set ipconfigUSE_DNS to 1 to include a basic DNS client/resolver. DNS is used * through the FreeRTOS_gethostbyname() API function. */ -#define ipconfigUSE_DNS 1 +#define ipconfigUSE_DNS 1 /* If ipconfigREPLY_TO_INCOMING_PINGS is set to 1 then the IP stack will * generate replies to incoming ICMP echo (ping) requests. */ -#define ipconfigREPLY_TO_INCOMING_PINGS 1 +#define ipconfigREPLY_TO_INCOMING_PINGS 1 /* If ipconfigSUPPORT_OUTGOING_PINGS is set to 1 then the * FreeRTOS_SendPingRequest() API function is available. */ -#define ipconfigSUPPORT_OUTGOING_PINGS 0 +#define ipconfigSUPPORT_OUTGOING_PINGS 0 /* If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select() * (and associated) API function is available. */ -#define ipconfigSUPPORT_SELECT_FUNCTION 1 +#define ipconfigSUPPORT_SELECT_FUNCTION 1 /* If ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is set to 1 then Ethernet frames * that are not in Ethernet II format will be dropped. This option is included for * potential future IP stack developments. */ -#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1 +#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1 /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 then it is the * responsibility of the Ethernet interface to filter out packets that are of no @@ -270,57 +270,57 @@ extern UBaseType_t uxRand(); * because the packet will already have been passed into the stack). If the * Ethernet driver does all the necessary filtering in hardware then software * filtering can be removed by using a value other than 1 or 0. */ -#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 +#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 /* The windows simulator cannot really simulate MAC interrupts, and needs to * block occasionally to allow other tasks to run. */ -#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS ) +#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS ) /* Advanced only: in order to access 32-bit fields in the IP packets with * 32-bit memory instructions, all packets will be stored 32-bit-aligned, plus 16-bits. * This has to do with the contents of the IP-packets: all 32-bit fields are * 32-bit-aligned, plus 16-bit(!) */ -#define ipconfigPACKET_FILLER_SIZE 2U +#define ipconfigPACKET_FILLER_SIZE 2U /* Define the size of the pool of TCP window descriptors. On the average, each * TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6 * outstanding packets (for Rx and Tx). When using up to 10 TP sockets * simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */ -#define ipconfigTCP_WIN_SEG_COUNT 240U +#define ipconfigTCP_WIN_SEG_COUNT 240U /* Each TCP socket has a circular buffers for Rx and Tx, which have a fixed * maximum size. Define the size of Rx buffer for TCP sockets. */ -#define ipconfigTCP_RX_BUFFER_LENGTH ( 4096U ) +#define ipconfigTCP_RX_BUFFER_LENGTH ( 4096U ) /* Define the size of Tx buffer for TCP sockets. */ -#define ipconfigTCP_TX_BUFFER_LENGTH ( 4096U ) +#define ipconfigTCP_TX_BUFFER_LENGTH ( 4096U ) /* When using call-back handlers, the driver may check if the handler points to * real program memory (RAM or flash) or just has a random non-zero value. */ -#define ipconfigIS_VALID_PROG_ADDRESS( x ) ( ( x ) != NULL ) +#define ipconfigIS_VALID_PROG_ADDRESS( x ) ( ( x ) != NULL ) /* Include support for TCP hang protection. All sockets in a connecting or * disconnecting stage will timeout after a period of non-activity. */ -#define ipconfigTCP_HANG_PROTECTION ( 1 ) -#define ipconfigTCP_HANG_PROTECTION_TIME ( 30 ) +#define ipconfigTCP_HANG_PROTECTION ( 1 ) +#define ipconfigTCP_HANG_PROTECTION_TIME ( 30 ) /* Include support for TCP keep-alive messages. */ -#define ipconfigTCP_KEEP_ALIVE ( 1 ) -#define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20U ) /* in seconds */ +#define ipconfigTCP_KEEP_ALIVE ( 1 ) +#define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20U ) /* in seconds */ -#define portINLINE __inline +#define portINLINE __inline #include /* Set ipconfigBUFFER_PADDING on 64-bit platforms */ #if INTPTR_MAX == INT64_MAX - #define ipconfigBUFFER_PADDING ( 14U ) + #define ipconfigBUFFER_PADDING ( 14U ) #endif /* INTPTR_MAX == INT64_MAX */ #define configMAC -extern BaseType_t xPlatformIsNetworkUp(void); +extern BaseType_t xPlatformIsNetworkUp( void ); #endif /* FREERTOS_IP_CONFIG_H */ diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/NetworkInterface_WinPCap.c b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/NetworkInterface_WinPCap.c index f886c0d5b..23bbe5bc8 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/NetworkInterface_WinPCap.c +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/NetworkInterface_WinPCap.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -458,16 +458,16 @@ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void ) printf( " (%s)\n", prvRemoveSpaces( cBuffer, sizeof( cBuffer ), xInterface->description ? xInterface->description : "No description" ) ); printf( "\n" ); #ifdef configNETWORK_INTERFACE_TYPE_TO_USE + { + if( xInterface->description != NULL ) { - if( xInterface->description != NULL ) + if( xDesiredAdapter( xInterface->description ) ) { - if( xDesiredAdapter( xInterface->description ) ) - { - printf( "The description of adapter %d matches with '%s'\n", lInterfaceNumber, configNETWORK_INTERFACE_TYPE_TO_USE ); - xConfigNetworkInterfaceToUse = lInterfaceNumber; - } + printf( "The description of adapter %d matches with '%s'\n", lInterfaceNumber, configNETWORK_INTERFACE_TYPE_TO_USE ); + xConfigNetworkInterfaceToUse = lInterfaceNumber; } } + } #endif /* ifdef configNETWORK_INTERFACE_TYPE_TO_USE */ lInterfaceNumber++; } @@ -846,9 +846,9 @@ static void prvInterruptSimulatorTask( void * pvParameters ) pxNetworkBuffer->xDataLength = ( size_t ) pxHeader->len; #if ( niDISRUPT_PACKETS == 1 ) - { - pxNetworkBuffer = vRxFaultInjection( pxNetworkBuffer, pucPacketData ); - } + { + pxNetworkBuffer = vRxFaultInjection( pxNetworkBuffer, pucPacketData ); + } #endif /* niDISRUPT_PACKETS */ if( pxNetworkBuffer != NULL ) diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/libslirp-version.h b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/libslirp-version.h index 4fd051fec..e188f02dc 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/libslirp-version.h +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/libslirp-version.h @@ -1,24 +1,24 @@ /* SPDX-License-Identifier: BSD-3-Clause */ #ifndef LIBSLIRP_VERSION_H_ -#define LIBSLIRP_VERSION_H_ + #define LIBSLIRP_VERSION_H_ -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif -#define SLIRP_MAJOR_VERSION 4 -#define SLIRP_MINOR_VERSION 7 -#define SLIRP_MICRO_VERSION 0 -#define SLIRP_VERSION_STRING "4.7.0" + #define SLIRP_MAJOR_VERSION 4 + #define SLIRP_MINOR_VERSION 7 + #define SLIRP_MICRO_VERSION 0 + #define SLIRP_VERSION_STRING "4.7.0" -#define SLIRP_CHECK_VERSION(major,minor,micro) \ - (SLIRP_MAJOR_VERSION > (major) || \ - (SLIRP_MAJOR_VERSION == (major) && SLIRP_MINOR_VERSION > (minor)) || \ - (SLIRP_MAJOR_VERSION == (major) && SLIRP_MINOR_VERSION == (minor) && \ - SLIRP_MICRO_VERSION >= (micro))) + #define SLIRP_CHECK_VERSION( major, minor, micro ) \ + ( SLIRP_MAJOR_VERSION > ( major ) || \ + ( SLIRP_MAJOR_VERSION == ( major ) && SLIRP_MINOR_VERSION > ( minor ) ) || \ + ( SLIRP_MAJOR_VERSION == ( major ) && SLIRP_MINOR_VERSION == ( minor ) && \ + SLIRP_MICRO_VERSION >= ( micro ) ) ) -#ifdef __cplusplus + #ifdef __cplusplus } /* extern "C" */ -#endif + #endif #endif /* LIBSLIRP_VERSION_H_ */ diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/plus_tcp_hooks_winsim.c b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/plus_tcp_hooks_winsim.c index 8f689da52..d3790851a 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/plus_tcp_hooks_winsim.c +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS+TCP/plus_tcp_hooks_winsim.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -39,12 +39,12 @@ #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - /* In case multiple interfaces are used, define them statically. */ +/* In case multiple interfaces are used, define them statically. */ - /* there is only 1 physical interface. */ +/* there is only 1 physical interface. */ static NetworkInterface_t xInterfaces[ 1 ]; - /* It will have several end-points. */ +/* It will have several end-points. */ static NetworkEndPoint_t xEndPoints[ 4 ]; #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ @@ -69,7 +69,7 @@ #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, - const char * pcName ) + const char * pcName ) #else BaseType_t xApplicationDNSQueryHook( const char * pcName ) #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ @@ -132,7 +132,7 @@ uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress, * events are only received if implemented in the MAC driver. */ #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, - struct xNetworkEndPoint * pxEndPoint ) + struct xNetworkEndPoint * pxEndPoint ) #else void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) #endif @@ -146,11 +146,11 @@ uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress, { /* Print out the network configuration, which may have come from a DHCP * server. */ - #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - FreeRTOS_GetEndPointConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress, pxNetworkEndPoints ); - #else - FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress ); - #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + FreeRTOS_GetEndPointConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress, pxNetworkEndPoints ); + #else + FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress ); + #endif /* defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ FreeRTOS_inet_ntoa( ulIPAddress, cBuffer ); FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) ); @@ -202,30 +202,30 @@ void vPlatformInitIpStack( void ) /* Initialise the network interface.*/ FreeRTOS_debug_printf( ( "FreeRTOS_IPInit\r\n" ) ); -#if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) - /* Initialise the interface descriptor for WinPCap. */ - #ifdef ipconfigUSE_LIBSLIRP - extern NetworkInterface_t* pxLibslirp_FillInterfaceDescriptor(BaseType_t xEMACIndex, - NetworkInterface_t * pxInterface); - pxLibslirp_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); - #else - pxWinPcap_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); - #endif + #if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) + /* Initialise the interface descriptor for WinPCap. */ + #ifdef ipconfigUSE_LIBSLIRP + extern NetworkInterface_t * pxLibslirp_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ); + pxLibslirp_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); + #else + pxWinPcap_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) ); + #endif - /* === End-point 0 === */ - FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + /* === End-point 0 === */ + FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); #if ( ipconfigUSE_DHCP != 0 ) - { - /* End-point 0 wants to use DHCPv4. */ - xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; - } - #endif /* ( ipconfigUSE_DHCP != 0 ) */ - memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof( ucMACAddress ) ); - xResult = FreeRTOS_IPInit_Multi(); -#else - /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ - xResult = FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); -#endif /* defined( FREERTOS_PLUS_TCP_VERSION ) && ( FREERTOS_PLUS_TCP_VERSION >= 10 ) */ + { + /* End-point 0 wants to use DHCPv4. */ + xEndPoints[ 0 ].bits.bWantDHCP = pdTRUE; + } + #endif /* ( ipconfigUSE_DHCP != 0 ) */ + memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof( ucMACAddress ) ); + xResult = FreeRTOS_IPInit_Multi(); + #else /* if defined( ipconfigIPv4_BACKWARD_COMPATIBLE ) && ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) */ + /* Using the old /single /IPv4 library, or using backward compatible mode of the new /multi library. */ + xResult = FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress ); + #endif /* defined( FREERTOS_PLUS_TCP_VERSION ) && ( FREERTOS_PLUS_TCP_VERSION >= 10 ) */ configASSERT( xResult == pdTRUE ); } @@ -254,5 +254,5 @@ BaseType_t xPlatformIsNetworkUp( void ) return eDHCPContinue; } -#endif +#endif /* if ( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_DHCP_HOOK != 0 ) ) */ /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/FreeRTOS-Kernel.vcxproj.filters b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/FreeRTOS-Kernel.vcxproj.filters index b1ba92a1d..974225fb0 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/FreeRTOS-Kernel.vcxproj.filters +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/FreeRTOS-Kernel.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/FreeRTOSConfig.h b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/FreeRTOSConfig.h index 67f64008c..6bc03048f 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/FreeRTOSConfig.h +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -96,7 +96,7 @@ #define INCLUDE_xEventGroupSetBitsFromISR 1 #define INCLUDE_xTimerPendFunctionCall 1 #define INCLUDE_pcTaskGetTaskName 1 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 /* This demo makes use of one or more example stats formatting functions. These * format the raw data provided by the uxTaskGetSystemState() function in to human @@ -119,7 +119,7 @@ unsigned long ulGetRunTimeCounterValue( void ); void vConfigureTimerForRunTimeStats( void ); -#define configGENERATE_RUN_TIME_STATS 1 +#define configGENERATE_RUN_TIME_STATS 1 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() #define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() @@ -210,19 +210,19 @@ extern void vLoggingPrintf( const char * pcFormatString, ... ); #define configPRINTF( X ) vLoggingPrintf X -#define portNOP() __nop() +#define portNOP() __nop() /* The UDP port to use for incoming command inputs. The outgoing port is -set to ( configUDP_CLI_PORT_NUMBER + 1 ). */ -#define configUDP_CLI_PORT_NUMBER 5001 + * set to ( configUDP_CLI_PORT_NUMBER + 1 ). */ +#define configUDP_CLI_PORT_NUMBER 5001 /* The size of the global output buffer that is available for use when there -are multiple command interpreters running at once (for example, one on a UART -and one on TCP/IP). This is done to prevent an output buffer being defined by -each implementation - which would waste RAM. In this case, there is only one -command interpreter running, and it has its own local output buffer, so the -global buffer is just set to be one byte long as it is not used and should not -take up unnecessary RAM. */ -#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1 + * are multiple command interpreters running at once (for example, one on a UART + * and one on TCP/IP). This is done to prevent an output buffer being defined by + * each implementation - which would waste RAM. In this case, there is only one + * command interpreter running, and it has its own local output buffer, so the + * global buffer is just set to be one byte long as it is not used and should not + * take up unnecessary RAM. */ +#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1 #endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/freertos_hooks_winsim.c b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/freertos_hooks_winsim.c index 437af12c2..65e351f40 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/freertos_hooks_winsim.c +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/freertos_hooks_winsim.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -89,58 +89,60 @@ UBaseType_t uxRand( void ) /*-----------------------------------------------------------*/ #if defined( configUSE_STATIC_ALLOCATION ) && ( configUSE_STATIC_ALLOCATION == 1U ) - /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an - * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is - * used by the Idle task. */ + +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an + * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is + * used by the Idle task. */ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t * pulIdleTaskStackSize ) { /* If the buffers to be provided to the Idle task are declared inside this - * function then they must be declared static - otherwise they will be allocated on - * the stack and so not exists after this function exits. */ + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; /* Pass out a pointer to the StaticTask_t structure in which the Idle task's - * state will be stored. */ + * state will be stored. */ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; /* Pass out the array that will be used as the Idle task's stack. */ *ppxIdleTaskStackBuffer = uxIdleTaskStack; /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. - * Note that, as the array is necessarily of type StackType_t, - * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + * Note that, as the array is necessarily of type StackType_t, + * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /*-----------------------------------------------------------*/ #if defined( configUSE_TIMERS ) && ( configUSE_TIMERS == 1U ) - /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the - * application must provide an implementation of vApplicationGetTimerTaskMemory() - * to provide the memory that is used by the Timer service task. */ + +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the + * application must provide an implementation of vApplicationGetTimerTaskMemory() + * to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, - StackType_t ** ppxTimerTaskStackBuffer, - uint32_t * pulTimerTaskStackSize ) + StackType_t ** ppxTimerTaskStackBuffer, + uint32_t * pulTimerTaskStackSize ) { /* If the buffers to be provided to the Timer task are declared inside this - * function then they must be declared static - otherwise they will be allocated on - * the stack and so not exists after this function exits. */ + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ static StaticTask_t xTimerTaskTCB; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; /* Pass out a pointer to the StaticTask_t structure in which the Timer - * task's state will be stored. */ + * task's state will be stored. */ *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; /* Pass out the array that will be used as the Timer task's stack. */ *ppxTimerTaskStackBuffer = uxTimerTaskStack; /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. - * Note that, as the array is necessarily of type StackType_t, - * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + * Note that, as the array is necessarily of type StackType_t, + * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } #endif /* defined( configUSE_TIMERS ) && ( configUSE_TIMERS == 1U ) */ @@ -149,7 +151,7 @@ UBaseType_t uxRand( void ) /*-----------------------------------------------------------*/ -#if( configUSE_MALLOC_FAILED_HOOK == 1U ) +#if ( configUSE_MALLOC_FAILED_HOOK == 1U ) void vApplicationMallocFailedHook( void ) { /* @@ -172,7 +174,7 @@ UBaseType_t uxRand( void ) /*-----------------------------------------------------------*/ -#if( configUSE_IDLE_HOOK == 1U ) +#if ( configUSE_IDLE_HOOK == 1U ) void vApplicationIdleHook( void ) { /* @@ -191,7 +193,7 @@ UBaseType_t uxRand( void ) /*-----------------------------------------------------------*/ -#if( configUSE_TICK_HOOK == 1U ) +#if ( configUSE_TICK_HOOK == 1U ) void vApplicationTickHook( void ) { /* @@ -206,15 +208,16 @@ UBaseType_t uxRand( void ) /*-----------------------------------------------------------*/ -#if( configSUPPORT_STATIC_ALLOCATION == 1U ) - /* - * configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the - * application must provide an implementation of vApplicationGetTimerTaskMemory() - * to provide the memory that is used by the Timer service task. - */ - void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, - StackType_t **ppxTimerTaskStackBuffer, - uint32_t *pulTimerTaskStackSize ) +#if ( configSUPPORT_STATIC_ALLOCATION == 1U ) + +/* + * configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the + * application must provide an implementation of vApplicationGetTimerTaskMemory() + * to provide the memory that is used by the Timer service task. + */ + void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + uint32_t * pulTimerTaskStackSize ) { /* * If the buffers to be provided to the Timer task are declared inside this @@ -244,15 +247,16 @@ UBaseType_t uxRand( void ) /*-----------------------------------------------------------*/ -#if( configSUPPORT_STATIC_ALLOCATION == 1U ) - /* - * configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an - * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is - * used by the Idle task. - */ - void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, - StackType_t **ppxIdleTaskStackBuffer, - uint32_t *pulIdleTaskStackSize ) +#if ( configSUPPORT_STATIC_ALLOCATION == 1U ) + +/* + * configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an + * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is + * used by the Idle task. + */ + void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + uint32_t * pulIdleTaskStackSize ) { /* * If the buffers to be provided to the Idle task are declared inside this @@ -280,4 +284,4 @@ UBaseType_t uxRand( void ) } #endif /* configSUPPORT_STATIC_ALLOCATION == 1U */ -/*-----------------------------------------------------------*/ \ No newline at end of file +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/runtime_stats_winsim.c b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/runtime_stats_winsim.c index f76f295e0..58d8cc843 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/runtime_stats_winsim.c +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS-Kernel/runtime_stats_winsim.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -34,7 +34,7 @@ * * Also note that it is assumed this demo is going to be used for short periods * of time only, and therefore timer overflows are not handled. -*/ + */ #include #include @@ -45,25 +45,25 @@ #if configGENERATE_RUN_TIME_STATS == 1 /* Time at start of day (in ns). */ -static LARGE_INTEGER lStartTime; + static LARGE_INTEGER lStartTime; /*-----------------------------------------------------------*/ -void vConfigureTimerForRunTimeStats( void ) -{ - ( void ) QueryPerformanceCounter( &lStartTime ); -} + void vConfigureTimerForRunTimeStats( void ) + { + ( void ) QueryPerformanceCounter( &lStartTime ); + } /*-----------------------------------------------------------*/ -unsigned long ulGetRunTimeCounterValue( void ) -{ - LARGE_INTEGER lCurrentTime; - ( void ) QueryPerformanceCounter( &lCurrentTime ); + unsigned long ulGetRunTimeCounterValue( void ) + { + LARGE_INTEGER lCurrentTime; - configASSERT( lCurrentTime.QuadPart > lStartTime.QuadPart ); + ( void ) QueryPerformanceCounter( &lCurrentTime ); - return ( unsigned long ) ( lCurrentTime.QuadPart - lStartTime.QuadPart ); + configASSERT( lCurrentTime.QuadPart > lStartTime.QuadPart ); -} + return ( unsigned long ) ( lCurrentTime.QuadPart - lStartTime.QuadPart ); + } /*-----------------------------------------------------------*/ #endif /* configGENERATE_RUN_TIME_STATS == 1 */ diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS_Plus_Libs.sln b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS_Plus_Libs.sln index 35ca82aff..1b678f14c 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS_Plus_Libs.sln +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/FreeRTOS_Plus_Libs.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.33529.622 diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/Logging/Logging.vcxproj.filters b/FreeRTOS-Plus/VisualStudio_StaticProjects/Logging/Logging.vcxproj.filters index dc525e99d..d92304c04 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/Logging/Logging.vcxproj.filters +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/Logging/Logging.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/MbedTLS.vcxproj.filters b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/MbedTLS.vcxproj.filters index 1a629eeaa..75a2f69aa 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/MbedTLS.vcxproj.filters +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/MbedTLS.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_config_v3.2.1.h b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_config_v3.2.1.h index 1256d4273..7d5dedc5a 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_config_v3.2.1.h +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_config_v3.2.1.h @@ -7,6 +7,7 @@ * or disable features selectively, and reduce the global * memory footprint. */ + /* * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 @@ -31,7 +32,7 @@ * It is equal to the #MBEDTLS_VERSION_NUMBER of the Mbed TLS version that * introduced the config format we want to be compatible with. */ -//#define MBEDTLS_CONFIG_VERSION 0x03000000 +/*#define MBEDTLS_CONFIG_VERSION 0x03000000 */ /** * \name SECTION: System support @@ -85,7 +86,7 @@ * example, if double-width division is implemented in software, disabling * it can reduce code size in some embedded targets. */ -//#define MBEDTLS_NO_UDBL_DIVISION +/*#define MBEDTLS_NO_UDBL_DIVISION */ /** * \def MBEDTLS_NO_64BIT_MULTIPLICATION @@ -107,7 +108,7 @@ * Note that depending on the compiler, this may decrease performance compared * to using the library function provided by the toolchain. */ -//#define MBEDTLS_NO_64BIT_MULTIPLICATION +/*#define MBEDTLS_NO_64BIT_MULTIPLICATION */ /** * \def MBEDTLS_HAVE_SSE2 @@ -116,7 +117,7 @@ * * Uncomment if the CPU supports SSE2 (IA-32 specific). */ -//#define MBEDTLS_HAVE_SSE2 +/*#define MBEDTLS_HAVE_SSE2 */ /** * \def MBEDTLS_HAVE_TIME @@ -136,7 +137,7 @@ * regardless of the setting of MBEDTLS_HAVE_TIME, unless * MBEDTLS_TIMING_ALT is used. See timing.c for more information. */ -//#define MBEDTLS_HAVE_TIME +/*#define MBEDTLS_HAVE_TIME */ /** * \def MBEDTLS_HAVE_TIME_DATE @@ -157,7 +158,7 @@ * mbedtls_platform_gmtime_r() at compile-time by using the macro * MBEDTLS_PLATFORM_GMTIME_R_ALT. */ -//#define MBEDTLS_HAVE_TIME_DATE +/*#define MBEDTLS_HAVE_TIME_DATE */ /** * \def MBEDTLS_PLATFORM_MEMORY @@ -205,7 +206,7 @@ void mbedtls_platform_free( void * ptr ); * Uncomment to prevent default assignment of standard functions in the * platform layer. */ -//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +/*#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ /** * \def MBEDTLS_PLATFORM_EXIT_ALT @@ -230,15 +231,15 @@ void mbedtls_platform_free( void * ptr ); * Uncomment a macro to enable alternate implementation of specific base * platform function */ -//#define MBEDTLS_PLATFORM_SETBUF_ALT -//#define MBEDTLS_PLATFORM_EXIT_ALT -//#define MBEDTLS_PLATFORM_TIME_ALT -//#define MBEDTLS_PLATFORM_FPRINTF_ALT -//#define MBEDTLS_PLATFORM_PRINTF_ALT -//#define MBEDTLS_PLATFORM_SNPRINTF_ALT -//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT -//#define MBEDTLS_PLATFORM_NV_SEED_ALT -//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT +/*#define MBEDTLS_PLATFORM_SETBUF_ALT */ +/*#define MBEDTLS_PLATFORM_EXIT_ALT */ +/*#define MBEDTLS_PLATFORM_TIME_ALT */ +/*#define MBEDTLS_PLATFORM_FPRINTF_ALT */ +/*#define MBEDTLS_PLATFORM_PRINTF_ALT */ +/*#define MBEDTLS_PLATFORM_SNPRINTF_ALT */ +/*#define MBEDTLS_PLATFORM_VSNPRINTF_ALT */ +/*#define MBEDTLS_PLATFORM_NV_SEED_ALT */ +/*#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ /** * \def MBEDTLS_DEPRECATED_WARNING @@ -253,7 +254,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to get warnings on using deprecated functions and features. */ -#if defined(__GNUC__) +#if defined( __GNUC__ ) #define MBEDTLS_DEPRECATED_WARNING #endif @@ -267,7 +268,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to get errors on using deprecated functions and features. */ -//#define MBEDTLS_DEPRECATED_REMOVED +/*#define MBEDTLS_DEPRECATED_REMOVED */ /** \} name SECTION: System support */ @@ -290,7 +291,7 @@ void mbedtls_platform_free( void * ptr ); * You will need to provide a header "timing_alt.h" and an implementation at * compile time. */ -//#define MBEDTLS_TIMING_ALT +/*#define MBEDTLS_TIMING_ALT */ /** * \def MBEDTLS_AES_ALT @@ -317,25 +318,25 @@ void mbedtls_platform_free( void * ptr ); * digests and ciphers instead. * */ -//#define MBEDTLS_AES_ALT -//#define MBEDTLS_ARIA_ALT -//#define MBEDTLS_CAMELLIA_ALT -//#define MBEDTLS_CCM_ALT -//#define MBEDTLS_CHACHA20_ALT -//#define MBEDTLS_CHACHAPOLY_ALT -//#define MBEDTLS_CMAC_ALT -//#define MBEDTLS_DES_ALT -//#define MBEDTLS_DHM_ALT -//#define MBEDTLS_ECJPAKE_ALT -//#define MBEDTLS_GCM_ALT -//#define MBEDTLS_NIST_KW_ALT -//#define MBEDTLS_MD5_ALT -//#define MBEDTLS_POLY1305_ALT -//#define MBEDTLS_RIPEMD160_ALT -//#define MBEDTLS_RSA_ALT -//#define MBEDTLS_SHA1_ALT -//#define MBEDTLS_SHA256_ALT -//#define MBEDTLS_SHA512_ALT +/*#define MBEDTLS_AES_ALT */ +/*#define MBEDTLS_ARIA_ALT */ +/*#define MBEDTLS_CAMELLIA_ALT */ +/*#define MBEDTLS_CCM_ALT */ +/*#define MBEDTLS_CHACHA20_ALT */ +/*#define MBEDTLS_CHACHAPOLY_ALT */ +/*#define MBEDTLS_CMAC_ALT */ +/*#define MBEDTLS_DES_ALT */ +/*#define MBEDTLS_DHM_ALT */ +/*#define MBEDTLS_ECJPAKE_ALT */ +/*#define MBEDTLS_GCM_ALT */ +/*#define MBEDTLS_NIST_KW_ALT */ +/*#define MBEDTLS_MD5_ALT */ +/*#define MBEDTLS_POLY1305_ALT */ +/*#define MBEDTLS_RIPEMD160_ALT */ +/*#define MBEDTLS_RSA_ALT */ +/*#define MBEDTLS_SHA1_ALT */ +/*#define MBEDTLS_SHA256_ALT */ +/*#define MBEDTLS_SHA512_ALT */ /* * When replacing the elliptic curve module, please consider, that it is @@ -346,7 +347,7 @@ void mbedtls_platform_free( void * ptr ); * macros as described above. The only difference is that you have to make sure * that you provide functionality for both .c files. */ -//#define MBEDTLS_ECP_ALT +/*#define MBEDTLS_ECP_ALT */ /** * \def MBEDTLS_SHA256_PROCESS_ALT @@ -385,23 +386,23 @@ void mbedtls_platform_free( void * ptr ); * implementation should be provided for mbedtls_ecdsa_sign_det_ext(). * */ -//#define MBEDTLS_MD5_PROCESS_ALT -//#define MBEDTLS_RIPEMD160_PROCESS_ALT -//#define MBEDTLS_SHA1_PROCESS_ALT -//#define MBEDTLS_SHA256_PROCESS_ALT -//#define MBEDTLS_SHA512_PROCESS_ALT -//#define MBEDTLS_DES_SETKEY_ALT -//#define MBEDTLS_DES_CRYPT_ECB_ALT -//#define MBEDTLS_DES3_CRYPT_ECB_ALT -//#define MBEDTLS_AES_SETKEY_ENC_ALT -//#define MBEDTLS_AES_SETKEY_DEC_ALT -//#define MBEDTLS_AES_ENCRYPT_ALT -//#define MBEDTLS_AES_DECRYPT_ALT -//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT -//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT -//#define MBEDTLS_ECDSA_VERIFY_ALT -//#define MBEDTLS_ECDSA_SIGN_ALT -//#define MBEDTLS_ECDSA_GENKEY_ALT +/*#define MBEDTLS_MD5_PROCESS_ALT */ +/*#define MBEDTLS_RIPEMD160_PROCESS_ALT */ +/*#define MBEDTLS_SHA1_PROCESS_ALT */ +/*#define MBEDTLS_SHA256_PROCESS_ALT */ +/*#define MBEDTLS_SHA512_PROCESS_ALT */ +/*#define MBEDTLS_DES_SETKEY_ALT */ +/*#define MBEDTLS_DES_CRYPT_ECB_ALT */ +/*#define MBEDTLS_DES3_CRYPT_ECB_ALT */ +/*#define MBEDTLS_AES_SETKEY_ENC_ALT */ +/*#define MBEDTLS_AES_SETKEY_DEC_ALT */ +/*#define MBEDTLS_AES_ENCRYPT_ALT */ +/*#define MBEDTLS_AES_DECRYPT_ALT */ +/*#define MBEDTLS_ECDH_GEN_PUBLIC_ALT */ +/*#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ +/*#define MBEDTLS_ECDSA_VERIFY_ALT */ +/*#define MBEDTLS_ECDSA_SIGN_ALT */ +/*#define MBEDTLS_ECDSA_GENKEY_ALT */ /** * \def MBEDTLS_ECP_INTERNAL_ALT @@ -454,19 +455,19 @@ void mbedtls_platform_free( void * ptr ); * function. */ /* Required for all the functions in this section */ -//#define MBEDTLS_ECP_INTERNAL_ALT +/*#define MBEDTLS_ECP_INTERNAL_ALT */ /* Turn off software fallback for curves not supported in hardware */ -//#define MBEDTLS_ECP_NO_FALLBACK +/*#define MBEDTLS_ECP_NO_FALLBACK */ /* Support for Weierstrass curves with Jacobi representation */ -//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT -//#define MBEDTLS_ECP_ADD_MIXED_ALT -//#define MBEDTLS_ECP_DOUBLE_JAC_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/*#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ +/*#define MBEDTLS_ECP_ADD_MIXED_ALT */ +/*#define MBEDTLS_ECP_DOUBLE_JAC_ALT */ +/*#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT */ +/*#define MBEDTLS_ECP_NORMALIZE_JAC_ALT */ /* Support for curves with Montgomery arithmetic */ -//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT -//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT -//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT +/*#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ +/*#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ +/*#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ /** * \def MBEDTLS_ENTROPY_HARDWARE_ALT @@ -522,7 +523,7 @@ void mbedtls_platform_free( void * ptr ); * This option is independent of \c MBEDTLS_AES_ROM_TABLES. * */ -//#define MBEDTLS_AES_FEWER_TABLES +/*#define MBEDTLS_AES_FEWER_TABLES */ /** * \def MBEDTLS_CAMELLIA_SMALL_MEMORY @@ -531,7 +532,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this macro to use less memory for Camellia. */ -//#define MBEDTLS_CAMELLIA_SMALL_MEMORY +/*#define MBEDTLS_CAMELLIA_SMALL_MEMORY */ /** * \def MBEDTLS_CHECK_RETURN_WARNING @@ -554,7 +555,7 @@ void mbedtls_platform_free( void * ptr ); * macro is not defined. To completely disable return value check * warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion. */ -//#define MBEDTLS_CHECK_RETURN_WARNING +/*#define MBEDTLS_CHECK_RETURN_WARNING */ /** * \def MBEDTLS_CIPHER_MODE_CBC @@ -621,7 +622,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this macro to enable the NULL cipher and ciphersuites */ -//#define MBEDTLS_CIPHER_NULL_CIPHER +/*#define MBEDTLS_CIPHER_NULL_CIPHER */ /** * \def MBEDTLS_CIPHER_PADDING_PKCS7 @@ -644,7 +645,7 @@ void mbedtls_platform_free( void * ptr ); * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. * By default, CTR_DRBG uses a 256-bit key. */ -//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY +/*#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ /** * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED @@ -655,17 +656,17 @@ void mbedtls_platform_free( void * ptr ); * Comment macros to disable the curve and functions for it */ /* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */ -//#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -//#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +/*#define MBEDTLS_ECP_DP_SECP192R1_ENABLED */ +/*#define MBEDTLS_ECP_DP_SECP224R1_ENABLED */ #define MBEDTLS_ECP_DP_SECP256R1_ENABLED #define MBEDTLS_ECP_DP_SECP384R1_ENABLED #define MBEDTLS_ECP_DP_SECP521R1_ENABLED -//#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -//#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -//#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -//#define MBEDTLS_ECP_DP_BP256R1_ENABLED -//#define MBEDTLS_ECP_DP_BP384R1_ENABLED -//#define MBEDTLS_ECP_DP_BP512R1_ENABLED +/*#define MBEDTLS_ECP_DP_SECP192K1_ENABLED */ +/*#define MBEDTLS_ECP_DP_SECP224K1_ENABLED */ +/*#define MBEDTLS_ECP_DP_SECP256K1_ENABLED */ +/*#define MBEDTLS_ECP_DP_BP256R1_ENABLED */ +/*#define MBEDTLS_ECP_DP_BP384R1_ENABLED */ +/*#define MBEDTLS_ECP_DP_BP512R1_ENABLED */ /* Montgomery curves (supporting ECP) */ #define MBEDTLS_ECP_DP_CURVE25519_ENABLED #define MBEDTLS_ECP_DP_CURVE448_ENABLED @@ -703,7 +704,7 @@ void mbedtls_platform_free( void * ptr ); * elliptic curve functionality. It is incompatible with * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT. */ -//#define MBEDTLS_ECP_RESTARTABLE +/*#define MBEDTLS_ECP_RESTARTABLE */ /** * \def MBEDTLS_ECDSA_DETERMINISTIC @@ -737,7 +738,7 @@ void mbedtls_platform_free( void * ptr ); * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */ -//#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED +/*#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ /** * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED @@ -766,7 +767,7 @@ void mbedtls_platform_free( void * ptr ); * See dhm.h for more details. * */ -//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED +/*#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ /** * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED @@ -784,7 +785,7 @@ void mbedtls_platform_free( void * ptr ); * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */ -//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED +/*#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ /** * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED @@ -807,7 +808,7 @@ void mbedtls_platform_free( void * ptr ); * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */ -//#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED +/*#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ /** * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED @@ -864,7 +865,7 @@ void mbedtls_platform_free( void * ptr ); * See dhm.h for more details. * */ -//#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED +/*#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ /** * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED @@ -931,7 +932,7 @@ void mbedtls_platform_free( void * ptr ); * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */ -//#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED +/*#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ /** * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED @@ -953,7 +954,7 @@ void mbedtls_platform_free( void * ptr ); * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */ -//#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED +/*#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ /** * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED @@ -972,7 +973,7 @@ void mbedtls_platform_free( void * ptr ); * enabled as well): * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 */ -//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +/*#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ /** * \def MBEDTLS_PK_PARSE_EC_EXTENDED @@ -1017,7 +1018,7 @@ void mbedtls_platform_free( void * ptr ); * * Enable functions that use the filesystem. */ -//#define MBEDTLS_FS_IO +/*#define MBEDTLS_FS_IO */ /** * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES @@ -1029,7 +1030,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this macro to prevent loading of default entropy functions. */ -//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES +/*#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ /** * \def MBEDTLS_NO_PLATFORM_ENTROPY @@ -1056,7 +1057,7 @@ void mbedtls_platform_free( void * ptr ); * This option is only useful if both MBEDTLS_SHA256_C and * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. */ -//#define MBEDTLS_ENTROPY_FORCE_SHA256 +/*#define MBEDTLS_ENTROPY_FORCE_SHA256 */ /** * \def MBEDTLS_ENTROPY_NV_SEED @@ -1084,7 +1085,7 @@ void mbedtls_platform_free( void * ptr ); * \note The entropy collector will write to the seed file before entropy is * given to an external source, to update it. */ -//#define MBEDTLS_ENTROPY_NV_SEED +/*#define MBEDTLS_ENTROPY_NV_SEED */ /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER * @@ -1096,7 +1097,7 @@ void mbedtls_platform_free( void * ptr ); * Note that this option is meant for internal use only and may be removed * without notice. */ -//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +/*#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ /** * \def MBEDTLS_MEMORY_DEBUG @@ -1109,7 +1110,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this macro to let the buffer allocator print out error messages. */ -//#define MBEDTLS_MEMORY_DEBUG +/*#define MBEDTLS_MEMORY_DEBUG */ /** * \def MBEDTLS_MEMORY_BACKTRACE @@ -1121,7 +1122,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this macro to include backtrace information */ -//#define MBEDTLS_MEMORY_BACKTRACE +/*#define MBEDTLS_MEMORY_BACKTRACE */ /** * \def MBEDTLS_PK_RSA_ALT_SUPPORT @@ -1130,7 +1131,7 @@ void mbedtls_platform_free( void * ptr ); * * Comment this macro to disable support for external private RSA keys. */ -//#define MBEDTLS_PK_RSA_ALT_SUPPORT +/*#define MBEDTLS_PK_RSA_ALT_SUPPORT */ /** * \def MBEDTLS_PKCS1_V15 @@ -1168,7 +1169,7 @@ void mbedtls_platform_free( void * ptr ); * \warning This interface is experimental and may change or be removed * without notice. */ -//#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS +/*#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ /** \def MBEDTLS_PSA_CRYPTO_CLIENT * @@ -1184,7 +1185,7 @@ void mbedtls_platform_free( void * ptr ); * \warning This interface is experimental and may change or be removed * without notice. */ -//#define MBEDTLS_PSA_CRYPTO_CLIENT +/*#define MBEDTLS_PSA_CRYPTO_CLIENT */ /** \def MBEDTLS_PSA_CRYPTO_DRIVERS * @@ -1196,7 +1197,7 @@ void mbedtls_platform_free( void * ptr ); * compatibility with application code that relies on drivers, * but the driver interfaces may change without notice. */ -//#define MBEDTLS_PSA_CRYPTO_DRIVERS +/*#define MBEDTLS_PSA_CRYPTO_DRIVERS */ /** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG * @@ -1234,7 +1235,7 @@ void mbedtls_platform_free( void * ptr ); * * \note This option is experimental and may be removed without notice. */ -//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG +/*#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ /** * \def MBEDTLS_PSA_CRYPTO_SPM @@ -1248,7 +1249,7 @@ void mbedtls_platform_free( void * ptr ); * Requires: MBEDTLS_PSA_CRYPTO_C * */ -//#define MBEDTLS_PSA_CRYPTO_SPM +/*#define MBEDTLS_PSA_CRYPTO_SPM */ /** * \def MBEDTLS_PSA_INJECT_ENTROPY @@ -1261,7 +1262,7 @@ void mbedtls_platform_free( void * ptr ); * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED * */ -//#define MBEDTLS_PSA_INJECT_ENTROPY +/*#define MBEDTLS_PSA_INJECT_ENTROPY */ /** * \def MBEDTLS_RSA_NO_CRT @@ -1272,14 +1273,14 @@ void mbedtls_platform_free( void * ptr ); * Uncomment this macro to disable the use of CRT in RSA. * */ -//#define MBEDTLS_RSA_NO_CRT +/*#define MBEDTLS_RSA_NO_CRT */ /** * \def MBEDTLS_SELF_TEST * * Enable the checkup functions (*_self_test). */ -//#define MBEDTLS_SELF_TEST +/*#define MBEDTLS_SELF_TEST */ /** * \def MBEDTLS_SHA256_SMALLER @@ -1295,7 +1296,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to enable the smaller implementation of SHA256. */ -//#define MBEDTLS_SHA256_SMALLER +/*#define MBEDTLS_SHA256_SMALLER */ /** * \def MBEDTLS_SHA512_SMALLER @@ -1305,7 +1306,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to enable the smaller implementation of SHA512. */ -//#define MBEDTLS_SHA512_SMALLER +/*#define MBEDTLS_SHA512_SMALLER */ /** * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES @@ -1348,7 +1349,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to enable the Connection ID extension. */ -//#define MBEDTLS_SSL_DTLS_CONNECTION_ID +/*#define MBEDTLS_SSL_DTLS_CONNECTION_ID */ /** * \def MBEDTLS_SSL_ASYNC_PRIVATE @@ -1359,7 +1360,7 @@ void mbedtls_platform_free( void * ptr ); * operation inside the library. * */ -//#define MBEDTLS_SSL_ASYNC_PRIVATE +/*#define MBEDTLS_SSL_ASYNC_PRIVATE */ /** * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION @@ -1386,7 +1387,7 @@ void mbedtls_platform_free( void * ptr ); * * Comment to disable the context serialization APIs. */ -//#define MBEDTLS_SSL_CONTEXT_SERIALIZATION +/*#define MBEDTLS_SSL_CONTEXT_SERIALIZATION */ /** * \def MBEDTLS_SSL_DEBUG_ALL @@ -1402,7 +1403,7 @@ void mbedtls_platform_free( void * ptr ); * a timing side-channel. * */ -//#define MBEDTLS_SSL_DEBUG_ALL +/*#define MBEDTLS_SSL_DEBUG_ALL */ /** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC * @@ -1480,7 +1481,7 @@ void mbedtls_platform_free( void * ptr ); * configuration of this extension). * */ -//#define MBEDTLS_SSL_RENEGOTIATION +/*#define MBEDTLS_SSL_RENEGOTIATION */ /** * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH @@ -1523,7 +1524,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this macro to enable the support for TLS 1.3. */ -//#define MBEDTLS_SSL_PROTO_TLS1_3 +/*#define MBEDTLS_SSL_PROTO_TLS1_3 */ /** * \def MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE @@ -1545,7 +1546,7 @@ void mbedtls_platform_free( void * ptr ); * effect on the build. * */ -//#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +/*#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ /** * \def MBEDTLS_SSL_PROTO_DTLS @@ -1631,7 +1632,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this to enable support for use_srtp extension. */ -//#define MBEDTLS_SSL_DTLS_SRTP +/*#define MBEDTLS_SSL_DTLS_SRTP */ /** * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE @@ -1698,7 +1699,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to enable testing of the constant-flow nature of selected code. */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN +/*#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */ /** * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND @@ -1717,7 +1718,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to enable testing of the constant-flow nature of selected code. */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND +/*#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */ /** * \def MBEDTLS_TEST_HOOKS @@ -1737,7 +1738,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to enable invasive tests. */ -//#define MBEDTLS_TEST_HOOKS +/*#define MBEDTLS_TEST_HOOKS */ /** * \def MBEDTLS_THREADING_ALT @@ -1748,7 +1749,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this to allow your own alternate threading implementation. */ -//#define MBEDTLS_THREADING_ALT +/*#define MBEDTLS_THREADING_ALT */ /** * \def MBEDTLS_THREADING_PTHREAD @@ -1759,7 +1760,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this to enable pthread mutexes. */ -//#define MBEDTLS_THREADING_PTHREAD +/*#define MBEDTLS_THREADING_PTHREAD */ /** * \def MBEDTLS_USE_PSA_CRYPTO @@ -1783,7 +1784,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment this to enable internal use of PSA Crypto and new associated APIs. */ -//#define MBEDTLS_USE_PSA_CRYPTO +/*#define MBEDTLS_USE_PSA_CRYPTO */ /** * \def MBEDTLS_PSA_CRYPTO_CONFIG @@ -1808,7 +1809,7 @@ void mbedtls_platform_free( void * ptr ); * This feature is still experimental and is not ready for production since * it is not completed. */ -//#define MBEDTLS_PSA_CRYPTO_CONFIG +/*#define MBEDTLS_PSA_CRYPTO_CONFIG */ /** * \def MBEDTLS_VERSION_FEATURES @@ -1821,7 +1822,7 @@ void mbedtls_platform_free( void * ptr ); * * Comment this to disable run-time checking and save ROM space */ -//#define MBEDTLS_VERSION_FEATURES +/*#define MBEDTLS_VERSION_FEATURES */ /** * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK @@ -1851,7 +1852,7 @@ void mbedtls_platform_free( void * ptr ); * and other functions/constants only used by these functions, thus reducing * the code footprint by several KB. */ -//#define MBEDTLS_X509_REMOVE_INFO +/*#define MBEDTLS_X509_REMOVE_INFO */ /** * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT @@ -1883,7 +1884,7 @@ void mbedtls_platform_free( void * ptr ); * * This modules adds support for the AES-NI instructions on x86-64 */ -//#define MBEDTLS_AESNI_C +/*#define MBEDTLS_AESNI_C */ /** * \def MBEDTLS_AES_C @@ -2070,7 +2071,7 @@ void mbedtls_platform_free( void * ptr ); * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */ -//#define MBEDTLS_CAMELLIA_C +/*#define MBEDTLS_CAMELLIA_C */ /** * \def MBEDTLS_ARIA_C @@ -2122,7 +2123,7 @@ void mbedtls_platform_free( void * ptr ); * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */ -//#define MBEDTLS_ARIA_C +/*#define MBEDTLS_ARIA_C */ /** * \def MBEDTLS_CCM_C @@ -2137,7 +2138,7 @@ void mbedtls_platform_free( void * ptr ); * This module enables the AES-CCM ciphersuites, if other requisites are * enabled as well. */ -//#define MBEDTLS_CCM_C +/*#define MBEDTLS_CCM_C */ /** * \def MBEDTLS_CHACHA20_C @@ -2232,7 +2233,7 @@ void mbedtls_platform_free( void * ptr ); * * This module provides debugging functions. */ -//#define MBEDTLS_DEBUG_C +/*#define MBEDTLS_DEBUG_C */ /** * \def MBEDTLS_DES_C @@ -2248,7 +2249,7 @@ void mbedtls_platform_free( void * ptr ); * \warning DES is considered a weak cipher and its use constitutes a * security risk. We recommend considering stronger ciphers instead. */ -//#define MBEDTLS_DES_C +/*#define MBEDTLS_DES_C */ /** * \def MBEDTLS_DHM_C @@ -2324,7 +2325,7 @@ void mbedtls_platform_free( void * ptr ); * * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C */ -//#define MBEDTLS_ECJPAKE_C +/*#define MBEDTLS_ECJPAKE_C */ /** * \def MBEDTLS_ECP_C @@ -2487,7 +2488,7 @@ void mbedtls_platform_free( void * ptr ); * * Enable this module to enable the buffer memory allocator. */ -//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C +/*#define MBEDTLS_MEMORY_BUFFER_ALLOC_C */ /** * \def MBEDTLS_NET_C @@ -2506,7 +2507,7 @@ void mbedtls_platform_free( void * ptr ); * * This module provides networking routines. */ -//#define MBEDTLS_NET_C +/*#define MBEDTLS_NET_C */ /** * \def MBEDTLS_OID_C @@ -2543,7 +2544,7 @@ void mbedtls_platform_free( void * ptr ); * * This modules adds support for the VIA PadLock on x86. */ -//#define MBEDTLS_PADLOCK_C +/*#define MBEDTLS_PADLOCK_C */ /** * \def MBEDTLS_PEM_PARSE_C @@ -2697,7 +2698,7 @@ void mbedtls_platform_free( void * ptr ); * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. * */ -//#define MBEDTLS_PSA_CRYPTO_C +/*#define MBEDTLS_PSA_CRYPTO_C */ /** * \def MBEDTLS_PSA_CRYPTO_SE_C @@ -2713,7 +2714,7 @@ void mbedtls_platform_free( void * ptr ); * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C * */ -//#define MBEDTLS_PSA_CRYPTO_SE_C +/*#define MBEDTLS_PSA_CRYPTO_SE_C */ /** * \def MBEDTLS_PSA_CRYPTO_STORAGE_C @@ -2726,7 +2727,7 @@ void mbedtls_platform_free( void * ptr ); * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of * the PSA ITS interface */ -//#define MBEDTLS_PSA_CRYPTO_STORAGE_C +/*#define MBEDTLS_PSA_CRYPTO_STORAGE_C */ /** * \def MBEDTLS_PSA_ITS_FILE_C @@ -2738,7 +2739,7 @@ void mbedtls_platform_free( void * ptr ); * * Requires: MBEDTLS_FS_IO */ -//#define MBEDTLS_PSA_ITS_FILE_C +/*#define MBEDTLS_PSA_ITS_FILE_C */ /** * \def MBEDTLS_RIPEMD160_C @@ -2849,7 +2850,7 @@ void mbedtls_platform_free( void * ptr ); * Uncomment to have the library check for the A64 SHA-256 crypto extensions * and use them if available. */ -//#define MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT +/*#define MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */ /** * \def MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY @@ -2874,7 +2875,7 @@ void mbedtls_platform_free( void * ptr ); * Uncomment to have the library use the A64 SHA-256 crypto extensions * unconditionally. */ -//#define MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY +/*#define MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */ /** * \def MBEDTLS_SHA384_C @@ -2934,7 +2935,7 @@ void mbedtls_platform_free( void * ptr ); * Uncomment to have the library check for the A64 SHA-512 crypto extensions * and use them if available. */ -//#define MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT +/*#define MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */ /** * \def MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY @@ -2961,7 +2962,7 @@ void mbedtls_platform_free( void * ptr ); * Uncomment to have the library use the A64 SHA-512 crypto extensions * unconditionally. */ -//#define MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY +/*#define MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */ /** * \def MBEDTLS_SSL_CACHE_C @@ -3023,7 +3024,7 @@ void mbedtls_platform_free( void * ptr ); * * This module is required for SSL/TLS server support. */ -//#define MBEDTLS_SSL_SRV +/*#define MBEDTLS_SSL_SRV */ /** * \def MBEDTLS_SSL_TLS_C @@ -3087,7 +3088,7 @@ void mbedtls_platform_free( void * ptr ); * * Module: library/timing.c */ -//#define MBEDTLS_TIMING_C +/*#define MBEDTLS_TIMING_C */ /** * \def MBEDTLS_VERSION_C @@ -3098,7 +3099,7 @@ void mbedtls_platform_free( void * ptr ); * * This module provides run-time version information. */ -//#define MBEDTLS_VERSION_C +/*#define MBEDTLS_VERSION_C */ /** * \def MBEDTLS_X509_USE_C @@ -3228,7 +3229,7 @@ void mbedtls_platform_free( void * ptr ); * The value of this symbol is typically a path in double quotes, either * absolute or relative to a directory on the include search path. */ -//#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h" +/*#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h" */ /** * \def MBEDTLS_USER_CONFIG_FILE @@ -3245,7 +3246,7 @@ void mbedtls_platform_free( void * ptr ); * The value of this symbol is typically a path in double quotes, either * absolute or relative to a directory on the include search path. */ -//#define MBEDTLS_USER_CONFIG_FILE "/dev/null" +/*#define MBEDTLS_USER_CONFIG_FILE "/dev/null" */ /** * \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE @@ -3263,7 +3264,7 @@ void mbedtls_platform_free( void * ptr ); * The value of this symbol is typically a path in double quotes, either * absolute or relative to a directory on the include search path. */ -//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h" +/*#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h" */ /** * \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE @@ -3280,7 +3281,7 @@ void mbedtls_platform_free( void * ptr ); * The value of this symbol is typically a path in double quotes, either * absolute or relative to a directory on the include search path. */ -//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null" +/*#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null" */ /** \} name SECTION: General configuration options */ @@ -3295,6 +3296,7 @@ void mbedtls_platform_free( void * ptr ); * only if you have a good reason and know the consequences. * \{ */ + /* The Doxygen documentation here is used when a user comments out a * setting and runs doxygen themselves. On the other hand, when we typeset * the full documentation including disabled settings, the documentation @@ -3304,66 +3306,66 @@ void mbedtls_platform_free( void * ptr ); * comment in the specific module. */ /* MPI / BIGNUM options */ -//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ -//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ +/*#define MBEDTLS_MPI_WINDOW_SIZE 6 / **< Maximum window size used. * / */ +/*#define MBEDTLS_MPI_MAX_SIZE 1024 / **< Maximum number of bytes for usable MPIs. * / */ /* CTR_DRBG options */ -//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ -//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +/*#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 / **< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) * / */ +/*#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 / **< Interval before reseed is performed by default * / */ +/*#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 / **< Maximum number of additional input bytes * / */ +/*#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 / **< Maximum number of requested bytes per call * / */ +/*#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 / **< Maximum size of (re)seed buffer * / */ /* HMAC_DRBG options */ -//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +/*#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 / **< Interval before reseed is performed by default * / */ +/*#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 / **< Maximum number of additional input bytes * / */ +/*#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 / **< Maximum number of requested bytes per call * / */ +/*#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 / **< Maximum size of (re)seed buffer * / */ /* ECP options */ -//#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */ -//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ +/*#define MBEDTLS_ECP_WINDOW_SIZE 4 / **< Maximum window size used * / */ +/*#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 / **< Enable fixed-point speed-up * / */ /* Entropy options */ -//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ +/*#define MBEDTLS_ENTROPY_MAX_SOURCES 20 / **< Maximum number of sources supported * / */ +/*#define MBEDTLS_ENTROPY_MAX_GATHER 128 / **< Maximum amount requested from entropy sources * / */ +/*#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 / **< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released * / */ /* Memory buffer allocator options */ -//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ +/*#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 / **< Align on multiples of this value * / */ /* Platform options */ -//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ -//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< Default setbuf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/*#define MBEDTLS_PLATFORM_STD_MEM_HDR / **< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. * / */ +/*#define MBEDTLS_PLATFORM_STD_CALLOC calloc / **< Default allocator to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_FREE free / **< Default free to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_SETBUF setbuf / **< Default setbuf to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_EXIT exit / **< Default exit to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_TIME time / **< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled * / */ +/*#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf / **< Default fprintf to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_PRINTF printf / **< Default printf to use, can be undefined * / */ /* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ +/*#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf / **< Default snprintf to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 / **< Default exit value to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 / **< Default exit value to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read / **< Default nv_seed_read function to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write / **< Default nv_seed_write function to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" / **< Seed file to read/write with default implementation * / */ /* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ /* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ #define MBEDTLS_PLATFORM_CALLOC_MACRO mbedtls_platform_calloc /**< Default allocator macro to use, can be undefined */ #define MBEDTLS_PLATFORM_FREE_MACRO mbedtls_platform_free /**< Default free macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_SETBUF_MACRO setbuf /**< Default setbuf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/*#define MBEDTLS_PLATFORM_EXIT_MACRO exit / **< Default exit macro to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_SETBUF_MACRO setbuf / **< Default setbuf macro to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_TIME_MACRO time / **< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled * / */ +/*#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t / **< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled * / */ +/*#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf / **< Default fprintf macro to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_PRINTF_MACRO printf / **< Default printf macro to use, can be undefined * / */ /* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +/*#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf / **< Default snprintf macro to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf / **< Default vsnprintf macro to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read / **< Default nv_seed_read function to use, can be undefined * / */ +/*#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write / **< Default nv_seed_write function to use, can be undefined * / */ /** \def MBEDTLS_CHECK_RETURN * @@ -3378,7 +3380,7 @@ void mbedtls_platform_free( void * ptr ); * If the implementation here is empty, this will effectively disable the * checking of functions' return values. */ -//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) +/*#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) */ /** \def MBEDTLS_IGNORE_RETURN * @@ -3386,9 +3388,10 @@ void mbedtls_platform_free( void * ptr ); * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this * warning is suppressed. */ -//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result)) +/*#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result)) */ /* PSA options */ + /** * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the * PSA crypto subsystem. @@ -3399,7 +3402,7 @@ void mbedtls_platform_free( void * ptr ); * #MBEDTLS_MD_SHA512 or #MBEDTLS_MD_SHA256 based on availability and * on unspecified heuristics. */ -//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 +/*#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 */ /** \def MBEDTLS_PSA_KEY_SLOT_COUNT * Restrict the PSA library to supporting a maximum amount of simultaneously @@ -3410,11 +3413,11 @@ void mbedtls_platform_free( void * ptr ); * If this option is unset, the library will fall back to a default value of * 32 keys. */ -//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 +/*#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 */ /* SSL Cache options */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ +/*#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 / **< 1 day * / */ +/*#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 / **< Maximum entries in cache * / */ /* SSL options */ @@ -3437,21 +3440,21 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to set the maximum plaintext size of the incoming I/O buffer. */ -//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 +/*#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 */ /** \def MBEDTLS_SSL_CID_IN_LEN_MAX * * The maximum length of CIDs used for incoming DTLS messages. * */ -//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 +/*#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 */ /** \def MBEDTLS_SSL_CID_OUT_LEN_MAX * * The maximum length of CIDs used for outgoing DTLS messages. * */ -//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 +/*#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 */ /** \def MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY * @@ -3467,7 +3470,7 @@ void mbedtls_platform_free( void * ptr ); * Note: On systems lacking division instructions, * a power of two should be preferred. */ -//#define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16 +/*#define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16 */ /** \def MBEDTLS_SSL_OUT_CONTENT_LEN * @@ -3487,7 +3490,7 @@ void mbedtls_platform_free( void * ptr ); * * Uncomment to set the maximum plaintext size of the outgoing I/O buffer. */ -//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 +/*#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 */ /** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING * @@ -3504,10 +3507,10 @@ void mbedtls_platform_free( void * ptr ); * while buffering multiple smaller handshake messages. * */ -//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 +/*#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 */ -//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ -//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ +/*#define MBEDTLS_PSK_MAX_LEN 32 / **< Max size of TLS pre-shared keys, in bytes (default 256 bits) * / */ +/*#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 / **< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued * / */ /** \def MBEDTLS_TLS_EXT_CID * @@ -3518,7 +3521,7 @@ void mbedtls_platform_free( void * ptr ); * A future minor revision of Mbed TLS may change the default value of * this option to match evolving standards and usage. */ -//#define MBEDTLS_TLS_EXT_CID 254 +/*#define MBEDTLS_TLS_EXT_CID 254 */ /** * Complete list of ciphersuites to use, in order of preference. @@ -3532,11 +3535,11 @@ void mbedtls_platform_free( void * ptr ); * * The value below is only an example, not the default. */ -//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +/*#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 */ /* X509 options */ -//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ -//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ +/*#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 / **< Maximum number of intermediate CAs in a verification chain. * / */ +/*#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 / **< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). * / */ /** * Uncomment the macro to let mbed TLS use your alternate implementation of @@ -3556,7 +3559,7 @@ void mbedtls_platform_free( void * ptr ); * C standards (e.g using memset_s() in C11) or calling a secure memset() from * their system (e.g explicit_bzero() in BSD). */ -//#define MBEDTLS_PLATFORM_ZEROIZE_ALT +/*#define MBEDTLS_PLATFORM_ZEROIZE_ALT */ /** * Uncomment the macro to let Mbed TLS use your alternate implementation of @@ -3575,7 +3578,7 @@ void mbedtls_platform_free( void * ptr ); * unconditionally use the implementation for mbedtls_platform_gmtime_r() * supplied at compile time. */ -//#define MBEDTLS_PLATFORM_GMTIME_R_ALT +/*#define MBEDTLS_PLATFORM_GMTIME_R_ALT */ /** * Enable the verified implementations of ECDH primitives from Project Everest @@ -3584,6 +3587,6 @@ void mbedtls_platform_free( void * ptr ); * fields of a mbedtls_ecdh_context structure directly. See also * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h. */ -//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED +/*#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED */ /** \} name SECTION: Module configuration options */ diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_freertos_port.c b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_freertos_port.c index e1ebc0782..a905fe93c 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_freertos_port.c +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_freertos_port.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -35,9 +35,9 @@ /* mbed TLS includes. */ #if defined( MBEDTLS_CONFIG_FILE ) -#include MBEDTLS_CONFIG_FILE + #include MBEDTLS_CONFIG_FILE #else -#include "mbedtls/mbedtls_config.h" + #include "mbedtls/mbedtls_config.h" #endif #include "mbedtls/entropy.h" @@ -103,21 +103,22 @@ void mbedtls_platform_free( void * ptr ) * * @param[in, out] pMutex mbedtls mutex handle. */ -static void mbedtls_platform_mutex_init( mbedtls_threading_mutex_t * pMutex ) -{ - configASSERT( pMutex != NULL ); + static void mbedtls_platform_mutex_init( mbedtls_threading_mutex_t * pMutex ) + { + configASSERT( pMutex != NULL ); - #if( configSUPPORT_STATIC_ALLOCATION == 1 ) - /* Create a statically-allocated FreeRTOS mutex. This should never fail as - * storage is provided. */ + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - pMutex->mutexHandle = xSemaphoreCreateMutexStatic( &( pMutex->mutexStorage ) ); - #elif( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - pMutex->mutexHandle = xSemaphoreCreateMutex(); - #endif + /* Create a statically-allocated FreeRTOS mutex. This should never fail as + * storage is provided. */ - configASSERT( pMutex->mutexHandle != NULL ); -} + pMutex->mutexHandle = xSemaphoreCreateMutexStatic( &( pMutex->mutexStorage ) ); + #elif ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + pMutex->mutexHandle = xSemaphoreCreateMutex(); + #endif + + configASSERT( pMutex->mutexHandle != NULL ); + } /*-----------------------------------------------------------*/ @@ -129,11 +130,11 @@ static void mbedtls_platform_mutex_init( mbedtls_threading_mutex_t * pMutex ) * @note This function is an empty stub as nothing needs to be done to free * a statically allocated FreeRTOS mutex. */ -static void mbedtls_platform_mutex_free( mbedtls_threading_mutex_t * pMutex ) -{ - vSemaphoreDelete( pMutex->mutexHandle ); - pMutex->mutexHandle = NULL; -} + static void mbedtls_platform_mutex_free( mbedtls_threading_mutex_t * pMutex ) + { + vSemaphoreDelete( pMutex->mutexHandle ); + pMutex->mutexHandle = NULL; + } /*-----------------------------------------------------------*/ @@ -144,23 +145,23 @@ static void mbedtls_platform_mutex_free( mbedtls_threading_mutex_t * pMutex ) * * @return 0 (success) is always returned as any other failure is asserted. */ -static int mbedtls_platform_mutex_lock( mbedtls_threading_mutex_t * pMutex ) -{ - BaseType_t mutexStatus = 0; + static int mbedtls_platform_mutex_lock( mbedtls_threading_mutex_t * pMutex ) + { + BaseType_t mutexStatus = 0; - configASSERT( pMutex != NULL ); - configASSERT( pMutex->mutexHandle != NULL ); + configASSERT( pMutex != NULL ); + configASSERT( pMutex->mutexHandle != NULL ); - /* mutexStatus is not used if asserts are disabled. */ - ( void ) mutexStatus; + /* mutexStatus is not used if asserts are disabled. */ + ( void ) mutexStatus; - /* This function should never fail if the mutex is initialized. */ - mutexStatus = xSemaphoreTake( pMutex->mutexHandle, portMAX_DELAY ); + /* This function should never fail if the mutex is initialized. */ + mutexStatus = xSemaphoreTake( pMutex->mutexHandle, portMAX_DELAY ); - configASSERT( mutexStatus == pdTRUE ); + configASSERT( mutexStatus == pdTRUE ); - return 0; -} + return 0; + } /*-----------------------------------------------------------*/ @@ -171,79 +172,79 @@ static int mbedtls_platform_mutex_lock( mbedtls_threading_mutex_t * pMutex ) * * @return 0 is always returned as any other failure is asserted. */ -static int mbedtls_platform_mutex_unlock( mbedtls_threading_mutex_t * pMutex ) -{ - BaseType_t mutexStatus = 0; + static int mbedtls_platform_mutex_unlock( mbedtls_threading_mutex_t * pMutex ) + { + BaseType_t mutexStatus = 0; - configASSERT( pMutex != NULL ); - configASSERT( pMutex->mutexHandle != NULL ); - /* mutexStatus is not used if asserts are disabled. */ - ( void ) mutexStatus; + configASSERT( pMutex != NULL ); + configASSERT( pMutex->mutexHandle != NULL ); + /* mutexStatus is not used if asserts are disabled. */ + ( void ) mutexStatus; - /* This function should never fail if the mutex is initialized. */ - mutexStatus = xSemaphoreGive( pMutex->mutexHandle ); - configASSERT( mutexStatus == pdTRUE ); + /* This function should never fail if the mutex is initialized. */ + mutexStatus = xSemaphoreGive( pMutex->mutexHandle ); + configASSERT( mutexStatus == pdTRUE ); - return 0; -} + return 0; + } /*-----------------------------------------------------------*/ -#if defined( MBEDTLS_THREADING_ALT ) -int mbedtls_platform_threading_init( void ) -{ - mbedtls_threading_set_alt( mbedtls_platform_mutex_init, - mbedtls_platform_mutex_free, - mbedtls_platform_mutex_lock, - mbedtls_platform_mutex_unlock ); - return 0; -} + #if defined( MBEDTLS_THREADING_ALT ) + int mbedtls_platform_threading_init( void ) + { + mbedtls_threading_set_alt( mbedtls_platform_mutex_init, + mbedtls_platform_mutex_free, + mbedtls_platform_mutex_lock, + mbedtls_platform_mutex_unlock ); + return 0; + } -#else /* !MBEDTLS_THREADING_ALT */ + #else /* !MBEDTLS_THREADING_ALT */ -void (* mbedtls_mutex_init)( mbedtls_threading_mutex_t * mutex ) = mbedtls_platform_mutex_init; -void (* mbedtls_mutex_free)( mbedtls_threading_mutex_t * mutex ) = mbedtls_platform_mutex_free; -int (* mbedtls_mutex_lock)( mbedtls_threading_mutex_t * mutex ) = mbedtls_platform_mutex_lock; -int (* mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * mutex ) = mbedtls_platform_mutex_unlock; + void (* mbedtls_mutex_init)( mbedtls_threading_mutex_t * mutex ) = mbedtls_platform_mutex_init; + void (* mbedtls_mutex_free)( mbedtls_threading_mutex_t * mutex ) = mbedtls_platform_mutex_free; + int (* mbedtls_mutex_lock)( mbedtls_threading_mutex_t * mutex ) = mbedtls_platform_mutex_lock; + int (* mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * mutex ) = mbedtls_platform_mutex_unlock; -#endif /* !MBEDTLS_THREADING_ALT */ + #endif /* !MBEDTLS_THREADING_ALT */ #endif /* MBEDTLS_THREADING_C */ /*-----------------------------------------------------------*/ #if defined( MBEDTLS_ENTROPY_HARDWARE_ALT ) /* Determine which API is available */ - #if defined(_WIN32) + #if defined( _WIN32 ) #define RNG_SOURCE_WINDOWS_CRYPT - #elif defined(__linux__) + #elif defined( __linux__ ) #include #include - #if defined(SYS_getrandom) + #if defined( SYS_getrandom ) #define RNG_SOURCE_GETRANDOM #endif /* SYS_getrandom */ #elif defined( ARM_RDI_MONITOR ) || defined( SEMIHOSTING ) #define RNG_SOURCE_SEMIHOST #else #define RNG_SOURCE_DEV_RANDOM - #endif + #endif /* if defined( _WIN32 ) */ - #if defined(RNG_SOURCE_WINDOWS_CRYPT) + #if defined( RNG_SOURCE_WINDOWS_CRYPT ) #include #include int mbedtls_hardware_poll( void * data, - unsigned char * output, - size_t len, - size_t * olen ) + unsigned char * output, + size_t len, + size_t * olen ) { int lStatus = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; HCRYPTPROV hProv = 0; - /* Unferenced parameter. */ + /* Unreferenced parameter. */ ( void ) data; /* - * This is port-specific for the Windows simulator, so just use Crypto API. - */ + * This is port-specific for the Windows simulator, so just use Crypto API. + */ if( TRUE == CryptAcquireContextA( &hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) ) @@ -274,13 +275,14 @@ int (* mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * mutex ) = mbedtls_plat if( rslt >= 0 ) { - *olen = (size_t) rslt; + *olen = ( size_t ) rslt; rslt = 0; } else { rslt = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; } + return rslt; } #elif defined( RNG_SOURCE_SEMIHOST ) @@ -292,7 +294,7 @@ int (* mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * mutex ) = mbedtls_plat int rslt = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; int file; - (void) data; + ( void ) data; configASSERT( olen != NULL ); configASSERT( output != NULL ); @@ -322,7 +324,7 @@ int (* mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * mutex ) = mbedtls_plat ( void ) _close( file ); return rslt; } - #else + #else /* if defined( RNG_SOURCE_WINDOWS_CRYPT ) */ #include int mbedtls_hardware_poll( void * data, unsigned char * output, @@ -336,7 +338,8 @@ int (* mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * mutex ) = mbedtls_plat configASSERT( olen != NULL ); configASSERT( output != NULL ); - file = fopen("/dev/urandom", "rb"); + file = fopen( "/dev/urandom", "rb" ); + if( file != NULL ) { rslt = fread( output, 1, len, file ); @@ -352,8 +355,9 @@ int (* mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * mutex ) = mbedtls_plat { rslt = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; } + return rslt; } - #endif -#endif + #endif /* if defined( RNG_SOURCE_WINDOWS_CRYPT ) */ +#endif /* if defined( MBEDTLS_ENTROPY_HARDWARE_ALT ) */ /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_freertos_port.h b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_freertos_port.h index e76023a0c..ad973a6e0 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_freertos_port.h +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/mbedtls_freertos_port.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -43,13 +43,13 @@ typedef struct mbedtls_threading_mutex { SemaphoreHandle_t mutexHandle; - #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) StaticSemaphore_t mutexStorage; #endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ } mbedtls_threading_mutex_t; #if defined( MBEDTLS_THREADING_ALT ) -int mbedtls_platform_threading_init( void ); + int mbedtls_platform_threading_init( void ); #endif int mbedtls_platform_send( void * ctx, diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/threading_alt.h b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/threading_alt.h index e3ebe1301..721a749ec 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/threading_alt.h +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/MbedTLS/threading_alt.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/coreHTTP/coreHTTP.vcxproj.filters b/FreeRTOS-Plus/VisualStudio_StaticProjects/coreHTTP/coreHTTP.vcxproj.filters index e7ad04eba..d846bd7c5 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/coreHTTP/coreHTTP.vcxproj.filters +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/coreHTTP/coreHTTP.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/coreHTTP/core_http_config.h b/FreeRTOS-Plus/VisualStudio_StaticProjects/coreHTTP/core_http_config.h index b49e494c6..64eaabe18 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/coreHTTP/core_http_config.h +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/coreHTTP/core_http_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/corePKCS11/corePKCS11.vcxproj.filters b/FreeRTOS-Plus/VisualStudio_StaticProjects/corePKCS11/corePKCS11.vcxproj.filters index c731ecd4d..3f252e49c 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/corePKCS11/corePKCS11.vcxproj.filters +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/corePKCS11/corePKCS11.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/FreeRTOS-Plus/VisualStudio_StaticProjects/corePKCS11/core_pkcs11_config.h b/FreeRTOS-Plus/VisualStudio_StaticProjects/corePKCS11/core_pkcs11_config.h index c7e0b2488..b0eb5797c 100644 --- a/FreeRTOS-Plus/VisualStudio_StaticProjects/corePKCS11/core_pkcs11_config.h +++ b/FreeRTOS-Plus/VisualStudio_StaticProjects/corePKCS11/core_pkcs11_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -26,7 +26,7 @@ /** * @file core_pkcs11_config.h - * @brief PCKS#11 config options. + * @brief PKCS#11 config options. */ diff --git a/FreeRTOS/Demo/Common/ARMv8M/mpu_demo/mpu_demo.c b/FreeRTOS/Demo/Common/ARMv8M/mpu_demo/mpu_demo.c index c3b04b3d7..35407cf1b 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/mpu_demo/mpu_demo.c +++ b/FreeRTOS/Demo/Common/ARMv8M/mpu_demo/mpu_demo.c @@ -1,347 +1,347 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/** - * @brief Size of the shared memory region. - */ -#define SHARED_MEMORY_SIZE 32 - -/** - * @brief Memory region shared between two tasks. - */ -static uint8_t ucSharedMemory[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); -#if ( configTOTAL_MPU_REGIONS == 16 ) - static uint8_t ucSharedMemory1[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); - static uint8_t ucSharedMemory2[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); - static uint8_t ucSharedMemory3[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); - static uint8_t ucSharedMemory4[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); - static uint8_t ucSharedMemory5[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); - static uint8_t ucSharedMemory6[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); - static uint8_t ucSharedMemory7[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); - static uint8_t ucSharedMemory8[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); -#endif /* configTOTAL_MPU_REGIONS == 16 */ - -/** - * @brief Memory region used to track Memory Fault intentionally caused by the - * RO Access task. - * - * RO Access task sets ucROTaskFaultTracker[ 0 ] to 1 before accessing illegal - * memory. Illegal memory access causes Memory Fault and the fault handler - * checks ucROTaskFaultTracker[ 0 ] to see if this is an expected fault. We - * recover gracefully from an expected fault by jumping to the next instruction. - * - * @note We are declaring a region of 32 bytes even though we need only one. The - * reason is that the size of an MPU region must be a multiple of 32 bytes. - */ -static volatile uint8_t ucROTaskFaultTracker[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ) = { 0 }; -/*-----------------------------------------------------------*/ - -/** - * @brief Implements the task which has Read Only access to the memory region - * ucSharedMemory. - * - * @param pvParameters[in] Parameters as passed during task creation. - */ -static void prvROAccessTask( void * pvParameters ); - -/** - * @brief Implements the task which has Read Write access to the memory region - * ucSharedMemory. - * - * @param pvParameters[in] Parameters as passed during task creation. - */ -static void prvRWAccessTask( void * pvParameters ); - -/*-----------------------------------------------------------*/ - -static void prvROAccessTask( void * pvParameters ) -{ - uint8_t ucVal; - - /* Unused parameters. */ - ( void ) pvParameters; - - for( ; ; ) - { - /* This task performs the following sequence for all the shared memory - * regions: - * - * 1. Perfrom a read access to the shared memory. Since this task has - * RO access to the shared memory, the read operation is successful. - * - * 2. Set ucROTaskFaultTracker[ 0 ] to 1 before performing a write to - * the shared memory. Since this task has Read Only access to the - * shared memory, the write operation would result in a Memory Fault. - * Setting ucROTaskFaultTracker[ 0 ] to 1 tells the Memory Fault - * Handler that this is an expected fault. The handler recovers from - * the expected fault gracefully by jumping to the next instruction. - * - * 3. Perfrom a write to the shared memory resulting in a memory fault. - * - * 4. Ensure that the write access did generate MemFault and the fault - * handler did clear the ucROTaskFaultTracker[ 0 ]. - */ - /* Perform the above mentioned sequence on ucSharedMemory. */ - ucVal = ucSharedMemory[ 0 ]; - /* Silent compiler warnings about unused variables. */ - ( void ) ucVal; - ucROTaskFaultTracker[ 0 ] = 1; - ucSharedMemory[ 0 ] = 0; - configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); - - #if ( configTOTAL_MPU_REGIONS == 16 ) - { - /* Perform the above mentioned sequence on ucSharedMemory1. */ - ucVal = ucSharedMemory1[ 0 ]; - /* Silent compiler warnings about unused variables. */ - ( void ) ucVal; - ucROTaskFaultTracker[ 0 ] = 1; - ucSharedMemory1[ 0 ] = 0; - configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); - - /* Perform the above mentioned sequence on ucSharedMemory2. */ - ucVal = ucSharedMemory2[ 0 ]; - /* Silent compiler warnings about unused variables. */ - ( void ) ucVal; - ucROTaskFaultTracker[ 0 ] = 1; - ucSharedMemory2[ 0 ] = 0; - configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); - - /* Perform the above mentioned sequence on ucSharedMemory3. */ - ucVal = ucSharedMemory3[ 0 ]; - /* Silent compiler warnings about unused variables. */ - ( void ) ucVal; - ucROTaskFaultTracker[ 0 ] = 1; - ucSharedMemory3[ 0 ] = 0; - configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); - - /* Perform the above mentioned sequence on ucSharedMemory4. */ - ucVal = ucSharedMemory4[ 0 ]; - /* Silent compiler warnings about unused variables. */ - ( void ) ucVal; - ucROTaskFaultTracker[ 0 ] = 1; - ucSharedMemory4[ 0 ] = 0; - configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); - - /* Perform the above mentioned sequence on ucSharedMemory5. */ - ucVal = ucSharedMemory5[ 0 ]; - /* Silent compiler warnings about unused variables. */ - ( void ) ucVal; - ucROTaskFaultTracker[ 0 ] = 1; - ucSharedMemory5[ 0 ] = 0; - configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); - - /* Perform the above mentioned sequence on ucSharedMemory6. */ - ucVal = ucSharedMemory6[ 0 ]; - /* Silent compiler warnings about unused variables. */ - ( void ) ucVal; - ucROTaskFaultTracker[ 0 ] = 1; - ucSharedMemory6[ 0 ] = 0; - configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); - - /* Perform the above mentioned sequence on ucSharedMemory7. */ - ucVal = ucSharedMemory7[ 0 ]; - /* Silent compiler warnings about unused variables. */ - ( void ) ucVal; - ucROTaskFaultTracker[ 0 ] = 1; - ucSharedMemory7[ 0 ] = 0; - configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); - - /* Perform the above mentioned sequence on ucSharedMemory8. */ - ucVal = ucSharedMemory8[ 0 ]; - /* Silent compiler warnings about unused variables. */ - ( void ) ucVal; - ucROTaskFaultTracker[ 0 ] = 1; - ucSharedMemory8[ 0 ] = 0; - configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); - } - #endif /* configTOTAL_MPU_REGIONS == 16 */ - - /* Wait for a second. */ - vTaskDelay( pdMS_TO_TICKS( 1000 ) ); - } -} -/*-----------------------------------------------------------*/ - -static void prvRWAccessTask( void * pvParameters ) -{ - /* Unused parameters. */ - ( void ) pvParameters; - - for( ; ; ) - { - /* This task has RW access to ucSharedMemory and therefore can write to - * it. */ - ucSharedMemory[ 0 ] = 0; - - #if ( configTOTAL_MPU_REGIONS == 16 ) - { - ucSharedMemory1[ 0 ] = 0; - ucSharedMemory2[ 0 ] = 0; - ucSharedMemory3[ 0 ] = 0; - ucSharedMemory4[ 0 ] = 0; - ucSharedMemory5[ 0 ] = 0; - ucSharedMemory6[ 0 ] = 0; - ucSharedMemory7[ 0 ] = 0; - ucSharedMemory8[ 0 ] = 0; - } - #endif /* configTOTAL_MPU_REGIONS == 16 */ - - /* Wait for a second. */ - vTaskDelay( pdMS_TO_TICKS( 1000 ) ); - } -} -/*-----------------------------------------------------------*/ - -void vStartMPUDemo( void ) -{ - static StackType_t xROAccessTaskStack[ configMINIMAL_STACK_SIZE ] __attribute__( ( aligned( 32 ) ) ); - static StackType_t xRWAccessTaskStack[ configMINIMAL_STACK_SIZE ] __attribute__( ( aligned( 32 ) ) ); - TaskParameters_t xROAccessTaskParameters = - { - .pvTaskCode = prvROAccessTask, - .pcName = "ROAccess", - .usStackDepth = configMINIMAL_STACK_SIZE, - .pvParameters = NULL, - .uxPriority = tskIDLE_PRIORITY, - .puxStackBuffer = xROAccessTaskStack, - .xRegions = - { - { ( void * ) ucSharedMemory, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, - #if ( configTOTAL_MPU_REGIONS == 16 ) - { ( void * ) ucSharedMemory1, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory2, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory3, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory4, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory5, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory6, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory7, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory8, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, - #endif /* configTOTAL_MPU_REGIONS == 16 */ - { ( void * ) ucROTaskFaultTracker, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - { 0, 0, 0 }, - } - }; - TaskParameters_t xRWAccessTaskParameters = - { - .pvTaskCode = prvRWAccessTask, - .pcName = "RWAccess", - .usStackDepth = configMINIMAL_STACK_SIZE, - .pvParameters = NULL, - .uxPriority = tskIDLE_PRIORITY, - .puxStackBuffer = xRWAccessTaskStack, - .xRegions = - { - { ( void * ) ucSharedMemory, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - #if ( configTOTAL_MPU_REGIONS == 16 ) - { ( void * ) ucSharedMemory1, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory2, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory3, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory4, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory5, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory6, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory7, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - { ( void * ) ucSharedMemory8, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - #endif /* configTOTAL_MPU_REGIONS == 16 */ - { 0, 0, 0 }, - { 0, 0, 0 }, - } - }; - - /* Create an unprivileged task with RO access to ucSharedMemory. */ - xTaskCreateRestricted( &( xROAccessTaskParameters ), NULL ); - - /* Create an unprivileged task with RW access to ucSharedMemory. */ - xTaskCreateRestricted( &( xRWAccessTaskParameters ), NULL ); -} -/*-----------------------------------------------------------*/ - -portDONT_DISCARD void vHandleMemoryFault( uint32_t * pulFaultStackAddress ) -{ - uint32_t ulPC; - uint16_t usOffendingInstruction; - - /* Is this an expected fault? */ - if( ucROTaskFaultTracker[ 0 ] == 1 ) - { - /* Read program counter. */ - ulPC = pulFaultStackAddress[ 6 ]; - - /* Read the offending instruction. */ - usOffendingInstruction = *( uint16_t * ) ulPC; - - /* From ARM docs: - * If the value of bits[15:11] of the halfword being decoded is one of - * the following, the halfword is the first halfword of a 32-bit - * instruction: - * - 0b11101. - * - 0b11110. - * - 0b11111. - * Otherwise, the halfword is a 16-bit instruction. - */ - - /* Extract bits[15:11] of the offending instruction. */ - usOffendingInstruction = usOffendingInstruction & 0xF800; - usOffendingInstruction = ( usOffendingInstruction >> 11 ); - - /* Determine if the offending instruction is a 32-bit instruction or - * a 16-bit instruction. */ - if( ( usOffendingInstruction == 0x001F ) || - ( usOffendingInstruction == 0x001E ) || - ( usOffendingInstruction == 0x001D ) ) - { - /* Since the offending instruction is a 32-bit instruction, - * increment the program counter by 4 to move to the next - * instruction. */ - ulPC += 4; - } - else - { - /* Since the offending instruction is a 16-bit instruction, - * increment the program counter by 2 to move to the next - * instruction. */ - ulPC += 2; - } - - /* Save the new program counter on the stack. */ - pulFaultStackAddress[ 6 ] = ulPC; - - /* Mark the fault as handled. */ - ucROTaskFaultTracker[ 0 ] = 0; - } - else - { - /* This is an unexpected fault - loop forever. */ - for( ; ; ) - { - } - } -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/** + * @brief Size of the shared memory region. + */ +#define SHARED_MEMORY_SIZE 32 + +/** + * @brief Memory region shared between two tasks. + */ +static uint8_t ucSharedMemory[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); +#if ( configTOTAL_MPU_REGIONS == 16 ) + static uint8_t ucSharedMemory1[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); + static uint8_t ucSharedMemory2[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); + static uint8_t ucSharedMemory3[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); + static uint8_t ucSharedMemory4[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); + static uint8_t ucSharedMemory5[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); + static uint8_t ucSharedMemory6[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); + static uint8_t ucSharedMemory7[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); + static uint8_t ucSharedMemory8[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ); +#endif /* configTOTAL_MPU_REGIONS == 16 */ + +/** + * @brief Memory region used to track Memory Fault intentionally caused by the + * RO Access task. + * + * RO Access task sets ucROTaskFaultTracker[ 0 ] to 1 before accessing illegal + * memory. Illegal memory access causes Memory Fault and the fault handler + * checks ucROTaskFaultTracker[ 0 ] to see if this is an expected fault. We + * recover gracefully from an expected fault by jumping to the next instruction. + * + * @note We are declaring a region of 32 bytes even though we need only one. The + * reason is that the size of an MPU region must be a multiple of 32 bytes. + */ +static volatile uint8_t ucROTaskFaultTracker[ SHARED_MEMORY_SIZE ] __attribute__( ( aligned( 32 ) ) ) = { 0 }; +/*-----------------------------------------------------------*/ + +/** + * @brief Implements the task which has Read Only access to the memory region + * ucSharedMemory. + * + * @param pvParameters[in] Parameters as passed during task creation. + */ +static void prvROAccessTask( void * pvParameters ); + +/** + * @brief Implements the task which has Read Write access to the memory region + * ucSharedMemory. + * + * @param pvParameters[in] Parameters as passed during task creation. + */ +static void prvRWAccessTask( void * pvParameters ); + +/*-----------------------------------------------------------*/ + +static void prvROAccessTask( void * pvParameters ) +{ + uint8_t ucVal; + + /* Unused parameters. */ + ( void ) pvParameters; + + for( ; ; ) + { + /* This task performs the following sequence for all the shared memory + * regions: + * + * 1. Perfrom a read access to the shared memory. Since this task has + * RO access to the shared memory, the read operation is successful. + * + * 2. Set ucROTaskFaultTracker[ 0 ] to 1 before performing a write to + * the shared memory. Since this task has Read Only access to the + * shared memory, the write operation would result in a Memory Fault. + * Setting ucROTaskFaultTracker[ 0 ] to 1 tells the Memory Fault + * Handler that this is an expected fault. The handler recovers from + * the expected fault gracefully by jumping to the next instruction. + * + * 3. Perfrom a write to the shared memory resulting in a memory fault. + * + * 4. Ensure that the write access did generate MemFault and the fault + * handler did clear the ucROTaskFaultTracker[ 0 ]. + */ + /* Perform the above mentioned sequence on ucSharedMemory. */ + ucVal = ucSharedMemory[ 0 ]; + /* Silent compiler warnings about unused variables. */ + ( void ) ucVal; + ucROTaskFaultTracker[ 0 ] = 1; + ucSharedMemory[ 0 ] = 0; + configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); + + #if ( configTOTAL_MPU_REGIONS == 16 ) + { + /* Perform the above mentioned sequence on ucSharedMemory1. */ + ucVal = ucSharedMemory1[ 0 ]; + /* Silent compiler warnings about unused variables. */ + ( void ) ucVal; + ucROTaskFaultTracker[ 0 ] = 1; + ucSharedMemory1[ 0 ] = 0; + configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); + + /* Perform the above mentioned sequence on ucSharedMemory2. */ + ucVal = ucSharedMemory2[ 0 ]; + /* Silent compiler warnings about unused variables. */ + ( void ) ucVal; + ucROTaskFaultTracker[ 0 ] = 1; + ucSharedMemory2[ 0 ] = 0; + configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); + + /* Perform the above mentioned sequence on ucSharedMemory3. */ + ucVal = ucSharedMemory3[ 0 ]; + /* Silent compiler warnings about unused variables. */ + ( void ) ucVal; + ucROTaskFaultTracker[ 0 ] = 1; + ucSharedMemory3[ 0 ] = 0; + configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); + + /* Perform the above mentioned sequence on ucSharedMemory4. */ + ucVal = ucSharedMemory4[ 0 ]; + /* Silent compiler warnings about unused variables. */ + ( void ) ucVal; + ucROTaskFaultTracker[ 0 ] = 1; + ucSharedMemory4[ 0 ] = 0; + configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); + + /* Perform the above mentioned sequence on ucSharedMemory5. */ + ucVal = ucSharedMemory5[ 0 ]; + /* Silent compiler warnings about unused variables. */ + ( void ) ucVal; + ucROTaskFaultTracker[ 0 ] = 1; + ucSharedMemory5[ 0 ] = 0; + configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); + + /* Perform the above mentioned sequence on ucSharedMemory6. */ + ucVal = ucSharedMemory6[ 0 ]; + /* Silent compiler warnings about unused variables. */ + ( void ) ucVal; + ucROTaskFaultTracker[ 0 ] = 1; + ucSharedMemory6[ 0 ] = 0; + configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); + + /* Perform the above mentioned sequence on ucSharedMemory7. */ + ucVal = ucSharedMemory7[ 0 ]; + /* Silent compiler warnings about unused variables. */ + ( void ) ucVal; + ucROTaskFaultTracker[ 0 ] = 1; + ucSharedMemory7[ 0 ] = 0; + configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); + + /* Perform the above mentioned sequence on ucSharedMemory8. */ + ucVal = ucSharedMemory8[ 0 ]; + /* Silent compiler warnings about unused variables. */ + ( void ) ucVal; + ucROTaskFaultTracker[ 0 ] = 1; + ucSharedMemory8[ 0 ] = 0; + configASSERT( ucROTaskFaultTracker[ 0 ] == 0 ); + } + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + /* Wait for a second. */ + vTaskDelay( pdMS_TO_TICKS( 1000 ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvRWAccessTask( void * pvParameters ) +{ + /* Unused parameters. */ + ( void ) pvParameters; + + for( ; ; ) + { + /* This task has RW access to ucSharedMemory and therefore can write to + * it. */ + ucSharedMemory[ 0 ] = 0; + + #if ( configTOTAL_MPU_REGIONS == 16 ) + { + ucSharedMemory1[ 0 ] = 0; + ucSharedMemory2[ 0 ] = 0; + ucSharedMemory3[ 0 ] = 0; + ucSharedMemory4[ 0 ] = 0; + ucSharedMemory5[ 0 ] = 0; + ucSharedMemory6[ 0 ] = 0; + ucSharedMemory7[ 0 ] = 0; + ucSharedMemory8[ 0 ] = 0; + } + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + /* Wait for a second. */ + vTaskDelay( pdMS_TO_TICKS( 1000 ) ); + } +} +/*-----------------------------------------------------------*/ + +void vStartMPUDemo( void ) +{ + static StackType_t xROAccessTaskStack[ configMINIMAL_STACK_SIZE ] __attribute__( ( aligned( 32 ) ) ); + static StackType_t xRWAccessTaskStack[ configMINIMAL_STACK_SIZE ] __attribute__( ( aligned( 32 ) ) ); + TaskParameters_t xROAccessTaskParameters = + { + .pvTaskCode = prvROAccessTask, + .pcName = "ROAccess", + .usStackDepth = configMINIMAL_STACK_SIZE, + .pvParameters = NULL, + .uxPriority = tskIDLE_PRIORITY, + .puxStackBuffer = xROAccessTaskStack, + .xRegions = + { + { ( void * ) ucSharedMemory, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, + #if ( configTOTAL_MPU_REGIONS == 16 ) + { ( void * ) ucSharedMemory1, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory2, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory3, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory4, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory5, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory6, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory7, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory8, 32, tskMPU_REGION_READ_ONLY | tskMPU_REGION_EXECUTE_NEVER }, + #endif /* configTOTAL_MPU_REGIONS == 16 */ + { ( void * ) ucROTaskFaultTracker, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + { 0, 0, 0 }, + } + }; + TaskParameters_t xRWAccessTaskParameters = + { + .pvTaskCode = prvRWAccessTask, + .pcName = "RWAccess", + .usStackDepth = configMINIMAL_STACK_SIZE, + .pvParameters = NULL, + .uxPriority = tskIDLE_PRIORITY, + .puxStackBuffer = xRWAccessTaskStack, + .xRegions = + { + { ( void * ) ucSharedMemory, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + #if ( configTOTAL_MPU_REGIONS == 16 ) + { ( void * ) ucSharedMemory1, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory2, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory3, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory4, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory5, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory6, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory7, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + { ( void * ) ucSharedMemory8, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + #endif /* configTOTAL_MPU_REGIONS == 16 */ + { 0, 0, 0 }, + { 0, 0, 0 }, + } + }; + + /* Create an unprivileged task with RO access to ucSharedMemory. */ + xTaskCreateRestricted( &( xROAccessTaskParameters ), NULL ); + + /* Create an unprivileged task with RW access to ucSharedMemory. */ + xTaskCreateRestricted( &( xRWAccessTaskParameters ), NULL ); +} +/*-----------------------------------------------------------*/ + +portDONT_DISCARD void vHandleMemoryFault( uint32_t * pulFaultStackAddress ) +{ + uint32_t ulPC; + uint16_t usOffendingInstruction; + + /* Is this an expected fault? */ + if( ucROTaskFaultTracker[ 0 ] == 1 ) + { + /* Read program counter. */ + ulPC = pulFaultStackAddress[ 6 ]; + + /* Read the offending instruction. */ + usOffendingInstruction = *( uint16_t * ) ulPC; + + /* From ARM docs: + * If the value of bits[15:11] of the halfword being decoded is one of + * the following, the halfword is the first halfword of a 32-bit + * instruction: + * - 0b11101. + * - 0b11110. + * - 0b11111. + * Otherwise, the halfword is a 16-bit instruction. + */ + + /* Extract bits[15:11] of the offending instruction. */ + usOffendingInstruction = usOffendingInstruction & 0xF800; + usOffendingInstruction = ( usOffendingInstruction >> 11 ); + + /* Determine if the offending instruction is a 32-bit instruction or + * a 16-bit instruction. */ + if( ( usOffendingInstruction == 0x001F ) || + ( usOffendingInstruction == 0x001E ) || + ( usOffendingInstruction == 0x001D ) ) + { + /* Since the offending instruction is a 32-bit instruction, + * increment the program counter by 4 to move to the next + * instruction. */ + ulPC += 4; + } + else + { + /* Since the offending instruction is a 16-bit instruction, + * increment the program counter by 2 to move to the next + * instruction. */ + ulPC += 2; + } + + /* Save the new program counter on the stack. */ + pulFaultStackAddress[ 6 ] = ulPC; + + /* Mark the fault as handled. */ + ucROTaskFaultTracker[ 0 ] = 0; + } + else + { + /* This is an unexpected fault - loop forever. */ + for( ; ; ) + { + } + } +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/Common/ARMv8M/mpu_demo/mpu_demo.h b/FreeRTOS/Demo/Common/ARMv8M/mpu_demo/mpu_demo.h index b02b1acc2..cef2060e1 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/mpu_demo/mpu_demo.h +++ b/FreeRTOS/Demo/Common/ARMv8M/mpu_demo/mpu_demo.h @@ -1,44 +1,44 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef __MPU_DEMO_H__ -#define __MPU_DEMO_H__ - -/** - * @brief Creates all the tasks for MPU demo. - * - * The MPU demo creates 2 unprivileged tasks - One of which has Read Only access - * to a shared memory region while the other has Read Write access. The task - * with Read Only access then tries to write to the shared memory which results - * in a Memory fault. The fault handler examines that it is the fault generated - * by the task with Read Only access and if so, it recovers from the fault - * gracefully by moving the Program Counter to the next instruction to the one - * which generated the fault. If any other memory access violation occurs, the - * fault handler will get stuck in an infinite loop. - */ -void vStartMPUDemo( void ); - -#endif /* __MPU_DEMO_H__ */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef __MPU_DEMO_H__ +#define __MPU_DEMO_H__ + +/** + * @brief Creates all the tasks for MPU demo. + * + * The MPU demo creates 2 unprivileged tasks - One of which has Read Only access + * to a shared memory region while the other has Read Write access. The task + * with Read Only access then tries to write to the shared memory which results + * in a Memory fault. The fault handler examines that it is the fault generated + * by the task with Read Only access and if so, it recovers from the fault + * gracefully by moving the Program Counter to the next instruction to the one + * which generated the fault. If any other memory access violation occurs, the + * fault handler will get stuck in an infinite loop. + */ +void vStartMPUDemo( void ); + +#endif /* __MPU_DEMO_H__ */ diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/non_secure/reg_test_asm.c b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/non_secure/reg_test_asm.c index c0af7c513..214b9bf68 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/non_secure/reg_test_asm.c +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/non_secure/reg_test_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/non_secure/reg_test_asm.h b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/non_secure/reg_test_asm.h index 088f2ce98..6d45c27b5 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/non_secure/reg_test_asm.h +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/non_secure/reg_test_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/secure/secure_reg_test_asm.c b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/secure/secure_reg_test_asm.c index 2230567e8..8ef5abf02 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/secure/secure_reg_test_asm.c +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/secure/secure_reg_test_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/secure/secure_reg_test_asm.h b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/secure/secure_reg_test_asm.h index 3b59c88d2..f424f0bdd 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/secure/secure_reg_test_asm.h +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM23/secure/secure_reg_test_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/non_secure/reg_test_asm.c b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/non_secure/reg_test_asm.c index 6b276ca29..58c1e8f9c 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/non_secure/reg_test_asm.c +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/non_secure/reg_test_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/non_secure/reg_test_asm.h b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/non_secure/reg_test_asm.h index e6e7f57d3..3e18a0513 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/non_secure/reg_test_asm.h +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/non_secure/reg_test_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/secure/secure_reg_test_asm.c b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/secure/secure_reg_test_asm.c index 171703180..c509d8953 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/secure/secure_reg_test_asm.c +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/secure/secure_reg_test_asm.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/secure/secure_reg_test_asm.h b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/secure/secure_reg_test_asm.h index 3b59c88d2..f424f0bdd 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/secure/secure_reg_test_asm.h +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/GCC/ARM_CM33/secure/secure_reg_test_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/non_secure/reg_test_asm.h b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/non_secure/reg_test_asm.h index 088f2ce98..6d45c27b5 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/non_secure/reg_test_asm.h +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/non_secure/reg_test_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/non_secure/reg_test_asm.s b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/non_secure/reg_test_asm.s index 630e0540c..5d5cd7ed9 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/non_secure/reg_test_asm.s +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/non_secure/reg_test_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test.c b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test.c index cbef60113..12fe2a62f 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test.c +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test_asm.h b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test_asm.h index 3b59c88d2..f424f0bdd 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test_asm.h +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test_asm.s b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test_asm.s index cdb2c0842..c36bdf9bf 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test_asm.s +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM23/secure/secure_reg_test_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/non_secure/reg_test_asm.h b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/non_secure/reg_test_asm.h index e6e7f57d3..3e18a0513 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/non_secure/reg_test_asm.h +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/non_secure/reg_test_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/non_secure/reg_test_asm.s b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/non_secure/reg_test_asm.s index 8f46cf762..848360f45 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/non_secure/reg_test_asm.s +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/non_secure/reg_test_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test.c b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test.c index cbef60113..12fe2a62f 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test.c +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test_asm.h b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test_asm.h index 3b59c88d2..f424f0bdd 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test_asm.h +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test_asm.s b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test_asm.s index a6f5d5823..942b7062b 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test_asm.s +++ b/FreeRTOS/Demo/Common/ARMv8M/reg_tests/IAR/ARM_CM33/secure/secure_reg_test_asm.s @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/ARMv8M/tz_demo/nsc_functions.c b/FreeRTOS/Demo/Common/ARMv8M/tz_demo/nsc_functions.c index 6fd50b9b3..492498571 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/tz_demo/nsc_functions.c +++ b/FreeRTOS/Demo/Common/ARMv8M/tz_demo/nsc_functions.c @@ -1,58 +1,58 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#include -#include "nsc_functions.h" -#include "secure_port_macros.h" - -/** - * @brief Counter returned from NSCFunction. - */ -static uint32_t ulSecureCounter = 0; - -/** - * @brief typedef for non-secure callback. - */ -typedef void ( *NonSecureCallback_t )( void ) __attribute__( ( cmse_nonsecure_call ) ); -/*-----------------------------------------------------------*/ - -secureportNON_SECURE_CALLABLE uint32_t NSCFunction( Callback_t pxCallback ) -{ - NonSecureCallback_t pxNonSecureCallback; - - /* Return function pointer with cleared LSB. */ - pxNonSecureCallback = ( NonSecureCallback_t ) cmse_nsfptr_create( pxCallback ); - - /* Invoke the supplied callback. */ - pxNonSecureCallback(); - - /* Increment the secure side counter. */ - ulSecureCounter += 1; - - /* Return the secure side counter. */ - return ulSecureCounter; -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#include +#include "nsc_functions.h" +#include "secure_port_macros.h" + +/** + * @brief Counter returned from NSCFunction. + */ +static uint32_t ulSecureCounter = 0; + +/** + * @brief typedef for non-secure callback. + */ +typedef void ( *NonSecureCallback_t )( void ) __attribute__( ( cmse_nonsecure_call ) ); +/*-----------------------------------------------------------*/ + +secureportNON_SECURE_CALLABLE uint32_t NSCFunction( Callback_t pxCallback ) +{ + NonSecureCallback_t pxNonSecureCallback; + + /* Return function pointer with cleared LSB. */ + pxNonSecureCallback = ( NonSecureCallback_t ) cmse_nsfptr_create( pxCallback ); + + /* Invoke the supplied callback. */ + pxNonSecureCallback(); + + /* Increment the secure side counter. */ + ulSecureCounter += 1; + + /* Return the secure side counter. */ + return ulSecureCounter; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/Common/ARMv8M/tz_demo/nsc_functions.h b/FreeRTOS/Demo/Common/ARMv8M/tz_demo/nsc_functions.h index b68a0ef23..350f679a6 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/tz_demo/nsc_functions.h +++ b/FreeRTOS/Demo/Common/ARMv8M/tz_demo/nsc_functions.h @@ -1,50 +1,50 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef __NSC_FUNCTIONS_H__ -#define __NSC_FUNCTIONS_H__ - -#include - -/** - * @brief Callback function pointer definition. - */ -typedef void ( * Callback_t ) ( void ); - -/** - * @brief Invokes the supplied callback which is on the non-secure side. - * - * Returns a number which is one more than the value returned in previous - * invocation of this function. Initial invocation returns 1. - * - * @param pxCallback[in] The callback to invoke. - * - * @return A number which is one more than the value returned in previous - * invocation of this function. - */ -uint32_t NSCFunction( Callback_t pxCallback ); - -#endif /* __NSC_FUNCTIONS_H__ */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef __NSC_FUNCTIONS_H__ +#define __NSC_FUNCTIONS_H__ + +#include + +/** + * @brief Callback function pointer definition. + */ +typedef void ( * Callback_t ) ( void ); + +/** + * @brief Invokes the supplied callback which is on the non-secure side. + * + * Returns a number which is one more than the value returned in previous + * invocation of this function. Initial invocation returns 1. + * + * @param pxCallback[in] The callback to invoke. + * + * @return A number which is one more than the value returned in previous + * invocation of this function. + */ +uint32_t NSCFunction( Callback_t pxCallback ); + +#endif /* __NSC_FUNCTIONS_H__ */ diff --git a/FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.c b/FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.c index 117a662dd..79963cefe 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.c +++ b/FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.c @@ -1,133 +1,133 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" - -/* Non-Secure callable functions. */ -#include "nsc_functions.h" - -/** - * @brief Counter incremented in the callback which is called from the secure - * side. - * - * The size of an MPU region must be a multiple of 32 bytes. Therefore we need - * to declare an array of size 8 to ensure that the total size is 32 bytes - - * even though we only need 4 bytes. If we do not do that, anything placed after - * 4 bytes and upto 32 bytes will also fall in the same MPU region and the task - * having access to ulNonSecureCounter will also have access to all those items. - */ -static uint32_t ulNonSecureCounter[ 8 ] __attribute__( ( aligned( 32 ) ) ) = { 0 }; -/*-----------------------------------------------------------*/ - -/** - * @brief Creates all the tasks for TZ demo. - */ -void vStartTZDemo( void ); - -/** - * @brief Increments the ulNonSecureCounter. - * - * This function is called from the secure side. - */ -static void prvCallback( void ); - -/** - * @brief Implements the task which calls the functions exported from the secure - * side. - * - * @param pvParameters[in] Parameters as passed during task creation. - */ -static void prvSecureCallingTask( void * pvParameters ); -/*-----------------------------------------------------------*/ - -void vStartTZDemo( void ) -{ - static StackType_t xSecureCallingTaskStack[ configMINIMAL_STACK_SIZE ] __attribute__( ( aligned( 32 ) ) ); - TaskParameters_t xSecureCallingTaskParameters = - { - .pvTaskCode = prvSecureCallingTask, - .pcName = "SecCalling", - .usStackDepth = configMINIMAL_STACK_SIZE, - .pvParameters = NULL, - .uxPriority = tskIDLE_PRIORITY, - .puxStackBuffer = xSecureCallingTaskStack, - .xRegions = - { - { ulNonSecureCounter, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, - { 0, 0, 0 }, - { 0, 0, 0 }, - } - }; - - /* Create an unprivileged task which calls secure functions. */ - xTaskCreateRestricted( &( xSecureCallingTaskParameters ), NULL ); -} -/*-----------------------------------------------------------*/ - -static void prvCallback( void ) -{ - /* This function is called from the secure side. Just increment the counter - * here. The check that this counter keeps incrementing is performed in the - * prvSecureCallingTask. */ - ulNonSecureCounter[ 0 ] += 1; -} -/*-----------------------------------------------------------*/ - -static void prvSecureCallingTask( void * pvParameters ) -{ - uint32_t ulLastSecureCounter = 0, ulLastNonSecureCounter = 0; - uint32_t ulCurrentSecureCounter = 0; - - /* This task calls secure side functions. So allocate a secure context for - * it. */ - portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE ); - - for( ; ; ) - { - /* Call the secure side function. It does two things: - * - It calls the supplied function (prvCallback) which in turn - * increments the non-secure counter. - * - It increments the secure counter and returns the incremented value. - * Therefore at the end of this function call both the secure and - * non-secure counters must have been incremented. - */ - ulCurrentSecureCounter = NSCFunction( prvCallback ); - - /* Make sure that both the counters are incremented. */ - configASSERT( ulCurrentSecureCounter == ulLastSecureCounter + 1 ); - configASSERT( ulNonSecureCounter[ 0 ] == ulLastNonSecureCounter + 1 ); - - /* Update the last values for both the counters. */ - ulLastSecureCounter = ulCurrentSecureCounter; - ulLastNonSecureCounter = ulNonSecureCounter[ 0 ]; - - /* Wait for a second. */ - vTaskDelay( pdMS_TO_TICKS( 1000 ) ); - } -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Non-Secure callable functions. */ +#include "nsc_functions.h" + +/** + * @brief Counter incremented in the callback which is called from the secure + * side. + * + * The size of an MPU region must be a multiple of 32 bytes. Therefore we need + * to declare an array of size 8 to ensure that the total size is 32 bytes - + * even though we only need 4 bytes. If we do not do that, anything placed after + * 4 bytes and upto 32 bytes will also fall in the same MPU region and the task + * having access to ulNonSecureCounter will also have access to all those items. + */ +static uint32_t ulNonSecureCounter[ 8 ] __attribute__( ( aligned( 32 ) ) ) = { 0 }; +/*-----------------------------------------------------------*/ + +/** + * @brief Creates all the tasks for TZ demo. + */ +void vStartTZDemo( void ); + +/** + * @brief Increments the ulNonSecureCounter. + * + * This function is called from the secure side. + */ +static void prvCallback( void ); + +/** + * @brief Implements the task which calls the functions exported from the secure + * side. + * + * @param pvParameters[in] Parameters as passed during task creation. + */ +static void prvSecureCallingTask( void * pvParameters ); +/*-----------------------------------------------------------*/ + +void vStartTZDemo( void ) +{ + static StackType_t xSecureCallingTaskStack[ configMINIMAL_STACK_SIZE ] __attribute__( ( aligned( 32 ) ) ); + TaskParameters_t xSecureCallingTaskParameters = + { + .pvTaskCode = prvSecureCallingTask, + .pcName = "SecCalling", + .usStackDepth = configMINIMAL_STACK_SIZE, + .pvParameters = NULL, + .uxPriority = tskIDLE_PRIORITY, + .puxStackBuffer = xSecureCallingTaskStack, + .xRegions = + { + { ulNonSecureCounter, 32, tskMPU_REGION_READ_WRITE | tskMPU_REGION_EXECUTE_NEVER }, + { 0, 0, 0 }, + { 0, 0, 0 }, + } + }; + + /* Create an unprivileged task which calls secure functions. */ + xTaskCreateRestricted( &( xSecureCallingTaskParameters ), NULL ); +} +/*-----------------------------------------------------------*/ + +static void prvCallback( void ) +{ + /* This function is called from the secure side. Just increment the counter + * here. The check that this counter keeps incrementing is performed in the + * prvSecureCallingTask. */ + ulNonSecureCounter[ 0 ] += 1; +} +/*-----------------------------------------------------------*/ + +static void prvSecureCallingTask( void * pvParameters ) +{ + uint32_t ulLastSecureCounter = 0, ulLastNonSecureCounter = 0; + uint32_t ulCurrentSecureCounter = 0; + + /* This task calls secure side functions. So allocate a secure context for + * it. */ + portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE ); + + for( ; ; ) + { + /* Call the secure side function. It does two things: + * - It calls the supplied function (prvCallback) which in turn + * increments the non-secure counter. + * - It increments the secure counter and returns the incremented value. + * Therefore at the end of this function call both the secure and + * non-secure counters must have been incremented. + */ + ulCurrentSecureCounter = NSCFunction( prvCallback ); + + /* Make sure that both the counters are incremented. */ + configASSERT( ulCurrentSecureCounter == ulLastSecureCounter + 1 ); + configASSERT( ulNonSecureCounter[ 0 ] == ulLastNonSecureCounter + 1 ); + + /* Update the last values for both the counters. */ + ulLastSecureCounter = ulCurrentSecureCounter; + ulLastNonSecureCounter = ulNonSecureCounter[ 0 ]; + + /* Wait for a second. */ + vTaskDelay( pdMS_TO_TICKS( 1000 ) ); + } +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.h b/FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.h index 545a8d809..70ced7f28 100644 --- a/FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.h +++ b/FreeRTOS/Demo/Common/ARMv8M/tz_demo/tz_demo.h @@ -1,44 +1,44 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef __TZ_DEMO_H__ -#define __TZ_DEMO_H__ - -/** - * @brief Creates all the tasks for TZ demo. - * - * The Trust Zone (TZ) demo creates an unprivileged task which calls a secure - * side function and passes a pointer to a callback function. The secure side - * function does two things: - * 1. It calls the provided callback function. The callback function increments - * a counter. - * 2. It increments a counter and returns the incremented value. - * After the secure function call finishes, it verifies that both the counters - * are incremented. - */ -void vStartTZDemo( void ); - -#endif /* __TZ_DEMO_H__ */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef __TZ_DEMO_H__ +#define __TZ_DEMO_H__ + +/** + * @brief Creates all the tasks for TZ demo. + * + * The Trust Zone (TZ) demo creates an unprivileged task which calls a secure + * side function and passes a pointer to a callback function. The secure side + * function does two things: + * 1. It calls the provided callback function. The callback function increments + * a counter. + * 2. It increments a counter and returns the incremented value. + * After the secure function call finishes, it verifies that both the counters + * are incremented. + */ +void vStartTZDemo( void ); + +#endif /* __TZ_DEMO_H__ */ diff --git a/FreeRTOS/Demo/Common/Full/BlockQ.c b/FreeRTOS/Demo/Common/Full/BlockQ.c index 98d4f63ff..0b1205a44 100644 --- a/FreeRTOS/Demo/Common/Full/BlockQ.c +++ b/FreeRTOS/Demo/Common/Full/BlockQ.c @@ -1,307 +1,307 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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 - *
- */ - -/* - * 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 - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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 + *
+ */ + +/* + * 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 + +/* 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; +} diff --git a/FreeRTOS/Demo/Common/Full/PollQ.c b/FreeRTOS/Demo/Common/Full/PollQ.c index 6e607a9a7..6aa40dcaf 100644 --- a/FreeRTOS/Demo/Common/Full/PollQ.c +++ b/FreeRTOS/Demo/Common/Full/PollQ.c @@ -1,221 +1,221 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/** - * 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 - *
- */ - -/* - * Changes from V2.0.0 - * - + Delay periods are now specified using variables and constants of - + TickType_t rather than unsigned long. - */ - -#include - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/** + * 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 + *
+ */ + +/* + * Changes from V2.0.0 + * + + Delay periods are now specified using variables and constants of + + TickType_t rather than unsigned long. + */ + +#include + +/* 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; +} diff --git a/FreeRTOS/Demo/Common/Full/comtest.c b/FreeRTOS/Demo/Common/Full/comtest.c index b8f192dc9..67233f57f 100644 --- a/FreeRTOS/Demo/Common/Full/comtest.c +++ b/FreeRTOS/Demo/Common/Full/comtest.c @@ -1,350 +1,350 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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 - *
- */ - -/* - * 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 transmissions. - + 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 -#include -#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 ); -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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 + *
+ */ + +/* + * 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 transmissions. + + 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 +#include +#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 resynchronize. */ + 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 ); +} diff --git a/FreeRTOS/Demo/Common/Full/death.c b/FreeRTOS/Demo/Common/Full/death.c index b85ca77de..36ca4597d 100644 --- a/FreeRTOS/Demo/Common/Full/death.c +++ b/FreeRTOS/Demo/Common/Full/death.c @@ -1,202 +1,202 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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 - *
- */ - -/* - * Changes from V2.0.0 - * - + Delay periods are now specified using variables and constants of - + TickType_t rather than unsigned long. - */ - -#include - -/* 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; - } - - sLastCreationCount = sCreationCount; - - uxTasksRunningNow = uxTaskGetNumberOfTasks(); - - if( uxTasksRunningNow < uxTasksRunningAtStart ) - { - sReturn = pdFALSE; - } - else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning ) - { - sReturn = pdFALSE; - } - else - { - /* Everything is okay. */ - } - - return sReturn; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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 + *
+ */ + +/* + * Changes from V2.0.0 + * + + Delay periods are now specified using variables and constants of + + TickType_t rather than unsigned long. + */ + +#include + +/* 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; + } + + sLastCreationCount = sCreationCount; + + uxTasksRunningNow = uxTaskGetNumberOfTasks(); + + if( uxTasksRunningNow < uxTasksRunningAtStart ) + { + sReturn = pdFALSE; + } + else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning ) + { + sReturn = pdFALSE; + } + else + { + /* Everything is okay. */ + } + + return sReturn; +} diff --git a/FreeRTOS/Demo/Common/Full/dynamic.c b/FreeRTOS/Demo/Common/Full/dynamic.c index 29c1abc8b..ee295869d 100644 --- a/FreeRTOS/Demo/Common/Full/dynamic.c +++ b/FreeRTOS/Demo/Common/Full/dynamic.c @@ -1,574 +1,574 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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 - *
- */ - -/* - * 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 - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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 + *
+ */ + +/* + * 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 + +/* 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; +} diff --git a/FreeRTOS/Demo/Common/Full/events.c b/FreeRTOS/Demo/Common/Full/events.c index 86dbab261..9745fdb4c 100644 --- a/FreeRTOS/Demo/Common/Full/events.c +++ b/FreeRTOS/Demo/Common/Full/events.c @@ -1,368 +1,368 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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 -#include -#include - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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 +#include +#include + +/* 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; +} diff --git a/FreeRTOS/Demo/Common/Full/flash.c b/FreeRTOS/Demo/Common/Full/flash.c index 5064b8328..3f4d83df4 100644 --- a/FreeRTOS/Demo/Common/Full/flash.c +++ b/FreeRTOS/Demo/Common/Full/flash.c @@ -1,126 +1,126 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/** - * 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 - *
- */ - -/* - * 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 - -/* 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 ); - } -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/** + * 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 + *
+ */ + +/* + * 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 + +/* 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 xLEDParameters + * 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 ); + } +} diff --git a/FreeRTOS/Demo/Common/Full/flop.c b/FreeRTOS/Demo/Common/Full/flop.c index 35e1ab901..2731f3f4e 100644 --- a/FreeRTOS/Demo/Common/Full/flop.c +++ b/FreeRTOS/Demo/Common/Full/flop.c @@ -1,329 +1,329 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 - *
- */ - -#include -#include - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 + *
+ */ + +#include +#include + +/* 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; +} diff --git a/FreeRTOS/Demo/Common/Full/integer.c b/FreeRTOS/Demo/Common/Full/integer.c index bafed0eb9..d2047da0b 100644 --- a/FreeRTOS/Demo/Common/Full/integer.c +++ b/FreeRTOS/Demo/Common/Full/integer.c @@ -1,325 +1,325 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 - *
- */ - -/* - * 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 - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 + *
+ */ + +/* + * 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 + +/* 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; +} diff --git a/FreeRTOS/Demo/Common/Full/print.c b/FreeRTOS/Demo/Common/Full/print.c index 84578ce3f..86d4418ad 100644 --- a/FreeRTOS/Demo/Common/Full/print.c +++ b/FreeRTOS/Demo/Common/Full/print.c @@ -1,103 +1,103 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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. - * - * NOTE: - * 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 - *
- */ - -/* - * Changes from V2.0.0 - * - + Delay periods are now specified using variables and constants of - + TickType_t rather than unsigned long. - */ - -#include - -/* 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; - } -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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. + * + * NOTE: + * 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 + *
+ */ + +/* + * Changes from V2.0.0 + * + + Delay periods are now specified using variables and constants of + + TickType_t rather than unsigned long. + */ + +#include + +/* 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; + } +} diff --git a/FreeRTOS/Demo/Common/Full/semtest.c b/FreeRTOS/Demo/Common/Full/semtest.c index 1c7d34d8d..a267760de 100644 --- a/FreeRTOS/Demo/Common/Full/semtest.c +++ b/FreeRTOS/Demo/Common/Full/semtest.c @@ -1,285 +1,285 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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 - *
- */ - -/* - * 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 - -/* 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. */ -BaseType_t 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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 + *
+ */ + +/* + * 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 + +/* 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. */ +BaseType_t 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/AbortDelay.c b/FreeRTOS/Demo/Common/Minimal/AbortDelay.c index 56fde73be..027151282 100644 --- a/FreeRTOS/Demo/Common/Minimal/AbortDelay.c +++ b/FreeRTOS/Demo/Common/Minimal/AbortDelay.c @@ -1,799 +1,799 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * This file contains some test scenarios that ensure tasks respond correctly - * to xTaskAbortDelay() calls. It also ensures tasks return the correct state - * of eBlocked when blocked indefinitely in both the case where a task is - * blocked on an object and when a task is blocked on a notification. - */ - -/* Standard includes. */ -#include "limits.h" - -/* Kernel includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "semphr.h" -#include "event_groups.h" -#include "stream_buffer.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 abtSTREAM_BUFFER_RECEIVE 7 - #define abtMAX_TESTS 8 - -/*-----------------------------------------------------------*/ - -/* - * 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 ); - static void prvTestAbortingStreamBufferReceive( void ); - -/* - * Performs a few tests to cover code paths not otherwise covered by the continuous - * tests. - */ - static void prvPerformSingleTaskTests( 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 ); - - if( xTaskAbortDelay( xBlockingTask ) != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - - /* 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; - - /* Start by performing a few tests to cover code not exercised in the loops - * below. */ - prvPerformSingleTaskTests(); - - 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; - - case abtSTREAM_BUFFER_RECEIVE: - prvTestAbortingStreamBufferReceive(); - 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 prvPerformSingleTaskTests( void ) - { - TaskHandle_t xThisTask; - BaseType_t xReturned; - - /* Try unblocking this task using both the task and ISR versions of the API - - * both should return false as this task is not blocked. */ - xThisTask = xTaskGetCurrentTaskHandle(); - - xReturned = xTaskAbortDelay( xThisTask ); - - if( xReturned != pdFALSE ) - { - xErrorOccurred = pdTRUE; - } - } -/*-----------------------------------------------------------*/ - - static void prvTestAbortingTaskDelayUntil( void ) - { - TickType_t xTimeAtStart, xLastBlockTime; - BaseType_t xReturned; - - /* 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 - * xTaskDelayUntil() 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. */ - xReturned = xTaskDelayUntil( &xLastBlockTime, xMaxBlockTime ); - prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); - configASSERT( xReturned == pdTRUE ); - - /* Remove compiler warning about value being set but not used in the case - * configASSERT() is not defined. */ - ( void ) xReturned; - - /* 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. This uses vTaskDelayUntil() - * in place of xTaskDelayUntil() for test coverage. */ - 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; - xReturned = xTaskDelayUntil( &xLastBlockTime, xMaxBlockTime ); - prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); - configASSERT( xReturned == pdTRUE ); - - /* Remove compiler warning about value being set but not used in the case - * configASSERT() is not defined. */ - ( void ) xReturned; - } -/*-----------------------------------------------------------*/ - - 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 /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ - - /* 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 prvTestAbortingStreamBufferReceive( void ) - { - TickType_t xTimeAtStart; - StreamBufferHandle_t xStreamBuffer; - size_t xReturn; - const size_t xTriggerLevelBytes = ( size_t ) 1; - uint8_t uxRxData; - - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - { - /* Defines the memory that will actually hold the streams within the - * stream buffer. */ - static uint8_t ucStorageBuffer[ sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) + 1 ]; - - /* The variable used to hold the stream buffer structure. */ - StaticStreamBuffer_t xStreamBufferStruct; - - - xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucStorageBuffer ), - xTriggerLevelBytes, - ucStorageBuffer, - &xStreamBufferStruct ); - } - #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ - { - xStreamBuffer = xStreamBufferCreate( sizeof( uint8_t ), xTriggerLevelBytes ); - configASSERT( xStreamBuffer ); - } - #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ - - /* Note the time before the delay so the length of the delay is known. */ - xTimeAtStart = xTaskGetTickCount(); - - /* This first delay should just time out. */ - xReturn = xStreamBufferReceive( xStreamBuffer, &uxRxData, sizeof( uxRxData ), 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 xMaxBlockTime. */ - xReturn = xStreamBufferReceive( xStreamBuffer, &uxRxData, sizeof( uxRxData ), 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 = xStreamBufferReceive( xStreamBuffer, &uxRxData, sizeof( uxRxData ), xMaxBlockTime ); - - if( xReturn != 0x00 ) - { - xErrorOccurred = pdTRUE; - } - - prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); - - /* Not really necessary in this case, but for completeness. */ - vStreamBufferDelete( xStreamBuffer ); - } -/*-----------------------------------------------------------*/ - - 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 /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ - - /* 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 xMaxBlockTime. */ - xReturn = xSemaphoreTake( xSemaphore, portMAX_DELAY ); - - 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 xMaxBlockTime. */ - xReturn = xTaskNotifyWait( 0, 0, NULL, portMAX_DELAY ); - - 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 */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * This file contains some test scenarios that ensure tasks respond correctly + * to xTaskAbortDelay() calls. It also ensures tasks return the correct state + * of eBlocked when blocked indefinitely in both the case where a task is + * blocked on an object and when a task is blocked on a notification. + */ + +/* Standard includes. */ +#include "limits.h" + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" +#include "event_groups.h" +#include "stream_buffer.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 abtSTREAM_BUFFER_RECEIVE 7 + #define abtMAX_TESTS 8 + +/*-----------------------------------------------------------*/ + +/* + * 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 ); + static void prvTestAbortingStreamBufferReceive( void ); + +/* + * Performs a few tests to cover code paths not otherwise covered by the continuous + * tests. + */ + static void prvPerformSingleTaskTests( 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 ); + + if( xTaskAbortDelay( xBlockingTask ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* 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; + + /* Start by performing a few tests to cover code not exercised in the loops + * below. */ + prvPerformSingleTaskTests(); + + 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; + + case abtSTREAM_BUFFER_RECEIVE: + prvTestAbortingStreamBufferReceive(); + 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 prvPerformSingleTaskTests( void ) + { + TaskHandle_t xThisTask; + BaseType_t xReturned; + + /* Try unblocking this task using both the task and ISR versions of the API - + * both should return false as this task is not blocked. */ + xThisTask = xTaskGetCurrentTaskHandle(); + + xReturned = xTaskAbortDelay( xThisTask ); + + if( xReturned != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + } +/*-----------------------------------------------------------*/ + + static void prvTestAbortingTaskDelayUntil( void ) + { + TickType_t xTimeAtStart, xLastBlockTime; + BaseType_t xReturned; + + /* 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 + * xTaskDelayUntil() 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. */ + xReturned = xTaskDelayUntil( &xLastBlockTime, xMaxBlockTime ); + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + configASSERT( xReturned == pdTRUE ); + + /* Remove compiler warning about value being set but not used in the case + * configASSERT() is not defined. */ + ( void ) xReturned; + + /* 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. This uses vTaskDelayUntil() + * in place of xTaskDelayUntil() for test coverage. */ + 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; + xReturned = xTaskDelayUntil( &xLastBlockTime, xMaxBlockTime ); + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + configASSERT( xReturned == pdTRUE ); + + /* Remove compiler warning about value being set but not used in the case + * configASSERT() is not defined. */ + ( void ) xReturned; + } +/*-----------------------------------------------------------*/ + + 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 /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + + /* 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 prvTestAbortingStreamBufferReceive( void ) + { + TickType_t xTimeAtStart; + StreamBufferHandle_t xStreamBuffer; + size_t xReturn; + const size_t xTriggerLevelBytes = ( size_t ) 1; + uint8_t uxRxData; + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Defines the memory that will actually hold the streams within the + * stream buffer. */ + static uint8_t ucStorageBuffer[ sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) + 1 ]; + + /* The variable used to hold the stream buffer structure. */ + StaticStreamBuffer_t xStreamBufferStruct; + + + xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucStorageBuffer ), + xTriggerLevelBytes, + ucStorageBuffer, + &xStreamBufferStruct ); + } + #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + { + xStreamBuffer = xStreamBufferCreate( sizeof( uint8_t ), xTriggerLevelBytes ); + configASSERT( xStreamBuffer ); + } + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This first delay should just time out. */ + xReturn = xStreamBufferReceive( xStreamBuffer, &uxRxData, sizeof( uxRxData ), 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 xMaxBlockTime. */ + xReturn = xStreamBufferReceive( xStreamBuffer, &uxRxData, sizeof( uxRxData ), 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 = xStreamBufferReceive( xStreamBuffer, &uxRxData, sizeof( uxRxData ), xMaxBlockTime ); + + if( xReturn != 0x00 ) + { + xErrorOccurred = pdTRUE; + } + + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Not really necessary in this case, but for completeness. */ + vStreamBufferDelete( xStreamBuffer ); + } +/*-----------------------------------------------------------*/ + + 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 /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + + /* 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 xMaxBlockTime. */ + xReturn = xSemaphoreTake( xSemaphore, portMAX_DELAY ); + + 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 xMaxBlockTime. */ + xReturn = xTaskNotifyWait( 0, 0, NULL, portMAX_DELAY ); + + 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 */ diff --git a/FreeRTOS/Demo/Common/Minimal/BlockQ.c b/FreeRTOS/Demo/Common/Minimal/BlockQ.c index 3744e0a7c..e8f8ef4ab 100644 --- a/FreeRTOS/Demo/Common/Minimal/BlockQ.c +++ b/FreeRTOS/Demo/Common/Minimal/BlockQ.c @@ -1,306 +1,306 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 - -/* 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 ) - -#define blckqSHORT_DELAY ( 5 ) -#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 ( configNUMBER_OF_CORES > 1 ) - { - if( pxQueueParameters->xBlockTime == 0 ) - { - vTaskDelay( blckqSHORT_DELAY ); - } - } - #elif configUSE_PREEMPTION == 0 - { - taskYIELD(); - } - #endif /* if ( configNUMBER_OF_CORES > 1 ) */ - } - } -} -/*-----------------------------------------------------------*/ - -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 ( configNUMBER_OF_CORES > 1 ) - { - if( pxQueueParameters->xBlockTime == 0 ) - { - vTaskDelay( blckqSHORT_DELAY ); - } - } - #elif configUSE_PREEMPTION == 0 - { - if( pxQueueParameters->xBlockTime == 0 ) - { - taskYIELD(); - } - } - #endif /* if ( configNUMBER_OF_CORES > 1 ) */ - } - } -} -/*-----------------------------------------------------------*/ - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 + +/* 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 ) + +#define blckqSHORT_DELAY ( 5 ) +#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 ( configNUMBER_OF_CORES > 1 ) + { + if( pxQueueParameters->xBlockTime == 0 ) + { + vTaskDelay( blckqSHORT_DELAY ); + } + } + #elif configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif /* if ( configNUMBER_OF_CORES > 1 ) */ + } + } +} +/*-----------------------------------------------------------*/ + +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 ( configNUMBER_OF_CORES > 1 ) + { + if( pxQueueParameters->xBlockTime == 0 ) + { + vTaskDelay( blckqSHORT_DELAY ); + } + } + #elif configUSE_PREEMPTION == 0 + { + if( pxQueueParameters->xBlockTime == 0 ) + { + taskYIELD(); + } + } + #endif /* if ( configNUMBER_OF_CORES > 1 ) */ + } + } +} +/*-----------------------------------------------------------*/ + +/* 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c b/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c index c118bf81f..4806e74fc 100644 --- a/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c +++ b/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c @@ -1,1058 +1,1058 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - - -/* - * 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. - * - * NOTE: The tests implemented in this file are informal 'sanity' tests - * only and are not part of the module tests that make use of the - * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. - */ - - -/* Scheduler include files. */ -#include "FreeRTOS.h" -#include "task.h" -#include "event_groups.h" - -/* Demo app includes. */ -#include "EventGroupsDemo.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 the tasks. */ -#define ebSET_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY ) -#define ebWAIT_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) - -/* Generic bit definitions. */ -#define ebBIT_0 ( 0x01 ) -#define ebBIT_1 ( 0x02 ) -#define ebBIT_2 ( 0x04 ) -#define ebBIT_3 ( 0x08 ) -#define ebBIT_4 ( 0x10 ) -#define ebBIT_5 ( 0x20 ) -#define ebBIT_6 ( 0x40 ) -#define ebBIT_7 ( 0x80 ) - -/* Combinations of bits used in the demo. */ -#define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 ) -#define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 ) - -/* Associate a bit to each task. These bits are used to identify all the tasks - * that synchronise with the xEventGroupSync() function. */ -#define ebSET_BIT_TASK_SYNC_BIT ebBIT_0 -#define ebWAIT_BIT_TASK_SYNC_BIT ebBIT_1 -#define ebRENDESVOUS_TASK_1_SYNC_BIT ebBIT_2 -#define ebRENDESVOUS_TASK_2_SYNC_BIT ebBIT_3 -#define ebALL_SYNC_BITS ( ebSET_BIT_TASK_SYNC_BIT | ebWAIT_BIT_TASK_SYNC_BIT | ebRENDESVOUS_TASK_1_SYNC_BIT | ebRENDESVOUS_TASK_2_SYNC_BIT ) - -/* A block time of zero simply means "don't block". */ -#define ebDONT_BLOCK ( 0 ) - -/* A 5ms delay. */ -#define ebSHORT_DELAY pdMS_TO_TICKS( ( TickType_t ) 5 ) - -/* Used in the selective bits test which checks no, one or both tasks blocked on - * event bits in a group are unblocked as appropriate as different bits get set. */ -#define ebSELECTIVE_BITS_1 0x03 -#define ebSELECTIVE_BITS_2 0x05 - -#ifndef ebRENDESVOUS_TEST_TASK_STACK_SIZE - #define ebRENDESVOUS_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE -#endif - -#ifndef ebEVENT_GROUP_SET_BITS_TEST_TASK_STACK_SIZE - #define ebEVENT_GROUP_SET_BITS_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE -#endif - -/*-----------------------------------------------------------*/ - -/* - * NOTE: The tests implemented in this function are informal 'sanity' tests - * only and are not part of the module tests that make use of the - * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. - * - * The master test task. This task: - * - * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two - * tasks are blocked on different bits in an event group. The counterpart of - * this test is implemented by the prvSelectiveBitsTestSlaveFunction() - * function (which is called by the two tasks that block on the event group). - * - * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when - * just one task is blocked on various combinations of bits within an event - * group. The counterpart of this test is implemented within the 'test - * slave' task. - * - * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour. - */ -static void prvTestMasterTask( void * pvParameters ); - -/* - * A helper task that enables the 'test master' task to perform several - * behavioural tests. See the comments above the prvTestMasterTask() prototype - * above. - */ -static void prvTestSlaveTask( void * pvParameters ); - -/* - * The part of the test that is performed between the 'test master' task and the - * 'test slave' task to test the behaviour when the slave blocks on various - * event bit combinations. - */ -static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, - TaskHandle_t xTestSlaveTaskHandle ); - -/* - * The part of the test that uses all the tasks to test the task synchronisation - * behaviour. - */ -static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, - TaskHandle_t xTestSlaveTaskHandle ); - -/* - * Two instances of prvSyncTask() are created. They start by calling - * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is - * executing the prvSelectiveBitsTestMasterFunction() function. They then loop - * to test the task synchronisation (rendezvous) behaviour. - */ -static void prvSyncTask( void * pvParameters ); - -/* - * Functions used in a test that blocks two tasks on various different bits - * within an event group - then sets each bit in turn and checks that the - * correct tasks unblock at the correct times. - */ -static BaseType_t prvSelectiveBitsTestMasterFunction( void ); -static void prvSelectiveBitsTestSlaveFunction( void ); - -/*-----------------------------------------------------------*/ - -/* Variables that are incremented by the tasks on each cycle provided no errors - * have been found. Used to detect an error or stall in the test cycling. */ -static volatile uint32_t ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0; - -/* The event group used by all the task based tests. */ -static EventGroupHandle_t xEventGroup = NULL; - -/* The event group used by the interrupt based tests. */ -static EventGroupHandle_t xISREventGroup = NULL; - -/* Handles to the tasks that only take part in the synchronisation calls. */ -static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL; - -/*-----------------------------------------------------------*/ - -void vStartEventGroupTasks( void ) -{ - TaskHandle_t xTestSlaveTaskHandle; - - /* - * 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. - * - * NOTE: The tests implemented in this file are informal 'sanity' tests - * only and are not part of the module tests that make use of the - * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. - * - * Create the test tasks as described at the top of this file. - */ - xTaskCreate( prvTestSlaveTask, "WaitO", ebRENDESVOUS_TEST_TASK_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle ); - xTaskCreate( prvTestMasterTask, "SetB", ebEVENT_GROUP_SET_BITS_TEST_TASK_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL ); - xTaskCreate( prvSyncTask, "Rndv", ebRENDESVOUS_TEST_TASK_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 ); - xTaskCreate( prvSyncTask, "Rndv", ebRENDESVOUS_TEST_TASK_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 ); - - /* If the last task was created then the others will have been too. */ - configASSERT( xSyncTask2 ); - - /* Create the event group used by the ISR tests. The event group used by - * the tasks is created by the tasks themselves. */ - xISREventGroup = xEventGroupCreate(); - configASSERT( xISREventGroup ); -} -/*-----------------------------------------------------------*/ - -static void prvTestMasterTask( void * pvParameters ) -{ - BaseType_t xError; - -/* The handle to the slave task is passed in as the task parameter. */ - TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters; - - /* Avoid compiler warnings. */ - ( void ) pvParameters; - - /* Create the event group used by the tasks ready for the initial tests. */ - xEventGroup = xEventGroupCreate(); - configASSERT( xEventGroup ); - - /* Perform the tests that block two tasks on different combinations of bits, - * then set each bit in turn and check the correct tasks unblock at the correct - * times. */ - xError = prvSelectiveBitsTestMasterFunction(); - - for( ; ; ) - { - /* Recreate the event group ready for the next cycle. */ - xEventGroup = xEventGroupCreate(); - configASSERT( xEventGroup ); - - /* Perform the tests that check the behaviour when a single task is - * blocked on various combinations of event bits. */ - xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle ); - - /* Perform the task synchronisation tests. */ - xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle ); - - /* Delete the event group. */ - vEventGroupDelete( xEventGroup ); - - /* Now all the other tasks should have completed and suspended - * themselves ready for the next go around the loop. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask1 ) != eSuspended ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask2 ) != eSuspended ) - { - xError = pdTRUE; - } - - /* Only increment the cycle variable if no errors have been detected. */ - if( xError == pdFALSE ) - { - ulTestMasterCycles++; - } - - configASSERT( xError == pdFALSE ); - } -} -/*-----------------------------------------------------------*/ - -static void prvSyncTask( void * pvParameters ) -{ - EventBits_t uxSynchronisationBit, uxReturned; - - /* A few tests that check the behaviour when two tasks are blocked on - * various different bits within an event group are performed before this task - * enters its infinite loop to carry out its main demo function. */ - prvSelectiveBitsTestSlaveFunction(); - - /* The bit to use to indicate this task is at the synchronisation point is - * passed in as the task parameter. */ - uxSynchronisationBit = ( EventBits_t ) pvParameters; - - for( ; ; ) - { - /* Now this task takes part in a task synchronisation - sometimes known - * as a 'rendezvous'. Its execution pattern is controlled by the 'test - * master' task, which is responsible for taking this task out of the - * Suspended state when it is time to test the synchronisation behaviour. - * See: http://www.freertos.org/xEventGroupSync.html. */ - vTaskSuspend( NULL ); - - /* Set the bit that indicates this task is at the synchronisation - * point. The first time this is done the 'test master' task has a lower - * priority than this task so this task will get to the sync point before - * the set bits task - test this by calling xEventGroupSync() with a zero - * block time before calling again with a max delay - the first call should - * return before the rendezvous completes, the second only after the - * rendezvous is complete. */ - uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ - uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */ - ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks taking part in the sync. */ - ebDONT_BLOCK ); /* The maximum time to wait for the sync condition to be met before giving up. */ - - /* No block time was specified, so as per the comments above, the - * rendezvous is not expected to have completed yet. */ - configASSERT( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ); - - uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ - uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */ - ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks taking part in the sync. */ - portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */ - - /* A max delay was used, so this task should only exit the above - * function call when the sync condition is met. Check this is the - * case. */ - configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS ); - - /* Remove compiler warning if configASSERT() is not defined. */ - ( void ) uxReturned; - - /* Wait until the 'test master' task unsuspends this task again. */ - vTaskSuspend( NULL ); - - /* Set the bit that indicates this task is at the synchronisation - * point again. This time the 'test master' task has a higher priority - * than this task so will get to the sync point before this task. */ - uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY ); - - /* Again a max delay was used, so this task should only exit the above - * function call when the sync condition is met. Check this is the - * case. */ - configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS ); - - /* Block on the event group again. This time the event group is going - * to be deleted while this task is blocked on it so it is expected that 0 - * be returned. */ - uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY ); - configASSERT( uxReturned == 0 ); - } -} -/*-----------------------------------------------------------*/ - -static void prvTestSlaveTask( void * pvParameters ) -{ - EventBits_t uxReturned; - BaseType_t xError = pdFALSE; - - /* Avoid compiler warnings. */ - ( void ) pvParameters; - - for( ; ; ) - { - /********************************************************************** - * Part 1: This section is the counterpart to the - * prvBitCombinationTestMasterFunction() function which is called by the - * test master task. - *********************************************************************** - * - * This task is controller by the 'test master' task (which is - * implemented by prvTestMasterTask()). Suspend until resumed by the - * 'test master' task. */ - vTaskSuspend( NULL ); - - /* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get - * set. Clear the bit on exit. */ - uxReturned = xEventGroupWaitBits( xEventGroup, /* The event group that contains the event bits being queried. */ - ebBIT_1, /* The bit to wait for. */ - pdTRUE, /* Clear the bit on exit. */ - pdTRUE, /* Wait for all the bits (only one in this case anyway). */ - portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */ - - /* The 'test master' task set all the bits defined by ebCOMBINED_BITS, - * only one of which was being waited for by this task. The return value - * shows the state of the event bits when the task was unblocked, however - * because the task was waiting for ebBIT_1 and 'clear on exit' was set to - * the current state of the event bits will have ebBIT_1 clear. */ - if( uxReturned != ebCOMBINED_BITS ) - { - xError = pdTRUE; - } - - /* Now call xEventGroupWaitBits() again, this time waiting for all the - * bits in ebCOMBINED_BITS to be set. This call should block until the - * 'test master' task sets ebBIT_1 - which was the bit cleared in the call - * to xEventGroupWaitBits() above. */ - uxReturned = xEventGroupWaitBits( xEventGroup, - ebCOMBINED_BITS, /* The bits being waited on. */ - pdFALSE, /* Don't clear the bits on exit. */ - pdTRUE, /* All the bits must be set to unblock. */ - portMAX_DELAY ); - - /* Were all the bits set? */ - if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS ) - { - xError = pdTRUE; - } - - /* Suspend again to wait for the 'test master' task. */ - vTaskSuspend( NULL ); - - /* Now call xEventGroupWaitBits() again, again waiting for all the bits - * in ebCOMBINED_BITS to be set, but this time clearing the bits when the - * task is unblocked. */ - uxReturned = xEventGroupWaitBits( xEventGroup, - ebCOMBINED_BITS, /* The bits being waited on. */ - pdTRUE, /* Clear the bits on exit. */ - pdTRUE, /* All the bits must be set to unblock. */ - portMAX_DELAY ); - - /* The 'test master' task set all the bits in the event group, so that - * is the value that should have been returned. The bits defined by - * ebCOMBINED_BITS will have been clear again in the current value though - * as 'clear on exit' was set to pdTRUE. */ - if( uxReturned != ebALL_BITS ) - { - xError = pdTRUE; - } - - /********************************************************************** - * Part 2: This section is the counterpart to the - * prvPerformTaskSyncTests() function which is called by the - * test master task. - *********************************************************************** - * - * - * Once again wait for the 'test master' task to unsuspend this task - * when it is time for the next test. */ - vTaskSuspend( NULL ); - - /* Now peform a synchronisation with all the other tasks. At this point - * the 'test master' task has the lowest priority so will get to the sync - * point after all the other synchronising tasks. */ - uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the sync. */ - ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */ - ebALL_SYNC_BITS, /* The bits to wait for. These bits are set by the other tasks taking part in the sync. */ - portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */ - - /* A sync with a max delay should only exit when all the synchronisation - * bits are set... */ - if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) - { - xError = pdTRUE; - } - - /* ...but now the synchronisation bits should be clear again. Read back - * the current value of the bits within the event group to check that is - * the case. Setting the bits to zero will return the bits previous value - * then leave all the bits clear. */ - if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 ) - { - xError = pdTRUE; - } - - /* Check the bits are indeed 0 now by simply reading then. */ - if( xEventGroupGetBits( xEventGroup ) != 0 ) - { - xError = pdTRUE; - } - - if( xError == pdFALSE ) - { - /* This task is still cycling without finding an error. */ - ulTestSlaveCycles++; - } - - vTaskSuspend( NULL ); - - /* This time sync when the 'test master' task has the highest priority - * at the point where it sets its sync bit - so this time the 'test master' - * task will get to the sync point before this task. */ - uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY ); - - /* A sync with a max delay should only exit when all the synchronisation - * bits are set... */ - if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) - { - xError = pdTRUE; - } - - /* ...but now the sync bits should be clear again. */ - if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 ) - { - xError = pdTRUE; - } - - /* Block on the event group again. This time the event group is going - * to be deleted while this task is blocked on it, so it is expected that 0 - * will be returned. */ - uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY ); - - if( uxReturned != 0 ) - { - xError = pdTRUE; - } - - if( xError == pdFALSE ) - { - /* This task is still cycling without finding an error. */ - ulTestSlaveCycles++; - } - - configASSERT( xError == pdFALSE ); - } -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, - TaskHandle_t xTestSlaveTaskHandle ) -{ - EventBits_t uxBits; - - /* The three tasks that take part in the synchronisation (rendezvous) are - * expected to be in the suspended state at the start of the test. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask1 ) != eSuspended ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask2 ) != eSuspended ) - { - xError = pdTRUE; - } - - /* Try a synch with no other tasks involved. First set all the bits other - * than this task's bit. */ - xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); - - /* Then wait on just one bit - the bit that is being set. */ - uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ - ebSET_BIT_TASK_SYNC_BIT, /* The bit set by this task when it reaches the sync point. */ - ebSET_BIT_TASK_SYNC_BIT, /* The bits to wait for - in this case it is just waiting for itself. */ - portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ - - /* A sync with a max delay should only exit when all the synchronise - * bits are set...check that is the case. In this case there is only one - * sync bit anyway. */ - if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT ) - { - xError = pdTRUE; - } - - /* ...but now the sync bits should be clear again, leaving all the other - * bits set (as only one bit was being waited for). */ - if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ) - { - xError = pdTRUE; - } - - /* Clear all the bits to zero again. */ - xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); - - if( xEventGroupGetBits( xEventGroup ) != 0 ) - { - xError = pdTRUE; - } - - /* Unsuspend the other tasks then check they have executed up to the - * synchronisation point. */ - vTaskResume( xTestSlaveTaskHandle ); - vTaskResume( xSyncTask1 ); - vTaskResume( xSyncTask2 ); - - if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask1 ) != eBlocked ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask2 ) != eBlocked ) - { - xError = pdTRUE; - } - - /* Set this task's sync bit. */ - uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ - ebSET_BIT_TASK_SYNC_BIT, /* The bit set by this task when it reaches the sync point. */ - ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */ - portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ - - /* A sync with a max delay should only exit when all the synchronise - * bits are set...check that is the case. */ - if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) - { - xError = pdTRUE; - } - - /* ...but now the sync bits should be clear again. */ - if( xEventGroupGetBits( xEventGroup ) != 0 ) - { - xError = pdTRUE; - } - - /* The other tasks should now all be suspended again, ready for the next - * synchronisation. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask1 ) != eSuspended ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask2 ) != eSuspended ) - { - xError = pdTRUE; - } - - /* Sync again - but this time set the last necessary bit as the - * highest priority task, rather than the lowest priority task. Unsuspend - * the other tasks then check they have executed up to the synchronisation - * point. */ - vTaskResume( xTestSlaveTaskHandle ); - vTaskResume( xSyncTask1 ); - vTaskResume( xSyncTask2 ); - - if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask1 ) != eBlocked ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask2 ) != eBlocked ) - { - xError = pdTRUE; - } - - /* Raise the priority of this task above that of the other tasks. */ - vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 ); - - /* Set this task's sync bit. */ - uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY ); - - /* A sync with a max delay should only exit when all the synchronisation - * bits are set... */ - if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) - { - xError = pdTRUE; - } - - /* ...but now the sync bits should be clear again. */ - if( xEventGroupGetBits( xEventGroup ) != 0 ) - { - xError = pdTRUE; - } - - /* The other tasks should now all be in the ready state again, but not - * executed yet as this task still has a higher relative priority. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eReady ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask1 ) != eReady ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask2 ) != eReady ) - { - xError = pdTRUE; - } - - /* Reset the priority of this task back to its original value. */ - vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY ); - - /* Now all the other tasks should have reblocked on the event bits - * to test the behaviour when the event bits are deleted. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask1 ) != eBlocked ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask2 ) != eBlocked ) - { - xError = pdTRUE; - } - - return xError; -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, - TaskHandle_t xTestSlaveTaskHandle ) -{ - EventBits_t uxBits; - - /* Resume the other task. It will block, pending a single bit from - * within ebCOMBINED_BITS. */ - vTaskResume( xTestSlaveTaskHandle ); - - /* Ensure the other task is blocked on the task. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) - { - xError = pdTRUE; - } - - /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only - * blocked waiting for one of them. */ - xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS ); - - /* The 'test slave' task should now have executed, clearing ebBIT_1 (the - * bit it was blocked on), then re-entered the Blocked state to wait for - * all the other bits in ebCOMBINED_BITS to be set again. First check - * ebBIT_1 is clear. */ - uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); - - if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) ) - { - xError = pdTRUE; - } - - /* Ensure the other task is still in the blocked state. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) - { - xError = pdTRUE; - } - - /* Set all the bits other than ebBIT_1 - which is the bit that must be - * set before the other task unblocks. */ - xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 ); - - /* Ensure all the expected bits are still set. */ - uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); - - if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) ) - { - xError = pdTRUE; - } - - /* Ensure the other task is still in the blocked state. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) - { - xError = pdTRUE; - } - - /* Now also set ebBIT_1, which should unblock the other task, which will - * then suspend itself. */ - xEventGroupSetBits( xEventGroup, ebBIT_1 ); - - /* Ensure the other task is suspended. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) - { - xError = pdTRUE; - } - - /* The other task should not have cleared the bits - so all the bits - * should still be set. */ - if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS ) - { - xError = pdTRUE; - } - - /* Clear ebBIT_1 again. */ - if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS ) - { - xError = pdTRUE; - } - - /* Resume the other task - which will wait on all the ebCOMBINED_BITS - * again - this time clearing the bits when it is unblocked. */ - vTaskResume( xTestSlaveTaskHandle ); - - /* Ensure the other task is blocked once again. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) - { - xError = pdTRUE; - } - - /* Set the bit the other task is waiting for. */ - xEventGroupSetBits( xEventGroup, ebBIT_1 ); - - /* Ensure the other task is suspended once again. */ - if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) - { - xError = pdTRUE; - } - - /* The other task should have cleared the bits in ebCOMBINED_BITS. - * Clear the remaining bits. */ - uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); - - if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) - { - xError = pdTRUE; - } - - /* Clear all bits ready for the sync with the other three tasks. The - * value returned is the value prior to the bits being cleared. */ - if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) - { - xError = pdTRUE; - } - - /* The bits should be clear now. */ - if( xEventGroupGetBits( xEventGroup ) != 0x00 ) - { - xError = pdTRUE; - } - - return xError; -} -/*-----------------------------------------------------------*/ - -static void prvSelectiveBitsTestSlaveFunction( void ) -{ - EventBits_t uxPendBits, uxReturned; - - /* Used in a test that blocks two tasks on various different bits within an - * event group - then sets each bit in turn and checks that the correct tasks - * unblock at the correct times. - * - * This function is called by two different tasks - each of which will use a - * different bit. Check the task handle to see which task the function was - * called by. */ - if( xTaskGetCurrentTaskHandle() == xSyncTask1 ) - { - uxPendBits = ebSELECTIVE_BITS_1; - } - else - { - uxPendBits = ebSELECTIVE_BITS_2; - } - - for( ; ; ) - { - /* Wait until it is time to perform the next cycle of the test. The - * task is unsuspended by the tests implemented in the - * prvSelectiveBitsTestMasterFunction() function. */ - vTaskSuspend( NULL ); - uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY ); - - if( uxReturned == ( EventBits_t ) 0 ) - { - break; - } - } -} -/*-----------------------------------------------------------*/ - -static BaseType_t prvSelectiveBitsTestMasterFunction( void ) -{ - BaseType_t xError = pdFALSE; - EventBits_t uxBit; - - /* Used in a test that blocks two tasks on various different bits within an - * event group - then sets each bit in turn and checks that the correct tasks - * unblock at the correct times. The two other tasks (xSyncTask1 and - * xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in - * this test. - * - * Both other tasks should start in the suspended state. */ - if( eTaskGetState( xSyncTask1 ) != eSuspended ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask2 ) != eSuspended ) - { - xError = pdTRUE; - } - - /* Test each bit in the byte individually. */ - for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 ) - { - /* Resume both tasks. */ - vTaskResume( xSyncTask1 ); - vTaskResume( xSyncTask2 ); - - /* Now both tasks should be blocked on the event group. */ - if( eTaskGetState( xSyncTask1 ) != eBlocked ) - { - xError = pdTRUE; - } - - if( eTaskGetState( xSyncTask2 ) != eBlocked ) - { - xError = pdTRUE; - } - - /* Set one bit. */ - xEventGroupSetBits( xEventGroup, uxBit ); - - /* Is the bit set in the first set of selective bits? If so the first - * sync task should have unblocked and returned to the suspended state. */ - if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 ) - { - /* Task should not have unblocked. */ - if( eTaskGetState( xSyncTask1 ) != eBlocked ) - { - xError = pdTRUE; - } - } - else - { - /* Task should have unblocked and returned to the suspended state. */ - if( eTaskGetState( xSyncTask1 ) != eSuspended ) - { - xError = pdTRUE; - } - } - - /* Same checks for the second sync task. */ - if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 ) - { - /* Task should not have unblocked. */ - if( eTaskGetState( xSyncTask2 ) != eBlocked ) - { - xError = pdTRUE; - } - } - else - { - /* Task should have unblocked and returned to the suspended state. */ - if( eTaskGetState( xSyncTask2 ) != eSuspended ) - { - xError = pdTRUE; - } - } - } - - /* Ensure both tasks are blocked on the event group again, then delete the - * event group so the other tasks leave this portion of the test. */ - vTaskResume( xSyncTask1 ); - vTaskResume( xSyncTask2 ); - - /* Deleting the event group is the signal that the two other tasks should - * leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main - * part of their functionality. */ - vEventGroupDelete( xEventGroup ); - - return xError; -} -/*-----------------------------------------------------------*/ - -void vPeriodicEventGroupsProcessing( void ) -{ - static BaseType_t xCallCount = 0, xISRTestError = pdFALSE; - const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300; - const EventBits_t uxBitsToSet = 0x12U; - EventBits_t uxReturned; - BaseType_t xMessagePosted; - - /* Called periodically from the tick hook to exercise the "FromISR" - * functions. */ - - /* Check the even group tasks were actually created. */ - configASSERT( xISREventGroup ); - - xCallCount++; - - if( xCallCount == xSetBitCount ) - { - /* All the event bits should start clear. */ - uxReturned = xEventGroupGetBitsFromISR( xISREventGroup ); - - if( uxReturned != 0x00 ) - { - xISRTestError = pdTRUE; - } - else - { - /* Set the bits. This is called from the tick hook so it is not - * necessary to use the last parameter to ensure a context switch - * occurs immediately. */ - xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL ); - - if( xMessagePosted != pdPASS ) - { - xISRTestError = pdTRUE; - } - } - } - else if( xCallCount == xGetBitsCount ) - { - /* Check the bits were set as expected. */ - uxReturned = xEventGroupGetBitsFromISR( xISREventGroup ); - - if( uxReturned != uxBitsToSet ) - { - xISRTestError = pdTRUE; - } - } - else if( xCallCount == xClearBitsCount ) - { - /* Clear the bits again. */ - uxReturned = ( EventBits_t ) xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet ); - - /* Check the message was posted. */ - if( uxReturned != pdPASS ) - { - xISRTestError = pdTRUE; - } - - /* Go back to the start. */ - xCallCount = 0; - - /* If no errors have been detected then increment the count of test - * cycles. */ - if( xISRTestError == pdFALSE ) - { - ulISRCycles++; - } - } - else - { - /* Nothing else to do. */ - } -} - -/*-----------------------------------------------------------*/ -/* This is called to check that all the created tasks are still running. */ -BaseType_t xAreEventGroupTasksStillRunning( void ) -{ - static uint32_t ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0; - BaseType_t xStatus = pdPASS; - - /* Check the tasks are still cycling without finding any errors. */ - if( ulPreviousSetBitCycles == ulTestMasterCycles ) - { - xStatus = pdFAIL; - } - - ulPreviousSetBitCycles = ulTestMasterCycles; - - if( ulPreviousWaitBitCycles == ulTestSlaveCycles ) - { - xStatus = pdFAIL; - } - - ulPreviousWaitBitCycles = ulTestSlaveCycles; - - if( ulPreviousISRCycles == ulISRCycles ) - { - xStatus = pdFAIL; - } - - ulPreviousISRCycles = ulISRCycles; - - return xStatus; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + + +/* + * 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. + * + * NOTE: The tests implemented in this file are informal 'sanity' tests + * only and are not part of the module tests that make use of the + * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. + */ + + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "event_groups.h" + +/* Demo app includes. */ +#include "EventGroupsDemo.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 the tasks. */ +#define ebSET_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define ebWAIT_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* Generic bit definitions. */ +#define ebBIT_0 ( 0x01 ) +#define ebBIT_1 ( 0x02 ) +#define ebBIT_2 ( 0x04 ) +#define ebBIT_3 ( 0x08 ) +#define ebBIT_4 ( 0x10 ) +#define ebBIT_5 ( 0x20 ) +#define ebBIT_6 ( 0x40 ) +#define ebBIT_7 ( 0x80 ) + +/* Combinations of bits used in the demo. */ +#define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 ) +#define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 ) + +/* Associate a bit to each task. These bits are used to identify all the tasks + * that synchronise with the xEventGroupSync() function. */ +#define ebSET_BIT_TASK_SYNC_BIT ebBIT_0 +#define ebWAIT_BIT_TASK_SYNC_BIT ebBIT_1 +#define ebRENDEZVOUS_TASK_1_SYNC_BIT ebBIT_2 +#define ebRENDEZVOUS_TASK_2_SYNC_BIT ebBIT_3 +#define ebALL_SYNC_BITS ( ebSET_BIT_TASK_SYNC_BIT | ebWAIT_BIT_TASK_SYNC_BIT | ebRENDEZVOUS_TASK_1_SYNC_BIT | ebRENDEZVOUS_TASK_2_SYNC_BIT ) + +/* A block time of zero simply means "don't block". */ +#define ebDONT_BLOCK ( 0 ) + +/* A 5ms delay. */ +#define ebSHORT_DELAY pdMS_TO_TICKS( ( TickType_t ) 5 ) + +/* Used in the selective bits test which checks no, one or both tasks blocked on + * event bits in a group are unblocked as appropriate as different bits get set. */ +#define ebSELECTIVE_BITS_1 0x03 +#define ebSELECTIVE_BITS_2 0x05 + +#ifndef ebRENDEZVOUS_TEST_TASK_STACK_SIZE + #define ebRENDEZVOUS_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE +#endif + +#ifndef ebEVENT_GROUP_SET_BITS_TEST_TASK_STACK_SIZE + #define ebEVENT_GROUP_SET_BITS_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE +#endif + +/*-----------------------------------------------------------*/ + +/* + * NOTE: The tests implemented in this function are informal 'sanity' tests + * only and are not part of the module tests that make use of the + * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. + * + * The master test task. This task: + * + * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two + * tasks are blocked on different bits in an event group. The counterpart of + * this test is implemented by the prvSelectiveBitsTestSlaveFunction() + * function (which is called by the two tasks that block on the event group). + * + * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when + * just one task is blocked on various combinations of bits within an event + * group. The counterpart of this test is implemented within the 'test + * slave' task. + * + * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour. + */ +static void prvTestMasterTask( void * pvParameters ); + +/* + * A helper task that enables the 'test master' task to perform several + * behavioural tests. See the comments above the prvTestMasterTask() prototype + * above. + */ +static void prvTestSlaveTask( void * pvParameters ); + +/* + * The part of the test that is performed between the 'test master' task and the + * 'test slave' task to test the behaviour when the slave blocks on various + * event bit combinations. + */ +static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, + TaskHandle_t xTestSlaveTaskHandle ); + +/* + * The part of the test that uses all the tasks to test the task synchronisation + * behaviour. + */ +static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, + TaskHandle_t xTestSlaveTaskHandle ); + +/* + * Two instances of prvSyncTask() are created. They start by calling + * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is + * executing the prvSelectiveBitsTestMasterFunction() function. They then loop + * to test the task synchronisation (rendezvous) behaviour. + */ +static void prvSyncTask( void * pvParameters ); + +/* + * Functions used in a test that blocks two tasks on various different bits + * within an event group - then sets each bit in turn and checks that the + * correct tasks unblock at the correct times. + */ +static BaseType_t prvSelectiveBitsTestMasterFunction( void ); +static void prvSelectiveBitsTestSlaveFunction( void ); + +/*-----------------------------------------------------------*/ + +/* Variables that are incremented by the tasks on each cycle provided no errors + * have been found. Used to detect an error or stall in the test cycling. */ +static volatile uint32_t ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0; + +/* The event group used by all the task based tests. */ +static EventGroupHandle_t xEventGroup = NULL; + +/* The event group used by the interrupt based tests. */ +static EventGroupHandle_t xISREventGroup = NULL; + +/* Handles to the tasks that only take part in the synchronisation calls. */ +static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL; + +/*-----------------------------------------------------------*/ + +void vStartEventGroupTasks( void ) +{ + TaskHandle_t xTestSlaveTaskHandle; + + /* + * 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. + * + * NOTE: The tests implemented in this file are informal 'sanity' tests + * only and are not part of the module tests that make use of the + * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. + * + * Create the test tasks as described at the top of this file. + */ + xTaskCreate( prvTestSlaveTask, "WaitO", ebRENDEZVOUS_TEST_TASK_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle ); + xTaskCreate( prvTestMasterTask, "SetB", ebEVENT_GROUP_SET_BITS_TEST_TASK_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL ); + xTaskCreate( prvSyncTask, "Rndv", ebRENDEZVOUS_TEST_TASK_STACK_SIZE, ( void * ) ebRENDEZVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 ); + xTaskCreate( prvSyncTask, "Rndv", ebRENDEZVOUS_TEST_TASK_STACK_SIZE, ( void * ) ebRENDEZVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 ); + + /* If the last task was created then the others will have been too. */ + configASSERT( xSyncTask2 ); + + /* Create the event group used by the ISR tests. The event group used by + * the tasks is created by the tasks themselves. */ + xISREventGroup = xEventGroupCreate(); + configASSERT( xISREventGroup ); +} +/*-----------------------------------------------------------*/ + +static void prvTestMasterTask( void * pvParameters ) +{ + BaseType_t xError; + +/* The handle to the slave task is passed in as the task parameter. */ + TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters; + + /* Avoid compiler warnings. */ + ( void ) pvParameters; + + /* Create the event group used by the tasks ready for the initial tests. */ + xEventGroup = xEventGroupCreate(); + configASSERT( xEventGroup ); + + /* Perform the tests that block two tasks on different combinations of bits, + * then set each bit in turn and check the correct tasks unblock at the correct + * times. */ + xError = prvSelectiveBitsTestMasterFunction(); + + for( ; ; ) + { + /* Recreate the event group ready for the next cycle. */ + xEventGroup = xEventGroupCreate(); + configASSERT( xEventGroup ); + + /* Perform the tests that check the behaviour when a single task is + * blocked on various combinations of event bits. */ + xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle ); + + /* Perform the task synchronisation tests. */ + xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle ); + + /* Delete the event group. */ + vEventGroupDelete( xEventGroup ); + + /* Now all the other tasks should have completed and suspended + * themselves ready for the next go around the loop. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Only increment the cycle variable if no errors have been detected. */ + if( xError == pdFALSE ) + { + ulTestMasterCycles++; + } + + configASSERT( xError == pdFALSE ); + } +} +/*-----------------------------------------------------------*/ + +static void prvSyncTask( void * pvParameters ) +{ + EventBits_t uxSynchronisationBit, uxReturned; + + /* A few tests that check the behaviour when two tasks are blocked on + * various different bits within an event group are performed before this task + * enters its infinite loop to carry out its main demo function. */ + prvSelectiveBitsTestSlaveFunction(); + + /* The bit to use to indicate this task is at the synchronisation point is + * passed in as the task parameter. */ + uxSynchronisationBit = ( EventBits_t ) pvParameters; + + for( ; ; ) + { + /* Now this task takes part in a task synchronisation - sometimes known + * as a 'rendezvous'. Its execution pattern is controlled by the 'test + * master' task, which is responsible for taking this task out of the + * Suspended state when it is time to test the synchronisation behaviour. + * See: http://www.freertos.org/xEventGroupSync.html. */ + vTaskSuspend( NULL ); + + /* Set the bit that indicates this task is at the synchronisation + * point. The first time this is done the 'test master' task has a lower + * priority than this task so this task will get to the sync point before + * the set bits task - test this by calling xEventGroupSync() with a zero + * block time before calling again with a max delay - the first call should + * return before the rendezvous completes, the second only after the + * rendezvous is complete. */ + uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */ + ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks taking part in the sync. */ + ebDONT_BLOCK ); /* The maximum time to wait for the sync condition to be met before giving up. */ + + /* No block time was specified, so as per the comments above, the + * rendezvous is not expected to have completed yet. */ + configASSERT( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ); + + uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */ + ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks taking part in the sync. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */ + + /* A max delay was used, so this task should only exit the above + * function call when the sync condition is met. Check this is the + * case. */ + configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS ); + + /* Remove compiler warning if configASSERT() is not defined. */ + ( void ) uxReturned; + + /* Wait until the 'test master' task unsuspends this task again. */ + vTaskSuspend( NULL ); + + /* Set the bit that indicates this task is at the synchronisation + * point again. This time the 'test master' task has a higher priority + * than this task so will get to the sync point before this task. */ + uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY ); + + /* Again a max delay was used, so this task should only exit the above + * function call when the sync condition is met. Check this is the + * case. */ + configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS ); + + /* Block on the event group again. This time the event group is going + * to be deleted while this task is blocked on it so it is expected that 0 + * be returned. */ + uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY ); + configASSERT( uxReturned == 0 ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTestSlaveTask( void * pvParameters ) +{ + EventBits_t uxReturned; + BaseType_t xError = pdFALSE; + + /* Avoid compiler warnings. */ + ( void ) pvParameters; + + for( ; ; ) + { + /********************************************************************** + * Part 1: This section is the counterpart to the + * prvBitCombinationTestMasterFunction() function which is called by the + * test master task. + *********************************************************************** + * + * This task is controller by the 'test master' task (which is + * implemented by prvTestMasterTask()). Suspend until resumed by the + * 'test master' task. */ + vTaskSuspend( NULL ); + + /* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get + * set. Clear the bit on exit. */ + uxReturned = xEventGroupWaitBits( xEventGroup, /* The event group that contains the event bits being queried. */ + ebBIT_1, /* The bit to wait for. */ + pdTRUE, /* Clear the bit on exit. */ + pdTRUE, /* Wait for all the bits (only one in this case anyway). */ + portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */ + + /* The 'test master' task set all the bits defined by ebCOMBINED_BITS, + * only one of which was being waited for by this task. The return value + * shows the state of the event bits when the task was unblocked, however + * because the task was waiting for ebBIT_1 and 'clear on exit' was set to + * the current state of the event bits will have ebBIT_1 clear. */ + if( uxReturned != ebCOMBINED_BITS ) + { + xError = pdTRUE; + } + + /* Now call xEventGroupWaitBits() again, this time waiting for all the + * bits in ebCOMBINED_BITS to be set. This call should block until the + * 'test master' task sets ebBIT_1 - which was the bit cleared in the call + * to xEventGroupWaitBits() above. */ + uxReturned = xEventGroupWaitBits( xEventGroup, + ebCOMBINED_BITS, /* The bits being waited on. */ + pdFALSE, /* Don't clear the bits on exit. */ + pdTRUE, /* All the bits must be set to unblock. */ + portMAX_DELAY ); + + /* Were all the bits set? */ + if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS ) + { + xError = pdTRUE; + } + + /* Suspend again to wait for the 'test master' task. */ + vTaskSuspend( NULL ); + + /* Now call xEventGroupWaitBits() again, again waiting for all the bits + * in ebCOMBINED_BITS to be set, but this time clearing the bits when the + * task is unblocked. */ + uxReturned = xEventGroupWaitBits( xEventGroup, + ebCOMBINED_BITS, /* The bits being waited on. */ + pdTRUE, /* Clear the bits on exit. */ + pdTRUE, /* All the bits must be set to unblock. */ + portMAX_DELAY ); + + /* The 'test master' task set all the bits in the event group, so that + * is the value that should have been returned. The bits defined by + * ebCOMBINED_BITS will have been clear again in the current value though + * as 'clear on exit' was set to pdTRUE. */ + if( uxReturned != ebALL_BITS ) + { + xError = pdTRUE; + } + + /********************************************************************** + * Part 2: This section is the counterpart to the + * prvPerformTaskSyncTests() function which is called by the + * test master task. + *********************************************************************** + * + * + * Once again wait for the 'test master' task to unsuspend this task + * when it is time for the next test. */ + vTaskSuspend( NULL ); + + /* Now perform a synchronisation with all the other tasks. At this point + * the 'test master' task has the lowest priority so will get to the sync + * point after all the other synchronising tasks. */ + uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the sync. */ + ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */ + ebALL_SYNC_BITS, /* The bits to wait for. These bits are set by the other tasks taking part in the sync. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */ + + /* A sync with a max delay should only exit when all the synchronisation + * bits are set... */ + if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the synchronisation bits should be clear again. Read back + * the current value of the bits within the event group to check that is + * the case. Setting the bits to zero will return the bits previous value + * then leave all the bits clear. */ + if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 ) + { + xError = pdTRUE; + } + + /* Check the bits are indeed 0 now by simply reading then. */ + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + if( xError == pdFALSE ) + { + /* This task is still cycling without finding an error. */ + ulTestSlaveCycles++; + } + + vTaskSuspend( NULL ); + + /* This time sync when the 'test master' task has the highest priority + * at the point where it sets its sync bit - so this time the 'test master' + * task will get to the sync point before this task. */ + uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY ); + + /* A sync with a max delay should only exit when all the synchronisation + * bits are set... */ + if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again. */ + if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 ) + { + xError = pdTRUE; + } + + /* Block on the event group again. This time the event group is going + * to be deleted while this task is blocked on it, so it is expected that 0 + * will be returned. */ + uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY ); + + if( uxReturned != 0 ) + { + xError = pdTRUE; + } + + if( xError == pdFALSE ) + { + /* This task is still cycling without finding an error. */ + ulTestSlaveCycles++; + } + + configASSERT( xError == pdFALSE ); + } +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, + TaskHandle_t xTestSlaveTaskHandle ) +{ + EventBits_t uxBits; + + /* The three tasks that take part in the synchronisation (rendezvous) are + * expected to be in the suspended state at the start of the test. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Try a synch with no other tasks involved. First set all the bits other + * than this task's bit. */ + xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); + + /* Then wait on just one bit - the bit that is being set. */ + uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + ebSET_BIT_TASK_SYNC_BIT, /* The bit set by this task when it reaches the sync point. */ + ebSET_BIT_TASK_SYNC_BIT, /* The bits to wait for - in this case it is just waiting for itself. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ + + /* A sync with a max delay should only exit when all the synchronise + * bits are set...check that is the case. In this case there is only one + * sync bit anyway. */ + if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again, leaving all the other + * bits set (as only one bit was being waited for). */ + if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ) + { + xError = pdTRUE; + } + + /* Clear all the bits to zero again. */ + xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); + + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + /* Unsuspend the other tasks then check they have executed up to the + * synchronisation point. */ + vTaskResume( xTestSlaveTaskHandle ); + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set this task's sync bit. */ + uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + ebSET_BIT_TASK_SYNC_BIT, /* The bit set by this task when it reaches the sync point. */ + ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ + + /* A sync with a max delay should only exit when all the synchronise + * bits are set...check that is the case. */ + if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again. */ + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + /* The other tasks should now all be suspended again, ready for the next + * synchronisation. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Sync again - but this time set the last necessary bit as the + * highest priority task, rather than the lowest priority task. Unsuspend + * the other tasks then check they have executed up to the synchronisation + * point. */ + vTaskResume( xTestSlaveTaskHandle ); + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Raise the priority of this task above that of the other tasks. */ + vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 ); + + /* Set this task's sync bit. */ + uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY ); + + /* A sync with a max delay should only exit when all the synchronisation + * bits are set... */ + if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again. */ + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + /* The other tasks should now all be in the ready state again, but not + * executed yet as this task still has a higher relative priority. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eReady ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eReady ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eReady ) + { + xError = pdTRUE; + } + + /* Reset the priority of this task back to its original value. */ + vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY ); + + /* Now all the other tasks should have reblocked on the event bits + * to test the behaviour when the event bits are deleted. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + return xError; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, + TaskHandle_t xTestSlaveTaskHandle ) +{ + EventBits_t uxBits; + + /* Resume the other task. It will block, pending a single bit from + * within ebCOMBINED_BITS. */ + vTaskResume( xTestSlaveTaskHandle ); + + /* Ensure the other task is blocked on the task. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only + * blocked waiting for one of them. */ + xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS ); + + /* The 'test slave' task should now have executed, clearing ebBIT_1 (the + * bit it was blocked on), then re-entered the Blocked state to wait for + * all the other bits in ebCOMBINED_BITS to be set again. First check + * ebBIT_1 is clear. */ + uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); + + if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) ) + { + xError = pdTRUE; + } + + /* Ensure the other task is still in the blocked state. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set all the bits other than ebBIT_1 - which is the bit that must be + * set before the other task unblocks. */ + xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 ); + + /* Ensure all the expected bits are still set. */ + uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); + + if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) ) + { + xError = pdTRUE; + } + + /* Ensure the other task is still in the blocked state. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Now also set ebBIT_1, which should unblock the other task, which will + * then suspend itself. */ + xEventGroupSetBits( xEventGroup, ebBIT_1 ); + + /* Ensure the other task is suspended. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + /* The other task should not have cleared the bits - so all the bits + * should still be set. */ + if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS ) + { + xError = pdTRUE; + } + + /* Clear ebBIT_1 again. */ + if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS ) + { + xError = pdTRUE; + } + + /* Resume the other task - which will wait on all the ebCOMBINED_BITS + * again - this time clearing the bits when it is unblocked. */ + vTaskResume( xTestSlaveTaskHandle ); + + /* Ensure the other task is blocked once again. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set the bit the other task is waiting for. */ + xEventGroupSetBits( xEventGroup, ebBIT_1 ); + + /* Ensure the other task is suspended once again. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + /* The other task should have cleared the bits in ebCOMBINED_BITS. + * Clear the remaining bits. */ + uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); + + if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) + { + xError = pdTRUE; + } + + /* Clear all bits ready for the sync with the other three tasks. The + * value returned is the value prior to the bits being cleared. */ + if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) + { + xError = pdTRUE; + } + + /* The bits should be clear now. */ + if( xEventGroupGetBits( xEventGroup ) != 0x00 ) + { + xError = pdTRUE; + } + + return xError; +} +/*-----------------------------------------------------------*/ + +static void prvSelectiveBitsTestSlaveFunction( void ) +{ + EventBits_t uxPendBits, uxReturned; + + /* Used in a test that blocks two tasks on various different bits within an + * event group - then sets each bit in turn and checks that the correct tasks + * unblock at the correct times. + * + * This function is called by two different tasks - each of which will use a + * different bit. Check the task handle to see which task the function was + * called by. */ + if( xTaskGetCurrentTaskHandle() == xSyncTask1 ) + { + uxPendBits = ebSELECTIVE_BITS_1; + } + else + { + uxPendBits = ebSELECTIVE_BITS_2; + } + + for( ; ; ) + { + /* Wait until it is time to perform the next cycle of the test. The + * task is unsuspended by the tests implemented in the + * prvSelectiveBitsTestMasterFunction() function. */ + vTaskSuspend( NULL ); + uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY ); + + if( uxReturned == ( EventBits_t ) 0 ) + { + break; + } + } +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvSelectiveBitsTestMasterFunction( void ) +{ + BaseType_t xError = pdFALSE; + EventBits_t uxBit; + + /* Used in a test that blocks two tasks on various different bits within an + * event group - then sets each bit in turn and checks that the correct tasks + * unblock at the correct times. The two other tasks (xSyncTask1 and + * xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in + * this test. + * + * Both other tasks should start in the suspended state. */ + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Test each bit in the byte individually. */ + for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 ) + { + /* Resume both tasks. */ + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + /* Now both tasks should be blocked on the event group. */ + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set one bit. */ + xEventGroupSetBits( xEventGroup, uxBit ); + + /* Is the bit set in the first set of selective bits? If so the first + * sync task should have unblocked and returned to the suspended state. */ + if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 ) + { + /* Task should not have unblocked. */ + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + } + else + { + /* Task should have unblocked and returned to the suspended state. */ + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + } + + /* Same checks for the second sync task. */ + if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 ) + { + /* Task should not have unblocked. */ + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + } + else + { + /* Task should have unblocked and returned to the suspended state. */ + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + } + } + + /* Ensure both tasks are blocked on the event group again, then delete the + * event group so the other tasks leave this portion of the test. */ + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + /* Deleting the event group is the signal that the two other tasks should + * leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main + * part of their functionality. */ + vEventGroupDelete( xEventGroup ); + + return xError; +} +/*-----------------------------------------------------------*/ + +void vPeriodicEventGroupsProcessing( void ) +{ + static BaseType_t xCallCount = 0, xISRTestError = pdFALSE; + const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300; + const EventBits_t uxBitsToSet = 0x12U; + EventBits_t uxReturned; + BaseType_t xMessagePosted; + + /* Called periodically from the tick hook to exercise the "FromISR" + * functions. */ + + /* Check the even group tasks were actually created. */ + configASSERT( xISREventGroup ); + + xCallCount++; + + if( xCallCount == xSetBitCount ) + { + /* All the event bits should start clear. */ + uxReturned = xEventGroupGetBitsFromISR( xISREventGroup ); + + if( uxReturned != 0x00 ) + { + xISRTestError = pdTRUE; + } + else + { + /* Set the bits. This is called from the tick hook so it is not + * necessary to use the last parameter to ensure a context switch + * occurs immediately. */ + xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL ); + + if( xMessagePosted != pdPASS ) + { + xISRTestError = pdTRUE; + } + } + } + else if( xCallCount == xGetBitsCount ) + { + /* Check the bits were set as expected. */ + uxReturned = xEventGroupGetBitsFromISR( xISREventGroup ); + + if( uxReturned != uxBitsToSet ) + { + xISRTestError = pdTRUE; + } + } + else if( xCallCount == xClearBitsCount ) + { + /* Clear the bits again. */ + uxReturned = ( EventBits_t ) xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet ); + + /* Check the message was posted. */ + if( uxReturned != pdPASS ) + { + xISRTestError = pdTRUE; + } + + /* Go back to the start. */ + xCallCount = 0; + + /* If no errors have been detected then increment the count of test + * cycles. */ + if( xISRTestError == pdFALSE ) + { + ulISRCycles++; + } + } + else + { + /* Nothing else to do. */ + } +} + +/*-----------------------------------------------------------*/ +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreEventGroupTasksStillRunning( void ) +{ + static uint32_t ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0; + BaseType_t xStatus = pdPASS; + + /* Check the tasks are still cycling without finding any errors. */ + if( ulPreviousSetBitCycles == ulTestMasterCycles ) + { + xStatus = pdFAIL; + } + + ulPreviousSetBitCycles = ulTestMasterCycles; + + if( ulPreviousWaitBitCycles == ulTestSlaveCycles ) + { + xStatus = pdFAIL; + } + + ulPreviousWaitBitCycles = ulTestSlaveCycles; + + if( ulPreviousISRCycles == ulISRCycles ) + { + xStatus = pdFAIL; + } + + ulPreviousISRCycles = ulISRCycles; + + return xStatus; +} diff --git a/FreeRTOS/Demo/Common/Minimal/GenQTest.c b/FreeRTOS/Demo/Common/Minimal/GenQTest.c index fca907c31..aac016fa9 100644 --- a/FreeRTOS/Demo/Common/Minimal/GenQTest.c +++ b/FreeRTOS/Demo/Common/Minimal/GenQTest.c @@ -1,1039 +1,1039 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* - * 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 - -/* 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 genqSHORT_BLOCK ( pdMS_TO_TICKS( 2 ) ) - -#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 ) - -#ifndef genqMUTEX_TEST_TASK_STACK_SIZE - #define genqMUTEX_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE -#endif - -#ifndef genqGENERIC_QUEUE_TEST_TASK_STACK_SIZE - #define genqGENERIC_QUEUE_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE -#endif -/*-----------------------------------------------------------*/ - -/* - * 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 ); - -/* - * Tests the behaviour when a low priority task inherits the priority of a - * higher priority task when taking two mutexes, and returns the mutexes in - * first the same order as the two mutexes were obtained, and second the - * opposite order as the two mutexes were obtained. - */ -static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, - SemaphoreHandle_t xLocalMutex ); -static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, - SemaphoreHandle_t xLocalMutex ); - -#if ( INCLUDE_xTaskAbortDelay == 1 ) - - #if ( configUSE_PREEMPTION == 0 ) - #error The additional tests included when INCLUDE_xTaskAbortDelay is 1 expect preemption to be used. - #endif - -/* Tests the behaviour when a low priority task inherits the priority of a - * high priority task only for the high priority task to timeout before - * obtaining the mutex. */ - static void prvHighPriorityTimeout( SemaphoreHandle_t xMutex ); -#endif - -/*-----------------------------------------------------------*/ - -/* 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; - -/* If INCLUDE_xTaskAbortDelay is 1 additional tests are performed, requiring an - * additional task. */ -#if ( INCLUDE_xTaskAbortDelay == 1 ) - static TaskHandle_t xSecondMediumPriorityMutexTask; -#endif - -/* Lets the high priority semaphore task know that its wait for the semaphore - * was aborted, in which case not being able to obtain the semaphore is not to be - * considered an error. */ -static volatile BaseType_t xBlockWasAborted = pdFALSE; - -/*-----------------------------------------------------------*/ - -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", genqGENERIC_QUEUE_TEST_TASK_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", genqMUTEX_TEST_TASK_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL ); - xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask ); - xTaskCreate( prvHighPriorityMutexTask, "MuHigh", genqMUTEX_TEST_TASK_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask ); - - /* If INCLUDE_xTaskAbortDelay is set then additional tests are performed, - * requiring two instances of prvHighPriorityMutexTask(). */ - #if ( INCLUDE_xTaskAbortDelay == 1 ) - { - xTaskCreate( prvHighPriorityMutexTask, "MuHigh2", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_MEDIUM_PRIORITY, &xSecondMediumPriorityMutexTask ); - } - #endif /* INCLUDE_xTaskAbortDelay */ - } -} -/*-----------------------------------------------------------*/ - -static void prvSendFrontAndBackTest( void * pvParameters ) -{ - uint32_t ulData, ulData2, ulLoopCounterSnapshot; - 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 effect as sending it to the front of the queue. - * - * First send to the front and check everything is as expected. */ - ulLoopCounterSnapshot = ulLoopCounter; - xQueueSendToFront( xQueue, ( void * ) &ulLoopCounterSnapshot, 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; - } - - ulLoopCounterSnapshot = ulLoopCounter; - xQueueSendToBack( xQueue, ( void * ) &ulLoopCounterSnapshot, 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 sent to the queue should equal the data 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; - } - - /* Increment the loop counter to indicate these tasks are still - * executing. */ - ulLoopCounter++; - } -} -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_xTaskAbortDelay == 1 ) - - static void prvHighPriorityTimeout( SemaphoreHandle_t xMutex ) - { - static UBaseType_t uxLoopCount = 0; - - /* The tests in this function are very similar, the slight variations - * are for code coverage purposes. */ - - /* Take the mutex. It should be available now. Check before and after - * taking that the holder is reported correctly. */ - if( xSemaphoreGetMutexHolder( xMutex ) != NULL ) - { - xErrorDetected = pdTRUE; - } - - if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - if( xSemaphoreGetMutexHolder( xMutex ) != xTaskGetCurrentTaskHandle() ) - { - xErrorDetected = pdTRUE; - } - - /* 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 ); - - /* This task should now have inherited the priority of the high priority - * task as by now the high priority task will have attempted to obtain the - * mutex. */ - if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) - { - xErrorDetected = pdTRUE; - } - - /* Unblock a second medium priority task. It too will attempt to take - * the mutex and enter the Blocked state - it won't run yet though as this - * task has inherited a priority above it. */ - vTaskResume( xSecondMediumPriorityMutexTask ); - - /* This task should still have the priority of the high priority task as - * that had already been inherited as is the highest priority of the three - * tasks using the mutex. */ - if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) - { - xErrorDetected = pdTRUE; - } - - /* On some loops, block for a short while to provide additional - * code coverage. Blocking here will allow the medium priority task to - * execute and so also block on the mutex so when the high priority task - * causes this task to disinherit the high priority it is inherited down to - * the priority of the medium priority task. When there is no delay the - * medium priority task will not run until after the disinheritance, so - * this task will disinherit back to its base priority, then only up to the - * medium priority after the medium priority has executed. */ - vTaskDelay( uxLoopCount & ( UBaseType_t ) 0x07 ); - - /* Now force the high priority task to unblock. It will fail to obtain - * the mutex and go back to the suspended state - allowing this task to - * execute again. xBlockWasAborted is set to pdTRUE so the higher priority - * task knows that its failure to obtain the semaphore is not an error. */ - xBlockWasAborted = pdTRUE; - - if( xTaskAbortDelay( xHighPriorityMutexTask ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - /* This task has inherited the priority of xHighPriorityMutexTask so - * could still be running even though xHighPriorityMutexTask is no longer - * blocked. Delay for a short while to ensure xHighPriorityMutexTask gets - * a chance to run - indicated by this task changing priority. It should - * disinherit the high priority task, but then inherit the priority of the - * medium priority task that is waiting for the same mutex. */ - while( uxTaskPriorityGet( NULL ) != genqMUTEX_MEDIUM_PRIORITY ) - { - /* If this task gets stuck here then the check variables will stop - * incrementing and the check task will detect the error. */ - vTaskDelay( genqSHORT_BLOCK ); - } - - /* Now force the medium priority task to unblock. xBlockWasAborted is - * set to pdTRUE so the medium priority task knows that its failure to - * obtain the semaphore is not an error. */ - xBlockWasAborted = pdTRUE; - - if( xTaskAbortDelay( xSecondMediumPriorityMutexTask ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - /* This time no other tasks are waiting for the mutex, so this task - * should return to its base priority. This might not happen straight - * away as it is running at the same priority as the task it just - * unblocked. */ - while( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) - { - /* If this task gets stuck here then the check variables will stop - * incrementing and the check task will detect the error. */ - vTaskDelay( genqSHORT_BLOCK ); - } - - /* Give the semaphore back ready for the next test. Check the mutex - * holder before and after using the "FromISR" version for code coverage. */ - if( xSemaphoreGetMutexHolderFromISR( xMutex ) != xTaskGetCurrentTaskHandle() ) - { - xErrorDetected = pdTRUE; - } - - xSemaphoreGive( xMutex ); - - if( xSemaphoreGetMutexHolderFromISR( xMutex ) != NULL ) - { - xErrorDetected = pdTRUE; - } - - configASSERT( xErrorDetected == pdFALSE ); - - /* Now do the same again, but this time unsuspend the tasks in the - * opposite order. This takes a different path though the code because - * when the high priority task has its block aborted there is already - * another task in the list of tasks waiting for the mutex, and the - * low priority task drops down to that priority, rather than dropping - * down to its base priority before inheriting the priority of the medium - * priority task. */ - if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) - { - xErrorDetected = pdTRUE; - } - - /* This time unsuspend the medium priority task first. This will - * attempt to take the mutex, and block when it finds it cannot obtain it. */ - vTaskResume( xSecondMediumPriorityMutexTask ); - - /* This time this task should now have inherited the priority of the - * medium task. */ - if( uxTaskPriorityGet( NULL ) != genqMUTEX_MEDIUM_PRIORITY ) - { - xErrorDetected = pdTRUE; - } - - /* This time the high priority task in unsuspended second. */ - vTaskResume( xHighPriorityMutexTask ); - - /* The high priority task should already have run, causing this task to - * inherit a priority for the second time. */ - if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) - { - xErrorDetected = pdTRUE; - } - - /* This time, when the high priority task has its delay aborted and it - * fails to obtain the mutex this task will immediately have its priority - * lowered down to that of the highest priority task waiting on the mutex, - * which is the medium priority task. */ - xBlockWasAborted = pdTRUE; - - if( xTaskAbortDelay( xHighPriorityMutexTask ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - while( uxTaskPriorityGet( NULL ) != genqMUTEX_MEDIUM_PRIORITY ) - { - /* If this task gets stuck here then the check variables will stop - * incrementing and the check task will detect the error. */ - vTaskDelay( genqSHORT_BLOCK ); - } - - /* And finally, when the medium priority task also have its delay - * aborted there are no other tasks waiting for the mutex so this task - * returns to its base priority. */ - xBlockWasAborted = pdTRUE; - - if( xTaskAbortDelay( xSecondMediumPriorityMutexTask ) != pdPASS ) - { - xErrorDetected = pdTRUE; - } - - while( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) - { - /* If this task gets stuck here then the check variables will stop - * incrementing and the check task will detect the error. */ - vTaskDelay( genqSHORT_BLOCK ); - } - - /* Give the semaphore back ready for the next test. */ - xSemaphoreGive( xMutex ); - - configASSERT( xErrorDetected == pdFALSE ); - - /* uxLoopCount is used to add a variable delay, and in-so-doing provide - * additional code coverage. */ - uxLoopCount++; - } - -#endif /* INCLUDE_xTaskAbortDelay == 1 */ -/*-----------------------------------------------------------*/ - -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 */ - - /* This task should now have inherited the priority of the high priority - * task as by now the high priority task will have attempted to obtain 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 */ - - /* This task should now have inherited the priority of the high priority - * task as by now the high priority task will have attempted to obtain 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 'mutex 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 - - #if ( INCLUDE_xTaskAbortDelay == 1 ) - { - /* Tests the behaviour when a low priority task inherits the - * priority of a high priority task only for the high priority task to - * timeout before obtaining the mutex. */ - prvHighPriorityTimeout( xMutex ); - } - #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 ) - { - /* This task would expect to obtain the mutex unless its wait for - * the mutex was aborted. */ - if( xBlockWasAborted == pdFALSE ) - { - xErrorDetected = pdTRUE; - } - else - { - xBlockWasAborted = pdFALSE; - } - } - else - { - /* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * 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 + +/* 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 genqSHORT_BLOCK ( pdMS_TO_TICKS( 2 ) ) + +#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 ) + +#ifndef genqMUTEX_TEST_TASK_STACK_SIZE + #define genqMUTEX_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE +#endif + +#ifndef genqGENERIC_QUEUE_TEST_TASK_STACK_SIZE + #define genqGENERIC_QUEUE_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE +#endif +/*-----------------------------------------------------------*/ + +/* + * 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 ); + +/* + * Tests the behaviour when a low priority task inherits the priority of a + * higher priority task when taking two mutexes, and returns the mutexes in + * first the same order as the two mutexes were obtained, and second the + * opposite order as the two mutexes were obtained. + */ +static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, + SemaphoreHandle_t xLocalMutex ); +static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, + SemaphoreHandle_t xLocalMutex ); + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + + #if ( configUSE_PREEMPTION == 0 ) + #error The additional tests included when INCLUDE_xTaskAbortDelay is 1 expect preemption to be used. + #endif + +/* Tests the behaviour when a low priority task inherits the priority of a + * high priority task only for the high priority task to timeout before + * obtaining the mutex. */ + static void prvHighPriorityTimeout( SemaphoreHandle_t xMutex ); +#endif + +/*-----------------------------------------------------------*/ + +/* 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; + +/* If INCLUDE_xTaskAbortDelay is 1 additional tests are performed, requiring an + * additional task. */ +#if ( INCLUDE_xTaskAbortDelay == 1 ) + static TaskHandle_t xSecondMediumPriorityMutexTask; +#endif + +/* Lets the high priority semaphore task know that its wait for the semaphore + * was aborted, in which case not being able to obtain the semaphore is not to be + * considered an error. */ +static volatile BaseType_t xBlockWasAborted = pdFALSE; + +/*-----------------------------------------------------------*/ + +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", genqGENERIC_QUEUE_TEST_TASK_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", genqMUTEX_TEST_TASK_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL ); + xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask ); + xTaskCreate( prvHighPriorityMutexTask, "MuHigh", genqMUTEX_TEST_TASK_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask ); + + /* If INCLUDE_xTaskAbortDelay is set then additional tests are performed, + * requiring two instances of prvHighPriorityMutexTask(). */ + #if ( INCLUDE_xTaskAbortDelay == 1 ) + { + xTaskCreate( prvHighPriorityMutexTask, "MuHigh2", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_MEDIUM_PRIORITY, &xSecondMediumPriorityMutexTask ); + } + #endif /* INCLUDE_xTaskAbortDelay */ + } +} +/*-----------------------------------------------------------*/ + +static void prvSendFrontAndBackTest( void * pvParameters ) +{ + uint32_t ulData, ulData2, ulLoopCounterSnapshot; + 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 effect as sending it to the front of the queue. + * + * First send to the front and check everything is as expected. */ + ulLoopCounterSnapshot = ulLoopCounter; + xQueueSendToFront( xQueue, ( void * ) &ulLoopCounterSnapshot, 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; + } + + ulLoopCounterSnapshot = ulLoopCounter; + xQueueSendToBack( xQueue, ( void * ) &ulLoopCounterSnapshot, 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 sent to the queue should equal the data 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; + } + + /* Increment the loop counter to indicate these tasks are still + * executing. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + + static void prvHighPriorityTimeout( SemaphoreHandle_t xMutex ) + { + static UBaseType_t uxLoopCount = 0; + + /* The tests in this function are very similar, the slight variations + * are for code coverage purposes. */ + + /* Take the mutex. It should be available now. Check before and after + * taking that the holder is reported correctly. */ + if( xSemaphoreGetMutexHolder( xMutex ) != NULL ) + { + xErrorDetected = pdTRUE; + } + + if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( xSemaphoreGetMutexHolder( xMutex ) != xTaskGetCurrentTaskHandle() ) + { + xErrorDetected = pdTRUE; + } + + /* 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 ); + + /* This task should now have inherited the priority of the high priority + * task as by now the high priority task will have attempted to obtain the + * mutex. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Unblock a second medium priority task. It too will attempt to take + * the mutex and enter the Blocked state - it won't run yet though as this + * task has inherited a priority above it. */ + vTaskResume( xSecondMediumPriorityMutexTask ); + + /* This task should still have the priority of the high priority task as + * that had already been inherited as is the highest priority of the three + * tasks using the mutex. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* On some loops, block for a short while to provide additional + * code coverage. Blocking here will allow the medium priority task to + * execute and so also block on the mutex so when the high priority task + * causes this task to disinherit the high priority it is inherited down to + * the priority of the medium priority task. When there is no delay the + * medium priority task will not run until after the disinheritance, so + * this task will disinherit back to its base priority, then only up to the + * medium priority after the medium priority has executed. */ + vTaskDelay( uxLoopCount & ( UBaseType_t ) 0x07 ); + + /* Now force the high priority task to unblock. It will fail to obtain + * the mutex and go back to the suspended state - allowing this task to + * execute again. xBlockWasAborted is set to pdTRUE so the higher priority + * task knows that its failure to obtain the semaphore is not an error. */ + xBlockWasAborted = pdTRUE; + + if( xTaskAbortDelay( xHighPriorityMutexTask ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* This task has inherited the priority of xHighPriorityMutexTask so + * could still be running even though xHighPriorityMutexTask is no longer + * blocked. Delay for a short while to ensure xHighPriorityMutexTask gets + * a chance to run - indicated by this task changing priority. It should + * disinherit the high priority task, but then inherit the priority of the + * medium priority task that is waiting for the same mutex. */ + while( uxTaskPriorityGet( NULL ) != genqMUTEX_MEDIUM_PRIORITY ) + { + /* If this task gets stuck here then the check variables will stop + * incrementing and the check task will detect the error. */ + vTaskDelay( genqSHORT_BLOCK ); + } + + /* Now force the medium priority task to unblock. xBlockWasAborted is + * set to pdTRUE so the medium priority task knows that its failure to + * obtain the semaphore is not an error. */ + xBlockWasAborted = pdTRUE; + + if( xTaskAbortDelay( xSecondMediumPriorityMutexTask ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* This time no other tasks are waiting for the mutex, so this task + * should return to its base priority. This might not happen straight + * away as it is running at the same priority as the task it just + * unblocked. */ + while( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + /* If this task gets stuck here then the check variables will stop + * incrementing and the check task will detect the error. */ + vTaskDelay( genqSHORT_BLOCK ); + } + + /* Give the semaphore back ready for the next test. Check the mutex + * holder before and after using the "FromISR" version for code coverage. */ + if( xSemaphoreGetMutexHolderFromISR( xMutex ) != xTaskGetCurrentTaskHandle() ) + { + xErrorDetected = pdTRUE; + } + + xSemaphoreGive( xMutex ); + + if( xSemaphoreGetMutexHolderFromISR( xMutex ) != NULL ) + { + xErrorDetected = pdTRUE; + } + + configASSERT( xErrorDetected == pdFALSE ); + + /* Now do the same again, but this time unsuspend the tasks in the + * opposite order. This takes a different path though the code because + * when the high priority task has its block aborted there is already + * another task in the list of tasks waiting for the mutex, and the + * low priority task drops down to that priority, rather than dropping + * down to its base priority before inheriting the priority of the medium + * priority task. */ + if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* This time unsuspend the medium priority task first. This will + * attempt to take the mutex, and block when it finds it cannot obtain it. */ + vTaskResume( xSecondMediumPriorityMutexTask ); + + /* This time this task should now have inherited the priority of the + * medium task. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_MEDIUM_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* This time the high priority task in unsuspended second. */ + vTaskResume( xHighPriorityMutexTask ); + + /* The high priority task should already have run, causing this task to + * inherit a priority for the second time. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* This time, when the high priority task has its delay aborted and it + * fails to obtain the mutex this task will immediately have its priority + * lowered down to that of the highest priority task waiting on the mutex, + * which is the medium priority task. */ + xBlockWasAborted = pdTRUE; + + if( xTaskAbortDelay( xHighPriorityMutexTask ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + while( uxTaskPriorityGet( NULL ) != genqMUTEX_MEDIUM_PRIORITY ) + { + /* If this task gets stuck here then the check variables will stop + * incrementing and the check task will detect the error. */ + vTaskDelay( genqSHORT_BLOCK ); + } + + /* And finally, when the medium priority task also have its delay + * aborted there are no other tasks waiting for the mutex so this task + * returns to its base priority. */ + xBlockWasAborted = pdTRUE; + + if( xTaskAbortDelay( xSecondMediumPriorityMutexTask ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + while( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + /* If this task gets stuck here then the check variables will stop + * incrementing and the check task will detect the error. */ + vTaskDelay( genqSHORT_BLOCK ); + } + + /* Give the semaphore back ready for the next test. */ + xSemaphoreGive( xMutex ); + + configASSERT( xErrorDetected == pdFALSE ); + + /* uxLoopCount is used to add a variable delay, and in-so-doing provide + * additional code coverage. */ + uxLoopCount++; + } + +#endif /* INCLUDE_xTaskAbortDelay == 1 */ +/*-----------------------------------------------------------*/ + +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 */ + + /* This task should now have inherited the priority of the high priority + * task as by now the high priority task will have attempted to obtain 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 */ + + /* This task should now have inherited the priority of the high priority + * task as by now the high priority task will have attempted to obtain 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 'mutex 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 + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + { + /* Tests the behaviour when a low priority task inherits the + * priority of a high priority task only for the high priority task to + * timeout before obtaining the mutex. */ + prvHighPriorityTimeout( xMutex ); + } + #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 ) + { + /* This task would expect to obtain the mutex unless its wait for + * the mutex was aborted. */ + if( xBlockWasAborted == pdFALSE ) + { + xErrorDetected = pdTRUE; + } + else + { + xBlockWasAborted = pdFALSE; + } + } + else + { + /* 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/IntQueue.c b/FreeRTOS/Demo/Common/Minimal/IntQueue.c index 2c0d59525..990427ce9 100644 --- a/FreeRTOS/Demo/Common/Minimal/IntQueue.c +++ b/FreeRTOS/Demo/Common/Minimal/IntQueue.c @@ -1,741 +1,741 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 - -/* 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 = taskENTER_CRITICAL_FROM_ISR(); \ - { \ - uxValueForNormallyEmptyQueue++; \ - if( xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \ - { \ - uxValueForNormallyEmptyQueue--; \ - } \ - } \ - taskEXIT_CRITICAL_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 = taskENTER_CRITICAL_FROM_ISR(); \ - { \ - uxValueForNormallyFullQueue++; \ - if( xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \ - { \ - uxValueForNormallyFullQueue--; \ - } \ - } \ - taskEXIT_CRITICAL_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++; - portENTER_CRITICAL(); - { - uxValueForNormallyEmptyQueue = 0; - } - portEXIT_CRITICAL(); - - /* 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++; - portENTER_CRITICAL(); - { - uxValueForNormallyFullQueue = 0; - } - portEXIT_CRITICAL(); - - /* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 + +/* 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 = taskENTER_CRITICAL_FROM_ISR(); \ + { \ + uxValueForNormallyEmptyQueue++; \ + if( xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \ + { \ + uxValueForNormallyEmptyQueue--; \ + } \ + } \ + taskEXIT_CRITICAL_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 = taskENTER_CRITICAL_FROM_ISR(); \ + { \ + uxValueForNormallyFullQueue++; \ + if( xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \ + { \ + uxValueForNormallyFullQueue--; \ + } \ + } \ + taskEXIT_CRITICAL_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++; + portENTER_CRITICAL(); + { + uxValueForNormallyEmptyQueue = 0; + } + portEXIT_CRITICAL(); + + /* 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++; + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue = 0; + } + portEXIT_CRITICAL(); + + /* 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/IntSemTest.c b/FreeRTOS/Demo/Common/Minimal/IntSemTest.c index 94cdc82a1..1990d6e26 100644 --- a/FreeRTOS/Demo/Common/Minimal/IntSemTest.c +++ b/FreeRTOS/Demo/Common/Minimal/IntSemTest.c @@ -1,530 +1,530 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* - * Demonstrates and tests mutexes being used from an interrupt. - */ - - -#include - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * Demonstrates and tests mutexes being used from an interrupt. + */ + + +#include + +/* 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 disturbed 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/MessageBufferAMP.c b/FreeRTOS/Demo/Common/Minimal/MessageBufferAMP.c index d0f90b5b8..7159adb68 100644 --- a/FreeRTOS/Demo/Common/Minimal/MessageBufferAMP.c +++ b/FreeRTOS/Demo/Common/Minimal/MessageBufferAMP.c @@ -1,328 +1,328 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * An example that mimics a message buffer being used to pass data from one core - * to another. The core that sends the data is referred to as core A. The core - * that receives the data is referred to as core B. The task implemented by - * prvCoreATask() runs on core A. Two instances of the task implemented by - * prvCoreBTasks() run on core B. prvCoreATask() sends messages via message - * buffers to both instances of prvCoreBTasks(), one message buffer per channel. - * A third message buffer is used to pass the handle of the message buffer - * written to by core A to an interrupt service routine that is triggered by - * core A but executes on core B. - * - * The example relies on the FreeRTOS provided default implementation of - * sbSEND_COMPLETED() being overridden by an implementation in FreeRTOSConfig.h - * that writes the handle of the message buffer that contains data into the - * control message buffer, then generates an interrupt in core B. The necessary - * implementation is provided in this file and can be enabled by adding the - * following to FreeRTOSConfig.h: - * - * #define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer ) - * - * Core to core communication via message buffer requires the message buffers - * to be at an address known to both cores within shared memory. - * - * Note that, while this example uses three message buffers, the same - * functionality can be implemented using a single message buffer by using the - * same design pattern described on the link below for queues, but using message - * buffers instead. It is actually simpler with a message buffer as variable - * length data can be written into the message buffer directly: - * https://www.FreeRTOS.org/Pend-on-multiple-rtos-objects.html#alternative_design_pattern - */ - -/* Standard includes. */ -#include "stdio.h" -#include "string.h" - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "message_buffer.h" - -/* Demo app includes. */ -#include "MessageBufferAMP.h" - -/* Enough for 3 4 byte pointers, including the additional 4 bytes per message - * overhead of message buffers. */ -#define mbaCONTROL_MESSAGE_BUFFER_SIZE ( 24 ) - -/* Enough four 4 8 byte strings, plus the additional 4 bytes per message - * overhead of message buffers. */ -#define mbaTASK_MESSAGE_BUFFER_SIZE ( 60 ) - -/* The number of instances of prvCoreBTasks that are created. */ -#define mbaNUMBER_OF_CORE_B_TASKS 2 - -/* A block time of 0 simply means, don't block. */ -#define mbaDONT_BLOCK 0 - -/* Macro that mimics an interrupt service routine executing by simply calling - * the routine inline. */ -#define mbaGENERATE_CORE_B_INTERRUPT() prvCoreBInterruptHandler() - -/*-----------------------------------------------------------*/ - -/* - * Implementation of the task that, on a real dual core device, would run on - * core A and send message to tasks running on core B. - */ -static void prvCoreATask( void * pvParameters ); - -/* - * Implementation of the task that, on a real dual core device, would run on - * core B and receive message from core A. The demo creates two instances of - * this task. - */ -static void prvCoreBTasks( void * pvParameters ); - -/* - * The function that, on a real dual core device, would handle inter-core - * interrupts, but in this case is just called inline. - */ -static void prvCoreBInterruptHandler( void ); - -/*-----------------------------------------------------------*/ - -/* The message buffers used to pass data from core A to core B. */ -static MessageBufferHandle_t xCoreBMessageBuffers[ mbaNUMBER_OF_CORE_B_TASKS ]; - -/* The control message buffer. This is used to pass the handle of the message - * message buffer that holds application data into the core to core interrupt - * service routine. */ -static MessageBufferHandle_t xControlMessageBuffer; - -/* Counters used to indicate to the check that the tasks are still executing. */ -static uint32_t ulCycleCounters[ mbaNUMBER_OF_CORE_B_TASKS ]; - -/* Set to pdFALSE if any errors are detected. Used to inform the check task - * that something might be wrong. */ -BaseType_t xDemoStatus = pdPASS; - -/*-----------------------------------------------------------*/ - -void vStartMessageBufferAMPTasks( configSTACK_DEPTH_TYPE xStackSize ) -{ - BaseType_t x; - - xControlMessageBuffer = xMessageBufferCreate( mbaCONTROL_MESSAGE_BUFFER_SIZE ); - - xTaskCreate( prvCoreATask, /* The function that implements the task. */ - "AMPCoreA", /* Human readable name for the task. */ - xStackSize, /* Stack size (in words!). */ - NULL, /* Task parameter is not used. */ - tskIDLE_PRIORITY, /* The priority at which the task is created. */ - NULL ); /* No use for the task handle. */ - - for( x = 0; x < mbaNUMBER_OF_CORE_B_TASKS; x++ ) - { - xCoreBMessageBuffers[ x ] = xMessageBufferCreate( mbaTASK_MESSAGE_BUFFER_SIZE ); - configASSERT( xCoreBMessageBuffers[ x ] ); - - /* Pass the loop counter into the created task using the task's - * parameter. The task then uses the value as an index into the - * ulCycleCounters and xCoreBMessageBuffers arrays. */ - xTaskCreate( prvCoreBTasks, - "AMPCoreB1", - xStackSize, - ( void * ) x, - tskIDLE_PRIORITY + 1, - NULL ); - } -} -/*-----------------------------------------------------------*/ - -static void prvCoreATask( void * pvParameters ) -{ - BaseType_t x; - uint32_t ulNextValue = 0; - const TickType_t xDelay = pdMS_TO_TICKS( 250 ); - char cString[ 15 ]; /* At least large enough to hold "4294967295\0" (0xffffffff). */ - - /* Remove warning about unused parameters. */ - ( void ) pvParameters; - - for( ; ; ) - { - /* Create the next string to send. The value is incremented on each - * loop iteration, and the length of the string changes as the number of - * digits in the value increases. */ - sprintf( cString, "%lu", ( unsigned long ) ulNextValue ); - - /* Send the value from this (pseudo) Core A to the tasks on the (pseudo) - * Core B via the message buffers. This will result in sbSEND_COMPLETED() - * being executed, which in turn will write the handle of the message - * buffer written to into xControlMessageBuffer then generate an interrupt - * in core B. */ - for( x = 0; x < mbaNUMBER_OF_CORE_B_TASKS; x++ ) - { - xMessageBufferSend( /* The message buffer to write to. */ - xCoreBMessageBuffers[ x ], - /* The source of the data to send. */ - ( void * ) cString, - /* The length of the data to send. */ - strlen( cString ), - /* The block time, should the buffer be full. */ - mbaDONT_BLOCK ); - } - - /* Delay before repeating with a different and potentially different - * length string. */ - vTaskDelay( xDelay ); - ulNextValue++; - } -} -/*-----------------------------------------------------------*/ - -static void prvCoreBTasks( void * pvParameters ) -{ - BaseType_t x; - size_t xReceivedBytes; - uint32_t ulNextValue = 0; - char cExpectedString[ 15 ]; /* At least large enough to hold "4294967295\0" (0xffffffff). */ - char cReceivedString[ 15 ]; - - /* The index into the xCoreBMessageBuffers and ulLoopCounter arrays is - * passed into this task using the task's parameter. */ - x = ( BaseType_t ) pvParameters; - configASSERT( x < mbaNUMBER_OF_CORE_B_TASKS ); - - for( ; ; ) - { - /* Create the string that is expected to be received this time round. */ - sprintf( cExpectedString, "%lu", ( unsigned long ) ulNextValue ); - - /* Wait to receive the next message from core A. */ - memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); - xReceivedBytes = xMessageBufferReceive( /* The message buffer to receive from. */ - xCoreBMessageBuffers[ x ], - /* Location to store received data. */ - cReceivedString, - /* Maximum number of bytes to receive. */ - sizeof( cReceivedString ), - /* Ticks to wait if buffer is empty. */ - portMAX_DELAY ); - - /* Check the number of bytes received was as expected. */ - configASSERT( xReceivedBytes == strlen( cExpectedString ) ); - ( void ) xReceivedBytes; /* Incase configASSERT() is not defined. */ - - /* If the received string matches that expected then increment the loop - * counter so the check task knows this task is still running. */ - if( strcmp( cReceivedString, cExpectedString ) == 0 ) - { - ( ulCycleCounters[ x ] )++; - } - else - { - xDemoStatus = pdFAIL; - } - - /* Expect the next string in sequence the next time around. */ - ulNextValue++; - } -} -/*-----------------------------------------------------------*/ - -/* Called by the reimplementation of sbSEND_COMPLETED(), which can be defined - * as follows in FreeRTOSConfig.h: - #define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer ) - */ -void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer ) -{ - MessageBufferHandle_t xUpdatedBuffer = ( MessageBufferHandle_t ) xUpdatedMessageBuffer; - - /* If sbSEND_COMPLETED() has been implemented as above, then this function - * is called from within xMessageBufferSend(). As this function also calls - * xMessageBufferSend() itself it is necessary to guard against a recursive - * call. If the message buffer just updated is the message buffer written to - * by this function, then this is a recursive call, and the function can just - * exit without taking further action. */ - if( xUpdatedBuffer != xControlMessageBuffer ) - { - /* Use xControlMessageBuffer to pass the handle of the message buffer - * written to by core A to the interrupt handler about to be generated in - * core B. */ - xMessageBufferSend( xControlMessageBuffer, &xUpdatedBuffer, sizeof( xUpdatedBuffer ), mbaDONT_BLOCK ); - - /* This is where the interrupt would be generated. In this case it is - * not a genuine interrupt handler that executes, just a standard function - * call. */ - mbaGENERATE_CORE_B_INTERRUPT(); - } -} -/*-----------------------------------------------------------*/ - -/* Handler for the interrupts that are triggered on core A but execute on core - * B. */ -static void prvCoreBInterruptHandler( void ) -{ - MessageBufferHandle_t xUpdatedMessageBuffer; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - - /* xControlMessageBuffer contains the handle of the message buffer that - * contains data. */ - if( xMessageBufferReceive( xControlMessageBuffer, - &xUpdatedMessageBuffer, - sizeof( xUpdatedMessageBuffer ), - mbaDONT_BLOCK ) == sizeof( xUpdatedMessageBuffer ) ) - { - /* Call the API function that sends a notification to any task that is - * blocked on the xUpdatedMessageBuffer message buffer waiting for data to - * arrive. */ - xMessageBufferSendCompletedFromISR( xUpdatedMessageBuffer, &xHigherPriorityTaskWoken ); - } - - /* Normal FreeRTOS yield from interrupt semantics, where - * xHigherPriorityTaskWoken is initialized to pdFALSE and will then get set to - * pdTRUE if the interrupt safe API unblocks a task that has a priority above - * that of the currently executing task. */ - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); -} -/*-----------------------------------------------------------*/ - -BaseType_t xAreMessageBufferAMPTasksStillRunning( void ) -{ - static uint32_t ulLastCycleCounters[ mbaNUMBER_OF_CORE_B_TASKS ] = { 0 }; - BaseType_t x; - - /* Called by the check task to determine the health status of the tasks - * implemented in this demo. */ - for( x = 0; x < mbaNUMBER_OF_CORE_B_TASKS; x++ ) - { - if( ulLastCycleCounters[ x ] == ulCycleCounters[ x ] ) - { - xDemoStatus = pdFAIL; - } - else - { - ulLastCycleCounters[ x ] = ulCycleCounters[ x ]; - } - } - - return xDemoStatus; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * An example that mimics a message buffer being used to pass data from one core + * to another. The core that sends the data is referred to as core A. The core + * that receives the data is referred to as core B. The task implemented by + * prvCoreATask() runs on core A. Two instances of the task implemented by + * prvCoreBTasks() run on core B. prvCoreATask() sends messages via message + * buffers to both instances of prvCoreBTasks(), one message buffer per channel. + * A third message buffer is used to pass the handle of the message buffer + * written to by core A to an interrupt service routine that is triggered by + * core A but executes on core B. + * + * The example relies on the FreeRTOS provided default implementation of + * sbSEND_COMPLETED() being overridden by an implementation in FreeRTOSConfig.h + * that writes the handle of the message buffer that contains data into the + * control message buffer, then generates an interrupt in core B. The necessary + * implementation is provided in this file and can be enabled by adding the + * following to FreeRTOSConfig.h: + * + * #define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer ) + * + * Core to core communication via message buffer requires the message buffers + * to be at an address known to both cores within shared memory. + * + * Note that, while this example uses three message buffers, the same + * functionality can be implemented using a single message buffer by using the + * same design pattern described on the link below for queues, but using message + * buffers instead. It is actually simpler with a message buffer as variable + * length data can be written into the message buffer directly: + * https://www.FreeRTOS.org/Pend-on-multiple-rtos-objects.html#alternative_design_pattern + */ + +/* Standard includes. */ +#include "stdio.h" +#include "string.h" + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "message_buffer.h" + +/* Demo app includes. */ +#include "MessageBufferAMP.h" + +/* Enough for 3 4 byte pointers, including the additional 4 bytes per message + * overhead of message buffers. */ +#define mbaCONTROL_MESSAGE_BUFFER_SIZE ( 24 ) + +/* Enough four 4 8 byte strings, plus the additional 4 bytes per message + * overhead of message buffers. */ +#define mbaTASK_MESSAGE_BUFFER_SIZE ( 60 ) + +/* The number of instances of prvCoreBTasks that are created. */ +#define mbaNUMBER_OF_CORE_B_TASKS 2 + +/* A block time of 0 simply means, don't block. */ +#define mbaDONT_BLOCK 0 + +/* Macro that mimics an interrupt service routine executing by simply calling + * the routine inline. */ +#define mbaGENERATE_CORE_B_INTERRUPT() prvCoreBInterruptHandler() + +/*-----------------------------------------------------------*/ + +/* + * Implementation of the task that, on a real dual core device, would run on + * core A and send message to tasks running on core B. + */ +static void prvCoreATask( void * pvParameters ); + +/* + * Implementation of the task that, on a real dual core device, would run on + * core B and receive message from core A. The demo creates two instances of + * this task. + */ +static void prvCoreBTasks( void * pvParameters ); + +/* + * The function that, on a real dual core device, would handle inter-core + * interrupts, but in this case is just called inline. + */ +static void prvCoreBInterruptHandler( void ); + +/*-----------------------------------------------------------*/ + +/* The message buffers used to pass data from core A to core B. */ +static MessageBufferHandle_t xCoreBMessageBuffers[ mbaNUMBER_OF_CORE_B_TASKS ]; + +/* The control message buffer. This is used to pass the handle of the message + * message buffer that holds application data into the core to core interrupt + * service routine. */ +static MessageBufferHandle_t xControlMessageBuffer; + +/* Counters used to indicate to the check that the tasks are still executing. */ +static uint32_t ulCycleCounters[ mbaNUMBER_OF_CORE_B_TASKS ]; + +/* Set to pdFALSE if any errors are detected. Used to inform the check task + * that something might be wrong. */ +BaseType_t xDemoStatus = pdPASS; + +/*-----------------------------------------------------------*/ + +void vStartMessageBufferAMPTasks( configSTACK_DEPTH_TYPE xStackSize ) +{ + BaseType_t x; + + xControlMessageBuffer = xMessageBufferCreate( mbaCONTROL_MESSAGE_BUFFER_SIZE ); + + xTaskCreate( prvCoreATask, /* The function that implements the task. */ + "AMPCoreA", /* Human readable name for the task. */ + xStackSize, /* Stack size (in words!). */ + NULL, /* Task parameter is not used. */ + tskIDLE_PRIORITY, /* The priority at which the task is created. */ + NULL ); /* No use for the task handle. */ + + for( x = 0; x < mbaNUMBER_OF_CORE_B_TASKS; x++ ) + { + xCoreBMessageBuffers[ x ] = xMessageBufferCreate( mbaTASK_MESSAGE_BUFFER_SIZE ); + configASSERT( xCoreBMessageBuffers[ x ] ); + + /* Pass the loop counter into the created task using the task's + * parameter. The task then uses the value as an index into the + * ulCycleCounters and xCoreBMessageBuffers arrays. */ + xTaskCreate( prvCoreBTasks, + "AMPCoreB1", + xStackSize, + ( void * ) x, + tskIDLE_PRIORITY + 1, + NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCoreATask( void * pvParameters ) +{ + BaseType_t x; + uint32_t ulNextValue = 0; + const TickType_t xDelay = pdMS_TO_TICKS( 250 ); + char cString[ 15 ]; /* At least large enough to hold "4294967295\0" (0xffffffff). */ + + /* Remove warning about unused parameters. */ + ( void ) pvParameters; + + for( ; ; ) + { + /* Create the next string to send. The value is incremented on each + * loop iteration, and the length of the string changes as the number of + * digits in the value increases. */ + sprintf( cString, "%lu", ( unsigned long ) ulNextValue ); + + /* Send the value from this (pseudo) Core A to the tasks on the (pseudo) + * Core B via the message buffers. This will result in sbSEND_COMPLETED() + * being executed, which in turn will write the handle of the message + * buffer written to into xControlMessageBuffer then generate an interrupt + * in core B. */ + for( x = 0; x < mbaNUMBER_OF_CORE_B_TASKS; x++ ) + { + xMessageBufferSend( /* The message buffer to write to. */ + xCoreBMessageBuffers[ x ], + /* The source of the data to send. */ + ( void * ) cString, + /* The length of the data to send. */ + strlen( cString ), + /* The block time, should the buffer be full. */ + mbaDONT_BLOCK ); + } + + /* Delay before repeating with a different and potentially different + * length string. */ + vTaskDelay( xDelay ); + ulNextValue++; + } +} +/*-----------------------------------------------------------*/ + +static void prvCoreBTasks( void * pvParameters ) +{ + BaseType_t x; + size_t xReceivedBytes; + uint32_t ulNextValue = 0; + char cExpectedString[ 15 ]; /* At least large enough to hold "4294967295\0" (0xffffffff). */ + char cReceivedString[ 15 ]; + + /* The index into the xCoreBMessageBuffers and ulLoopCounter arrays is + * passed into this task using the task's parameter. */ + x = ( BaseType_t ) pvParameters; + configASSERT( x < mbaNUMBER_OF_CORE_B_TASKS ); + + for( ; ; ) + { + /* Create the string that is expected to be received this time round. */ + sprintf( cExpectedString, "%lu", ( unsigned long ) ulNextValue ); + + /* Wait to receive the next message from core A. */ + memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); + xReceivedBytes = xMessageBufferReceive( /* The message buffer to receive from. */ + xCoreBMessageBuffers[ x ], + /* Location to store received data. */ + cReceivedString, + /* Maximum number of bytes to receive. */ + sizeof( cReceivedString ), + /* Ticks to wait if buffer is empty. */ + portMAX_DELAY ); + + /* Check the number of bytes received was as expected. */ + configASSERT( xReceivedBytes == strlen( cExpectedString ) ); + ( void ) xReceivedBytes; /* Incase configASSERT() is not defined. */ + + /* If the received string matches that expected then increment the loop + * counter so the check task knows this task is still running. */ + if( strcmp( cReceivedString, cExpectedString ) == 0 ) + { + ( ulCycleCounters[ x ] )++; + } + else + { + xDemoStatus = pdFAIL; + } + + /* Expect the next string in sequence the next time around. */ + ulNextValue++; + } +} +/*-----------------------------------------------------------*/ + +/* Called by the re-implementation of sbSEND_COMPLETED(), which can be defined + * as follows in FreeRTOSConfig.h: + #define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer ) + */ +void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer ) +{ + MessageBufferHandle_t xUpdatedBuffer = ( MessageBufferHandle_t ) xUpdatedMessageBuffer; + + /* If sbSEND_COMPLETED() has been implemented as above, then this function + * is called from within xMessageBufferSend(). As this function also calls + * xMessageBufferSend() itself it is necessary to guard against a recursive + * call. If the message buffer just updated is the message buffer written to + * by this function, then this is a recursive call, and the function can just + * exit without taking further action. */ + if( xUpdatedBuffer != xControlMessageBuffer ) + { + /* Use xControlMessageBuffer to pass the handle of the message buffer + * written to by core A to the interrupt handler about to be generated in + * core B. */ + xMessageBufferSend( xControlMessageBuffer, &xUpdatedBuffer, sizeof( xUpdatedBuffer ), mbaDONT_BLOCK ); + + /* This is where the interrupt would be generated. In this case it is + * not a genuine interrupt handler that executes, just a standard function + * call. */ + mbaGENERATE_CORE_B_INTERRUPT(); + } +} +/*-----------------------------------------------------------*/ + +/* Handler for the interrupts that are triggered on core A but execute on core + * B. */ +static void prvCoreBInterruptHandler( void ) +{ + MessageBufferHandle_t xUpdatedMessageBuffer; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + /* xControlMessageBuffer contains the handle of the message buffer that + * contains data. */ + if( xMessageBufferReceive( xControlMessageBuffer, + &xUpdatedMessageBuffer, + sizeof( xUpdatedMessageBuffer ), + mbaDONT_BLOCK ) == sizeof( xUpdatedMessageBuffer ) ) + { + /* Call the API function that sends a notification to any task that is + * blocked on the xUpdatedMessageBuffer message buffer waiting for data to + * arrive. */ + xMessageBufferSendCompletedFromISR( xUpdatedMessageBuffer, &xHigherPriorityTaskWoken ); + } + + /* Normal FreeRTOS yield from interrupt semantics, where + * xHigherPriorityTaskWoken is initialized to pdFALSE and will then get set to + * pdTRUE if the interrupt safe API unblocks a task that has a priority above + * that of the currently executing task. */ + portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreMessageBufferAMPTasksStillRunning( void ) +{ + static uint32_t ulLastCycleCounters[ mbaNUMBER_OF_CORE_B_TASKS ] = { 0 }; + BaseType_t x; + + /* Called by the check task to determine the health status of the tasks + * implemented in this demo. */ + for( x = 0; x < mbaNUMBER_OF_CORE_B_TASKS; x++ ) + { + if( ulLastCycleCounters[ x ] == ulCycleCounters[ x ] ) + { + xDemoStatus = pdFAIL; + } + else + { + ulLastCycleCounters[ x ] = ulCycleCounters[ x ]; + } + } + + return xDemoStatus; +} diff --git a/FreeRTOS/Demo/Common/Minimal/MessageBufferDemo.c b/FreeRTOS/Demo/Common/Minimal/MessageBufferDemo.c index f1800d4ae..d436727fb 100644 --- a/FreeRTOS/Demo/Common/Minimal/MessageBufferDemo.c +++ b/FreeRTOS/Demo/Common/Minimal/MessageBufferDemo.c @@ -1,971 +1,971 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* Standard includes. */ -#include "stdio.h" -#include "string.h" - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "message_buffer.h" - -/* Demo app includes. */ -#include "MessageBufferDemo.h" - -/* The number of bytes of storage in the message buffers used in this test. */ -#define mbMESSAGE_BUFFER_LENGTH_BYTES ( ( size_t ) 50 ) - -/* The number of additional bytes used to store the length of each message. */ -#define mbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) - -/* Start and end ASCII characters used in messages sent to the buffers. */ -#define mbASCII_SPACE 32 -#define mbASCII_TILDA 126 - -/* Defines the number of tasks to create in this test and demo. */ -#define mbNUMBER_OF_ECHO_CLIENTS ( 2 ) -#define mbNUMBER_OF_SENDER_TASKS ( 2 ) - -/* Priority of the test tasks. The send and receive go from low to high - * priority tasks, and from high to low priority tasks. */ -#define mbLOWER_PRIORITY ( tskIDLE_PRIORITY ) -#define mbHIGHER_PRIORITY ( tskIDLE_PRIORITY + 1 ) - -/* Block times used when sending and receiving from the message buffers. */ -#define mbRX_TX_BLOCK_TIME pdMS_TO_TICKS( 175UL ) - -/* A block time of 0 means "don't block". */ -#define mbDONT_BLOCK ( 0 ) - -/*-----------------------------------------------------------*/ - -/* - * Performs various tests that do not require multiple tasks to interact. - */ -static void prvSingleTaskTests( MessageBufferHandle_t xMessageBuffer ); - -/* - * Tests sending and receiving various lengths of messages via a message buffer. - * The echo client sends the messages to the echo server, which then sends the - * message back to the echo client which, checks it receives exactly what it - * sent. - */ -static void prvEchoClient( void * pvParameters ); -static void prvEchoServer( void * pvParameters ); - -/* - * Tasks that send and receive to a message buffer at a low priority and without - * blocking, so the send and receive functions interleave in time as the tasks - * are switched in and out. - */ -static void prvNonBlockingReceiverTask( void * pvParameters ); -static void prvNonBlockingSenderTask( void * pvParameters ); - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - -/* This file tests both statically and dynamically allocated message buffers. - * Allocate the structures and buffers to be used by the statically allocated - * objects, which get used in the echo tests. */ - static void prvReceiverTask( void * pvParameters ); - static void prvSenderTask( void * pvParameters ); - - static StaticMessageBuffer_t xStaticMessageBuffers[ mbNUMBER_OF_ECHO_CLIENTS ]; - static uint8_t ucBufferStorage[ mbNUMBER_OF_SENDER_TASKS ][ mbMESSAGE_BUFFER_LENGTH_BYTES + 1 ]; - static uint32_t ulSenderLoopCounters[ mbNUMBER_OF_SENDER_TASKS ] = { 0 }; -#endif /* configSUPPORT_STATIC_ALLOCATION */ - - -#if ( configRUN_ADDITIONAL_TESTS == 1 ) - #define mbCOHERENCE_TEST_BUFFER_SIZE 20 - #define mbCOHERENCE_TEST_BYTES_WRITTEN 5 - #define mbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) - #define mbEXPECTED_FREE_BYTES_AFTER_WRITING_STRING ( mbCOHERENCE_TEST_BUFFER_SIZE - ( mbCOHERENCE_TEST_BYTES_WRITTEN + mbBYTES_TO_STORE_MESSAGE_LENGTH ) ) - - static void prvSpaceAvailableCoherenceActor( void * pvParameters ); - static void prvSpaceAvailableCoherenceTester( void * pvParameters ); - static MessageBufferHandle_t xCoherenceTestMessageBuffer = NULL; - - static uint32_t ulSizeCoherencyTestCycles = 0UL; -#endif /* if ( configRUN_ADDITIONAL_TESTS == 1 ) */ - -/*-----------------------------------------------------------*/ - -/* The buffers used by the echo client and server tasks. */ -typedef struct ECHO_MESSAGE_BUFFERS -{ - /* Handles to the data structures that describe the message buffers. */ - MessageBufferHandle_t xEchoClientBuffer; - MessageBufferHandle_t xEchoServerBuffer; -} EchoMessageBuffers_t; -static uint32_t ulEchoLoopCounters[ mbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; - -/* The non-blocking tasks monitor their operation, and if no errors have been - * found, increment ulNonBlockingRxCounter. xAreMessageBufferTasksStillRunning() - * then checks ulNonBlockingRxCounter and only returns pdPASS if - * ulNonBlockingRxCounter is still incrementing. */ -static uint32_t ulNonBlockingRxCounter = 0; - -/* A message that is longer than the buffer, parts of which are written to the - * message buffer to test writing different lengths at different offsets. */ -static const char * pc55ByteString = "One two three four five six seven eight nine ten eleve"; - -/* Remember the required stack size so tasks can be created at run time (after - * initialisation time. */ -static configSTACK_DEPTH_TYPE xBlockingStackSize = 0; - -/*-----------------------------------------------------------*/ - -void vStartMessageBufferTasks( configSTACK_DEPTH_TYPE xStackSize ) -{ - MessageBufferHandle_t xMessageBuffer; - - #ifndef configMESSAGE_BUFFER_BLOCK_TASK_STACK_SIZE - xBlockingStackSize = ( xStackSize + ( xStackSize >> 1U ) ); - #else - xBlockingStackSize = configMESSAGE_BUFFER_BLOCK_TASK_STACK_SIZE; - #endif - - /* The echo servers sets up the message buffers before creating the echo - * client tasks. One set of tasks has the server as the higher priority, and - * the other has the client as the higher priority. */ - xTaskCreate( prvEchoServer, "1EchoServer", xBlockingStackSize, NULL, mbHIGHER_PRIORITY, NULL ); - xTaskCreate( prvEchoServer, "2EchoServer", xBlockingStackSize, NULL, mbLOWER_PRIORITY, NULL ); - - /* The non blocking tasks run continuously and will interleave with each - * other, so must be created at the lowest priority. The message buffer they - * use is created and passed in using the task's parameter. */ - xMessageBuffer = xMessageBufferCreate( mbMESSAGE_BUFFER_LENGTH_BYTES ); - xTaskCreate( prvNonBlockingReceiverTask, "NonBlkRx", xStackSize, ( void * ) xMessageBuffer, tskIDLE_PRIORITY, NULL ); - xTaskCreate( prvNonBlockingSenderTask, "NonBlkTx", xStackSize, ( void * ) xMessageBuffer, tskIDLE_PRIORITY, NULL ); - - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - { - /* The sender tasks set up the message buffers before creating the - * receiver tasks. Priorities must be 0 and 1 as the priority is used to - * index into the xStaticMessageBuffers and ucBufferStorage arrays. */ - xTaskCreate( prvSenderTask, "1Sender", xBlockingStackSize, NULL, mbHIGHER_PRIORITY, NULL ); - xTaskCreate( prvSenderTask, "2Sender", xBlockingStackSize, NULL, mbLOWER_PRIORITY, NULL ); - } - #endif /* configSUPPORT_STATIC_ALLOCATION */ - - #if ( configRUN_ADDITIONAL_TESTS == 1 ) - { - xCoherenceTestMessageBuffer = xMessageBufferCreate( mbCOHERENCE_TEST_BUFFER_SIZE ); - configASSERT( xCoherenceTestMessageBuffer ); - - xTaskCreate( prvSpaceAvailableCoherenceActor, "mbsanity1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); - xTaskCreate( prvSpaceAvailableCoherenceTester, "mbsanity2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); - } - #endif -} -/*-----------------------------------------------------------*/ - -static void prvSingleTaskTests( MessageBufferHandle_t xMessageBuffer ) -{ - size_t xReturned, xItem, xExpectedSpace, xNextLength; - const size_t xMax6ByteMessages = mbMESSAGE_BUFFER_LENGTH_BYTES / ( 6 + mbBYTES_TO_STORE_MESSAGE_LENGTH ); - const size_t x6ByteLength = 6, x17ByteLength = 17; - uint8_t * pucFullBuffer, * pucData, * pucReadData; - TickType_t xTimeBeforeCall, xTimeAfterCall; - const TickType_t xBlockTime = pdMS_TO_TICKS( 25 ), xAllowableMargin = pdMS_TO_TICKS( 3 ); - UBaseType_t uxOriginalPriority; - - /* Remove warning in case configASSERT() is not defined. */ - ( void ) xAllowableMargin; - - /* To minimise stack and heap usage a full size buffer is allocated from - * the heap, then buffers which hold smaller amounts of data are overlayed - * with the larger buffer - just make sure not to use both at once!. */ - pucFullBuffer = pvPortMalloc( mbMESSAGE_BUFFER_LENGTH_BYTES ); - configASSERT( pucFullBuffer ); - - pucData = pucFullBuffer; - pucReadData = pucData + x17ByteLength; - - /* Nothing has been added or removed yet, so expect the free space to be - * exactly as created and the length of the next message to be 0. */ - xExpectedSpace = xMessageBufferSpaceAvailable( xMessageBuffer ); - configASSERT( xExpectedSpace == mbMESSAGE_BUFFER_LENGTH_BYTES ); - configASSERT( xMessageBufferIsEmpty( xMessageBuffer ) == pdTRUE ); - xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); - configASSERT( xNextLength == 0 ); - /* In case configASSERT() is not define. */ - ( void ) xExpectedSpace; - ( void ) xNextLength; - - /* Try sending more bytes than possible, first using the FromISR version, then - * with an infinite block time to ensure this task does not lock up. */ - xReturned = xMessageBufferSendFromISR( xMessageBuffer, ( void * ) pucData, mbMESSAGE_BUFFER_LENGTH_BYTES + sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ), NULL ); - configASSERT( xReturned == ( size_t ) 0 ); - /* In case configASSERT() is not defined. */ - ( void ) xReturned; - xReturned = xMessageBufferSend( xMessageBuffer, ( void * ) pucData, mbMESSAGE_BUFFER_LENGTH_BYTES + sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ), portMAX_DELAY ); - configASSERT( xReturned == ( size_t ) 0 ); - /* In case configASSERT() is not defined. */ - ( void ) xReturned; - - /* The buffer is 50 bytes long. When an item is added to the buffer an - * additional 4 bytes are added to hold the item's size. That means adding - * 6 bytes to the buffer will actually add 10 bytes to the buffer. Therefore, - * with a 50 byte buffer, a maximum of 5 6 bytes items can be added before the - * buffer is completely full. NOTE: The numbers in this paragraph assume - * sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) == 4. */ - for( xItem = 0; xItem < xMax6ByteMessages; xItem++ ) - { - configASSERT( xMessageBufferIsFull( xMessageBuffer ) == pdFALSE ); - - /* Generate recognisable data to write to the buffer. This is just - * ascii characters that shows which loop iteration the data was written - * in. The 'FromISR' version is used to give it some exercise as a block - * time is not used. That requires the call to be in a critical section - * so this code can also run on FreeRTOS ports that do not support - * interrupt nesting (and so don't have interrupt safe critical - * sections).*/ - memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength ); - taskENTER_CRITICAL(); - { - xReturned = xMessageBufferSendFromISR( xMessageBuffer, ( void * ) pucData, x6ByteLength, NULL ); - } - taskEXIT_CRITICAL(); - configASSERT( xReturned == x6ByteLength ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* The space in the buffer will have reduced by the amount of user data - * written into the buffer and the amount of space used to store the length - * of the data written into the buffer. */ - xExpectedSpace -= ( x6ByteLength + mbBYTES_TO_STORE_MESSAGE_LENGTH ); - xReturned = xMessageBufferSpaceAvailable( xMessageBuffer ); - configASSERT( xReturned == xExpectedSpace ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* Only 6 byte messages are written. */ - xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); - configASSERT( xNextLength == x6ByteLength ); - ( void ) xNextLength; /* In case configASSERT() is not defined. */ - } - - /* Now the buffer should be full, and attempting to add anything will should - * fail. */ - configASSERT( xMessageBufferIsFull( xMessageBuffer ) == pdTRUE ); - xReturned = xMessageBufferSend( xMessageBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), mbDONT_BLOCK ); - configASSERT( xReturned == 0 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* Adding with a timeout should also fail after the appropriate time. The - * priority is temporarily boosted in this part of the test to keep the - * allowable margin to a minimum. */ - uxOriginalPriority = uxTaskPriorityGet( NULL ); - vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); - xTimeBeforeCall = xTaskGetTickCount(); - xReturned = xMessageBufferSend( xMessageBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), xBlockTime ); - xTimeAfterCall = xTaskGetTickCount(); - vTaskPrioritySet( NULL, uxOriginalPriority ); - configASSERT( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) >= xBlockTime ); - configASSERT( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) < ( xBlockTime + xAllowableMargin ) ); - configASSERT( xReturned == 0 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - ( void ) xTimeBeforeCall; - ( void ) xTimeAfterCall; - - /* The buffer is now full of data in the form "000000", "111111", etc. Make - * sure the data is read out as expected. */ - for( xItem = 0; xItem < xMax6ByteMessages; xItem++ ) - { - /* Generate the data that is expected to be read out for this loop - * iteration. */ - memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength ); - - /* Try reading the message into a buffer that is too small. The message - * should remain in the buffer. */ - xReturned = xMessageBufferReceive( xMessageBuffer, ( void * ) pucReadData, x6ByteLength - 1, mbDONT_BLOCK ); - configASSERT( xReturned == 0 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* Should still be at least one 6 byte message still available. */ - xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); - configASSERT( xNextLength == x6ByteLength ); - ( void ) xNextLength; /* In case configASSERT() is not defined. */ - - /* Read the next 6 bytes out. The 'FromISR' version is used to give it - * some exercise as a block time is not used. THa requires the code to be - * in a critical section so this test can be run with FreeRTOS ports that - * do not support interrupt nesting (and therefore don't have interrupt - * safe critical sections). */ - taskENTER_CRITICAL(); - { - xReturned = xMessageBufferReceiveFromISR( xMessageBuffer, ( void * ) pucReadData, x6ByteLength, NULL ); - } - taskEXIT_CRITICAL(); - configASSERT( xReturned == x6ByteLength ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* Does the data read out match that expected? */ - configASSERT( memcmp( ( void * ) pucData, ( void * ) pucReadData, x6ByteLength ) == 0 ); - - /* The space in the buffer will have increased by the amount of user - * data read from into the buffer and the amount of space used to store the - * length of the data read into the buffer. */ - xExpectedSpace += ( x6ByteLength + mbBYTES_TO_STORE_MESSAGE_LENGTH ); - xReturned = xMessageBufferSpaceAvailable( xMessageBuffer ); - configASSERT( xReturned == xExpectedSpace ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - } - - /* The buffer should be empty again. */ - configASSERT( xMessageBufferIsEmpty( xMessageBuffer ) == pdTRUE ); - xExpectedSpace = xMessageBufferSpaceAvailable( xMessageBuffer ); - configASSERT( xExpectedSpace == mbMESSAGE_BUFFER_LENGTH_BYTES ); - ( void ) xExpectedSpace; /* In case configASSERT() is not defined. */ - xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); - configASSERT( xNextLength == 0 ); - ( void ) xNextLength; /* In case configASSERT() is not defined. */ - - - /* Reading with a timeout should also fail after the appropriate time. The - * priority is temporarily boosted in this part of the test to keep the - * allowable margin to a minimum. */ - vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); - xTimeBeforeCall = xTaskGetTickCount(); - xReturned = xMessageBufferReceive( xMessageBuffer, ( void * ) pucReadData, x6ByteLength, xBlockTime ); - xTimeAfterCall = xTaskGetTickCount(); - vTaskPrioritySet( NULL, uxOriginalPriority ); - configASSERT( ( xTimeAfterCall - xTimeBeforeCall ) >= xBlockTime ); - configASSERT( ( xTimeAfterCall - xTimeBeforeCall ) < ( xBlockTime + xAllowableMargin ) ); - configASSERT( xReturned == 0 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - ( void ) xTimeBeforeCall; - ( void ) xTimeAfterCall; - - - /* In the next loop 17 bytes are written to then read out on each iteration. - * The expected length variable is always used after 17 bytes have been written - * into the buffer - the length of the message is also written, making a total - * of 21 bytes consumed for each 17 byte message. */ - xExpectedSpace = mbMESSAGE_BUFFER_LENGTH_BYTES - ( x17ByteLength + mbBYTES_TO_STORE_MESSAGE_LENGTH ); - - /* Reading and writing 17 bytes at a time will result in 21 bytes being - * written into the buffer, and as 50 is not divisible by 21, writing multiple - * times will cause the data to wrap in the buffer.*/ - for( xItem = 0; xItem < 100; xItem++ ) - { - /* Generate recognisable data to write to the queue. This is just - * ascii characters that shows which loop iteration the data was written - * in. */ - memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x17ByteLength ); - xReturned = xMessageBufferSend( xMessageBuffer, ( void * ) pucData, x17ByteLength, mbDONT_BLOCK ); - configASSERT( xReturned == x17ByteLength ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* Only 17 byte messages are written. */ - xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); - configASSERT( xNextLength == x17ByteLength ); - ( void ) xNextLength; /* In case configASSERT() is not defined. */ - - /* The space in the buffer will have reduced by the amount of user data - * written into the buffer and the amount of space used to store the length - * of the data written into the buffer. */ - xReturned = xMessageBufferSpaceAvailable( xMessageBuffer ); - configASSERT( xReturned == xExpectedSpace ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* Read the 17 bytes out again. */ - xReturned = xMessageBufferReceive( xMessageBuffer, ( void * ) pucReadData, x17ByteLength, mbDONT_BLOCK ); - configASSERT( xReturned == x17ByteLength ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* Does the data read out match that expected? */ - configASSERT( memcmp( ( void * ) pucData, ( void * ) pucReadData, x17ByteLength ) == 0 ); - - /* Don't expect any messages to be available as the data was read out - * again. */ - xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); - configASSERT( xNextLength == 0 ); - ( void ) xNextLength; /* In case configASSERT() is not defined. */ - } - - /* The buffer should be empty again. */ - configASSERT( xMessageBufferIsEmpty( xMessageBuffer ) == pdTRUE ); - xExpectedSpace = xMessageBufferSpaceAvailable( xMessageBuffer ); - configASSERT( xExpectedSpace == mbMESSAGE_BUFFER_LENGTH_BYTES ); - - /* Cannot write within sizeof( size_t ) (assumed to be 4 bytes in this test) - * bytes of the full 50 bytes, as that would not leave space for the four bytes - * taken by the data length. */ - xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES, mbDONT_BLOCK ); - configASSERT( xReturned == 0 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - #ifndef configMESSAGE_BUFFER_LENGTH_TYPE - { - /* The following will fail if configMESSAGE_BUFFER_LENGTH_TYPE is set - * to a non 32-bit type. */ - xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - 1, mbDONT_BLOCK ); - configASSERT( xReturned == 0 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - 2, mbDONT_BLOCK ); - configASSERT( xReturned == 0 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - 3, mbDONT_BLOCK ); - configASSERT( xReturned == 0 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - } - #endif /* ifndef configMESSAGE_BUFFER_LENGTH_TYPE */ - - /* Don't expect any messages to be available as the above were too large to - * get written. */ - xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); - configASSERT( xNextLength == 0 ); - ( void ) xNextLength; /* In case configASSERT() is not defined. */ - - /* Can write mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) bytes though. */ - xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ), mbDONT_BLOCK ); - configASSERT( xReturned == mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); - configASSERT( xNextLength == ( mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) ); - ( void ) xNextLength; /* In case configASSERT() is not defined. */ - xReturned = xMessageBufferReceive( xMessageBuffer, ( void * ) pucFullBuffer, mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ), mbDONT_BLOCK ); - configASSERT( xReturned == ( mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - configASSERT( memcmp( ( const void * ) pucFullBuffer, pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) == 0 ); - - /* Clean up. */ - vPortFree( pucFullBuffer ); - xMessageBufferReset( xMessageBuffer ); -} -/*-----------------------------------------------------------*/ - -static void prvNonBlockingSenderTask( void * pvParameters ) -{ - MessageBufferHandle_t xMessageBuffer; - int32_t iDataToSend = 0; - size_t xStringLength; - const int32_t iMaxValue = 1500; - char cTxString[ 12 ]; /* Large enough to hold a 32 number in ASCII. */ - - /* In this case the message buffer has already been created and is passed - * into the task using the task's parameter. */ - - xMessageBuffer = ( MessageBufferHandle_t ) pvParameters; - - /* Create a string from an incrementing number. The length of the - * string will increase and decrease as the value of the number increases - * then overflows. */ - memset( cTxString, 0x00, sizeof( cTxString ) ); - sprintf( cTxString, "%d", ( int ) iDataToSend ); - xStringLength = strlen( cTxString ); - - for( ; ; ) - { - /* Doesn't block so calls can interleave with the non-blocking - * receives performed by prvNonBlockingReceiverTask(). */ - if( xMessageBufferSend( xMessageBuffer, ( void * ) cTxString, strlen( cTxString ), mbDONT_BLOCK ) == xStringLength ) - { - iDataToSend++; - - if( iDataToSend > iMaxValue ) - { - /* The value sent is reset back to 0 to ensure the string being sent - * does not remain at the same length for too long. */ - iDataToSend = 0; - } - - /* Create the next string. */ - memset( cTxString, 0x00, sizeof( cTxString ) ); - sprintf( cTxString, "%d", ( int ) iDataToSend ); - xStringLength = strlen( cTxString ); - } - } -} -/*-----------------------------------------------------------*/ - -static void prvNonBlockingReceiverTask( void * pvParameters ) -{ - MessageBufferHandle_t xMessageBuffer; - BaseType_t xNonBlockingReceiveError = pdFALSE; - int32_t iDataToSend = 0; - size_t xStringLength, xReceiveLength; - const int32_t iMaxValue = 1500; - char cExpectedString[ 12 ]; /* Large enough to hold a 32 number in ASCII. */ - char cRxString[ 12 ]; - - /* In this case the message buffer has already been created and is passed - * into the task using the task's parameter. */ - xMessageBuffer = ( MessageBufferHandle_t ) pvParameters; - - /* Create a string from an incrementing number. The length of the - * string will increase and decrease as the value of the number increases - * then overflows. This should always match the string sent to the buffer by - * the non blocking sender task. */ - memset( cExpectedString, 0x00, sizeof( cExpectedString ) ); - memset( cRxString, 0x00, sizeof( cRxString ) ); - sprintf( cExpectedString, "%d", ( int ) iDataToSend ); - xStringLength = strlen( cExpectedString ); - - for( ; ; ) - { - /* Doesn't block so calls can interleave with the non-blocking - * receives performed by prvNonBlockingReceiverTask(). */ - xReceiveLength = xMessageBufferReceive( xMessageBuffer, ( void * ) cRxString, sizeof( cRxString ), mbDONT_BLOCK ); - - /* Should only ever receive no data is available, or the expected - * length of data is available. */ - if( ( xReceiveLength != 0 ) && ( xReceiveLength != xStringLength ) ) - { - xNonBlockingReceiveError = pdTRUE; - } - - if( xReceiveLength == xStringLength ) - { - /* Ensure the received data was that expected, then generate the - * next expected string. */ - if( strcmp( cRxString, cExpectedString ) != 0 ) - { - xNonBlockingReceiveError = pdTRUE; - } - - iDataToSend++; - - if( iDataToSend > iMaxValue ) - { - /* The value sent is reset back to 0 to ensure the string being sent - * does not remain at the same length for too long. */ - iDataToSend = 0; - } - - memset( cExpectedString, 0x00, sizeof( cExpectedString ) ); - memset( cRxString, 0x00, sizeof( cRxString ) ); - sprintf( cExpectedString, "%d", ( int ) iDataToSend ); - xStringLength = strlen( cExpectedString ); - - if( xNonBlockingReceiveError == pdFALSE ) - { - /* No errors detected so increment the counter that lets the - * check task know this test is still functioning correctly. */ - ulNonBlockingRxCounter++; - } - } - } -} -/*-----------------------------------------------------------*/ - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - - static void prvSenderTask( void * pvParameters ) - { - MessageBufferHandle_t xMessageBuffer, xTempMessageBuffer; - int32_t iDataToSend = 0; - const int32_t iSendsBetweenIncrements = 100; - char cTxString[ 12 ]; /* Large enough to hold a 32 number in ASCII. */ - const TickType_t xTicksToWait = mbRX_TX_BLOCK_TIME, xShortDelay = pdMS_TO_TICKS( 50 ); - StaticMessageBuffer_t xStaticMessageBuffer; - size_t xBytesSent; - - - /* The task's priority is used as an index into the loop counters used to - * indicate this task is still running. */ - UBaseType_t uxIndex = uxTaskPriorityGet( NULL ); - - /* Make sure a change in priority does not inadvertently result in an - * invalid array index. */ - configASSERT( uxIndex < mbNUMBER_OF_ECHO_CLIENTS ); - - /* Avoid compiler warnings about unused parameters. */ - ( void ) pvParameters; - - xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ) / mbNUMBER_OF_SENDER_TASKS, /* The number of bytes in each buffer in the array. */ - &( ucBufferStorage[ uxIndex ][ 0 ] ), /* The address of the buffer to use within the array. */ - &( xStaticMessageBuffers[ uxIndex ] ) ); /* The static message buffer structure to use within the array. */ - - /* Now the message buffer has been created the receiver task can be created. - * If this sender task has the higher priority then the receiver task is - * created at the lower priority - if this sender task has the lower priority - * then the receiver task is created at the higher priority. */ - if( uxTaskPriorityGet( NULL ) == mbLOWER_PRIORITY ) - { - /* Here prvSingleTaskTests() performs various tests on a message buffer - * that was created statically. */ - prvSingleTaskTests( xMessageBuffer ); - xTaskCreate( prvReceiverTask, "MsgReceiver", xBlockingStackSize, ( void * ) xMessageBuffer, mbHIGHER_PRIORITY, NULL ); - } - else - { - xTaskCreate( prvReceiverTask, "MsgReceiver", xBlockingStackSize, ( void * ) xMessageBuffer, mbLOWER_PRIORITY, NULL ); - } - - for( ; ; ) - { - /* Create a string from an incrementing number. The length of the - * string will increase and decrease as the value of the number increases - * then overflows. */ - memset( cTxString, 0x00, sizeof( cTxString ) ); - sprintf( cTxString, "%d", ( int ) iDataToSend ); - - do - { - xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) cTxString, strlen( cTxString ), xTicksToWait ); - } while( xBytesSent == 0 ); /* Buffer may become full when receiver is running at the idle priority. */ - - iDataToSend++; - - if( ( iDataToSend % iSendsBetweenIncrements ) == 0 ) - { - /* Increment a loop counter so a check task can tell this task is - * still running as expected. */ - ulSenderLoopCounters[ uxIndex ]++; - - if( uxTaskPriorityGet( NULL ) == mbHIGHER_PRIORITY ) - { - /* Allow other tasks to run. */ - vTaskDelay( xShortDelay ); - } - - /* This message buffer is just created and deleted to ensure no - * issues when attempting to delete a message buffer that was - * created using statically allocated memory. To save stack space - * the buffer is set to point to the cTxString array - this is - * ok because nothing is actually written to the memory. */ - xTempMessageBuffer = xMessageBufferCreateStatic( sizeof( cTxString ), ( uint8_t * ) cTxString, &xStaticMessageBuffer ); - vMessageBufferDelete( xTempMessageBuffer ); - } - } - } - -#endif /* configSUPPORT_STATIC_ALLOCATION */ -/*-----------------------------------------------------------*/ - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - - static void prvReceiverTask( void * pvParameters ) - { - MessageBufferHandle_t const pxMessageBuffer = ( MessageBufferHandle_t ) pvParameters; - char cExpectedString[ 12 ]; /* Large enough to hold a 32-bit number in ASCII. */ - char cReceivedString[ 12 ]; /* Large enough to hold a 32-bit number in ASCII. */ - int32_t iExpectedData = 0; - const TickType_t xTicksToWait = pdMS_TO_TICKS( 5UL ); - size_t xReceivedBytes; - - for( ; ; ) - { - /* Generate the next expected string in the cExpectedString buffer. */ - memset( cExpectedString, 0x00, sizeof( cExpectedString ) ); - sprintf( cExpectedString, "%d", ( int ) iExpectedData ); - - /* Receive the next string from the message buffer. */ - memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); - - do - { - xReceivedBytes = xMessageBufferReceive( pxMessageBuffer, ( void * ) cReceivedString, sizeof( cExpectedString ), xTicksToWait ); - } while( xReceivedBytes == 0 ); - - /* Ensure the received string matches the expected string. */ - configASSERT( strcmp( cExpectedString, cReceivedString ) == 0 ); - - iExpectedData++; - } - } - -#endif /* configSUPPORT_STATIC_ALLOCATION */ -/*-----------------------------------------------------------*/ - -static void prvEchoClient( void * pvParameters ) -{ - size_t xSendLength = 0, ux; - char * pcStringToSend, * pcStringReceived, cNextChar = mbASCII_SPACE; - const TickType_t xTicksToWait = pdMS_TO_TICKS( 50 ); - -/* The task's priority is used as an index into the loop counters used to - * indicate this task is still running. */ - UBaseType_t uxIndex = uxTaskPriorityGet( NULL ); - -/* Pointers to the client and server message buffers are passed into this task - * using the task's parameter. */ - EchoMessageBuffers_t * pxMessageBuffers = ( EchoMessageBuffers_t * ) pvParameters; - - /* Prevent compiler warnings. */ - ( void ) pvParameters; - - /* Create the buffer into which strings to send to the server will be - * created, and the buffer into which strings echoed back from the server will - * be copied. */ - pcStringToSend = ( char * ) pvPortMalloc( mbMESSAGE_BUFFER_LENGTH_BYTES ); - pcStringReceived = ( char * ) pvPortMalloc( mbMESSAGE_BUFFER_LENGTH_BYTES ); - - configASSERT( pcStringToSend ); - configASSERT( pcStringReceived ); - - for( ; ; ) - { - /* Generate the length of the next string to send. */ - xSendLength++; - - /* The message buffer is being used to hold variable length data, so - * each data item requires sizeof( size_t ) bytes to hold the data's - * length, hence the sizeof() in the if() condition below. */ - if( xSendLength > ( mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) ) - { - /* Back to a string length of 1. */ - xSendLength = sizeof( char ); - - /* Maintain a count of the number of times this code executes so a - * check task can determine if this task is still functioning as - * expected or not. As there are two client tasks, and the priorities - * used are 0 and 1, the task's priority is used as an index into the - * loop count array. */ - ulEchoLoopCounters[ uxIndex ]++; - } - - memset( pcStringToSend, 0x00, mbMESSAGE_BUFFER_LENGTH_BYTES ); - - for( ux = 0; ux < xSendLength; ux++ ) - { - pcStringToSend[ ux ] = cNextChar; - - cNextChar++; - - if( cNextChar > mbASCII_TILDA ) - { - cNextChar = mbASCII_SPACE; - } - } - - /* Send the generated string to the buffer. */ - do - { - ux = xMessageBufferSend( pxMessageBuffers->xEchoClientBuffer, ( void * ) pcStringToSend, xSendLength, xTicksToWait ); - - if( ux == 0 ) - { - mtCOVERAGE_TEST_MARKER(); - } - } while( ux == 0 ); - - /* Wait for the string to be echoed back. */ - memset( pcStringReceived, 0x00, mbMESSAGE_BUFFER_LENGTH_BYTES ); - xMessageBufferReceive( pxMessageBuffers->xEchoServerBuffer, ( void * ) pcStringReceived, xSendLength, portMAX_DELAY ); - - configASSERT( strcmp( pcStringToSend, pcStringReceived ) == 0 ); - } -} -/*-----------------------------------------------------------*/ - -static void prvEchoServer( void * pvParameters ) -{ - MessageBufferHandle_t xTempMessageBuffer; - size_t xReceivedLength; - char * pcReceivedString; - EchoMessageBuffers_t xMessageBuffers; - TickType_t xTimeOnEntering; - const TickType_t xTicksToBlock = pdMS_TO_TICKS( 250UL ); - - /* Prevent compiler warnings about unused parameters. */ - ( void ) pvParameters; - - /* Create the message buffer used to send data from the client to the server, - * and the message buffer used to echo the data from the server back to the - * client. */ - xMessageBuffers.xEchoClientBuffer = xMessageBufferCreate( mbMESSAGE_BUFFER_LENGTH_BYTES ); - xMessageBuffers.xEchoServerBuffer = xMessageBufferCreate( mbMESSAGE_BUFFER_LENGTH_BYTES ); - configASSERT( xMessageBuffers.xEchoClientBuffer ); - configASSERT( xMessageBuffers.xEchoServerBuffer ); - - /* Create the buffer into which received strings will be copied. */ - pcReceivedString = ( char * ) pvPortMalloc( mbMESSAGE_BUFFER_LENGTH_BYTES ); - configASSERT( pcReceivedString ); - - /* Don't expect to receive anything yet! */ - xTimeOnEntering = xTaskGetTickCount(); - xReceivedLength = xMessageBufferReceive( xMessageBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, mbMESSAGE_BUFFER_LENGTH_BYTES, xTicksToBlock ); - configASSERT( ( ( TickType_t ) ( xTaskGetTickCount() - xTimeOnEntering ) ) >= xTicksToBlock ); - configASSERT( xReceivedLength == 0 ); - ( void ) xTimeOnEntering; /* In case configASSERT() is not defined. */ - - /* Now the message buffers have been created the echo client task can be - * created. If this server task has the higher priority then the client task - * is created at the lower priority - if this server task has the lower - * priority then the client task is created at the higher priority. */ - if( uxTaskPriorityGet( NULL ) == mbLOWER_PRIORITY ) - { - xTaskCreate( prvEchoClient, "EchoClient", configMINIMAL_STACK_SIZE, ( void * ) &xMessageBuffers, mbHIGHER_PRIORITY, NULL ); - } - else - { - /* Here prvSingleTaskTests() performs various tests on a message buffer - * that was created dynamically. */ - prvSingleTaskTests( xMessageBuffers.xEchoClientBuffer ); - xTaskCreate( prvEchoClient, "EchoClient", configMINIMAL_STACK_SIZE, ( void * ) &xMessageBuffers, mbLOWER_PRIORITY, NULL ); - } - - for( ; ; ) - { - memset( pcReceivedString, 0x00, mbMESSAGE_BUFFER_LENGTH_BYTES ); - - /* Has any data been sent by the client? */ - xReceivedLength = xMessageBufferReceive( xMessageBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, mbMESSAGE_BUFFER_LENGTH_BYTES, portMAX_DELAY ); - - /* Should always receive data as max delay was used. */ - configASSERT( xReceivedLength > 0 ); - - /* Echo the received data back to the client. */ - xMessageBufferSend( xMessageBuffers.xEchoServerBuffer, ( void * ) pcReceivedString, xReceivedLength, portMAX_DELAY ); - - /* This message buffer is just created and deleted to ensure no memory - * leaks. */ - xTempMessageBuffer = xMessageBufferCreate( mbMESSAGE_BUFFER_LENGTH_BYTES ); - vMessageBufferDelete( xTempMessageBuffer ); - } -} -/*-----------------------------------------------------------*/ - -/* Tests within configRUN_ADDITIONAL_TESTS blocks only execute on larger - * platforms or have been added to pre-existing files that are already in use - * by other test projects without ensuring they don't cause those pre-existing - * projects to run out of program or data memory. */ -#if ( configRUN_ADDITIONAL_TESTS == 1 ) - - static void prvSpaceAvailableCoherenceActor( void * pvParameters ) - { - static char * cTxString = "12345"; - char cRxString[ mbCOHERENCE_TEST_BYTES_WRITTEN + 1 ]; /* +1 for NULL terminator. */ - - ( void ) pvParameters; - - for( ; ; ) - { - /* Add bytes to the buffer so the other task should see - * mbEXPECTED_FREE_BYTES_AFTER_WRITING_STRING bytes free. */ - xMessageBufferSend( xCoherenceTestMessageBuffer, ( void * ) cTxString, strlen( cTxString ), 0 ); - configASSERT( xMessageBufferSpacesAvailable( xCoherenceTestMessageBuffer ) == mbEXPECTED_FREE_BYTES_AFTER_WRITING_STRING ); - - /* Read out message again so the other task should read the full - * mbCOHERENCE_TEST_BUFFER_SIZE bytes free again. */ - memset( ( void * ) cRxString, 0x00, sizeof( cRxString ) ); - xMessageBufferReceive( xCoherenceTestMessageBuffer, ( void * ) cRxString, mbCOHERENCE_TEST_BYTES_WRITTEN, 0 ); - configASSERT( strcmp( cTxString, cRxString ) == 0 ); - } - } - /*-----------------------------------------------------------*/ - - static void prvSpaceAvailableCoherenceTester( void * pvParameters ) - { - size_t xSpaceAvailable; - BaseType_t xErrorFound = pdFALSE; - - ( void ) pvParameters; - - for( ; ; ) - { - /* This message buffer is only ever empty or contains 5 bytes. So all - * queries of its free space should result in one of the two values tested - * below. */ - xSpaceAvailable = xMessageBufferSpacesAvailable( xCoherenceTestMessageBuffer ); - - if( ( xSpaceAvailable == mbCOHERENCE_TEST_BUFFER_SIZE ) || - ( xSpaceAvailable == mbEXPECTED_FREE_BYTES_AFTER_WRITING_STRING ) ) - { - /* Only continue to increment the variable that shows this task - * is still executing if no errors have been found. */ - if( xErrorFound == pdFALSE ) - { - ulSizeCoherencyTestCycles++; - } - } - else - { - xErrorFound = pdTRUE; - } - - configASSERT( xErrorFound == pdFALSE ); - } - } - -#endif /* configRUN_ADDITIONAL_TESTS == 1 */ -/*-----------------------------------------------------------*/ - -BaseType_t xAreMessageBufferTasksStillRunning( void ) -{ - static uint32_t ulLastEchoLoopCounters[ mbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; - static uint32_t ulLastNonBlockingRxCounter = 0; - BaseType_t xReturn = pdPASS, x; - - for( x = 0; x < mbNUMBER_OF_ECHO_CLIENTS; x++ ) - { - if( ulLastEchoLoopCounters[ x ] == ulEchoLoopCounters[ x ] ) - { - xReturn = pdFAIL; - } - else - { - ulLastEchoLoopCounters[ x ] = ulEchoLoopCounters[ x ]; - } - } - - if( ulNonBlockingRxCounter == ulLastNonBlockingRxCounter ) - { - xReturn = pdFAIL; - } - else - { - ulLastNonBlockingRxCounter = ulNonBlockingRxCounter; - } - - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - { - static uint32_t ulLastSenderLoopCounters[ mbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; - - for( x = 0; x < mbNUMBER_OF_SENDER_TASKS; x++ ) - { - if( ulLastSenderLoopCounters[ x ] == ulSenderLoopCounters[ x ] ) - { - xReturn = pdFAIL; - } - else - { - ulLastSenderLoopCounters[ x ] = ulSenderLoopCounters[ x ]; - } - } - } - #endif /* configSUPPORT_STATIC_ALLOCATION */ - - #if ( configRUN_ADDITIONAL_TESTS == 1 ) - { - static uint32_t ullastSizeCoherencyTestCycles = 0UL; - - if( ullastSizeCoherencyTestCycles == ulSizeCoherencyTestCycles ) - { - xReturn = pdFAIL; - } - else - { - ullastSizeCoherencyTestCycles = ulSizeCoherencyTestCycles; - } - } - #endif /* if ( configRUN_ADDITIONAL_TESTS == 1 ) */ - - return xReturn; -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include "stdio.h" +#include "string.h" + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "message_buffer.h" + +/* Demo app includes. */ +#include "MessageBufferDemo.h" + +/* The number of bytes of storage in the message buffers used in this test. */ +#define mbMESSAGE_BUFFER_LENGTH_BYTES ( ( size_t ) 50 ) + +/* The number of additional bytes used to store the length of each message. */ +#define mbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) + +/* Start and end ASCII characters used in messages sent to the buffers. */ +#define mbASCII_SPACE 32 +#define mbASCII_TILDA 126 + +/* Defines the number of tasks to create in this test and demo. */ +#define mbNUMBER_OF_ECHO_CLIENTS ( 2 ) +#define mbNUMBER_OF_SENDER_TASKS ( 2 ) + +/* Priority of the test tasks. The send and receive go from low to high + * priority tasks, and from high to low priority tasks. */ +#define mbLOWER_PRIORITY ( tskIDLE_PRIORITY ) +#define mbHIGHER_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* Block times used when sending and receiving from the message buffers. */ +#define mbRX_TX_BLOCK_TIME pdMS_TO_TICKS( 175UL ) + +/* A block time of 0 means "don't block". */ +#define mbDONT_BLOCK ( 0 ) + +/*-----------------------------------------------------------*/ + +/* + * Performs various tests that do not require multiple tasks to interact. + */ +static void prvSingleTaskTests( MessageBufferHandle_t xMessageBuffer ); + +/* + * Tests sending and receiving various lengths of messages via a message buffer. + * The echo client sends the messages to the echo server, which then sends the + * message back to the echo client which, checks it receives exactly what it + * sent. + */ +static void prvEchoClient( void * pvParameters ); +static void prvEchoServer( void * pvParameters ); + +/* + * Tasks that send and receive to a message buffer at a low priority and without + * blocking, so the send and receive functions interleave in time as the tasks + * are switched in and out. + */ +static void prvNonBlockingReceiverTask( void * pvParameters ); +static void prvNonBlockingSenderTask( void * pvParameters ); + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + +/* This file tests both statically and dynamically allocated message buffers. + * Allocate the structures and buffers to be used by the statically allocated + * objects, which get used in the echo tests. */ + static void prvReceiverTask( void * pvParameters ); + static void prvSenderTask( void * pvParameters ); + + static StaticMessageBuffer_t xStaticMessageBuffers[ mbNUMBER_OF_ECHO_CLIENTS ]; + static uint8_t ucBufferStorage[ mbNUMBER_OF_SENDER_TASKS ][ mbMESSAGE_BUFFER_LENGTH_BYTES + 1 ]; + static uint32_t ulSenderLoopCounters[ mbNUMBER_OF_SENDER_TASKS ] = { 0 }; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + + +#if ( configRUN_ADDITIONAL_TESTS == 1 ) + #define mbCOHERENCE_TEST_BUFFER_SIZE 20 + #define mbCOHERENCE_TEST_BYTES_WRITTEN 5 + #define mbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) + #define mbEXPECTED_FREE_BYTES_AFTER_WRITING_STRING ( mbCOHERENCE_TEST_BUFFER_SIZE - ( mbCOHERENCE_TEST_BYTES_WRITTEN + mbBYTES_TO_STORE_MESSAGE_LENGTH ) ) + + static void prvSpaceAvailableCoherenceActor( void * pvParameters ); + static void prvSpaceAvailableCoherenceTester( void * pvParameters ); + static MessageBufferHandle_t xCoherenceTestMessageBuffer = NULL; + + static uint32_t ulSizeCoherencyTestCycles = 0UL; +#endif /* if ( configRUN_ADDITIONAL_TESTS == 1 ) */ + +/*-----------------------------------------------------------*/ + +/* The buffers used by the echo client and server tasks. */ +typedef struct ECHO_MESSAGE_BUFFERS +{ + /* Handles to the data structures that describe the message buffers. */ + MessageBufferHandle_t xEchoClientBuffer; + MessageBufferHandle_t xEchoServerBuffer; +} EchoMessageBuffers_t; +static uint32_t ulEchoLoopCounters[ mbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; + +/* The non-blocking tasks monitor their operation, and if no errors have been + * found, increment ulNonBlockingRxCounter. xAreMessageBufferTasksStillRunning() + * then checks ulNonBlockingRxCounter and only returns pdPASS if + * ulNonBlockingRxCounter is still incrementing. */ +static uint32_t ulNonBlockingRxCounter = 0; + +/* A message that is longer than the buffer, parts of which are written to the + * message buffer to test writing different lengths at different offsets. */ +static const char * pc55ByteString = "One two three four five six seven eight nine ten eleven"; + +/* Remember the required stack size so tasks can be created at run time (after + * initialisation time. */ +static configSTACK_DEPTH_TYPE xBlockingStackSize = 0; + +/*-----------------------------------------------------------*/ + +void vStartMessageBufferTasks( configSTACK_DEPTH_TYPE xStackSize ) +{ + MessageBufferHandle_t xMessageBuffer; + + #ifndef configMESSAGE_BUFFER_BLOCK_TASK_STACK_SIZE + xBlockingStackSize = ( xStackSize + ( xStackSize >> 1U ) ); + #else + xBlockingStackSize = configMESSAGE_BUFFER_BLOCK_TASK_STACK_SIZE; + #endif + + /* The echo servers sets up the message buffers before creating the echo + * client tasks. One set of tasks has the server as the higher priority, and + * the other has the client as the higher priority. */ + xTaskCreate( prvEchoServer, "1EchoServer", xBlockingStackSize, NULL, mbHIGHER_PRIORITY, NULL ); + xTaskCreate( prvEchoServer, "2EchoServer", xBlockingStackSize, NULL, mbLOWER_PRIORITY, NULL ); + + /* The non blocking tasks run continuously and will interleave with each + * other, so must be created at the lowest priority. The message buffer they + * use is created and passed in using the task's parameter. */ + xMessageBuffer = xMessageBufferCreate( mbMESSAGE_BUFFER_LENGTH_BYTES ); + xTaskCreate( prvNonBlockingReceiverTask, "NonBlkRx", xStackSize, ( void * ) xMessageBuffer, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvNonBlockingSenderTask, "NonBlkTx", xStackSize, ( void * ) xMessageBuffer, tskIDLE_PRIORITY, NULL ); + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* The sender tasks set up the message buffers before creating the + * receiver tasks. Priorities must be 0 and 1 as the priority is used to + * index into the xStaticMessageBuffers and ucBufferStorage arrays. */ + xTaskCreate( prvSenderTask, "1Sender", xBlockingStackSize, NULL, mbHIGHER_PRIORITY, NULL ); + xTaskCreate( prvSenderTask, "2Sender", xBlockingStackSize, NULL, mbLOWER_PRIORITY, NULL ); + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + #if ( configRUN_ADDITIONAL_TESTS == 1 ) + { + xCoherenceTestMessageBuffer = xMessageBufferCreate( mbCOHERENCE_TEST_BUFFER_SIZE ); + configASSERT( xCoherenceTestMessageBuffer ); + + xTaskCreate( prvSpaceAvailableCoherenceActor, "mbsanity1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvSpaceAvailableCoherenceTester, "mbsanity2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvSingleTaskTests( MessageBufferHandle_t xMessageBuffer ) +{ + size_t xReturned, xItem, xExpectedSpace, xNextLength; + const size_t xMax6ByteMessages = mbMESSAGE_BUFFER_LENGTH_BYTES / ( 6 + mbBYTES_TO_STORE_MESSAGE_LENGTH ); + const size_t x6ByteLength = 6, x17ByteLength = 17; + uint8_t * pucFullBuffer, * pucData, * pucReadData; + TickType_t xTimeBeforeCall, xTimeAfterCall; + const TickType_t xBlockTime = pdMS_TO_TICKS( 25 ), xAllowableMargin = pdMS_TO_TICKS( 3 ); + UBaseType_t uxOriginalPriority; + + /* Remove warning in case configASSERT() is not defined. */ + ( void ) xAllowableMargin; + + /* To minimise stack and heap usage a full size buffer is allocated from + * the heap, then buffers which hold smaller amounts of data are overlayed + * with the larger buffer - just make sure not to use both at once!. */ + pucFullBuffer = pvPortMalloc( mbMESSAGE_BUFFER_LENGTH_BYTES ); + configASSERT( pucFullBuffer ); + + pucData = pucFullBuffer; + pucReadData = pucData + x17ByteLength; + + /* Nothing has been added or removed yet, so expect the free space to be + * exactly as created and the length of the next message to be 0. */ + xExpectedSpace = xMessageBufferSpaceAvailable( xMessageBuffer ); + configASSERT( xExpectedSpace == mbMESSAGE_BUFFER_LENGTH_BYTES ); + configASSERT( xMessageBufferIsEmpty( xMessageBuffer ) == pdTRUE ); + xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); + configASSERT( xNextLength == 0 ); + /* In case configASSERT() is not define. */ + ( void ) xExpectedSpace; + ( void ) xNextLength; + + /* Try sending more bytes than possible, first using the FromISR version, then + * with an infinite block time to ensure this task does not lock up. */ + xReturned = xMessageBufferSendFromISR( xMessageBuffer, ( void * ) pucData, mbMESSAGE_BUFFER_LENGTH_BYTES + sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ), NULL ); + configASSERT( xReturned == ( size_t ) 0 ); + /* In case configASSERT() is not defined. */ + ( void ) xReturned; + xReturned = xMessageBufferSend( xMessageBuffer, ( void * ) pucData, mbMESSAGE_BUFFER_LENGTH_BYTES + sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ), portMAX_DELAY ); + configASSERT( xReturned == ( size_t ) 0 ); + /* In case configASSERT() is not defined. */ + ( void ) xReturned; + + /* The buffer is 50 bytes long. When an item is added to the buffer an + * additional 4 bytes are added to hold the item's size. That means adding + * 6 bytes to the buffer will actually add 10 bytes to the buffer. Therefore, + * with a 50 byte buffer, a maximum of 5 6 bytes items can be added before the + * buffer is completely full. NOTE: The numbers in this paragraph assume + * sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) == 4. */ + for( xItem = 0; xItem < xMax6ByteMessages; xItem++ ) + { + configASSERT( xMessageBufferIsFull( xMessageBuffer ) == pdFALSE ); + + /* Generate recognizable data to write to the buffer. This is just + * ascii characters that shows which loop iteration the data was written + * in. The 'FromISR' version is used to give it some exercise as a block + * time is not used. That requires the call to be in a critical section + * so this code can also run on FreeRTOS ports that do not support + * interrupt nesting (and so don't have interrupt safe critical + * sections).*/ + memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength ); + taskENTER_CRITICAL(); + { + xReturned = xMessageBufferSendFromISR( xMessageBuffer, ( void * ) pucData, x6ByteLength, NULL ); + } + taskEXIT_CRITICAL(); + configASSERT( xReturned == x6ByteLength ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* The space in the buffer will have reduced by the amount of user data + * written into the buffer and the amount of space used to store the length + * of the data written into the buffer. */ + xExpectedSpace -= ( x6ByteLength + mbBYTES_TO_STORE_MESSAGE_LENGTH ); + xReturned = xMessageBufferSpaceAvailable( xMessageBuffer ); + configASSERT( xReturned == xExpectedSpace ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* Only 6 byte messages are written. */ + xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); + configASSERT( xNextLength == x6ByteLength ); + ( void ) xNextLength; /* In case configASSERT() is not defined. */ + } + + /* Now the buffer should be full, and attempting to add anything will should + * fail. */ + configASSERT( xMessageBufferIsFull( xMessageBuffer ) == pdTRUE ); + xReturned = xMessageBufferSend( xMessageBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), mbDONT_BLOCK ); + configASSERT( xReturned == 0 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* Adding with a timeout should also fail after the appropriate time. The + * priority is temporarily boosted in this part of the test to keep the + * allowable margin to a minimum. */ + uxOriginalPriority = uxTaskPriorityGet( NULL ); + vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); + xTimeBeforeCall = xTaskGetTickCount(); + xReturned = xMessageBufferSend( xMessageBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), xBlockTime ); + xTimeAfterCall = xTaskGetTickCount(); + vTaskPrioritySet( NULL, uxOriginalPriority ); + configASSERT( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) >= xBlockTime ); + configASSERT( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) < ( xBlockTime + xAllowableMargin ) ); + configASSERT( xReturned == 0 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + ( void ) xTimeBeforeCall; + ( void ) xTimeAfterCall; + + /* The buffer is now full of data in the form "000000", "111111", etc. Make + * sure the data is read out as expected. */ + for( xItem = 0; xItem < xMax6ByteMessages; xItem++ ) + { + /* Generate the data that is expected to be read out for this loop + * iteration. */ + memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength ); + + /* Try reading the message into a buffer that is too small. The message + * should remain in the buffer. */ + xReturned = xMessageBufferReceive( xMessageBuffer, ( void * ) pucReadData, x6ByteLength - 1, mbDONT_BLOCK ); + configASSERT( xReturned == 0 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* Should still be at least one 6 byte message still available. */ + xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); + configASSERT( xNextLength == x6ByteLength ); + ( void ) xNextLength; /* In case configASSERT() is not defined. */ + + /* Read the next 6 bytes out. The 'FromISR' version is used to give it + * some exercise as a block time is not used. THa requires the code to be + * in a critical section so this test can be run with FreeRTOS ports that + * do not support interrupt nesting (and therefore don't have interrupt + * safe critical sections). */ + taskENTER_CRITICAL(); + { + xReturned = xMessageBufferReceiveFromISR( xMessageBuffer, ( void * ) pucReadData, x6ByteLength, NULL ); + } + taskEXIT_CRITICAL(); + configASSERT( xReturned == x6ByteLength ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* Does the data read out match that expected? */ + configASSERT( memcmp( ( void * ) pucData, ( void * ) pucReadData, x6ByteLength ) == 0 ); + + /* The space in the buffer will have increased by the amount of user + * data read from into the buffer and the amount of space used to store the + * length of the data read into the buffer. */ + xExpectedSpace += ( x6ByteLength + mbBYTES_TO_STORE_MESSAGE_LENGTH ); + xReturned = xMessageBufferSpaceAvailable( xMessageBuffer ); + configASSERT( xReturned == xExpectedSpace ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + } + + /* The buffer should be empty again. */ + configASSERT( xMessageBufferIsEmpty( xMessageBuffer ) == pdTRUE ); + xExpectedSpace = xMessageBufferSpaceAvailable( xMessageBuffer ); + configASSERT( xExpectedSpace == mbMESSAGE_BUFFER_LENGTH_BYTES ); + ( void ) xExpectedSpace; /* In case configASSERT() is not defined. */ + xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); + configASSERT( xNextLength == 0 ); + ( void ) xNextLength; /* In case configASSERT() is not defined. */ + + + /* Reading with a timeout should also fail after the appropriate time. The + * priority is temporarily boosted in this part of the test to keep the + * allowable margin to a minimum. */ + vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); + xTimeBeforeCall = xTaskGetTickCount(); + xReturned = xMessageBufferReceive( xMessageBuffer, ( void * ) pucReadData, x6ByteLength, xBlockTime ); + xTimeAfterCall = xTaskGetTickCount(); + vTaskPrioritySet( NULL, uxOriginalPriority ); + configASSERT( ( xTimeAfterCall - xTimeBeforeCall ) >= xBlockTime ); + configASSERT( ( xTimeAfterCall - xTimeBeforeCall ) < ( xBlockTime + xAllowableMargin ) ); + configASSERT( xReturned == 0 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + ( void ) xTimeBeforeCall; + ( void ) xTimeAfterCall; + + + /* In the next loop 17 bytes are written to then read out on each iteration. + * The expected length variable is always used after 17 bytes have been written + * into the buffer - the length of the message is also written, making a total + * of 21 bytes consumed for each 17 byte message. */ + xExpectedSpace = mbMESSAGE_BUFFER_LENGTH_BYTES - ( x17ByteLength + mbBYTES_TO_STORE_MESSAGE_LENGTH ); + + /* Reading and writing 17 bytes at a time will result in 21 bytes being + * written into the buffer, and as 50 is not divisible by 21, writing multiple + * times will cause the data to wrap in the buffer.*/ + for( xItem = 0; xItem < 100; xItem++ ) + { + /* Generate recognizable data to write to the queue. This is just + * ascii characters that shows which loop iteration the data was written + * in. */ + memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x17ByteLength ); + xReturned = xMessageBufferSend( xMessageBuffer, ( void * ) pucData, x17ByteLength, mbDONT_BLOCK ); + configASSERT( xReturned == x17ByteLength ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* Only 17 byte messages are written. */ + xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); + configASSERT( xNextLength == x17ByteLength ); + ( void ) xNextLength; /* In case configASSERT() is not defined. */ + + /* The space in the buffer will have reduced by the amount of user data + * written into the buffer and the amount of space used to store the length + * of the data written into the buffer. */ + xReturned = xMessageBufferSpaceAvailable( xMessageBuffer ); + configASSERT( xReturned == xExpectedSpace ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* Read the 17 bytes out again. */ + xReturned = xMessageBufferReceive( xMessageBuffer, ( void * ) pucReadData, x17ByteLength, mbDONT_BLOCK ); + configASSERT( xReturned == x17ByteLength ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* Does the data read out match that expected? */ + configASSERT( memcmp( ( void * ) pucData, ( void * ) pucReadData, x17ByteLength ) == 0 ); + + /* Don't expect any messages to be available as the data was read out + * again. */ + xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); + configASSERT( xNextLength == 0 ); + ( void ) xNextLength; /* In case configASSERT() is not defined. */ + } + + /* The buffer should be empty again. */ + configASSERT( xMessageBufferIsEmpty( xMessageBuffer ) == pdTRUE ); + xExpectedSpace = xMessageBufferSpaceAvailable( xMessageBuffer ); + configASSERT( xExpectedSpace == mbMESSAGE_BUFFER_LENGTH_BYTES ); + + /* Cannot write within sizeof( size_t ) (assumed to be 4 bytes in this test) + * bytes of the full 50 bytes, as that would not leave space for the four bytes + * taken by the data length. */ + xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES, mbDONT_BLOCK ); + configASSERT( xReturned == 0 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + #ifndef configMESSAGE_BUFFER_LENGTH_TYPE + { + /* The following will fail if configMESSAGE_BUFFER_LENGTH_TYPE is set + * to a non 32-bit type. */ + xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - 1, mbDONT_BLOCK ); + configASSERT( xReturned == 0 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - 2, mbDONT_BLOCK ); + configASSERT( xReturned == 0 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - 3, mbDONT_BLOCK ); + configASSERT( xReturned == 0 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + } + #endif /* ifndef configMESSAGE_BUFFER_LENGTH_TYPE */ + + /* Don't expect any messages to be available as the above were too large to + * get written. */ + xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); + configASSERT( xNextLength == 0 ); + ( void ) xNextLength; /* In case configASSERT() is not defined. */ + + /* Can write mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) bytes though. */ + xReturned = xMessageBufferSend( xMessageBuffer, ( const void * ) pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ), mbDONT_BLOCK ); + configASSERT( xReturned == mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + xNextLength = xMessageBufferNextLengthBytes( xMessageBuffer ); + configASSERT( xNextLength == ( mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) ); + ( void ) xNextLength; /* In case configASSERT() is not defined. */ + xReturned = xMessageBufferReceive( xMessageBuffer, ( void * ) pucFullBuffer, mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ), mbDONT_BLOCK ); + configASSERT( xReturned == ( mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + configASSERT( memcmp( ( const void * ) pucFullBuffer, pc55ByteString, mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) == 0 ); + + /* Clean up. */ + vPortFree( pucFullBuffer ); + xMessageBufferReset( xMessageBuffer ); +} +/*-----------------------------------------------------------*/ + +static void prvNonBlockingSenderTask( void * pvParameters ) +{ + MessageBufferHandle_t xMessageBuffer; + int32_t iDataToSend = 0; + size_t xStringLength; + const int32_t iMaxValue = 1500; + char cTxString[ 12 ]; /* Large enough to hold a 32 number in ASCII. */ + + /* In this case the message buffer has already been created and is passed + * into the task using the task's parameter. */ + + xMessageBuffer = ( MessageBufferHandle_t ) pvParameters; + + /* Create a string from an incrementing number. The length of the + * string will increase and decrease as the value of the number increases + * then overflows. */ + memset( cTxString, 0x00, sizeof( cTxString ) ); + sprintf( cTxString, "%d", ( int ) iDataToSend ); + xStringLength = strlen( cTxString ); + + for( ; ; ) + { + /* Doesn't block so calls can interleave with the non-blocking + * receives performed by prvNonBlockingReceiverTask(). */ + if( xMessageBufferSend( xMessageBuffer, ( void * ) cTxString, strlen( cTxString ), mbDONT_BLOCK ) == xStringLength ) + { + iDataToSend++; + + if( iDataToSend > iMaxValue ) + { + /* The value sent is reset back to 0 to ensure the string being sent + * does not remain at the same length for too long. */ + iDataToSend = 0; + } + + /* Create the next string. */ + memset( cTxString, 0x00, sizeof( cTxString ) ); + sprintf( cTxString, "%d", ( int ) iDataToSend ); + xStringLength = strlen( cTxString ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvNonBlockingReceiverTask( void * pvParameters ) +{ + MessageBufferHandle_t xMessageBuffer; + BaseType_t xNonBlockingReceiveError = pdFALSE; + int32_t iDataToSend = 0; + size_t xStringLength, xReceiveLength; + const int32_t iMaxValue = 1500; + char cExpectedString[ 12 ]; /* Large enough to hold a 32 number in ASCII. */ + char cRxString[ 12 ]; + + /* In this case the message buffer has already been created and is passed + * into the task using the task's parameter. */ + xMessageBuffer = ( MessageBufferHandle_t ) pvParameters; + + /* Create a string from an incrementing number. The length of the + * string will increase and decrease as the value of the number increases + * then overflows. This should always match the string sent to the buffer by + * the non blocking sender task. */ + memset( cExpectedString, 0x00, sizeof( cExpectedString ) ); + memset( cRxString, 0x00, sizeof( cRxString ) ); + sprintf( cExpectedString, "%d", ( int ) iDataToSend ); + xStringLength = strlen( cExpectedString ); + + for( ; ; ) + { + /* Doesn't block so calls can interleave with the non-blocking + * receives performed by prvNonBlockingReceiverTask(). */ + xReceiveLength = xMessageBufferReceive( xMessageBuffer, ( void * ) cRxString, sizeof( cRxString ), mbDONT_BLOCK ); + + /* Should only ever receive no data is available, or the expected + * length of data is available. */ + if( ( xReceiveLength != 0 ) && ( xReceiveLength != xStringLength ) ) + { + xNonBlockingReceiveError = pdTRUE; + } + + if( xReceiveLength == xStringLength ) + { + /* Ensure the received data was that expected, then generate the + * next expected string. */ + if( strcmp( cRxString, cExpectedString ) != 0 ) + { + xNonBlockingReceiveError = pdTRUE; + } + + iDataToSend++; + + if( iDataToSend > iMaxValue ) + { + /* The value sent is reset back to 0 to ensure the string being sent + * does not remain at the same length for too long. */ + iDataToSend = 0; + } + + memset( cExpectedString, 0x00, sizeof( cExpectedString ) ); + memset( cRxString, 0x00, sizeof( cRxString ) ); + sprintf( cExpectedString, "%d", ( int ) iDataToSend ); + xStringLength = strlen( cExpectedString ); + + if( xNonBlockingReceiveError == pdFALSE ) + { + /* No errors detected so increment the counter that lets the + * check task know this test is still functioning correctly. */ + ulNonBlockingRxCounter++; + } + } + } +} +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + static void prvSenderTask( void * pvParameters ) + { + MessageBufferHandle_t xMessageBuffer, xTempMessageBuffer; + int32_t iDataToSend = 0; + const int32_t iSendsBetweenIncrements = 100; + char cTxString[ 12 ]; /* Large enough to hold a 32 number in ASCII. */ + const TickType_t xTicksToWait = mbRX_TX_BLOCK_TIME, xShortDelay = pdMS_TO_TICKS( 50 ); + StaticMessageBuffer_t xStaticMessageBuffer; + size_t xBytesSent; + + + /* The task's priority is used as an index into the loop counters used to + * indicate this task is still running. */ + UBaseType_t uxIndex = uxTaskPriorityGet( NULL ); + + /* Make sure a change in priority does not inadvertently result in an + * invalid array index. */ + configASSERT( uxIndex < mbNUMBER_OF_ECHO_CLIENTS ); + + /* Avoid compiler warnings about unused parameters. */ + ( void ) pvParameters; + + xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ) / mbNUMBER_OF_SENDER_TASKS, /* The number of bytes in each buffer in the array. */ + &( ucBufferStorage[ uxIndex ][ 0 ] ), /* The address of the buffer to use within the array. */ + &( xStaticMessageBuffers[ uxIndex ] ) ); /* The static message buffer structure to use within the array. */ + + /* Now the message buffer has been created the receiver task can be created. + * If this sender task has the higher priority then the receiver task is + * created at the lower priority - if this sender task has the lower priority + * then the receiver task is created at the higher priority. */ + if( uxTaskPriorityGet( NULL ) == mbLOWER_PRIORITY ) + { + /* Here prvSingleTaskTests() performs various tests on a message buffer + * that was created statically. */ + prvSingleTaskTests( xMessageBuffer ); + xTaskCreate( prvReceiverTask, "MsgReceiver", xBlockingStackSize, ( void * ) xMessageBuffer, mbHIGHER_PRIORITY, NULL ); + } + else + { + xTaskCreate( prvReceiverTask, "MsgReceiver", xBlockingStackSize, ( void * ) xMessageBuffer, mbLOWER_PRIORITY, NULL ); + } + + for( ; ; ) + { + /* Create a string from an incrementing number. The length of the + * string will increase and decrease as the value of the number increases + * then overflows. */ + memset( cTxString, 0x00, sizeof( cTxString ) ); + sprintf( cTxString, "%d", ( int ) iDataToSend ); + + do + { + xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) cTxString, strlen( cTxString ), xTicksToWait ); + } while( xBytesSent == 0 ); /* Buffer may become full when receiver is running at the idle priority. */ + + iDataToSend++; + + if( ( iDataToSend % iSendsBetweenIncrements ) == 0 ) + { + /* Increment a loop counter so a check task can tell this task is + * still running as expected. */ + ulSenderLoopCounters[ uxIndex ]++; + + if( uxTaskPriorityGet( NULL ) == mbHIGHER_PRIORITY ) + { + /* Allow other tasks to run. */ + vTaskDelay( xShortDelay ); + } + + /* This message buffer is just created and deleted to ensure no + * issues when attempting to delete a message buffer that was + * created using statically allocated memory. To save stack space + * the buffer is set to point to the cTxString array - this is + * ok because nothing is actually written to the memory. */ + xTempMessageBuffer = xMessageBufferCreateStatic( sizeof( cTxString ), ( uint8_t * ) cTxString, &xStaticMessageBuffer ); + vMessageBufferDelete( xTempMessageBuffer ); + } + } + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + static void prvReceiverTask( void * pvParameters ) + { + MessageBufferHandle_t const pxMessageBuffer = ( MessageBufferHandle_t ) pvParameters; + char cExpectedString[ 12 ]; /* Large enough to hold a 32-bit number in ASCII. */ + char cReceivedString[ 12 ]; /* Large enough to hold a 32-bit number in ASCII. */ + int32_t iExpectedData = 0; + const TickType_t xTicksToWait = pdMS_TO_TICKS( 5UL ); + size_t xReceivedBytes; + + for( ; ; ) + { + /* Generate the next expected string in the cExpectedString buffer. */ + memset( cExpectedString, 0x00, sizeof( cExpectedString ) ); + sprintf( cExpectedString, "%d", ( int ) iExpectedData ); + + /* Receive the next string from the message buffer. */ + memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); + + do + { + xReceivedBytes = xMessageBufferReceive( pxMessageBuffer, ( void * ) cReceivedString, sizeof( cExpectedString ), xTicksToWait ); + } while( xReceivedBytes == 0 ); + + /* Ensure the received string matches the expected string. */ + configASSERT( strcmp( cExpectedString, cReceivedString ) == 0 ); + + iExpectedData++; + } + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvEchoClient( void * pvParameters ) +{ + size_t xSendLength = 0, ux; + char * pcStringToSend, * pcStringReceived, cNextChar = mbASCII_SPACE; + const TickType_t xTicksToWait = pdMS_TO_TICKS( 50 ); + +/* The task's priority is used as an index into the loop counters used to + * indicate this task is still running. */ + UBaseType_t uxIndex = uxTaskPriorityGet( NULL ); + +/* Pointers to the client and server message buffers are passed into this task + * using the task's parameter. */ + EchoMessageBuffers_t * pxMessageBuffers = ( EchoMessageBuffers_t * ) pvParameters; + + /* Prevent compiler warnings. */ + ( void ) pvParameters; + + /* Create the buffer into which strings to send to the server will be + * created, and the buffer into which strings echoed back from the server will + * be copied. */ + pcStringToSend = ( char * ) pvPortMalloc( mbMESSAGE_BUFFER_LENGTH_BYTES ); + pcStringReceived = ( char * ) pvPortMalloc( mbMESSAGE_BUFFER_LENGTH_BYTES ); + + configASSERT( pcStringToSend ); + configASSERT( pcStringReceived ); + + for( ; ; ) + { + /* Generate the length of the next string to send. */ + xSendLength++; + + /* The message buffer is being used to hold variable length data, so + * each data item requires sizeof( size_t ) bytes to hold the data's + * length, hence the sizeof() in the if() condition below. */ + if( xSendLength > ( mbMESSAGE_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) ) + { + /* Back to a string length of 1. */ + xSendLength = sizeof( char ); + + /* Maintain a count of the number of times this code executes so a + * check task can determine if this task is still functioning as + * expected or not. As there are two client tasks, and the priorities + * used are 0 and 1, the task's priority is used as an index into the + * loop count array. */ + ulEchoLoopCounters[ uxIndex ]++; + } + + memset( pcStringToSend, 0x00, mbMESSAGE_BUFFER_LENGTH_BYTES ); + + for( ux = 0; ux < xSendLength; ux++ ) + { + pcStringToSend[ ux ] = cNextChar; + + cNextChar++; + + if( cNextChar > mbASCII_TILDA ) + { + cNextChar = mbASCII_SPACE; + } + } + + /* Send the generated string to the buffer. */ + do + { + ux = xMessageBufferSend( pxMessageBuffers->xEchoClientBuffer, ( void * ) pcStringToSend, xSendLength, xTicksToWait ); + + if( ux == 0 ) + { + mtCOVERAGE_TEST_MARKER(); + } + } while( ux == 0 ); + + /* Wait for the string to be echoed back. */ + memset( pcStringReceived, 0x00, mbMESSAGE_BUFFER_LENGTH_BYTES ); + xMessageBufferReceive( pxMessageBuffers->xEchoServerBuffer, ( void * ) pcStringReceived, xSendLength, portMAX_DELAY ); + + configASSERT( strcmp( pcStringToSend, pcStringReceived ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +static void prvEchoServer( void * pvParameters ) +{ + MessageBufferHandle_t xTempMessageBuffer; + size_t xReceivedLength; + char * pcReceivedString; + EchoMessageBuffers_t xMessageBuffers; + TickType_t xTimeOnEntering; + const TickType_t xTicksToBlock = pdMS_TO_TICKS( 250UL ); + + /* Prevent compiler warnings about unused parameters. */ + ( void ) pvParameters; + + /* Create the message buffer used to send data from the client to the server, + * and the message buffer used to echo the data from the server back to the + * client. */ + xMessageBuffers.xEchoClientBuffer = xMessageBufferCreate( mbMESSAGE_BUFFER_LENGTH_BYTES ); + xMessageBuffers.xEchoServerBuffer = xMessageBufferCreate( mbMESSAGE_BUFFER_LENGTH_BYTES ); + configASSERT( xMessageBuffers.xEchoClientBuffer ); + configASSERT( xMessageBuffers.xEchoServerBuffer ); + + /* Create the buffer into which received strings will be copied. */ + pcReceivedString = ( char * ) pvPortMalloc( mbMESSAGE_BUFFER_LENGTH_BYTES ); + configASSERT( pcReceivedString ); + + /* Don't expect to receive anything yet! */ + xTimeOnEntering = xTaskGetTickCount(); + xReceivedLength = xMessageBufferReceive( xMessageBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, mbMESSAGE_BUFFER_LENGTH_BYTES, xTicksToBlock ); + configASSERT( ( ( TickType_t ) ( xTaskGetTickCount() - xTimeOnEntering ) ) >= xTicksToBlock ); + configASSERT( xReceivedLength == 0 ); + ( void ) xTimeOnEntering; /* In case configASSERT() is not defined. */ + + /* Now the message buffers have been created the echo client task can be + * created. If this server task has the higher priority then the client task + * is created at the lower priority - if this server task has the lower + * priority then the client task is created at the higher priority. */ + if( uxTaskPriorityGet( NULL ) == mbLOWER_PRIORITY ) + { + xTaskCreate( prvEchoClient, "EchoClient", configMINIMAL_STACK_SIZE, ( void * ) &xMessageBuffers, mbHIGHER_PRIORITY, NULL ); + } + else + { + /* Here prvSingleTaskTests() performs various tests on a message buffer + * that was created dynamically. */ + prvSingleTaskTests( xMessageBuffers.xEchoClientBuffer ); + xTaskCreate( prvEchoClient, "EchoClient", configMINIMAL_STACK_SIZE, ( void * ) &xMessageBuffers, mbLOWER_PRIORITY, NULL ); + } + + for( ; ; ) + { + memset( pcReceivedString, 0x00, mbMESSAGE_BUFFER_LENGTH_BYTES ); + + /* Has any data been sent by the client? */ + xReceivedLength = xMessageBufferReceive( xMessageBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, mbMESSAGE_BUFFER_LENGTH_BYTES, portMAX_DELAY ); + + /* Should always receive data as max delay was used. */ + configASSERT( xReceivedLength > 0 ); + + /* Echo the received data back to the client. */ + xMessageBufferSend( xMessageBuffers.xEchoServerBuffer, ( void * ) pcReceivedString, xReceivedLength, portMAX_DELAY ); + + /* This message buffer is just created and deleted to ensure no memory + * leaks. */ + xTempMessageBuffer = xMessageBufferCreate( mbMESSAGE_BUFFER_LENGTH_BYTES ); + vMessageBufferDelete( xTempMessageBuffer ); + } +} +/*-----------------------------------------------------------*/ + +/* Tests within configRUN_ADDITIONAL_TESTS blocks only execute on larger + * platforms or have been added to pre-existing files that are already in use + * by other test projects without ensuring they don't cause those pre-existing + * projects to run out of program or data memory. */ +#if ( configRUN_ADDITIONAL_TESTS == 1 ) + + static void prvSpaceAvailableCoherenceActor( void * pvParameters ) + { + static char * cTxString = "12345"; + char cRxString[ mbCOHERENCE_TEST_BYTES_WRITTEN + 1 ]; /* +1 for NULL terminator. */ + + ( void ) pvParameters; + + for( ; ; ) + { + /* Add bytes to the buffer so the other task should see + * mbEXPECTED_FREE_BYTES_AFTER_WRITING_STRING bytes free. */ + xMessageBufferSend( xCoherenceTestMessageBuffer, ( void * ) cTxString, strlen( cTxString ), 0 ); + configASSERT( xMessageBufferSpacesAvailable( xCoherenceTestMessageBuffer ) == mbEXPECTED_FREE_BYTES_AFTER_WRITING_STRING ); + + /* Read out message again so the other task should read the full + * mbCOHERENCE_TEST_BUFFER_SIZE bytes free again. */ + memset( ( void * ) cRxString, 0x00, sizeof( cRxString ) ); + xMessageBufferReceive( xCoherenceTestMessageBuffer, ( void * ) cRxString, mbCOHERENCE_TEST_BYTES_WRITTEN, 0 ); + configASSERT( strcmp( cTxString, cRxString ) == 0 ); + } + } + /*-----------------------------------------------------------*/ + + static void prvSpaceAvailableCoherenceTester( void * pvParameters ) + { + size_t xSpaceAvailable; + BaseType_t xErrorFound = pdFALSE; + + ( void ) pvParameters; + + for( ; ; ) + { + /* This message buffer is only ever empty or contains 5 bytes. So all + * queries of its free space should result in one of the two values tested + * below. */ + xSpaceAvailable = xMessageBufferSpacesAvailable( xCoherenceTestMessageBuffer ); + + if( ( xSpaceAvailable == mbCOHERENCE_TEST_BUFFER_SIZE ) || + ( xSpaceAvailable == mbEXPECTED_FREE_BYTES_AFTER_WRITING_STRING ) ) + { + /* Only continue to increment the variable that shows this task + * is still executing if no errors have been found. */ + if( xErrorFound == pdFALSE ) + { + ulSizeCoherencyTestCycles++; + } + } + else + { + xErrorFound = pdTRUE; + } + + configASSERT( xErrorFound == pdFALSE ); + } + } + +#endif /* configRUN_ADDITIONAL_TESTS == 1 */ +/*-----------------------------------------------------------*/ + +BaseType_t xAreMessageBufferTasksStillRunning( void ) +{ + static uint32_t ulLastEchoLoopCounters[ mbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; + static uint32_t ulLastNonBlockingRxCounter = 0; + BaseType_t xReturn = pdPASS, x; + + for( x = 0; x < mbNUMBER_OF_ECHO_CLIENTS; x++ ) + { + if( ulLastEchoLoopCounters[ x ] == ulEchoLoopCounters[ x ] ) + { + xReturn = pdFAIL; + } + else + { + ulLastEchoLoopCounters[ x ] = ulEchoLoopCounters[ x ]; + } + } + + if( ulNonBlockingRxCounter == ulLastNonBlockingRxCounter ) + { + xReturn = pdFAIL; + } + else + { + ulLastNonBlockingRxCounter = ulNonBlockingRxCounter; + } + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + static uint32_t ulLastSenderLoopCounters[ mbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; + + for( x = 0; x < mbNUMBER_OF_SENDER_TASKS; x++ ) + { + if( ulLastSenderLoopCounters[ x ] == ulSenderLoopCounters[ x ] ) + { + xReturn = pdFAIL; + } + else + { + ulLastSenderLoopCounters[ x ] = ulSenderLoopCounters[ x ]; + } + } + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + #if ( configRUN_ADDITIONAL_TESTS == 1 ) + { + static uint32_t ullastSizeCoherencyTestCycles = 0UL; + + if( ullastSizeCoherencyTestCycles == ulSizeCoherencyTestCycles ) + { + xReturn = pdFAIL; + } + else + { + ullastSizeCoherencyTestCycles = ulSizeCoherencyTestCycles; + } + } + #endif /* if ( configRUN_ADDITIONAL_TESTS == 1 ) */ + + return xReturn; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/Common/Minimal/PollQ.c b/FreeRTOS/Demo/Common/Minimal/PollQ.c index daafafeb1..e49cd0620 100644 --- a/FreeRTOS/Demo/Common/Minimal/PollQ.c +++ b/FreeRTOS/Demo/Common/Minimal/PollQ.c @@ -1,222 +1,222 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 + +/* 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/QPeek.c b/FreeRTOS/Demo/Common/Minimal/QPeek.c index 14b1be790..ba33723f8 100644 --- a/FreeRTOS/Demo/Common/Minimal/QPeek.c +++ b/FreeRTOS/Demo/Common/Minimal/QPeek.c @@ -1,440 +1,440 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* - * Tests the behaviour when data is peeked from a queue when there are - * multiple tasks blocked on the queue. - */ - - -#include - -/* 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. */ - xErrorDetected = pdTRUE; - } - - /* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * Tests the behaviour when data is peeked from a queue when there are + * multiple tasks blocked on the queue. + */ + + +#include + +/* 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. */ + xErrorDetected = pdTRUE; + } + + /* 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/QueueOverwrite.c b/FreeRTOS/Demo/Common/Minimal/QueueOverwrite.c index 5221aa7f6..7bbb02a81 100644 --- a/FreeRTOS/Demo/Common/Minimal/QueueOverwrite.c +++ b/FreeRTOS/Demo/Common/Minimal/QueueOverwrite.c @@ -1,235 +1,235 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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; - } -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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; + } +} diff --git a/FreeRTOS/Demo/Common/Minimal/QueueSet.c b/FreeRTOS/Demo/Common/Minimal/QueueSet.c index 686c92c1b..9bdfb7310 100644 --- a/FreeRTOS/Demo/Common/Minimal/QueueSet.c +++ b/FreeRTOS/Demo/Common/Minimal/QueueSet.c @@ -1,1160 +1,1160 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 -#include - -/* Kernel includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" - -/* Demo includes. */ -#include "QueueSet.h" - - -#if ( configUSE_QUEUE_SETS == 1 ) /* Remove the tests if queue sets are not defined. */ - - -/* 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 ); - -/* - * Queue overwrites can only be performed on queues of length of one, requiring - * a special test function so a queue of length 1 can temporarily be added to a - * set. - */ - static void prvTestQueueOverwriteWithQueueSet( void ); - -/* - * Test the case where two queues within a set are written to with - * xQueueOverwrite(). - */ - static void prvTestQueueOverwriteOnTwoQueusInQueueSet( void ); - static void prvTestQueueOverwriteFromISROnTwoQueusInQueueSet( 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; - uint32_t ulTxValueSnapshot = ulISRTxValue; - - if( xQueueSendFromISR( xQueues[ xQueueToWriteTo ], ( void * ) &ulTxValueSnapshot, 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 prvTestQueueOverwriteWithQueueSet( void ) - { - uint32_t ulValueToSend = 0, ulValueReceived = 0; - QueueHandle_t xQueueHandle = NULL, xReceivedHandle = NULL; - const UBaseType_t xLengthOfOne = ( UBaseType_t ) 1; - - /* Create a queue that has a length of one - a requirement in order to call - * xQueueOverwrite. This will get deleted again when this test completes. */ - xQueueHandle = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); - configASSERT( xQueueHandle ); - - if( xQueueHandle != NULL ) - { - xQueueAddToSet( xQueueHandle, xQueueSet ); - - /* Add an item to the queue then ensure the queue set correctly - * indicates that one item is available, and that item is indeed the - * queue written to. */ - xQueueOverwrite( xQueueHandle, ( void * ) &ulValueToSend ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) - { - /* Expected one item in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle ) - { - /* Wrote to xQueueHandle so expected xQueueHandle to be the handle - * held in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Now overwrite the value in the queue and ensure the queue set state - * doesn't change as the number of items in the queues within the set have - * not changed. */ - ulValueToSend++; - xQueueOverwrite( xQueueHandle, ( void * ) &ulValueToSend ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) - { - /* Still expected one item in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle ) - { - /* Wrote to xQueueHandle so expected xQueueHandle to be the handle - * held in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Also ensure the value received from the queue is the overwritten - * value, not the value originally written. */ - xQueueReceive( xQueueHandle, &ulValueReceived, queuesetDONT_BLOCK ); - - if( ulValueReceived != ulValueToSend ) - { - /* Unexpected value received from the queue. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Should be anything in the queue set now. */ - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 0 ) - { - xQueueSetTasksStatus = pdFAIL; - } - - xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); - - if( xReceivedHandle != NULL ) - { - xQueueSetTasksStatus = pdFAIL; - } - - /* Clean up. */ - xQueueRemoveFromSet( xQueueHandle, xQueueSet ); - vQueueDelete( xQueueHandle ); - } - } -/*-----------------------------------------------------------*/ - - static void prvTestQueueOverwriteOnTwoQueusInQueueSet( void ) - { - uint32_t ulValueToSend1 = 1, ulValueToSend2 = 2UL, ulValueReceived = 0; - QueueHandle_t xQueueHandle1 = NULL, xQueueHandle2 = NULL, xReceivedHandle = NULL; - const UBaseType_t xLengthOfOne = ( UBaseType_t ) 1; - - /* Create two queues that have a length of one - a requirement in order to call - * xQueueOverwrite. These will get deleted again when this test completes. */ - xQueueHandle1 = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); - configASSERT( xQueueHandle1 ); - xQueueHandle2 = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); - configASSERT( xQueueHandle2 ); - - if( ( xQueueHandle1 != NULL ) && ( xQueueHandle2 != NULL ) ) - { - /* Add both queues to the queue set. */ - xQueueAddToSet( xQueueHandle1, xQueueSet ); - xQueueAddToSet( xQueueHandle2, xQueueSet ); - - /* Add an item using the first queue. */ - xQueueOverwrite( xQueueHandle1, ( void * ) &ulValueToSend1 ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) - { - /* Expected one item in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle1 ) - { - /* Wrote to xQueueHandle so expected xQueueHandle to be the handle - * held in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Next add an item to the second queue. */ - xQueueOverwrite( xQueueHandle2, ( void * ) &ulValueToSend2 ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* The head of the queue set should not have changed though. */ - xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle1 ) - { - /* Wrote to xQueueHandle so expected xQueueHandle to be the handle - * held in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Now overwrite the value in the queue and ensure the queue set state - * doesn't change as the number of items in the queues within the set have - * not changed. NOTE: after this queue 1 should hold ulValueToSend2 and queue - * 2 should hold the value ulValueToSend1. */ - xQueueOverwrite( xQueueHandle1, ( void * ) &ulValueToSend2 ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Still expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueueOverwrite( xQueueHandle2, ( void * ) &ulValueToSend1 ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Still expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Repeat the above to ensure the queue set state doesn't change. */ - xQueueOverwrite( xQueueHandle1, ( void * ) &ulValueToSend2 ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Still expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueueOverwrite( xQueueHandle2, ( void * ) &ulValueToSend1 ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Still expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Now when reading from the queue set we expect the handle to the first - * queue to be received first, and for that queue to hold ulValueToSend2 as the - * originally written value was overwritten. Likewise the second handle received - * from the set should be that of the second queue, and that queue should hold - * ulValueToSend1 as the originally written value was overwritten. */ - xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle1 ) - { - /* Wrote to xQueueHandle1 first so expected that handle to be read from - * the set first. */ - xQueueSetTasksStatus = pdFAIL; - } - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) - { - /* One value was read from the set, so now only expect a single value - * in the set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueueReceive( xReceivedHandle, &ulValueReceived, queuesetDONT_BLOCK ); - - if( ulValueReceived != ulValueToSend2 ) - { - /* Unexpected value received from the queue. ulValueToSend1 was written - * first, but then overwritten with ulValueToSend2; */ - xQueueSetTasksStatus = pdFAIL; - } - - xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle2 ) - { - /* xQueueHandle1 has already been removed from the set so expect only - * xQueueHandle2 to be left. */ - xQueueSetTasksStatus = pdFAIL; - } - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 0 ) - { - /* The last value was read from the set so don't expect any more. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueueReceive( xReceivedHandle, &ulValueReceived, queuesetDONT_BLOCK ); - - if( ulValueReceived != ulValueToSend1 ) - { - /* Unexpected value received from the queue. ulValueToSend2 was written - * first, but then overwritten with ulValueToSend1. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Should be anything in the queue set now. */ - xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); - - if( xReceivedHandle != NULL ) - { - xQueueSetTasksStatus = pdFAIL; - } - - /* Clean up. */ - xQueueRemoveFromSet( xQueueHandle1, xQueueSet ); - xQueueRemoveFromSet( xQueueHandle2, xQueueSet ); - vQueueDelete( xQueueHandle1 ); - vQueueDelete( xQueueHandle2 ); - } - } -/*-----------------------------------------------------------*/ - - static void prvTestQueueOverwriteFromISROnTwoQueusInQueueSet( void ) - { - uint32_t ulValueToSend1 = 1, ulValueToSend2 = 2UL, ulValueReceived = 0; - QueueHandle_t xQueueHandle1 = NULL, xQueueHandle2 = NULL, xReceivedHandle = NULL; - const UBaseType_t xLengthOfOne = ( UBaseType_t ) 1; - - /* Create two queues that have a length of one - a requirement in order to call - * xQueueOverwrite. These will get deleted again when this test completes. */ - xQueueHandle1 = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); - configASSERT( xQueueHandle1 ); - xQueueHandle2 = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); - configASSERT( xQueueHandle2 ); - - if( ( xQueueHandle1 != NULL ) && ( xQueueHandle2 != NULL ) ) - { - /* Add both queues to the queue set. */ - xQueueAddToSet( xQueueHandle1, xQueueSet ); - xQueueAddToSet( xQueueHandle2, xQueueSet ); - - /* Add an item using the first queue using the 'FromISR' version of the - * overwrite function. */ - xQueueOverwriteFromISR( xQueueHandle1, ( void * ) &ulValueToSend1, NULL ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) - { - /* Expected one item in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle1 ) - { - /* Wrote to xQueueHandle so expected xQueueHandle to be the handle - * held in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Next add an item to the second queue using the 'FromISR' version of the - * overwrite function. */ - xQueueOverwriteFromISR( xQueueHandle2, ( void * ) &ulValueToSend2, NULL ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* The head of the queue set should not have changed though. */ - xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle1 ) - { - /* Wrote to xQueueHandle so expected xQueueHandle to be the handle - * held in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Now overwrite the value in the queue and ensure the queue set state - * doesn't change as the number of items in the queues within the set have - * not changed. NOTE: after this queue 1 should hold ulValueToSend2 and queue - * 2 should hold the value ulValueToSend1. */ - xQueueOverwriteFromISR( xQueueHandle1, ( void * ) &ulValueToSend2, NULL ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Still expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueueOverwriteFromISR( xQueueHandle2, ( void * ) &ulValueToSend1, NULL ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Still expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Repeat the above to ensure the queue set state doesn't change. */ - xQueueOverwriteFromISR( xQueueHandle1, ( void * ) &ulValueToSend2, NULL ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Still expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueueOverwriteFromISR( xQueueHandle2, ( void * ) &ulValueToSend1, NULL ); - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) - { - /* Still expected two items in the queue set. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Now when reading from the queue set we expect the handle to the first - * queue to be received first, and for that queue to hold ulValueToSend2 as the - * originally written value was overwritten. Likewise the second handle received - * from the set should be that of the second queue, and that queue should hold - * ulValueToSend1 as the originally written value was overwritten. */ - xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle1 ) - { - /* Wrote to xQueueHandle1 first so expected that handle to be read from - * the set first. */ - xQueueSetTasksStatus = pdFAIL; - } - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) - { - /* One value was read from the set, so now only expect a single value - * in the set. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueueReceive( xReceivedHandle, &ulValueReceived, queuesetDONT_BLOCK ); - - if( ulValueReceived != ulValueToSend2 ) - { - /* Unexpected value received from the queue. ulValueToSend1 was written - * first, but then overwritten with ulValueToSend2; */ - xQueueSetTasksStatus = pdFAIL; - } - - xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); - - if( xReceivedHandle != xQueueHandle2 ) - { - /* xQueueHandle1 has already been removed from the set so expect only - * xQueueHandle2 to be left. */ - xQueueSetTasksStatus = pdFAIL; - } - - if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 0 ) - { - /* The last value was read from the set so don't expect any more. */ - xQueueSetTasksStatus = pdFAIL; - } - - xQueueReceive( xReceivedHandle, &ulValueReceived, queuesetDONT_BLOCK ); - - if( ulValueReceived != ulValueToSend1 ) - { - /* Unexpected value received from the queue. ulValueToSend2 was written - * first, but then overwritten with ulValueToSend1. */ - xQueueSetTasksStatus = pdFAIL; - } - - /* Should be anything in the queue set now. */ - xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); - - if( xReceivedHandle != NULL ) - { - xQueueSetTasksStatus = pdFAIL; - } - - /* Clean up. */ - xQueueRemoveFromSet( xQueueHandle1, xQueueSet ); - xQueueRemoveFromSet( xQueueHandle2, xQueueSet ); - vQueueDelete( xQueueHandle1 ); - vQueueDelete( xQueueHandle2 ); - } - } -/*-----------------------------------------------------------*/ - - 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; - } - - /* Testing the behaviour of queue sets when a queue overwrite operation is - * performed on a set member requires a special test as overwrites can only - * be performed on queues that have a length of 1. */ - prvTestQueueOverwriteWithQueueSet(); - - /* Test the case where two queues within a set are written to with - * xQueueOverwrite(). */ - prvTestQueueOverwriteOnTwoQueusInQueueSet(); - prvTestQueueOverwriteFromISROnTwoQueusInQueueSet(); - - /* In case any of the above have already indicated a failure. */ - configASSERT( 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; - } - -#endif /* ( configUSE_QUEUE_SETS == 1 ) */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "QueueSet.h" + + +#if ( configUSE_QUEUE_SETS == 1 ) /* Remove the tests if queue sets are not defined. */ + + +/* 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 ); + +/* + * Queue overwrites can only be performed on queues of length of one, requiring + * a special test function so a queue of length 1 can temporarily be added to a + * set. + */ + static void prvTestQueueOverwriteWithQueueSet( void ); + +/* + * Test the case where two queues within a set are written to with + * xQueueOverwrite(). + */ + static void prvTestQueueOverwriteOnTwoQueuesInQueueSet( void ); + static void prvTestQueueOverwriteFromISROnTwoQueuesInQueueSet( 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 xQueueSetTasksStatus 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 + * xAreQueueSetTasksStillRunning() 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; + uint32_t ulTxValueSnapshot = ulISRTxValue; + + if( xQueueSendFromISR( xQueues[ xQueueToWriteTo ], ( void * ) &ulTxValueSnapshot, 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 prvTestQueueOverwriteWithQueueSet( void ) + { + uint32_t ulValueToSend = 0, ulValueReceived = 0; + QueueHandle_t xQueueHandle = NULL, xReceivedHandle = NULL; + const UBaseType_t xLengthOfOne = ( UBaseType_t ) 1; + + /* Create a queue that has a length of one - a requirement in order to call + * xQueueOverwrite. This will get deleted again when this test completes. */ + xQueueHandle = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); + configASSERT( xQueueHandle ); + + if( xQueueHandle != NULL ) + { + xQueueAddToSet( xQueueHandle, xQueueSet ); + + /* Add an item to the queue then ensure the queue set correctly + * indicates that one item is available, and that item is indeed the + * queue written to. */ + xQueueOverwrite( xQueueHandle, ( void * ) &ulValueToSend ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) + { + /* Expected one item in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle ) + { + /* Wrote to xQueueHandle so expected xQueueHandle to be the handle + * held in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Now overwrite the value in the queue and ensure the queue set state + * doesn't change as the number of items in the queues within the set have + * not changed. */ + ulValueToSend++; + xQueueOverwrite( xQueueHandle, ( void * ) &ulValueToSend ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) + { + /* Still expected one item in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle ) + { + /* Wrote to xQueueHandle so expected xQueueHandle to be the handle + * held in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Also ensure the value received from the queue is the overwritten + * value, not the value originally written. */ + xQueueReceive( xQueueHandle, &ulValueReceived, queuesetDONT_BLOCK ); + + if( ulValueReceived != ulValueToSend ) + { + /* Unexpected value received from the queue. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Should be anything in the queue set now. */ + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 0 ) + { + xQueueSetTasksStatus = pdFAIL; + } + + xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); + + if( xReceivedHandle != NULL ) + { + xQueueSetTasksStatus = pdFAIL; + } + + /* Clean up. */ + xQueueRemoveFromSet( xQueueHandle, xQueueSet ); + vQueueDelete( xQueueHandle ); + } + } +/*-----------------------------------------------------------*/ + + static void prvTestQueueOverwriteOnTwoQueuesInQueueSet( void ) + { + uint32_t ulValueToSend1 = 1, ulValueToSend2 = 2UL, ulValueReceived = 0; + QueueHandle_t xQueueHandle1 = NULL, xQueueHandle2 = NULL, xReceivedHandle = NULL; + const UBaseType_t xLengthOfOne = ( UBaseType_t ) 1; + + /* Create two queues that have a length of one - a requirement in order to call + * xQueueOverwrite. These will get deleted again when this test completes. */ + xQueueHandle1 = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); + configASSERT( xQueueHandle1 ); + xQueueHandle2 = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); + configASSERT( xQueueHandle2 ); + + if( ( xQueueHandle1 != NULL ) && ( xQueueHandle2 != NULL ) ) + { + /* Add both queues to the queue set. */ + xQueueAddToSet( xQueueHandle1, xQueueSet ); + xQueueAddToSet( xQueueHandle2, xQueueSet ); + + /* Add an item using the first queue. */ + xQueueOverwrite( xQueueHandle1, ( void * ) &ulValueToSend1 ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) + { + /* Expected one item in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle1 ) + { + /* Wrote to xQueueHandle so expected xQueueHandle to be the handle + * held in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Next add an item to the second queue. */ + xQueueOverwrite( xQueueHandle2, ( void * ) &ulValueToSend2 ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* The head of the queue set should not have changed though. */ + xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle1 ) + { + /* Wrote to xQueueHandle so expected xQueueHandle to be the handle + * held in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Now overwrite the value in the queue and ensure the queue set state + * doesn't change as the number of items in the queues within the set have + * not changed. NOTE: after this queue 1 should hold ulValueToSend2 and queue + * 2 should hold the value ulValueToSend1. */ + xQueueOverwrite( xQueueHandle1, ( void * ) &ulValueToSend2 ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Still expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueueOverwrite( xQueueHandle2, ( void * ) &ulValueToSend1 ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Still expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Repeat the above to ensure the queue set state doesn't change. */ + xQueueOverwrite( xQueueHandle1, ( void * ) &ulValueToSend2 ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Still expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueueOverwrite( xQueueHandle2, ( void * ) &ulValueToSend1 ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Still expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Now when reading from the queue set we expect the handle to the first + * queue to be received first, and for that queue to hold ulValueToSend2 as the + * originally written value was overwritten. Likewise the second handle received + * from the set should be that of the second queue, and that queue should hold + * ulValueToSend1 as the originally written value was overwritten. */ + xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle1 ) + { + /* Wrote to xQueueHandle1 first so expected that handle to be read from + * the set first. */ + xQueueSetTasksStatus = pdFAIL; + } + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) + { + /* One value was read from the set, so now only expect a single value + * in the set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueueReceive( xReceivedHandle, &ulValueReceived, queuesetDONT_BLOCK ); + + if( ulValueReceived != ulValueToSend2 ) + { + /* Unexpected value received from the queue. ulValueToSend1 was written + * first, but then overwritten with ulValueToSend2; */ + xQueueSetTasksStatus = pdFAIL; + } + + xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle2 ) + { + /* xQueueHandle1 has already been removed from the set so expect only + * xQueueHandle2 to be left. */ + xQueueSetTasksStatus = pdFAIL; + } + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 0 ) + { + /* The last value was read from the set so don't expect any more. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueueReceive( xReceivedHandle, &ulValueReceived, queuesetDONT_BLOCK ); + + if( ulValueReceived != ulValueToSend1 ) + { + /* Unexpected value received from the queue. ulValueToSend2 was written + * first, but then overwritten with ulValueToSend1. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Should be anything in the queue set now. */ + xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); + + if( xReceivedHandle != NULL ) + { + xQueueSetTasksStatus = pdFAIL; + } + + /* Clean up. */ + xQueueRemoveFromSet( xQueueHandle1, xQueueSet ); + xQueueRemoveFromSet( xQueueHandle2, xQueueSet ); + vQueueDelete( xQueueHandle1 ); + vQueueDelete( xQueueHandle2 ); + } + } +/*-----------------------------------------------------------*/ + + static void prvTestQueueOverwriteFromISROnTwoQueuesInQueueSet( void ) + { + uint32_t ulValueToSend1 = 1, ulValueToSend2 = 2UL, ulValueReceived = 0; + QueueHandle_t xQueueHandle1 = NULL, xQueueHandle2 = NULL, xReceivedHandle = NULL; + const UBaseType_t xLengthOfOne = ( UBaseType_t ) 1; + + /* Create two queues that have a length of one - a requirement in order to call + * xQueueOverwrite. These will get deleted again when this test completes. */ + xQueueHandle1 = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); + configASSERT( xQueueHandle1 ); + xQueueHandle2 = xQueueCreate( xLengthOfOne, sizeof( uint32_t ) ); + configASSERT( xQueueHandle2 ); + + if( ( xQueueHandle1 != NULL ) && ( xQueueHandle2 != NULL ) ) + { + /* Add both queues to the queue set. */ + xQueueAddToSet( xQueueHandle1, xQueueSet ); + xQueueAddToSet( xQueueHandle2, xQueueSet ); + + /* Add an item using the first queue using the 'FromISR' version of the + * overwrite function. */ + xQueueOverwriteFromISR( xQueueHandle1, ( void * ) &ulValueToSend1, NULL ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) + { + /* Expected one item in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle1 ) + { + /* Wrote to xQueueHandle so expected xQueueHandle to be the handle + * held in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Next add an item to the second queue using the 'FromISR' version of the + * overwrite function. */ + xQueueOverwriteFromISR( xQueueHandle2, ( void * ) &ulValueToSend2, NULL ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* The head of the queue set should not have changed though. */ + xQueuePeek( xQueueSet, &xReceivedHandle, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle1 ) + { + /* Wrote to xQueueHandle so expected xQueueHandle to be the handle + * held in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Now overwrite the value in the queue and ensure the queue set state + * doesn't change as the number of items in the queues within the set have + * not changed. NOTE: after this queue 1 should hold ulValueToSend2 and queue + * 2 should hold the value ulValueToSend1. */ + xQueueOverwriteFromISR( xQueueHandle1, ( void * ) &ulValueToSend2, NULL ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Still expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueueOverwriteFromISR( xQueueHandle2, ( void * ) &ulValueToSend1, NULL ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Still expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Repeat the above to ensure the queue set state doesn't change. */ + xQueueOverwriteFromISR( xQueueHandle1, ( void * ) &ulValueToSend2, NULL ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Still expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueueOverwriteFromISR( xQueueHandle2, ( void * ) &ulValueToSend1, NULL ); + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 2 ) + { + /* Still expected two items in the queue set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Now when reading from the queue set we expect the handle to the first + * queue to be received first, and for that queue to hold ulValueToSend2 as the + * originally written value was overwritten. Likewise the second handle received + * from the set should be that of the second queue, and that queue should hold + * ulValueToSend1 as the originally written value was overwritten. */ + xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle1 ) + { + /* Wrote to xQueueHandle1 first so expected that handle to be read from + * the set first. */ + xQueueSetTasksStatus = pdFAIL; + } + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 1 ) + { + /* One value was read from the set, so now only expect a single value + * in the set. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueueReceive( xReceivedHandle, &ulValueReceived, queuesetDONT_BLOCK ); + + if( ulValueReceived != ulValueToSend2 ) + { + /* Unexpected value received from the queue. ulValueToSend1 was written + * first, but then overwritten with ulValueToSend2; */ + xQueueSetTasksStatus = pdFAIL; + } + + xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); + + if( xReceivedHandle != xQueueHandle2 ) + { + /* xQueueHandle1 has already been removed from the set so expect only + * xQueueHandle2 to be left. */ + xQueueSetTasksStatus = pdFAIL; + } + + if( uxQueueMessagesWaiting( xQueueSet ) != ( UBaseType_t ) 0 ) + { + /* The last value was read from the set so don't expect any more. */ + xQueueSetTasksStatus = pdFAIL; + } + + xQueueReceive( xReceivedHandle, &ulValueReceived, queuesetDONT_BLOCK ); + + if( ulValueReceived != ulValueToSend1 ) + { + /* Unexpected value received from the queue. ulValueToSend2 was written + * first, but then overwritten with ulValueToSend1. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Should be anything in the queue set now. */ + xReceivedHandle = xQueueSelectFromSet( xQueueSet, queuesetDONT_BLOCK ); + + if( xReceivedHandle != NULL ) + { + xQueueSetTasksStatus = pdFAIL; + } + + /* Clean up. */ + xQueueRemoveFromSet( xQueueHandle1, xQueueSet ); + xQueueRemoveFromSet( xQueueHandle2, xQueueSet ); + vQueueDelete( xQueueHandle1 ); + vQueueDelete( xQueueHandle2 ); + } + } +/*-----------------------------------------------------------*/ + + 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; + } + + /* Testing the behaviour of queue sets when a queue overwrite operation is + * performed on a set member requires a special test as overwrites can only + * be performed on queues that have a length of 1. */ + prvTestQueueOverwriteWithQueueSet(); + + /* Test the case where two queues within a set are written to with + * xQueueOverwrite(). */ + prvTestQueueOverwriteOnTwoQueuesInQueueSet(); + prvTestQueueOverwriteFromISROnTwoQueuesInQueueSet(); + + /* In case any of the above have already indicated a failure. */ + configASSERT( 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; + } + +#endif /* ( configUSE_QUEUE_SETS == 1 ) */ diff --git a/FreeRTOS/Demo/Common/Minimal/QueueSetPolling.c b/FreeRTOS/Demo/Common/Minimal/QueueSetPolling.c index 11d8000f5..cfed76607 100644 --- a/FreeRTOS/Demo/Common/Minimal/QueueSetPolling.c +++ b/FreeRTOS/Demo/Common/Minimal/QueueSetPolling.c @@ -1,182 +1,182 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 -#include - -/* Kernel includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" - -/* Demo includes. */ -#include "QueueSetPolling.h" - -#if ( configUSE_QUEUE_SETS == 1 ) /* Remove tests if queue sets are not defined. */ - -/* 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; - } -/*-----------------------------------------------------------*/ - - -#endif /* ( configUSE_QUEUE_SETS == 1 ) */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "QueueSetPolling.h" + +#if ( configUSE_QUEUE_SETS == 1 ) /* Remove tests if queue sets are not defined. */ + +/* 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 xQueueSetTasksStatus 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; + } +/*-----------------------------------------------------------*/ + + +#endif /* ( configUSE_QUEUE_SETS == 1 ) */ diff --git a/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c b/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c index a6e07ce5a..1e921e0f5 100644 --- a/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c +++ b/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c @@ -1,1113 +1,1113 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* - * Demonstrates how to create FreeRTOS objects using pre-allocated memory, - * rather than the normal dynamically allocated memory, and tests objects being - * created and deleted with both statically allocated memory and dynamically - * allocated memory. - * - * See http://www.FreeRTOS.org/Static_Vs_Dynamic_Memory_Allocation.html - */ - -/* Scheduler include files. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "semphr.h" -#include "event_groups.h" -#include "timers.h" - -/* Demo program include files. */ -#include "StaticAllocation.h" - -/* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */ -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - -/* The priority at which the task that performs the tests is created. */ - #define staticTASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) - -/* The length of the queue, in items, not bytes, used in the queue static - * allocation tests. */ - #define staticQUEUE_LENGTH_IN_ITEMS ( 5 ) - -/* A block time of 0 simply means "don't block". */ - #define staticDONT_BLOCK ( ( TickType_t ) 0 ) - -/* Binary semaphores have a maximum count of 1. */ - #define staticBINARY_SEMAPHORE_MAX_COUNT ( 1 ) - -/* The size of the stack used by the task that runs the tests. */ - #define staticCREATOR_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) - -/* The number of times the software timer will execute before stopping itself. */ - #define staticMAX_TIMER_CALLBACK_EXECUTIONS ( 5 ) - - -/*-----------------------------------------------------------*/ - -/* - * The task that repeatedly creates and deletes statically allocated tasks, and - * other RTOS objects. - */ - static void prvStaticallyAllocatedCreator( void * pvParameters ); - -/* - * The callback function used by the software timer that is repeatedly created - * and deleted using both static and dynamically allocated memory. - */ - static void prvTimerCallback( TimerHandle_t xExpiredTimer ); - -/* - * A task that is created and deleted multiple times, using both statically and - * dynamically allocated stack and TCB. - */ - static void prvStaticallyAllocatedTask( void * pvParameters ); - -/* - * A function that demonstrates and tests the API functions that create and - * delete tasks using both statically and dynamically allocated TCBs and stacks. - */ - static void prvCreateAndDeleteStaticallyAllocatedTasks( void ); - -/* - * A function that demonstrates and tests the API functions that create and - * delete event groups using both statically and dynamically allocated RAM. - */ - static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void ); - -/* - * A function that demonstrates and tests the API functions that create and - * delete queues using both statically and dynamically allocated RAM. - */ - static void prvCreateAndDeleteStaticallyAllocatedQueues( void ); - -/* - * A function that demonstrates and tests the API functions that create and - * delete binary semaphores using both statically and dynamically allocated RAM. - */ - static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void ); - -/* - * A function that demonstrates and tests the API functions that create and - * delete software timers using both statically and dynamically allocated RAM. - */ - static void prvCreateAndDeleteStaticallyAllocatedTimers( void ); - -/* - * A function that demonstrates and tests the API functions that create and - * delete mutexes using both statically and dynamically allocated RAM. - */ - static void prvCreateAndDeleteStaticallyAllocatedMutexes( void ); - -/* - * A function that demonstrates and tests the API functions that create and - * delete counting semaphores using both statically and dynamically allocated - * RAM. - */ - static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void ); - -/* - * A function that demonstrates and tests the API functions that create and - * delete recursive mutexes using both statically and dynamically allocated RAM. - */ - static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void ); - -/* - * Utility function to create pseudo random numbers. - */ - static UBaseType_t prvRand( void ); - -/* - * The task that creates and deletes other tasks has to delay occasionally to - * ensure lower priority tasks are not starved of processing time. A pseudo - * random delay time is used just to add a little bit of randomisation into the - * execution pattern. prvGetNextDelayTime() generates the pseudo random delay. - */ - static TickType_t prvGetNextDelayTime( void ); - -/* - * Checks the basic operation of a queue after it has been created. - */ - static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue ); - -/* - * Checks the basic operation of a recursive mutex after it has been created. - */ - static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore ); - -/* - * Checks the basic operation of a binary semaphore after it has been created. - */ - static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, - UBaseType_t uxMaxCount ); - -/* - * Checks the basic operation of an event group after it has been created. - */ - static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup ); - -/*-----------------------------------------------------------*/ - -/* StaticTask_t is a publicly accessible structure that has the same size and - * alignment requirements as the real TCB structure. It is provided as a mechanism - * for applications to know the size of the TCB (which is dependent on the - * architecture and configuration file settings) without breaking the strict data - * hiding policy by exposing the real TCB. This StaticTask_t variable is passed - * into the xTaskCreateStatic() function that creates the - * prvStaticallyAllocatedCreator() task, and will hold the TCB of the created - * tasks. */ - static StaticTask_t xCreatorTaskTCBBuffer; - -/* This is the stack that will be used by the prvStaticallyAllocatedCreator() - * task, which is itself created using statically allocated buffers (so without any - * dynamic memory allocation). */ - static StackType_t uxCreatorTaskStackBuffer[ staticCREATOR_TASK_STACK_SIZE ]; - -/* Used by the pseudo random number generating function. */ - static uint32_t ulNextRand = 0; - -/* Used so a check task can ensure this test is still executing, and not - * stalled. */ - static volatile UBaseType_t uxCycleCounter = 0; - -/* A variable that gets set to pdTRUE if an error is detected. */ - static volatile BaseType_t xErrorOccurred = pdFALSE; - -/*-----------------------------------------------------------*/ - - void vStartStaticallyAllocatedTasks( void ) - { - /* Create a single task, which then repeatedly creates and deletes the other - * RTOS objects using both statically and dynamically allocated RAM. */ - xTaskCreateStatic( prvStaticallyAllocatedCreator, /* The function that implements the task being created. */ - "StatCreate", /* Text name for the task - not used by the RTOS, its just to assist debugging. */ - staticCREATOR_TASK_STACK_SIZE, /* Size of the buffer passed in as the stack - in words, not bytes! */ - NULL, /* Parameter passed into the task - not used in this case. */ - staticTASK_PRIORITY, /* Priority of the task. */ - &( uxCreatorTaskStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */ - &xCreatorTaskTCBBuffer ); /* The variable that will hold the task's TCB. */ - } -/*-----------------------------------------------------------*/ - - static void prvStaticallyAllocatedCreator( void * pvParameters ) - { - /* Avoid compiler warnings. */ - ( void ) pvParameters; - - for( ; ; ) - { - /* Loop, running functions that create and delete the various RTOS - * objects that can be optionally created using either static or dynamic - * memory allocation. */ - prvCreateAndDeleteStaticallyAllocatedTasks(); - prvCreateAndDeleteStaticallyAllocatedQueues(); - - /* Delay to ensure lower priority tasks get CPU time, and increment the - * cycle counter so a 'check' task can determine that this task is still - * executing. */ - vTaskDelay( prvGetNextDelayTime() ); - uxCycleCounter++; - - prvCreateAndDeleteStaticallyAllocatedBinarySemaphores(); - prvCreateAndDeleteStaticallyAllocatedCountingSemaphores(); - - vTaskDelay( prvGetNextDelayTime() ); - uxCycleCounter++; - - prvCreateAndDeleteStaticallyAllocatedMutexes(); - prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes(); - - vTaskDelay( prvGetNextDelayTime() ); - uxCycleCounter++; - - prvCreateAndDeleteStaticallyAllocatedEventGroups(); - prvCreateAndDeleteStaticallyAllocatedTimers(); - } - } -/*-----------------------------------------------------------*/ - - static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void ) - { - SemaphoreHandle_t xSemaphore; - const UBaseType_t uxMaxCount = ( UBaseType_t ) 10; - -/* StaticSemaphore_t is a publicly accessible structure that has the same size - * and alignment requirements as the real semaphore structure. It is provided as a - * mechanism for applications to know the size of the semaphore (which is dependent - * on the architecture and configuration file settings) without breaking the strict - * data hiding policy by exposing the real semaphore internals. This - * StaticSemaphore_t variable is passed into the xSemaphoreCreateCountingStatic() - * function calls within this function. NOTE: In most usage scenarios now it is - * faster and more memory efficient to use a direct to task notification instead of - * a counting semaphore. http://www.freertos.org/RTOS-task-notifications.html */ - StaticSemaphore_t xSemaphoreBuffer; - - /* Create the semaphore. xSemaphoreCreateCountingStatic() has one more - * parameter than the usual xSemaphoreCreateCounting() function. The parameter - * is a pointer to the pre-allocated StaticSemaphore_t structure, which will - * hold information on the semaphore in an anonymous way. If the pointer is - * passed as NULL then the structure will be allocated dynamically, just as - * when xSemaphoreCreateCounting() is called. */ - xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, 0, &xSemaphoreBuffer ); - - /* The semaphore handle should equal the static semaphore structure passed - * into the xSemaphoreCreateBinaryStatic() function. */ - configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); - - /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ - prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount ); - - /* Delete the semaphore again so the buffers can be reused. */ - vSemaphoreDelete( xSemaphore ); - - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - /* Now do the same but using dynamically allocated buffers to ensure the - * delete functions are working correctly in both the static and dynamic - * allocation cases. */ - xSemaphore = xSemaphoreCreateCounting( uxMaxCount, 0 ); - configASSERT( xSemaphore != NULL ); - prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount ); - vSemaphoreDelete( xSemaphore ); - } - #endif - } -/*-----------------------------------------------------------*/ - - static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void ) - { - SemaphoreHandle_t xSemaphore; - -/* StaticSemaphore_t is a publicly accessible structure that has the same size - * and alignment requirements as the real semaphore structure. It is provided as a - * mechanism for applications to know the size of the semaphore (which is dependent - * on the architecture and configuration file settings) without breaking the strict - * data hiding policy by exposing the real semaphore internals. This - * StaticSemaphore_t variable is passed into the - * xSemaphoreCreateRecursiveMutexStatic() function calls within this function. */ - StaticSemaphore_t xSemaphoreBuffer; - - /* Create the semaphore. xSemaphoreCreateRecursiveMutexStatic() has one - * more parameter than the usual xSemaphoreCreateRecursiveMutex() function. - * The parameter is a pointer to the pre-allocated StaticSemaphore_t structure, - * which will hold information on the semaphore in an anonymous way. If the - * pointer is passed as NULL then the structure will be allocated dynamically, - * just as when xSemaphoreCreateRecursiveMutex() is called. */ - xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xSemaphoreBuffer ); - - /* The semaphore handle should equal the static semaphore structure passed - * into the xSemaphoreCreateBinaryStatic() function. */ - configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); - - /* Ensure the semaphore passes a few sanity checks as a valid - * recursive semaphore. */ - prvSanityCheckCreatedRecursiveMutex( xSemaphore ); - - /* Delete the semaphore again so the buffers can be reused. */ - vSemaphoreDelete( xSemaphore ); - - /* Now do the same using dynamically allocated buffers to ensure the delete - * functions are working correctly in both the static and dynamic memory - * allocation cases. */ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - xSemaphore = xSemaphoreCreateRecursiveMutex(); - configASSERT( xSemaphore != NULL ); - prvSanityCheckCreatedRecursiveMutex( xSemaphore ); - vSemaphoreDelete( xSemaphore ); - } - #endif - } -/*-----------------------------------------------------------*/ - - static void prvCreateAndDeleteStaticallyAllocatedQueues( void ) - { - QueueHandle_t xQueue; - -/* StaticQueue_t is a publicly accessible structure that has the same size and - * alignment requirements as the real queue structure. It is provided as a - * mechanism for applications to know the size of the queue (which is dependent on - * the architecture and configuration file settings) without breaking the strict - * data hiding policy by exposing the real queue internals. This StaticQueue_t - * variable is passed into the xQueueCreateStatic() function calls within this - * function. */ - static StaticQueue_t xStaticQueue; - -/* The queue storage area must be large enough to hold the maximum number of - * items it is possible for the queue to hold at any one time, which equals the - * queue length (in items, not bytes) multiplied by the size of each item. In this - * case the queue will hold staticQUEUE_LENGTH_IN_ITEMS 64-bit items. See - * https://www.FreeRTOS.org/Embedded-RTOS-Queues.html */ - static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ]; - - /* Create the queue. xQueueCreateStatic() has two more parameters than the - * usual xQueueCreate() function. The first new parameter is a pointer to the - * pre-allocated queue storage area. The second new parameter is a pointer to - * the StaticQueue_t structure that will hold the queue state information in - * an anonymous way. If the two pointers are passed as NULL then the data - * will be allocated dynamically as if xQueueCreate() had been called. */ - xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */ - sizeof( uint64_t ), /* The size of each item. */ - ucQueueStorageArea, /* The buffer used to hold items within the queue. */ - &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */ - - /* The queue handle should equal the static queue structure passed into the - * xQueueCreateStatic() function. */ - configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue ); - - /* Ensure the queue passes a few sanity checks as a valid queue. */ - prvSanityCheckCreatedQueue( xQueue ); - - /* Delete the queue again so the buffers can be reused. */ - vQueueDelete( xQueue ); - - /* Now do the same using a dynamically allocated queue to ensure the delete - * function is working correctly in both the static and dynamic memory - * allocation cases. */ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - xQueue = xQueueCreate( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */ - sizeof( uint64_t ) ); /* The size of each item. */ - - /* The queue handle should equal the static queue structure passed into the - * xQueueCreateStatic() function. */ - configASSERT( xQueue != NULL ); - - /* Ensure the queue passes a few sanity checks as a valid queue. */ - prvSanityCheckCreatedQueue( xQueue ); - - /* Delete the queue again so the buffers can be reused. */ - vQueueDelete( xQueue ); - } - #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ - } -/*-----------------------------------------------------------*/ - - static void prvCreateAndDeleteStaticallyAllocatedMutexes( void ) - { - SemaphoreHandle_t xSemaphore; - BaseType_t xReturned; - -/* StaticSemaphore_t is a publicly accessible structure that has the same size - * and alignment requirements as the real semaphore structure. It is provided as a - * mechanism for applications to know the size of the semaphore (which is dependent - * on the architecture and configuration file settings) without breaking the strict - * data hiding policy by exposing the real semaphore internals. This - * StaticSemaphore_t variable is passed into the xSemaphoreCreateMutexStatic() - * function calls within this function. */ - StaticSemaphore_t xSemaphoreBuffer; - - /* Create the semaphore. xSemaphoreCreateMutexStatic() has one more - * parameter than the usual xSemaphoreCreateMutex() function. The parameter - * is a pointer to the pre-allocated StaticSemaphore_t structure, which will - * hold information on the semaphore in an anonymous way. If the pointer is - * passed as NULL then the structure will be allocated dynamically, just as - * when xSemaphoreCreateMutex() is called. */ - xSemaphore = xSemaphoreCreateMutexStatic( &xSemaphoreBuffer ); - - /* The semaphore handle should equal the static semaphore structure passed - * into the xSemaphoreCreateMutexStatic() function. */ - configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); - - /* Take the mutex so the mutex is in the state expected by the - * prvSanityCheckCreatedSemaphore() function. */ - xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - - /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ - prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); - - /* Delete the semaphore again so the buffers can be reused. */ - vSemaphoreDelete( xSemaphore ); - - /* Now do the same using a dynamically allocated mutex to ensure the delete - * function is working correctly in both the static and dynamic allocation - * cases. */ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - xSemaphore = xSemaphoreCreateMutex(); - - /* The semaphore handle should equal the static semaphore structure - * passed into the xSemaphoreCreateMutexStatic() function. */ - configASSERT( xSemaphore != NULL ); - - /* Take the mutex so the mutex is in the state expected by the - * prvSanityCheckCreatedSemaphore() function. */ - xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - - /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ - prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); - - /* Delete the semaphore again so the buffers can be reused. */ - vSemaphoreDelete( xSemaphore ); - } - #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ - } -/*-----------------------------------------------------------*/ - - static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void ) - { - SemaphoreHandle_t xSemaphore; - -/* StaticSemaphore_t is a publicly accessible structure that has the same size -* and alignment requirements as the real semaphore structure. It is provided as a -* mechanism for applications to know the size of the semaphore (which is dependent -* on the architecture and configuration file settings) without breaking the strict -* data hiding policy by exposing the real semaphore internals. This -* StaticSemaphore_t variable is passed into the xSemaphoreCreateBinaryStatic() -* function calls within this function. NOTE: In most usage scenarios now it is -* faster and more memory efficient to use a direct to task notification instead of -* a binary semaphore. http://www.freertos.org/RTOS-task-notifications.html */ - StaticSemaphore_t xSemaphoreBuffer; - - /* Create the semaphore. xSemaphoreCreateBinaryStatic() has one more - * parameter than the usual xSemaphoreCreateBinary() function. The parameter - * is a pointer to the pre-allocated StaticSemaphore_t structure, which will - * hold information on the semaphore in an anonymous way. If the pointer is - * passed as NULL then the structure will be allocated dynamically, just as - * when xSemaphoreCreateBinary() is called. */ - xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer ); - - /* The semaphore handle should equal the static semaphore structure passed - * into the xSemaphoreCreateBinaryStatic() function. */ - configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); - - /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ - prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); - - /* Delete the semaphore again so the buffers can be reused. */ - vSemaphoreDelete( xSemaphore ); - - /* Now do the same using a dynamically allocated semaphore to check the - * delete function is working correctly in both the static and dynamic - * allocation cases. */ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - xSemaphore = xSemaphoreCreateBinary(); - configASSERT( xSemaphore != NULL ); - prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); - vSemaphoreDelete( xSemaphore ); - } - #endif - - /* There isn't a static version of the old and deprecated - * vSemaphoreCreateBinary() macro (because its deprecated!), but check it is - * still functioning correctly. */ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - vSemaphoreCreateBinary( xSemaphore ); - - /* The macro starts with the binary semaphore available, but the test - * function expects it to be unavailable. */ - if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL ) - { - xErrorOccurred = pdTRUE; - } - - prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); - vSemaphoreDelete( xSemaphore ); - } - #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ - } -/*-----------------------------------------------------------*/ - - static void prvTimerCallback( TimerHandle_t xExpiredTimer ) - { - UBaseType_t * puxVariableToIncrement; - BaseType_t xReturned; - - /* The timer callback just demonstrates it is executing by incrementing a - * variable - the address of which is passed into the timer as its ID. Obtain - * the address of the variable to increment. */ - puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); - - /* Increment the variable to show the timer callback has executed. */ - ( *puxVariableToIncrement )++; - - /* If this callback has executed the required number of times, stop the - * timer. */ - if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS ) - { - /* This is called from a timer callback so must not block. See - * https://www.FreeRTOS.org/FreeRTOS-timers-xTimerStop.html */ - xReturned = xTimerStop( xExpiredTimer, staticDONT_BLOCK ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - } - } -/*-----------------------------------------------------------*/ - - static void prvCreateAndDeleteStaticallyAllocatedTimers( void ) - { - TimerHandle_t xTimer; - UBaseType_t uxVariableToIncrement; - const TickType_t xTimerPeriod = pdMS_TO_TICKS( 20 ); - BaseType_t xReturned; - -/* StaticTimer_t is a publicly accessible structure that has the same size - * and alignment requirements as the real timer structure. It is provided as a - * mechanism for applications to know the size of the timer structure (which is - * dependent on the architecture and configuration file settings) without breaking - * the strict data hiding policy by exposing the real timer internals. This - * StaticTimer_t variable is passed into the xTimerCreateStatic() function calls - * within this function. */ - StaticTimer_t xTimerBuffer; - - /* Create the software time. xTimerCreateStatic() has an extra parameter - * than the normal xTimerCreate() API function. The parameter is a pointer to - * the StaticTimer_t structure that will hold the software timer structure. If - * the parameter is passed as NULL then the structure will be allocated - * dynamically, just as if xTimerCreate() had been called. */ - xTimer = xTimerCreateStatic( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */ - xTimerPeriod, /* The period of the timer in ticks. */ - pdTRUE, /* This is an auto-reload timer. */ - ( void * ) &uxVariableToIncrement, /* The variable incremented by the test is passed into the timer callback using the timer ID. */ - prvTimerCallback, /* The function to execute when the timer expires. */ - &xTimerBuffer ); /* The buffer that will hold the software timer structure. */ - - /* The timer handle should equal the static timer structure passed into the - * xTimerCreateStatic() function. */ - configASSERT( xTimer == ( TimerHandle_t ) &xTimerBuffer ); - - /* Set the variable to 0, wait for a few timer periods to expire, then check - * the timer callback has incremented the variable to the expected value. */ - uxVariableToIncrement = 0; - - /* This is a low priority so a block time should not be needed. */ - xReturned = xTimerStart( xTimer, staticDONT_BLOCK ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - - vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS ); - - /* By now the timer should have expired staticMAX_TIMER_CALLBACK_EXECUTIONS - * times, and then stopped itself. */ - if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS ) - { - xErrorOccurred = pdTRUE; - } - - /* Finished with the timer, delete it. */ - xReturned = xTimerDelete( xTimer, staticDONT_BLOCK ); - - /* Again, as this is a low priority task it is expected that the timer - * command will have been sent even without a block time being used. */ - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - - /* Just to show the check task that this task is still executing. */ - uxCycleCounter++; - - /* Now do the same using a dynamically allocated software timer to ensure - * the delete function is working correctly in both the static and dynamic - * allocation cases. */ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - xTimer = xTimerCreate( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */ - xTimerPeriod, /* The period of the timer in ticks. */ - pdTRUE, /* This is an auto-reload timer. */ - ( void * ) &uxVariableToIncrement, /* The variable incremented by the test is passed into the timer callback using the timer ID. */ - prvTimerCallback ); /* The function to execute when the timer expires. */ - - configASSERT( xTimer != NULL ); - - uxVariableToIncrement = 0; - xReturned = xTimerStart( xTimer, staticDONT_BLOCK ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - - vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS ); - - if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS ) - { - xErrorOccurred = pdTRUE; - } - - xReturned = xTimerDelete( xTimer, staticDONT_BLOCK ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - } - #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ - } -/*-----------------------------------------------------------*/ - - static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void ) - { - EventGroupHandle_t xEventGroup; - -/* 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 calls within this function. */ - StaticEventGroup_t xEventGroupBuffer; - - /* Create the event group. xEventGroupCreateStatic() has an extra parameter - * than the normal xEventGroupCreate() API function. The parameter is a - * pointer to the StaticEventGroup_t structure that will hold the event group - * structure. */ - xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); - - /* The event group handle should equal the static event group structure - * passed into the xEventGroupCreateStatic() function. */ - configASSERT( xEventGroup == ( EventGroupHandle_t ) &xEventGroupBuffer ); - - /* Ensure the event group passes a few sanity checks as a valid event - * group. */ - prvSanityCheckCreatedEventGroup( xEventGroup ); - - /* Delete the event group again so the buffers can be reused. */ - vEventGroupDelete( xEventGroup ); - - /* Now do the same using a dynamically allocated event group to ensure the - * delete function is working correctly in both the static and dynamic - * allocation cases. */ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - xEventGroup = xEventGroupCreate(); - configASSERT( xEventGroup != NULL ); - prvSanityCheckCreatedEventGroup( xEventGroup ); - vEventGroupDelete( xEventGroup ); - } - #endif - } -/*-----------------------------------------------------------*/ - - static void prvCreateAndDeleteStaticallyAllocatedTasks( void ) - { - TaskHandle_t xCreatedTask; - -/* The variable that will hold the TCB of tasks created by this function. See - * the comments above the declaration of the xCreatorTaskTCBBuffer variable for - * more information. NOTE: This is not static so relies on the tasks that use it - * being deleted before this function returns and deallocates its stack. That will - * only be the case if configUSE_PREEMPTION is set to 1. */ - StaticTask_t xTCBBuffer; - -/* This buffer that will be used as the stack of tasks created by this function. - * See the comments above the declaration of the uxCreatorTaskStackBuffer[] array - * above for more information. */ - static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ]; - - /* Create the task. xTaskCreateStatic() has two more parameters than - * the usual xTaskCreate() function. The first new parameter is a pointer to - * the pre-allocated stack. The second new parameter is a pointer to the - * StaticTask_t structure that will hold the task's TCB. If both pointers are - * passed as NULL then the respective object will be allocated dynamically as - * if xTaskCreate() had been called. */ - xCreatedTask = xTaskCreateStatic( - prvStaticallyAllocatedTask, /* Function that implements the task. */ - "Static", /* Human readable name for the task. */ - configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */ - NULL, /* Parameter to pass into the task. */ - uxTaskPriorityGet( NULL ) + 1, /* The priority of the task. */ - &( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */ - &xTCBBuffer ); /* The variable that will hold that task's TCB. */ - - /* Check the task was created correctly, then delete the task. */ - if( xCreatedTask == NULL ) - { - xErrorOccurred = pdTRUE; - } - else if( eTaskGetState( xCreatedTask ) != eSuspended ) - { - /* The created task had a higher priority so should have executed and - * suspended itself by now. */ - xErrorOccurred = pdTRUE; - } - else - { - vTaskDelete( xCreatedTask ); - } - - /* Now do the same using a dynamically allocated task to ensure the delete - * function is working correctly in both the static and dynamic allocation - * cases. */ - #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - BaseType_t xReturned; - - xReturned = xTaskCreate( - prvStaticallyAllocatedTask, /* Function that implements the task - the same function is used but is actually dynamically allocated this time. */ - "Static", /* Human readable name for the task. */ - configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */ - NULL, /* Parameter to pass into the task. */ - uxTaskPriorityGet( NULL ) + 1, /* The priority of the task. */ - &xCreatedTask ); /* Handle of the task being created. */ - - if( eTaskGetState( xCreatedTask ) != eSuspended ) - { - xErrorOccurred = pdTRUE; - } - - configASSERT( xReturned == pdPASS ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - - vTaskDelete( xCreatedTask ); - } - #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ - } -/*-----------------------------------------------------------*/ - - static void prvStaticallyAllocatedTask( void * pvParameters ) - { - ( void ) pvParameters; - - /* The created task just suspends itself to wait to get deleted. The task - * that creates this task checks this task is in the expected Suspended state - * before deleting it. */ - vTaskSuspend( NULL ); - } -/*-----------------------------------------------------------*/ - - static UBaseType_t prvRand( void ) - { - const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL; - - /* Utility function to generate a pseudo random number. */ - ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement; - return( ( ulNextRand >> 16UL ) & 0x7fffUL ); - } -/*-----------------------------------------------------------*/ - - static TickType_t prvGetNextDelayTime( void ) - { - TickType_t xNextDelay; - const TickType_t xMaxDelay = pdMS_TO_TICKS( ( TickType_t ) 150 ); - const TickType_t xMinDelay = pdMS_TO_TICKS( ( TickType_t ) 75 ); - const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 ); - - /* Generate the next delay time. This is kept within a narrow band so as - * not to disturb the timing of other tests - but does add in some pseudo - * randomisation into the tests. */ - do - { - xNextDelay = prvRand() % xMaxDelay; - - /* Just in case this loop is executed lots of times. */ - vTaskDelay( xTinyDelay ); - } while( xNextDelay < xMinDelay ); - - return xNextDelay; - } -/*-----------------------------------------------------------*/ - - static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup ) - { - EventBits_t xEventBits; - const EventBits_t xFirstTestBits = ( EventBits_t ) 0xaa, xSecondTestBits = ( EventBits_t ) 0x55; - - /* The event group should not have any bits set yet. */ - xEventBits = xEventGroupGetBits( xEventGroup ); - - if( xEventBits != ( EventBits_t ) 0 ) - { - xErrorOccurred = pdTRUE; - } - - /* Some some bits, then read them back to check they are as expected. */ - xEventGroupSetBits( xEventGroup, xFirstTestBits ); - - xEventBits = xEventGroupGetBits( xEventGroup ); - - if( xEventBits != xFirstTestBits ) - { - xErrorOccurred = pdTRUE; - } - - xEventGroupSetBits( xEventGroup, xSecondTestBits ); - - xEventBits = xEventGroupGetBits( xEventGroup ); - - if( xEventBits != ( xFirstTestBits | xSecondTestBits ) ) - { - xErrorOccurred = pdTRUE; - } - - /* Finally try clearing some bits too and check that operation proceeds as - * expected. */ - xEventGroupClearBits( xEventGroup, xFirstTestBits ); - - xEventBits = xEventGroupGetBits( xEventGroup ); - - if( xEventBits != xSecondTestBits ) - { - xErrorOccurred = pdTRUE; - } - } -/*-----------------------------------------------------------*/ - - static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, - UBaseType_t uxMaxCount ) - { - BaseType_t xReturned; - UBaseType_t x; - const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 ); - TickType_t xTickCount; - - /* The binary semaphore should start 'empty', so a call to xSemaphoreTake() - * should fail. */ - xTickCount = xTaskGetTickCount(); - xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime ); - - if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime ) - { - /* Did not block on the semaphore as long as expected. */ - xErrorOccurred = pdTRUE; - } - - if( xReturned != pdFAIL ) - { - xErrorOccurred = pdTRUE; - } - - /* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount - * times. */ - for( x = 0; x < uxMaxCount; x++ ) - { - xReturned = xSemaphoreGive( xSemaphore ); - - if( xReturned == pdFAIL ) - { - xErrorOccurred = pdTRUE; - } - } - - /* Giving the semaphore again should fail, as it is 'full'. */ - xReturned = xSemaphoreGive( xSemaphore ); - - if( xReturned != pdFAIL ) - { - xErrorOccurred = pdTRUE; - } - - configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount ); - - /* Should now be possible to 'take' the semaphore up to a maximum of - * uxMaxCount times without blocking. */ - for( x = 0; x < uxMaxCount; x++ ) - { - xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK ); - - if( xReturned == pdFAIL ) - { - xErrorOccurred = pdTRUE; - } - } - - /* Back to the starting condition, where the semaphore should not be - * available. */ - xTickCount = xTaskGetTickCount(); - xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime ); - - if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime ) - { - /* Did not block on the semaphore as long as expected. */ - xErrorOccurred = pdTRUE; - } - - if( xReturned != pdFAIL ) - { - xErrorOccurred = pdTRUE; - } - - configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 ); - } -/*-----------------------------------------------------------*/ - - static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue ) - { - uint64_t ull, ullRead; - BaseType_t xReturned, xLoop; - - /* This test is done twice to ensure the queue storage area wraps. */ - for( xLoop = 0; xLoop < 2; xLoop++ ) - { - /* A very basic test that the queue can be written to and read from as - * expected. First the queue should be empty. */ - xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK ); - - if( xReturned != errQUEUE_EMPTY ) - { - xErrorOccurred = pdTRUE; - } - - /* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS - * times. */ - for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ ) - { - xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - } - - /* Should not now be possible to write to the queue again. */ - xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK ); - - if( xReturned != errQUEUE_FULL ) - { - xErrorOccurred = pdTRUE; - } - - /* Now read back from the queue to ensure the data read back matches that - * written. */ - for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ ) - { - xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - - if( ullRead != ull ) - { - xErrorOccurred = pdTRUE; - } - } - - /* The queue should be empty again. */ - xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK ); - - if( xReturned != errQUEUE_EMPTY ) - { - xErrorOccurred = pdTRUE; - } - } - } -/*-----------------------------------------------------------*/ - - static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore ) - { - const BaseType_t xLoops = 5; - BaseType_t x, xReturned; - - /* A very basic test that the recursive semaphore behaved like a recursive - * semaphore. First the semaphore should not be able to be given, as it has not - * yet been taken. */ - xReturned = xSemaphoreGiveRecursive( xSemaphore ); - - if( xReturned != pdFAIL ) - { - xErrorOccurred = pdTRUE; - } - - /* Now it should be possible to take the mutex a number of times. */ - for( x = 0; x < xLoops; x++ ) - { - xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - } - - /* Should be possible to give the semaphore the same number of times as it - * was given in the loop above. */ - for( x = 0; x < xLoops; x++ ) - { - xReturned = xSemaphoreGiveRecursive( xSemaphore ); - - if( xReturned != pdPASS ) - { - xErrorOccurred = pdTRUE; - } - } - - /* No more gives should be possible though. */ - xReturned = xSemaphoreGiveRecursive( xSemaphore ); - - if( xReturned != pdFAIL ) - { - xErrorOccurred = pdTRUE; - } - } -/*-----------------------------------------------------------*/ - - BaseType_t xAreStaticAllocationTasksStillRunning( void ) - { - static UBaseType_t uxLastCycleCounter = 0; - BaseType_t xReturn; - - if( uxCycleCounter == uxLastCycleCounter ) - { - xErrorOccurred = pdTRUE; - } - else - { - uxLastCycleCounter = uxCycleCounter; - } - - if( xErrorOccurred != pdFALSE ) - { - xReturn = pdFAIL; - } - else - { - xReturn = pdPASS; - } - - return xReturn; - } -/*-----------------------------------------------------------*/ - -/* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */ -#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * Demonstrates how to create FreeRTOS objects using pre-allocated memory, + * rather than the normal dynamically allocated memory, and tests objects being + * created and deleted with both statically allocated memory and dynamically + * allocated memory. + * + * See http://www.FreeRTOS.org/Static_Vs_Dynamic_Memory_Allocation.html + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" +#include "event_groups.h" +#include "timers.h" + +/* Demo program include files. */ +#include "StaticAllocation.h" + +/* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + +/* The priority at which the task that performs the tests is created. */ + #define staticTASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) + +/* The length of the queue, in items, not bytes, used in the queue static + * allocation tests. */ + #define staticQUEUE_LENGTH_IN_ITEMS ( 5 ) + +/* A block time of 0 simply means "don't block". */ + #define staticDONT_BLOCK ( ( TickType_t ) 0 ) + +/* Binary semaphores have a maximum count of 1. */ + #define staticBINARY_SEMAPHORE_MAX_COUNT ( 1 ) + +/* The size of the stack used by the task that runs the tests. */ + #define staticCREATOR_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) + +/* The number of times the software timer will execute before stopping itself. */ + #define staticMAX_TIMER_CALLBACK_EXECUTIONS ( 5 ) + + +/*-----------------------------------------------------------*/ + +/* + * The task that repeatedly creates and deletes statically allocated tasks, and + * other RTOS objects. + */ + static void prvStaticallyAllocatedCreator( void * pvParameters ); + +/* + * The callback function used by the software timer that is repeatedly created + * and deleted using both static and dynamically allocated memory. + */ + static void prvTimerCallback( TimerHandle_t xExpiredTimer ); + +/* + * A task that is created and deleted multiple times, using both statically and + * dynamically allocated stack and TCB. + */ + static void prvStaticallyAllocatedTask( void * pvParameters ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete tasks using both statically and dynamically allocated TCBs and stacks. + */ + static void prvCreateAndDeleteStaticallyAllocatedTasks( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete event groups using both statically and dynamically allocated RAM. + */ + static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete queues using both statically and dynamically allocated RAM. + */ + static void prvCreateAndDeleteStaticallyAllocatedQueues( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete binary semaphores using both statically and dynamically allocated RAM. + */ + static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete software timers using both statically and dynamically allocated RAM. + */ + static void prvCreateAndDeleteStaticallyAllocatedTimers( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete mutexes using both statically and dynamically allocated RAM. + */ + static void prvCreateAndDeleteStaticallyAllocatedMutexes( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete counting semaphores using both statically and dynamically allocated + * RAM. + */ + static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete recursive mutexes using both statically and dynamically allocated RAM. + */ + static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void ); + +/* + * Utility function to create pseudo random numbers. + */ + static UBaseType_t prvRand( void ); + +/* + * The task that creates and deletes other tasks has to delay occasionally to + * ensure lower priority tasks are not starved of processing time. A pseudo + * random delay time is used just to add a little bit of randomisation into the + * execution pattern. prvGetNextDelayTime() generates the pseudo random delay. + */ + static TickType_t prvGetNextDelayTime( void ); + +/* + * Checks the basic operation of a queue after it has been created. + */ + static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue ); + +/* + * Checks the basic operation of a recursive mutex after it has been created. + */ + static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore ); + +/* + * Checks the basic operation of a binary semaphore after it has been created. + */ + static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, + UBaseType_t uxMaxCount ); + +/* + * Checks the basic operation of an event group after it has been created. + */ + static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup ); + +/*-----------------------------------------------------------*/ + +/* StaticTask_t is a publicly accessible structure that has the same size and + * alignment requirements as the real TCB structure. It is provided as a mechanism + * for applications to know the size of the TCB (which is dependent on the + * architecture and configuration file settings) without breaking the strict data + * hiding policy by exposing the real TCB. This StaticTask_t variable is passed + * into the xTaskCreateStatic() function that creates the + * prvStaticallyAllocatedCreator() task, and will hold the TCB of the created + * tasks. */ + static StaticTask_t xCreatorTaskTCBBuffer; + +/* This is the stack that will be used by the prvStaticallyAllocatedCreator() + * task, which is itself created using statically allocated buffers (so without any + * dynamic memory allocation). */ + static StackType_t uxCreatorTaskStackBuffer[ staticCREATOR_TASK_STACK_SIZE ]; + +/* Used by the pseudo random number generating function. */ + static uint32_t ulNextRand = 0; + +/* Used so a check task can ensure this test is still executing, and not + * stalled. */ + static volatile UBaseType_t uxCycleCounter = 0; + +/* A variable that gets set to pdTRUE if an error is detected. */ + static volatile BaseType_t xErrorOccurred = pdFALSE; + +/*-----------------------------------------------------------*/ + + void vStartStaticallyAllocatedTasks( void ) + { + /* Create a single task, which then repeatedly creates and deletes the other + * RTOS objects using both statically and dynamically allocated RAM. */ + xTaskCreateStatic( prvStaticallyAllocatedCreator, /* The function that implements the task being created. */ + "StatCreate", /* Text name for the task - not used by the RTOS, its just to assist debugging. */ + staticCREATOR_TASK_STACK_SIZE, /* Size of the buffer passed in as the stack - in words, not bytes! */ + NULL, /* Parameter passed into the task - not used in this case. */ + staticTASK_PRIORITY, /* Priority of the task. */ + &( uxCreatorTaskStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */ + &xCreatorTaskTCBBuffer ); /* The variable that will hold the task's TCB. */ + } +/*-----------------------------------------------------------*/ + + static void prvStaticallyAllocatedCreator( void * pvParameters ) + { + /* Avoid compiler warnings. */ + ( void ) pvParameters; + + for( ; ; ) + { + /* Loop, running functions that create and delete the various RTOS + * objects that can be optionally created using either static or dynamic + * memory allocation. */ + prvCreateAndDeleteStaticallyAllocatedTasks(); + prvCreateAndDeleteStaticallyAllocatedQueues(); + + /* Delay to ensure lower priority tasks get CPU time, and increment the + * cycle counter so a 'check' task can determine that this task is still + * executing. */ + vTaskDelay( prvGetNextDelayTime() ); + uxCycleCounter++; + + prvCreateAndDeleteStaticallyAllocatedBinarySemaphores(); + prvCreateAndDeleteStaticallyAllocatedCountingSemaphores(); + + vTaskDelay( prvGetNextDelayTime() ); + uxCycleCounter++; + + prvCreateAndDeleteStaticallyAllocatedMutexes(); + prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes(); + + vTaskDelay( prvGetNextDelayTime() ); + uxCycleCounter++; + + prvCreateAndDeleteStaticallyAllocatedEventGroups(); + prvCreateAndDeleteStaticallyAllocatedTimers(); + } + } +/*-----------------------------------------------------------*/ + + static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void ) + { + SemaphoreHandle_t xSemaphore; + const UBaseType_t uxMaxCount = ( UBaseType_t ) 10; + +/* StaticSemaphore_t is a publicly accessible structure that has the same size + * and alignment requirements as the real semaphore structure. It is provided as a + * mechanism for applications to know the size of the semaphore (which is dependent + * on the architecture and configuration file settings) without breaking the strict + * data hiding policy by exposing the real semaphore internals. This + * StaticSemaphore_t variable is passed into the xSemaphoreCreateCountingStatic() + * function calls within this function. NOTE: In most usage scenarios now it is + * faster and more memory efficient to use a direct to task notification instead of + * a counting semaphore. http://www.freertos.org/RTOS-task-notifications.html */ + StaticSemaphore_t xSemaphoreBuffer; + + /* Create the semaphore. xSemaphoreCreateCountingStatic() has one more + * parameter than the usual xSemaphoreCreateCounting() function. The parameter + * is a pointer to the pre-allocated StaticSemaphore_t structure, which will + * hold information on the semaphore in an anonymous way. If the pointer is + * passed as NULL then the structure will be allocated dynamically, just as + * when xSemaphoreCreateCounting() is called. */ + xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, 0, &xSemaphoreBuffer ); + + /* The semaphore handle should equal the static semaphore structure passed + * into the xSemaphoreCreateBinaryStatic() function. */ + configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); + + /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ + prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Now do the same but using dynamically allocated buffers to ensure the + * delete functions are working correctly in both the static and dynamic + * allocation cases. */ + xSemaphore = xSemaphoreCreateCounting( uxMaxCount, 0 ); + configASSERT( xSemaphore != NULL ); + prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount ); + vSemaphoreDelete( xSemaphore ); + } + #endif + } +/*-----------------------------------------------------------*/ + + static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void ) + { + SemaphoreHandle_t xSemaphore; + +/* StaticSemaphore_t is a publicly accessible structure that has the same size + * and alignment requirements as the real semaphore structure. It is provided as a + * mechanism for applications to know the size of the semaphore (which is dependent + * on the architecture and configuration file settings) without breaking the strict + * data hiding policy by exposing the real semaphore internals. This + * StaticSemaphore_t variable is passed into the + * xSemaphoreCreateRecursiveMutexStatic() function calls within this function. */ + StaticSemaphore_t xSemaphoreBuffer; + + /* Create the semaphore. xSemaphoreCreateRecursiveMutexStatic() has one + * more parameter than the usual xSemaphoreCreateRecursiveMutex() function. + * The parameter is a pointer to the pre-allocated StaticSemaphore_t structure, + * which will hold information on the semaphore in an anonymous way. If the + * pointer is passed as NULL then the structure will be allocated dynamically, + * just as when xSemaphoreCreateRecursiveMutex() is called. */ + xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xSemaphoreBuffer ); + + /* The semaphore handle should equal the static semaphore structure passed + * into the xSemaphoreCreateBinaryStatic() function. */ + configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); + + /* Ensure the semaphore passes a few sanity checks as a valid + * recursive semaphore. */ + prvSanityCheckCreatedRecursiveMutex( xSemaphore ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + + /* Now do the same using dynamically allocated buffers to ensure the delete + * functions are working correctly in both the static and dynamic memory + * allocation cases. */ + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xSemaphore = xSemaphoreCreateRecursiveMutex(); + configASSERT( xSemaphore != NULL ); + prvSanityCheckCreatedRecursiveMutex( xSemaphore ); + vSemaphoreDelete( xSemaphore ); + } + #endif + } +/*-----------------------------------------------------------*/ + + static void prvCreateAndDeleteStaticallyAllocatedQueues( void ) + { + QueueHandle_t xQueue; + +/* StaticQueue_t is a publicly accessible structure that has the same size and + * alignment requirements as the real queue structure. It is provided as a + * mechanism for applications to know the size of the queue (which is dependent on + * the architecture and configuration file settings) without breaking the strict + * data hiding policy by exposing the real queue internals. This StaticQueue_t + * variable is passed into the xQueueCreateStatic() function calls within this + * function. */ + static StaticQueue_t xStaticQueue; + +/* The queue storage area must be large enough to hold the maximum number of + * items it is possible for the queue to hold at any one time, which equals the + * queue length (in items, not bytes) multiplied by the size of each item. In this + * case the queue will hold staticQUEUE_LENGTH_IN_ITEMS 64-bit items. See + * https://www.FreeRTOS.org/Embedded-RTOS-Queues.html */ + static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ]; + + /* Create the queue. xQueueCreateStatic() has two more parameters than the + * usual xQueueCreate() function. The first new parameter is a pointer to the + * pre-allocated queue storage area. The second new parameter is a pointer to + * the StaticQueue_t structure that will hold the queue state information in + * an anonymous way. If the two pointers are passed as NULL then the data + * will be allocated dynamically as if xQueueCreate() had been called. */ + xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */ + sizeof( uint64_t ), /* The size of each item. */ + ucQueueStorageArea, /* The buffer used to hold items within the queue. */ + &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */ + + /* The queue handle should equal the static queue structure passed into the + * xQueueCreateStatic() function. */ + configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue ); + + /* Ensure the queue passes a few sanity checks as a valid queue. */ + prvSanityCheckCreatedQueue( xQueue ); + + /* Delete the queue again so the buffers can be reused. */ + vQueueDelete( xQueue ); + + /* Now do the same using a dynamically allocated queue to ensure the delete + * function is working correctly in both the static and dynamic memory + * allocation cases. */ + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xQueue = xQueueCreate( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */ + sizeof( uint64_t ) ); /* The size of each item. */ + + /* The queue handle should equal the static queue structure passed into the + * xQueueCreateStatic() function. */ + configASSERT( xQueue != NULL ); + + /* Ensure the queue passes a few sanity checks as a valid queue. */ + prvSanityCheckCreatedQueue( xQueue ); + + /* Delete the queue again so the buffers can be reused. */ + vQueueDelete( xQueue ); + } + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ + } +/*-----------------------------------------------------------*/ + + static void prvCreateAndDeleteStaticallyAllocatedMutexes( void ) + { + SemaphoreHandle_t xSemaphore; + BaseType_t xReturned; + +/* StaticSemaphore_t is a publicly accessible structure that has the same size + * and alignment requirements as the real semaphore structure. It is provided as a + * mechanism for applications to know the size of the semaphore (which is dependent + * on the architecture and configuration file settings) without breaking the strict + * data hiding policy by exposing the real semaphore internals. This + * StaticSemaphore_t variable is passed into the xSemaphoreCreateMutexStatic() + * function calls within this function. */ + StaticSemaphore_t xSemaphoreBuffer; + + /* Create the semaphore. xSemaphoreCreateMutexStatic() has one more + * parameter than the usual xSemaphoreCreateMutex() function. The parameter + * is a pointer to the pre-allocated StaticSemaphore_t structure, which will + * hold information on the semaphore in an anonymous way. If the pointer is + * passed as NULL then the structure will be allocated dynamically, just as + * when xSemaphoreCreateMutex() is called. */ + xSemaphore = xSemaphoreCreateMutexStatic( &xSemaphoreBuffer ); + + /* The semaphore handle should equal the static semaphore structure passed + * into the xSemaphoreCreateMutexStatic() function. */ + configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); + + /* Take the mutex so the mutex is in the state expected by the + * prvSanityCheckCreatedSemaphore() function. */ + xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + + /* Now do the same using a dynamically allocated mutex to ensure the delete + * function is working correctly in both the static and dynamic allocation + * cases. */ + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xSemaphore = xSemaphoreCreateMutex(); + + /* The semaphore handle should equal the static semaphore structure + * passed into the xSemaphoreCreateMutexStatic() function. */ + configASSERT( xSemaphore != NULL ); + + /* Take the mutex so the mutex is in the state expected by the + * prvSanityCheckCreatedSemaphore() function. */ + xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + } + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ + } +/*-----------------------------------------------------------*/ + + static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void ) + { + SemaphoreHandle_t xSemaphore; + +/* StaticSemaphore_t is a publicly accessible structure that has the same size +* and alignment requirements as the real semaphore structure. It is provided as a +* mechanism for applications to know the size of the semaphore (which is dependent +* on the architecture and configuration file settings) without breaking the strict +* data hiding policy by exposing the real semaphore internals. This +* StaticSemaphore_t variable is passed into the xSemaphoreCreateBinaryStatic() +* function calls within this function. NOTE: In most usage scenarios now it is +* faster and more memory efficient to use a direct to task notification instead of +* a binary semaphore. http://www.freertos.org/RTOS-task-notifications.html */ + StaticSemaphore_t xSemaphoreBuffer; + + /* Create the semaphore. xSemaphoreCreateBinaryStatic() has one more + * parameter than the usual xSemaphoreCreateBinary() function. The parameter + * is a pointer to the pre-allocated StaticSemaphore_t structure, which will + * hold information on the semaphore in an anonymous way. If the pointer is + * passed as NULL then the structure will be allocated dynamically, just as + * when xSemaphoreCreateBinary() is called. */ + xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer ); + + /* The semaphore handle should equal the static semaphore structure passed + * into the xSemaphoreCreateBinaryStatic() function. */ + configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); + + /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + + /* Now do the same using a dynamically allocated semaphore to check the + * delete function is working correctly in both the static and dynamic + * allocation cases. */ + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xSemaphore = xSemaphoreCreateBinary(); + configASSERT( xSemaphore != NULL ); + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + vSemaphoreDelete( xSemaphore ); + } + #endif + + /* There isn't a static version of the old and deprecated + * vSemaphoreCreateBinary() macro (because its deprecated!), but check it is + * still functioning correctly. */ + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + vSemaphoreCreateBinary( xSemaphore ); + + /* The macro starts with the binary semaphore available, but the test + * function expects it to be unavailable. */ + if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + vSemaphoreDelete( xSemaphore ); + } + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ + } +/*-----------------------------------------------------------*/ + + static void prvTimerCallback( TimerHandle_t xExpiredTimer ) + { + UBaseType_t * puxVariableToIncrement; + BaseType_t xReturned; + + /* The timer callback just demonstrates it is executing by incrementing a + * variable - the address of which is passed into the timer as its ID. Obtain + * the address of the variable to increment. */ + puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + + /* Increment the variable to show the timer callback has executed. */ + ( *puxVariableToIncrement )++; + + /* If this callback has executed the required number of times, stop the + * timer. */ + if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS ) + { + /* This is called from a timer callback so must not block. See + * https://www.FreeRTOS.org/FreeRTOS-timers-xTimerStop.html */ + xReturned = xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + } +/*-----------------------------------------------------------*/ + + static void prvCreateAndDeleteStaticallyAllocatedTimers( void ) + { + TimerHandle_t xTimer; + UBaseType_t uxVariableToIncrement; + const TickType_t xTimerPeriod = pdMS_TO_TICKS( 20 ); + BaseType_t xReturned; + +/* StaticTimer_t is a publicly accessible structure that has the same size + * and alignment requirements as the real timer structure. It is provided as a + * mechanism for applications to know the size of the timer structure (which is + * dependent on the architecture and configuration file settings) without breaking + * the strict data hiding policy by exposing the real timer internals. This + * StaticTimer_t variable is passed into the xTimerCreateStatic() function calls + * within this function. */ + StaticTimer_t xTimerBuffer; + + /* Create the software time. xTimerCreateStatic() has an extra parameter + * than the normal xTimerCreate() API function. The parameter is a pointer to + * the StaticTimer_t structure that will hold the software timer structure. If + * the parameter is passed as NULL then the structure will be allocated + * dynamically, just as if xTimerCreate() had been called. */ + xTimer = xTimerCreateStatic( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */ + xTimerPeriod, /* The period of the timer in ticks. */ + pdTRUE, /* This is an auto-reload timer. */ + ( void * ) &uxVariableToIncrement, /* The variable incremented by the test is passed into the timer callback using the timer ID. */ + prvTimerCallback, /* The function to execute when the timer expires. */ + &xTimerBuffer ); /* The buffer that will hold the software timer structure. */ + + /* The timer handle should equal the static timer structure passed into the + * xTimerCreateStatic() function. */ + configASSERT( xTimer == ( TimerHandle_t ) &xTimerBuffer ); + + /* Set the variable to 0, wait for a few timer periods to expire, then check + * the timer callback has incremented the variable to the expected value. */ + uxVariableToIncrement = 0; + + /* This is a low priority so a block time should not be needed. */ + xReturned = xTimerStart( xTimer, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS ); + + /* By now the timer should have expired staticMAX_TIMER_CALLBACK_EXECUTIONS + * times, and then stopped itself. */ + if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS ) + { + xErrorOccurred = pdTRUE; + } + + /* Finished with the timer, delete it. */ + xReturned = xTimerDelete( xTimer, staticDONT_BLOCK ); + + /* Again, as this is a low priority task it is expected that the timer + * command will have been sent even without a block time being used. */ + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Just to show the check task that this task is still executing. */ + uxCycleCounter++; + + /* Now do the same using a dynamically allocated software timer to ensure + * the delete function is working correctly in both the static and dynamic + * allocation cases. */ + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xTimer = xTimerCreate( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */ + xTimerPeriod, /* The period of the timer in ticks. */ + pdTRUE, /* This is an auto-reload timer. */ + ( void * ) &uxVariableToIncrement, /* The variable incremented by the test is passed into the timer callback using the timer ID. */ + prvTimerCallback ); /* The function to execute when the timer expires. */ + + configASSERT( xTimer != NULL ); + + uxVariableToIncrement = 0; + xReturned = xTimerStart( xTimer, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS ); + + if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS ) + { + xErrorOccurred = pdTRUE; + } + + xReturned = xTimerDelete( xTimer, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ + } +/*-----------------------------------------------------------*/ + + static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void ) + { + EventGroupHandle_t xEventGroup; + +/* 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 calls within this function. */ + StaticEventGroup_t xEventGroupBuffer; + + /* Create the event group. xEventGroupCreateStatic() has an extra parameter + * than the normal xEventGroupCreate() API function. The parameter is a + * pointer to the StaticEventGroup_t structure that will hold the event group + * structure. */ + xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); + + /* The event group handle should equal the static event group structure + * passed into the xEventGroupCreateStatic() function. */ + configASSERT( xEventGroup == ( EventGroupHandle_t ) &xEventGroupBuffer ); + + /* Ensure the event group passes a few sanity checks as a valid event + * group. */ + prvSanityCheckCreatedEventGroup( xEventGroup ); + + /* Delete the event group again so the buffers can be reused. */ + vEventGroupDelete( xEventGroup ); + + /* Now do the same using a dynamically allocated event group to ensure the + * delete function is working correctly in both the static and dynamic + * allocation cases. */ + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xEventGroup = xEventGroupCreate(); + configASSERT( xEventGroup != NULL ); + prvSanityCheckCreatedEventGroup( xEventGroup ); + vEventGroupDelete( xEventGroup ); + } + #endif + } +/*-----------------------------------------------------------*/ + + static void prvCreateAndDeleteStaticallyAllocatedTasks( void ) + { + TaskHandle_t xCreatedTask; + +/* The variable that will hold the TCB of tasks created by this function. See + * the comments above the declaration of the xCreatorTaskTCBBuffer variable for + * more information. NOTE: This is not static so relies on the tasks that use it + * being deleted before this function returns and deallocates its stack. That will + * only be the case if configUSE_PREEMPTION is set to 1. */ + StaticTask_t xTCBBuffer; + +/* This buffer that will be used as the stack of tasks created by this function. + * See the comments above the declaration of the uxCreatorTaskStackBuffer[] array + * above for more information. */ + static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ]; + + /* Create the task. xTaskCreateStatic() has two more parameters than + * the usual xTaskCreate() function. The first new parameter is a pointer to + * the pre-allocated stack. The second new parameter is a pointer to the + * StaticTask_t structure that will hold the task's TCB. If both pointers are + * passed as NULL then the respective object will be allocated dynamically as + * if xTaskCreate() had been called. */ + xCreatedTask = xTaskCreateStatic( + prvStaticallyAllocatedTask, /* Function that implements the task. */ + "Static", /* Human readable name for the task. */ + configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */ + NULL, /* Parameter to pass into the task. */ + uxTaskPriorityGet( NULL ) + 1, /* The priority of the task. */ + &( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */ + &xTCBBuffer ); /* The variable that will hold that task's TCB. */ + + /* Check the task was created correctly, then delete the task. */ + if( xCreatedTask == NULL ) + { + xErrorOccurred = pdTRUE; + } + else if( eTaskGetState( xCreatedTask ) != eSuspended ) + { + /* The created task had a higher priority so should have executed and + * suspended itself by now. */ + xErrorOccurred = pdTRUE; + } + else + { + vTaskDelete( xCreatedTask ); + } + + /* Now do the same using a dynamically allocated task to ensure the delete + * function is working correctly in both the static and dynamic allocation + * cases. */ + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + BaseType_t xReturned; + + xReturned = xTaskCreate( + prvStaticallyAllocatedTask, /* Function that implements the task - the same function is used but is actually dynamically allocated this time. */ + "Static", /* Human readable name for the task. */ + configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */ + NULL, /* Parameter to pass into the task. */ + uxTaskPriorityGet( NULL ) + 1, /* The priority of the task. */ + &xCreatedTask ); /* Handle of the task being created. */ + + if( eTaskGetState( xCreatedTask ) != eSuspended ) + { + xErrorOccurred = pdTRUE; + } + + configASSERT( xReturned == pdPASS ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + vTaskDelete( xCreatedTask ); + } + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ + } +/*-----------------------------------------------------------*/ + + static void prvStaticallyAllocatedTask( void * pvParameters ) + { + ( void ) pvParameters; + + /* The created task just suspends itself to wait to get deleted. The task + * that creates this task checks this task is in the expected Suspended state + * before deleting it. */ + vTaskSuspend( NULL ); + } +/*-----------------------------------------------------------*/ + + static UBaseType_t prvRand( void ) + { + const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL; + + /* Utility function to generate a pseudo random number. */ + ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement; + return( ( ulNextRand >> 16UL ) & 0x7fffUL ); + } +/*-----------------------------------------------------------*/ + + static TickType_t prvGetNextDelayTime( void ) + { + TickType_t xNextDelay; + const TickType_t xMaxDelay = pdMS_TO_TICKS( ( TickType_t ) 150 ); + const TickType_t xMinDelay = pdMS_TO_TICKS( ( TickType_t ) 75 ); + const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 ); + + /* Generate the next delay time. This is kept within a narrow band so as + * not to disturb the timing of other tests - but does add in some pseudo + * randomisation into the tests. */ + do + { + xNextDelay = prvRand() % xMaxDelay; + + /* Just in case this loop is executed lots of times. */ + vTaskDelay( xTinyDelay ); + } while( xNextDelay < xMinDelay ); + + return xNextDelay; + } +/*-----------------------------------------------------------*/ + + static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup ) + { + EventBits_t xEventBits; + const EventBits_t xFirstTestBits = ( EventBits_t ) 0xaa, xSecondTestBits = ( EventBits_t ) 0x55; + + /* The event group should not have any bits set yet. */ + xEventBits = xEventGroupGetBits( xEventGroup ); + + if( xEventBits != ( EventBits_t ) 0 ) + { + xErrorOccurred = pdTRUE; + } + + /* Some some bits, then read them back to check they are as expected. */ + xEventGroupSetBits( xEventGroup, xFirstTestBits ); + + xEventBits = xEventGroupGetBits( xEventGroup ); + + if( xEventBits != xFirstTestBits ) + { + xErrorOccurred = pdTRUE; + } + + xEventGroupSetBits( xEventGroup, xSecondTestBits ); + + xEventBits = xEventGroupGetBits( xEventGroup ); + + if( xEventBits != ( xFirstTestBits | xSecondTestBits ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Finally try clearing some bits too and check that operation proceeds as + * expected. */ + xEventGroupClearBits( xEventGroup, xFirstTestBits ); + + xEventBits = xEventGroupGetBits( xEventGroup ); + + if( xEventBits != xSecondTestBits ) + { + xErrorOccurred = pdTRUE; + } + } +/*-----------------------------------------------------------*/ + + static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, + UBaseType_t uxMaxCount ) + { + BaseType_t xReturned; + UBaseType_t x; + const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 ); + TickType_t xTickCount; + + /* The binary semaphore should start 'empty', so a call to xSemaphoreTake() + * should fail. */ + xTickCount = xTaskGetTickCount(); + xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime ); + + if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime ) + { + /* Did not block on the semaphore as long as expected. */ + xErrorOccurred = pdTRUE; + } + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + /* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount + * times. */ + for( x = 0; x < uxMaxCount; x++ ) + { + xReturned = xSemaphoreGive( xSemaphore ); + + if( xReturned == pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Giving the semaphore again should fail, as it is 'full'. */ + xReturned = xSemaphoreGive( xSemaphore ); + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount ); + + /* Should now be possible to 'take' the semaphore up to a maximum of + * uxMaxCount times without blocking. */ + for( x = 0; x < uxMaxCount; x++ ) + { + xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK ); + + if( xReturned == pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Back to the starting condition, where the semaphore should not be + * available. */ + xTickCount = xTaskGetTickCount(); + xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime ); + + if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime ) + { + /* Did not block on the semaphore as long as expected. */ + xErrorOccurred = pdTRUE; + } + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 ); + } +/*-----------------------------------------------------------*/ + + static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue ) + { + uint64_t ull, ullRead; + BaseType_t xReturned, xLoop; + + /* This test is done twice to ensure the queue storage area wraps. */ + for( xLoop = 0; xLoop < 2; xLoop++ ) + { + /* A very basic test that the queue can be written to and read from as + * expected. First the queue should be empty. */ + xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK ); + + if( xReturned != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + /* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS + * times. */ + for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ ) + { + xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Should not now be possible to write to the queue again. */ + xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK ); + + if( xReturned != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* Now read back from the queue to ensure the data read back matches that + * written. */ + for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ ) + { + xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( ullRead != ull ) + { + xErrorOccurred = pdTRUE; + } + } + + /* The queue should be empty again. */ + xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK ); + + if( xReturned != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + } + } +/*-----------------------------------------------------------*/ + + static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore ) + { + const BaseType_t xLoops = 5; + BaseType_t x, xReturned; + + /* A very basic test that the recursive semaphore behaved like a recursive + * semaphore. First the semaphore should not be able to be given, as it has not + * yet been taken. */ + xReturned = xSemaphoreGiveRecursive( xSemaphore ); + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + /* Now it should be possible to take the mutex a number of times. */ + for( x = 0; x < xLoops; x++ ) + { + xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Should be possible to give the semaphore the same number of times as it + * was given in the loop above. */ + for( x = 0; x < xLoops; x++ ) + { + xReturned = xSemaphoreGiveRecursive( xSemaphore ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* No more gives should be possible though. */ + xReturned = xSemaphoreGiveRecursive( xSemaphore ); + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + } +/*-----------------------------------------------------------*/ + + BaseType_t xAreStaticAllocationTasksStillRunning( void ) + { + static UBaseType_t uxLastCycleCounter = 0; + BaseType_t xReturn; + + if( uxCycleCounter == uxLastCycleCounter ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastCycleCounter = uxCycleCounter; + } + + if( xErrorOccurred != pdFALSE ) + { + xReturn = pdFAIL; + } + else + { + xReturn = pdPASS; + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + +/* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */ +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ diff --git a/FreeRTOS/Demo/Common/Minimal/StreamBufferDemo.c b/FreeRTOS/Demo/Common/Minimal/StreamBufferDemo.c index 1327eee0f..17214f104 100644 --- a/FreeRTOS/Demo/Common/Minimal/StreamBufferDemo.c +++ b/FreeRTOS/Demo/Common/Minimal/StreamBufferDemo.c @@ -1,1247 +1,1247 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* Standard includes. */ -#include "stdio.h" -#include "string.h" - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "stream_buffer.h" - -/* Demo app includes. */ -#include "StreamBufferDemo.h" - -/* The number of bytes of storage in the stream buffers used in this test. */ -#define sbSTREAM_BUFFER_LENGTH_BYTES ( ( size_t ) 30 ) - -/* Stream buffer length one. */ -#define sbSTREAM_BUFFER_LENGTH_ONE ( ( size_t ) 1 ) - -/* Start and end ASCII characters used in data sent to the buffers. */ -#define sbASCII_SPACE 32 -#define sbASCII_TILDA 126 - -/* Defines the number of tasks to create in this test and demo. */ -#define sbNUMBER_OF_ECHO_CLIENTS ( 2 ) -#define sbNUMBER_OF_SENDER_TASKS ( 2 ) - -/* Priority of the test tasks. The send and receive go from low to high - * priority tasks, and from high to low priority tasks. */ -#define sbLOWER_PRIORITY ( tskIDLE_PRIORITY ) -#define sbHIGHER_PRIORITY ( tskIDLE_PRIORITY + 1 ) - -/* Block times used when sending and receiving from the stream buffers. */ -#define sbRX_TX_BLOCK_TIME pdMS_TO_TICKS( 125UL ) - -/* A block time of 0 means "don't block". */ -#define sbDONT_BLOCK ( 0 ) - -/* The trigger level sets the number of bytes that must be present in the - * stream buffer before a task that is blocked on the stream buffer is moved out of - * the Blocked state so it can read the bytes. */ -#define sbTRIGGER_LEVEL_1 ( 1 ) - -/* The size of the stack allocated to the tasks that run as part of this demo/ - * test. The stack size is over generous in most cases. */ -#ifndef configSTREAM_BUFFER_SENDER_TASK_STACK_SIZE - #define sbSTACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) -#else - #define sbSTACK_SIZE configSTREAM_BUFFER_SENDER_TASK_STACK_SIZE -#endif - -#ifndef configSTREAM_BUFFER_SMALLER_TASK_STACK_SIZE - #define sbSMALLER_STACK_SIZE sbSTACK_SIZE -#else - #define sbSMALLER_STACK_SIZE configSTREAM_BUFFER_SMALLER_TASK_STACK_SIZE -#endif - -/*-----------------------------------------------------------*/ - -/* - * Performs various tests that do not require multiple tasks to interact. - */ -static void prvSingleTaskTests( StreamBufferHandle_t xStreamBuffer ); - -/* - * Tests sending and receiving various lengths of data via a stream buffer. - * The echo client sends the data to the echo server, which then sends the - * data back to the echo client, which checks it receives exactly what it - * sent. - */ -static void prvEchoClient( void * pvParameters ); -static void prvEchoServer( void * pvParameters ); - -/* - * Tasks that send and receive to a stream buffer at a low priority and without - * blocking, so the send and receive functions interleave in time as the tasks - * are switched in and out. - */ -static void prvNonBlockingReceiverTask( void * pvParameters ); -static void prvNonBlockingSenderTask( void * pvParameters ); - -/* Performs an assert() like check in a way that won't get removed when - * performing a code coverage analysis. */ -static void prvCheckExpectedState( BaseType_t xState ); - -/* - * A task that creates a stream buffer with a specific trigger level, then - * receives a string from an interrupt (the RTOS tick hook) byte by byte to - * check it is only unblocked when the specified trigger level is reached. - */ -static void prvInterruptTriggerLevelTest( void * pvParameters ); - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - -/* This file tests both statically and dynamically allocated stream buffers. - * Allocate the structures and buffers to be used by the statically allocated - * objects, which get used in the echo tests. */ - static void prvReceiverTask( void * pvParameters ); - static void prvSenderTask( void * pvParameters ); - - static StaticStreamBuffer_t xStaticStreamBuffers[ sbNUMBER_OF_ECHO_CLIENTS ]; - static uint32_t ulSenderLoopCounters[ sbNUMBER_OF_SENDER_TASKS ] = { 0 }; -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -/* The +1 is to make the test logic easier as the function that calculates the - * free space will return one less than the actual free space - adding a 1 to the - * actual length makes it appear to the tests as if the free space is returned as - * it might logically be expected. Returning 1 less than the actual free space is - * fine as it can never result in an overrun. */ -static uint8_t ucBufferStorage[ sbNUMBER_OF_SENDER_TASKS ][ sbSTREAM_BUFFER_LENGTH_BYTES + 1 ]; - -/*-----------------------------------------------------------*/ - -/* The buffers used by the echo client and server tasks. */ -typedef struct ECHO_STREAM_BUFFERS -{ - /* Handles to the data structures that describe the stream buffers. */ - StreamBufferHandle_t xEchoClientBuffer; - StreamBufferHandle_t xEchoServerBuffer; -} EchoStreamBuffers_t; -static volatile uint32_t ulEchoLoopCounters[ sbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; - -/* The non-blocking tasks monitor their operation, and if no errors have been - * found, increment ulNonBlockingRxCounter. xAreStreamBufferTasksStillRunning() - * then checks ulNonBlockingRxCounter and only returns pdPASS if - * ulNonBlockingRxCounter is still incrementing. */ -static volatile uint32_t ulNonBlockingRxCounter = 0; - -/* The task that receives characters from the tick interrupt in order to test - * different trigger levels monitors its own behaviour. If it has not detected any - * error then it increments ulInterruptTriggerCounter to indicate to the check task - * that it is still operating correctly. */ -static volatile uint32_t ulInterruptTriggerCounter = 0UL; - -/* The stream buffer used from the tick interrupt. This sends one byte at a time - * to a test task to test the trigger level operation. The variable is set to NULL - * in between test runs. */ -static volatile StreamBufferHandle_t xInterruptStreamBuffer = NULL; - -/* The data sent from the tick interrupt to the task that tests the trigger - * level functionality. */ -static const char * pcDataSentFromInterrupt = "0123456789"; - -/* Data that is longer than the buffer that is sent to the buffers as a stream - * of bytes. Parts of which are written to the stream buffer to test writing - * different lengths at different offsets, to many bytes, part streams, streams - * that wrap, etc.. Two messages are defined to ensure left over data is not - * accidentally read out of the buffer. */ -static const char * pc55ByteString = "One two three four five six seven eight nine ten eleven"; -static const char * pc54ByteString = "01234567891abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ"; - -/* Used to log the status of the tests contained within this file for reporting - * to a monitoring task ('check' task). */ -static BaseType_t xErrorStatus = pdPASS; - -/*-----------------------------------------------------------*/ - -void vStartStreamBufferTasks( void ) -{ - StreamBufferHandle_t xStreamBuffer; - - /* The echo servers sets up the stream buffers before creating the echo - * client tasks. One set of tasks has the server as the higher priority, and - * the other has the client as the higher priority. */ - xTaskCreate( prvEchoServer, "1StrEchoServer", sbSMALLER_STACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL ); - xTaskCreate( prvEchoServer, "2StrEchoServer", sbSMALLER_STACK_SIZE, NULL, sbLOWER_PRIORITY, NULL ); - - /* The non blocking tasks run continuously and will interleave with each - * other, so must be created at the lowest priority. The stream buffer they - * use is created and passed in using the task's parameter. */ - xStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 ); - xTaskCreate( prvNonBlockingReceiverTask, "StrNonBlkRx", configMINIMAL_STACK_SIZE, ( void * ) xStreamBuffer, tskIDLE_PRIORITY, NULL ); - xTaskCreate( prvNonBlockingSenderTask, "StrNonBlkTx", configMINIMAL_STACK_SIZE, ( void * ) xStreamBuffer, tskIDLE_PRIORITY, NULL ); - - /* The task that receives bytes from an interrupt to test that it unblocks - * at a specific trigger level must run at a high priority to minimise the risk - * of it receiving more characters before it can execute again after being - * unblocked. */ - xTaskCreate( prvInterruptTriggerLevelTest, "StrTrig", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL ); - - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - { - /* The sender tasks set up the stream buffers before creating the - * receiver tasks. Priorities must be 0 and 1 as the priority is used to - * index into the xStaticStreamBuffers and ucBufferStorage arrays. */ - xTaskCreate( prvSenderTask, "Str1Sender", sbSMALLER_STACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL ); - xTaskCreate( prvSenderTask, "Str2Sender", sbSMALLER_STACK_SIZE, NULL, sbLOWER_PRIORITY, NULL ); - } - #endif /* configSUPPORT_STATIC_ALLOCATION */ -} -/*-----------------------------------------------------------*/ - -static void prvCheckExpectedState( BaseType_t xState ) -{ - configASSERT( xState ); - - if( xState == pdFAIL ) - { - xErrorStatus = pdFAIL; - } -} -/*-----------------------------------------------------------*/ - -static void prvSingleTaskTests( StreamBufferHandle_t xStreamBuffer ) -{ - size_t xReturned, xItem, xExpected, xExpectedSpaces, xExpectedBytes; - const size_t xMax6ByteMessages = sbSTREAM_BUFFER_LENGTH_BYTES / 6; - const size_t xTrueSize = ( sizeof( ucBufferStorage ) / sbNUMBER_OF_SENDER_TASKS ); - const size_t x6ByteLength = 6, x17ByteLength = 17, xFullBufferSize = sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2; - uint8_t * pucFullBuffer, * pucData, * pucReadData; - TickType_t xTimeBeforeCall, xTimeAfterCall; - const TickType_t xBlockTime = pdMS_TO_TICKS( 15 ), xAllowableMargin = pdMS_TO_TICKS( 3 ), xMinimalBlockTime = 2; - UBaseType_t uxOriginalPriority; - - /* Remove warning in case configASSERT() is not defined. */ - ( void ) xAllowableMargin; - - /* To minimise stack and heap usage a full size buffer is allocated from the - * heap, then buffers which hold smaller amounts of data are overlayed with the - * larger buffer - just make sure not to use both at once! */ - pucFullBuffer = pvPortMalloc( xFullBufferSize ); - configASSERT( pucFullBuffer ); - - pucData = pucFullBuffer; - pucReadData = pucData + x17ByteLength; - - /* Nothing has been added or removed yet, so expect the free space to be - * exactly as created. Head and tail are both at 0. */ - xExpectedSpaces = sbSTREAM_BUFFER_LENGTH_BYTES; - xExpectedBytes = 0; - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedSpaces ); - xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedBytes ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - - /* Add a single item - number of bytes available should go up by one and spaces - * available down by one. Head is in front of tail. */ - xExpectedSpaces--; - xExpectedBytes++; - xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); - prvCheckExpectedState( xReturned == sizeof( *pucData ) ); - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedSpaces ); - xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedBytes ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - - /* Now fill the buffer by adding another 29 bytes. Head is 30 tail is at 0. */ - xExpectedSpaces -= 29; - xExpectedBytes += 29; - xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, ( sbSTREAM_BUFFER_LENGTH_BYTES - 1 ), ( TickType_t ) 0 ); - prvCheckExpectedState( xReturned == ( sbSTREAM_BUFFER_LENGTH_BYTES - 1 ) ); - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedSpaces ); - xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedBytes ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); - - /* Should not be able to add another byte now. */ - xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); - prvCheckExpectedState( xReturned == ( size_t ) 0 ); - - /* Remove a byte so the tail pointer moves off 0. Head pointer remains at the - * end of the buffer. */ - xExpectedSpaces += 1; - xExpectedBytes -= 1; - xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); - prvCheckExpectedState( xReturned == sizeof( *pucData ) ); - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedSpaces ); - xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedBytes ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - - /* Should be able to add another byte to fill the buffer again now. */ - xExpectedSpaces -= 1; - xExpectedBytes += 1; - xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); - prvCheckExpectedState( xReturned == sizeof( *pucData ) ); - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedSpaces ); - xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedBytes ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); - - /* Now the head pointer is behind the tail pointer. Read another 29 bytes so - * the tail pointer moves to the end of the buffer. */ - xExpectedSpaces += 29; - xExpectedBytes -= 29; - xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucData, ( size_t ) 29, ( TickType_t ) 0 ); - prvCheckExpectedState( xReturned == ( size_t ) 29 ); - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedSpaces ); - xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedBytes ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - - /* Read out one more byte to wrap the tail back around to the start, to get back - * to where we started. */ - xExpectedSpaces += 1; - xExpectedBytes -= 1; - xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); - prvCheckExpectedState( xReturned == sizeof( *pucData ) ); - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedSpaces ); - xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedBytes ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - - /* Try filling the message buffer in one write, blocking indefinitely. Expect to - * have written one byte less. */ - xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, xTrueSize, portMAX_DELAY ); - xExpectedSpaces = ( size_t ) 0; - prvCheckExpectedState( xReturned == ( xTrueSize - ( size_t ) 1 ) ); - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == xExpectedSpaces ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); - - /* Empty the buffer again ready for the rest of the tests. Again block - * indefinitely to ensure reading more than there can possible be won't lock this - * task up, so expect to actually receive one byte less than requested. */ - xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucData, xTrueSize, portMAX_DELAY ); - prvCheckExpectedState( xReturned == ( xTrueSize - ( size_t ) 1 ) ); - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == sbSTREAM_BUFFER_LENGTH_BYTES ); - xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == ( size_t ) 0 ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - - - /* The buffer is 30 bytes long. 6 5 byte messages should fit before the - * buffer is completely full. */ - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - - for( xItem = 0; xItem < xMax6ByteMessages; xItem++ ) - { - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - - /* Generate recognisable data to write to the buffer. This is just - * ascii characters that shows which loop iteration the data was written - * in. The 'FromISR' version is used to give it some exercise as a block - * time is not used, so the call must be inside a critical section so it - * runs with ports that don't support interrupt nesting (and therefore - * don't have interrupt safe critical sections). */ - memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength ); - taskENTER_CRITICAL(); - { - xReturned = xStreamBufferSendFromISR( xStreamBuffer, ( void * ) pucData, x6ByteLength, NULL ); - } - taskEXIT_CRITICAL(); - prvCheckExpectedState( xReturned == x6ByteLength ); - - /* The space in the buffer will have reduced by the amount of user data - * written into the buffer. */ - xExpected -= x6ByteLength; - xReturned = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xReturned == xExpected ); - xReturned = xStreamBufferBytesAvailable( xStreamBuffer ); - /* +1 as it is zero indexed. */ - prvCheckExpectedState( xReturned == ( ( xItem + 1 ) * x6ByteLength ) ); - } - - /* Now the buffer should be full, and attempting to add anything should fail. */ - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); - xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), sbDONT_BLOCK ); - prvCheckExpectedState( xReturned == 0 ); - - /* Adding with a timeout should also fail after the appropriate time. The - * priority is temporarily boosted in this part of the test to keep the - * allowable margin to a minimum. */ - uxOriginalPriority = uxTaskPriorityGet( NULL ); - vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); - xTimeBeforeCall = xTaskGetTickCount(); - xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), xBlockTime ); - xTimeAfterCall = xTaskGetTickCount(); - vTaskPrioritySet( NULL, uxOriginalPriority ); - prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) >= xBlockTime ); - prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) < ( xBlockTime + xAllowableMargin ) ); - prvCheckExpectedState( xReturned == 0 ); - - /* The buffer is now full of data in the form "000000", "111111", etc. Make - * sure the data is read out as expected. */ - for( xItem = 0; xItem < xMax6ByteMessages; xItem++ ) - { - /* Generate the data that is expected to be read out for this loop - * iteration. */ - memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength ); - - /* Read the next 6 bytes out. The 'FromISR' version is used to give it - * some exercise as a block time is not used, so a it must be called from - * a critical section so this will work on ports that don't support - * interrupt nesting (so don't have interrupt safe critical sections). */ - taskENTER_CRITICAL(); - { - xReturned = xStreamBufferReceiveFromISR( xStreamBuffer, ( void * ) pucReadData, x6ByteLength, NULL ); - } - taskEXIT_CRITICAL(); - prvCheckExpectedState( xReturned == x6ByteLength ); - - /* Does the data read out match that expected? */ - prvCheckExpectedState( memcmp( ( void * ) pucData, ( void * ) pucReadData, x6ByteLength ) == 0 ); - - /* The space in the buffer will have increased by the amount of user - * data removed from the buffer. */ - xExpected += x6ByteLength; - xReturned = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xReturned == xExpected ); - xReturned = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xReturned == ( sbSTREAM_BUFFER_LENGTH_BYTES - xExpected ) ); - } - - /* The buffer should be empty again. */ - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); - xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xExpected == sbSTREAM_BUFFER_LENGTH_BYTES ); - - /* Reading with a timeout should also fail after the appropriate time. The - * priority is temporarily boosted in this part of the test to keep the - * allowable margin to a minimum. */ - vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); - xTimeBeforeCall = xTaskGetTickCount(); - xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucReadData, x6ByteLength, xBlockTime ); - xTimeAfterCall = xTaskGetTickCount(); - vTaskPrioritySet( NULL, uxOriginalPriority ); - prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) >= xBlockTime ); - prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) < ( xBlockTime + xAllowableMargin ) ); - prvCheckExpectedState( xReturned == 0 ); - - - /* In the next loop 17 bytes are written to then read out on each - * iteration. As 30 is not divisible by 17 the data will wrap around. */ - xExpected = sbSTREAM_BUFFER_LENGTH_BYTES - x17ByteLength; - - for( xItem = 0; xItem < 100; xItem++ ) - { - /* Generate recognisable data to write to the queue. This is just - * ascii characters that shows which loop iteration the data was written - * in. */ - memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x17ByteLength ); - xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, x17ByteLength, sbDONT_BLOCK ); - prvCheckExpectedState( xReturned == x17ByteLength ); - - /* The space in the buffer will have reduced by the amount of user data - * written into the buffer. */ - xReturned = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xReturned == xExpected ); - xReturned = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xReturned == x17ByteLength ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); - - /* Read the 17 bytes out again. */ - xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucReadData, x17ByteLength, sbDONT_BLOCK ); - prvCheckExpectedState( xReturned == x17ByteLength ); - - /* Does the data read out match that expected? */ - prvCheckExpectedState( memcmp( ( void * ) pucData, ( void * ) pucReadData, x17ByteLength ) == 0 ); - - /* Full buffer space available again. */ - xReturned = xStreamBufferSpacesAvailable( xStreamBuffer ); - prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES ); - xReturned = xStreamBufferBytesAvailable( xStreamBuffer ); - prvCheckExpectedState( xReturned == 0 ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); - } - - /* Fill the buffer with one message, check it is full, then read it back - * again and check the correct data is received. */ - xStreamBufferSend( xStreamBuffer, ( const void * ) pc55ByteString, sbSTREAM_BUFFER_LENGTH_BYTES, sbDONT_BLOCK ); - xStreamBufferReceive( xStreamBuffer, ( void * ) pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES, sbDONT_BLOCK ); - prvCheckExpectedState( memcmp( pc55ByteString, pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES ) == 0 ); - - /* Fill the buffer one bytes at a time. */ - for( xItem = 0; xItem < sbSTREAM_BUFFER_LENGTH_BYTES; xItem++ ) - { - /* Block time is only for test coverage, the task should never actually - * block here. */ - xStreamBufferSend( xStreamBuffer, ( const void * ) &( pc54ByteString[ xItem ] ), sizeof( char ), sbRX_TX_BLOCK_TIME ); - } - - /* The buffer should now be full. */ - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); - - /* Read the message out in one go, even though it was written in individual - * bytes. Try reading much more data than is actually available to ensure only - * the available bytes are returned (otherwise this read will write outside of - * the memory allocated anyway!). */ - xReturned = xStreamBufferReceive( xStreamBuffer, pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2, sbRX_TX_BLOCK_TIME ); - prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES ); - prvCheckExpectedState( memcmp( ( const void * ) pc54ByteString, ( const void * ) pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES ) == 0 ); - - /* Now do the opposite, write in one go and read out in single bytes. */ - xReturned = xStreamBufferSend( xStreamBuffer, ( const void * ) pc55ByteString, sbSTREAM_BUFFER_LENGTH_BYTES, sbRX_TX_BLOCK_TIME ); - prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferBytesAvailable( xStreamBuffer ) == sbSTREAM_BUFFER_LENGTH_BYTES ); - prvCheckExpectedState( xStreamBufferSpacesAvailable( xStreamBuffer ) == 0 ); - - /* Read from the buffer one byte at a time. */ - for( xItem = 0; xItem < sbSTREAM_BUFFER_LENGTH_BYTES; xItem++ ) - { - /* Block time is only for test coverage, the task should never actually - * block here. */ - xStreamBufferReceive( xStreamBuffer, ( void * ) pucFullBuffer, sizeof( char ), sbRX_TX_BLOCK_TIME ); - prvCheckExpectedState( pc55ByteString[ xItem ] == pucFullBuffer[ 0 ] ); - } - - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - - /* Try writing more bytes than there is space. */ - vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); - xReturned = xStreamBufferSend( xStreamBuffer, ( const void * ) pc54ByteString, sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2, xMinimalBlockTime ); - vTaskPrioritySet( NULL, uxOriginalPriority ); - prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); - - /* No space now though. */ - xReturned = xStreamBufferSend( xStreamBuffer, ( const void * ) pc54ByteString, sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2, xMinimalBlockTime ); - prvCheckExpectedState( xReturned == 0 ); - - /* Ensure data was written as expected even when there was an attempt to - * write more than was available. This also tries to read more bytes than are - * available. */ - xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucFullBuffer, xFullBufferSize, xMinimalBlockTime ); - prvCheckExpectedState( memcmp( ( const void * ) pucFullBuffer, ( const void * ) pc54ByteString, sbSTREAM_BUFFER_LENGTH_BYTES ) == 0 ); - prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); - prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); - - /* Clean up with data in the buffer to ensure the tests that follow don't - * see the data (the data should be discarded). */ - ( void ) xStreamBufferSend( xStreamBuffer, ( const void * ) pc55ByteString, sbSTREAM_BUFFER_LENGTH_BYTES / ( size_t ) 2, sbDONT_BLOCK ); - vPortFree( pucFullBuffer ); - xStreamBufferReset( xStreamBuffer ); -} -/*-----------------------------------------------------------*/ - -static void prvNonBlockingSenderTask( void * pvParameters ) -{ - StreamBufferHandle_t xStreamBuffer; - size_t xNextChar = 0, xBytesToSend, xBytesActuallySent; - const size_t xStringLength = strlen( pc54ByteString ); - - /* In this case the stream buffer has already been created and is passed - * into the task using the task's parameter. */ - xStreamBuffer = ( StreamBufferHandle_t ) pvParameters; - - /* Keep sending the string to the stream buffer as many bytes as possible in - * each go. Doesn't block so calls can interleave with the non-blocking - * receives performed by prvNonBlockingReceiverTask(). */ - for( ; ; ) - { - /* The whole string cannot be sent at once, so xNextChar is an index to - * the position within the string that has been sent so far. How many - * bytes are there left to send before the end of the string? */ - xBytesToSend = xStringLength - xNextChar; - - /* Attempt to send right up to the end of the string. */ - xBytesActuallySent = xStreamBufferSend( xStreamBuffer, ( const void * ) &( pc54ByteString[ xNextChar ] ), xBytesToSend, sbDONT_BLOCK ); - prvCheckExpectedState( xBytesActuallySent <= xBytesToSend ); - - /* Move the index up the string to the next character to be sent, - * wrapping if the end of the string has been reached. */ - xNextChar += xBytesActuallySent; - prvCheckExpectedState( xNextChar <= xStringLength ); - - if( xNextChar == xStringLength ) - { - xNextChar = 0; - } - } -} -/*-----------------------------------------------------------*/ - -static void prvNonBlockingReceiverTask( void * pvParameters ) -{ - StreamBufferHandle_t xStreamBuffer; - size_t xNextChar = 0, xReceiveLength, xBytesToTest, xStartIndex; - const size_t xStringLength = strlen( pc54ByteString ); - char cRxString[ 12 ]; /* Holds received characters. */ - BaseType_t xNonBlockingReceiveError = pdFALSE; - - /* In this case the stream buffer has already been created and is passed - * into the task using the task's parameter. */ - xStreamBuffer = ( StreamBufferHandle_t ) pvParameters; - - /* Expects to receive the pc54ByteString over and over again. Sends and - * receives are not blocking so will interleave. */ - for( ; ; ) - { - /* Attempt to receive as many bytes as possible, up to the limit of the - * Rx buffer size. */ - xReceiveLength = xStreamBufferReceive( xStreamBuffer, ( void * ) cRxString, sizeof( cRxString ), sbDONT_BLOCK ); - - if( xReceiveLength > 0 ) - { - /* xNextChar is the index into pc54ByteString that has been received - * already. If xReceiveLength bytes are added to that, will it go off - * the end of the string? If so, then first test up to the end of the - * string, then go back to the start of pc54ByteString to test the - * remains of the received data. */ - xBytesToTest = xReceiveLength; - - if( ( xNextChar + xBytesToTest ) > xStringLength ) - { - /* Cap to test the received data to the end of the string. */ - xBytesToTest = xStringLength - xNextChar; - - if( memcmp( ( const void * ) &( pc54ByteString[ xNextChar ] ), ( const void * ) cRxString, xBytesToTest ) != 0 ) - { - xNonBlockingReceiveError = pdTRUE; - } - - /* Then move back to the start of the string to test the - * remaining received bytes. */ - xNextChar = 0; - xStartIndex = xBytesToTest; - xBytesToTest = xReceiveLength - xBytesToTest; - } - else - { - /* The string didn't wrap in the buffer, so start comparing from - * the start of the received data. */ - xStartIndex = 0; - } - - /* Test the received bytes are as expected, then move the index - * along the string to the next expected char to receive. */ - if( memcmp( ( const void * ) &( pc54ByteString[ xNextChar ] ), ( const void * ) &( cRxString[ xStartIndex ] ), xBytesToTest ) != 0 ) - { - xNonBlockingReceiveError = pdTRUE; - } - - if( xNonBlockingReceiveError == pdFALSE ) - { - /* No errors detected so increment the counter that lets the - * check task know this test is still functioning correctly. */ - ulNonBlockingRxCounter++; - } - - xNextChar += xBytesToTest; - - if( xNextChar >= xStringLength ) - { - xNextChar = 0; - } - } - } -} -/*-----------------------------------------------------------*/ - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - - static void prvSenderTask( void * pvParameters ) - { - StreamBufferHandle_t xStreamBuffer, xTempStreamBuffer; - static uint8_t ucTempBuffer[ 10 ]; /* Just used to exercise stream buffer creating and deletion. */ - const TickType_t xTicksToWait = sbRX_TX_BLOCK_TIME, xShortDelay = pdMS_TO_TICKS( 50 ); - StaticStreamBuffer_t xStaticStreamBuffer; - size_t xNextChar = 0, xBytesToSend, xBytesActuallySent; - const size_t xStringLength = strlen( pc55ByteString ); - - /* The task's priority is used as an index into the loop counters used to - * indicate this task is still running. */ - UBaseType_t uxIndex = uxTaskPriorityGet( NULL ); - - /* Make sure a change in priority does not inadvertently result in an - * invalid array index. */ - prvCheckExpectedState( uxIndex < sbNUMBER_OF_ECHO_CLIENTS ); - - /* Avoid compiler warnings about unused parameters. */ - ( void ) pvParameters; - - xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ) / sbNUMBER_OF_SENDER_TASKS, /* The number of bytes in each buffer in the array. */ - sbTRIGGER_LEVEL_1, /* The number of bytes to be in the buffer before a task blocked to wait for data is unblocked. */ - &( ucBufferStorage[ uxIndex ][ 0 ] ), /* The address of the buffer to use within the array. */ - &( xStaticStreamBuffers[ uxIndex ] ) ); /* The static stream buffer structure to use within the array. */ - - /* Now the stream buffer has been created the receiver task can be - * created. If this sender task has the higher priority then the receiver - * task is created at the lower priority - if this sender task has the - * lower priority then the receiver task is created at the higher - * priority. */ - if( uxTaskPriorityGet( NULL ) == sbLOWER_PRIORITY ) - { - /* Here prvSingleTaskTests() performs various tests on a stream buffer - * that was created statically. */ - prvSingleTaskTests( xStreamBuffer ); - xTaskCreate( prvReceiverTask, "StrReceiver", sbSMALLER_STACK_SIZE, ( void * ) xStreamBuffer, sbHIGHER_PRIORITY, NULL ); - } - else - { - xTaskCreate( prvReceiverTask, "StrReceiver", sbSMALLER_STACK_SIZE, ( void * ) xStreamBuffer, sbLOWER_PRIORITY, NULL ); - } - - for( ; ; ) - { - /* The whole string cannot be sent at once, so xNextChar is an index - * to the position within the string that has been sent so far. How - * many bytes are there left to send before the end of the string? */ - xBytesToSend = xStringLength - xNextChar; - - /* Attempt to send right up to the end of the string. */ - xBytesActuallySent = xStreamBufferSend( xStreamBuffer, ( const void * ) &( pc55ByteString[ xNextChar ] ), xBytesToSend, xTicksToWait ); - prvCheckExpectedState( xBytesActuallySent <= xBytesToSend ); - - /* Move the index up the string to the next character to be sent, - * wrapping if the end of the string has been reached. */ - xNextChar += xBytesActuallySent; - prvCheckExpectedState( xNextChar <= xStringLength ); - - if( xNextChar == xStringLength ) - { - xNextChar = 0; - } - - /* Increment a loop counter so a check task can tell this task is - * still running as expected. */ - ulSenderLoopCounters[ uxIndex ]++; - - if( uxTaskPriorityGet( NULL ) == sbHIGHER_PRIORITY ) - { - /* Allow other tasks to run. */ - vTaskDelay( xShortDelay ); - } - - /* This stream buffer is just created and deleted to ensure no - * issues when attempting to delete a stream buffer that was - * created using statically allocated memory. To save stack space - * the buffer is set to point to the pc55ByteString, which is a const - * string, but no data is written into the buffer so any valid address - * will do. */ - xTempStreamBuffer = xStreamBufferCreateStatic( sizeof( ucTempBuffer ), sbTRIGGER_LEVEL_1, ucTempBuffer, &xStaticStreamBuffer ); - xStreamBufferReset( xTempStreamBuffer ); - vStreamBufferDelete( xTempStreamBuffer ); - } - } - -#endif /* configSUPPORT_STATIC_ALLOCATION */ -/*-----------------------------------------------------------*/ - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - - static void prvReceiverTask( void * pvParameters ) - { - StreamBufferHandle_t const pxStreamBuffer = ( StreamBufferHandle_t ) pvParameters; - char cRxString[ 12 ]; /* Large enough to hold a 32-bit number in ASCII. */ - const TickType_t xTicksToWait = pdMS_TO_TICKS( 5UL ); - const size_t xStringLength = strlen( pc55ByteString ); - size_t xNextChar = 0, xReceivedLength, xBytesToReceive; - - for( ; ; ) - { - /* Attempt to receive the number of bytes to the end of the string, - * or the number of byte that can be placed into the rx buffer, - * whichever is smallest. */ - xBytesToReceive = configMIN( ( xStringLength - xNextChar ), sizeof( cRxString ) ); - - do - { - xReceivedLength = xStreamBufferReceive( pxStreamBuffer, ( void * ) cRxString, xBytesToReceive, xTicksToWait ); - } while( xReceivedLength == 0 ); - - /* Ensure the received string matches the expected string. */ - prvCheckExpectedState( memcmp( ( void * ) cRxString, ( const void * ) &( pc55ByteString[ xNextChar ] ), xReceivedLength ) == 0 ); - - /* Move the index into the string up to the end of the bytes - * received so far - wrapping if the end of the string has been - * reached. */ - xNextChar += xReceivedLength; - - if( xNextChar >= xStringLength ) - { - xNextChar = 0; - } - } - } - -#endif /* configSUPPORT_STATIC_ALLOCATION */ -/*-----------------------------------------------------------*/ - -static void prvEchoClient( void * pvParameters ) -{ - size_t xSendLength = 0, ux; - char * pcStringToSend, * pcStringReceived, cNextChar = sbASCII_SPACE; - const TickType_t xTicksToWait = pdMS_TO_TICKS( 50 ); - StreamBufferHandle_t xTempStreamBuffer; - -/* The task's priority is used as an index into the loop counters used to - * indicate this task is still running. */ - UBaseType_t uxIndex = uxTaskPriorityGet( NULL ); - -/* Pointers to the client and server stream buffers are passed into this task - * using the task's parameter. */ - EchoStreamBuffers_t * pxStreamBuffers = ( EchoStreamBuffers_t * ) pvParameters; - - /* Prevent compiler warnings. */ - ( void ) pvParameters; - - /* Create the buffer into which strings to send to the server will be - * created, and the buffer into which strings echoed back from the server will - * be copied. */ - pcStringToSend = ( char * ) pvPortMalloc( sbSTREAM_BUFFER_LENGTH_BYTES ); - pcStringReceived = ( char * ) pvPortMalloc( sbSTREAM_BUFFER_LENGTH_BYTES ); - - configASSERT( pcStringToSend ); - configASSERT( pcStringReceived ); - - for( ; ; ) - { - /* Generate the length of the next string to send. */ - xSendLength++; - - /* The stream buffer is being used to hold variable length data, so - * each data item requires sizeof( size_t ) bytes to hold the data's - * length, hence the sizeof() in the if() condition below. */ - if( xSendLength > ( sbSTREAM_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) ) - { - /* Back to a string length of 1. */ - xSendLength = sizeof( char ); - } - - memset( pcStringToSend, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); - - for( ux = 0; ux < xSendLength; ux++ ) - { - pcStringToSend[ ux ] = cNextChar; - - cNextChar++; - - if( cNextChar > sbASCII_TILDA ) - { - cNextChar = sbASCII_SPACE; - } - } - - /* Send the generated string to the buffer. */ - do - { - ux = xStreamBufferSend( pxStreamBuffers->xEchoClientBuffer, ( void * ) pcStringToSend, xSendLength, xTicksToWait ); - } while( ux == 0 ); - - /* Wait for the string to be echoed back. */ - memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); - xStreamBufferReceive( pxStreamBuffers->xEchoServerBuffer, ( void * ) pcStringReceived, xSendLength, portMAX_DELAY ); - - prvCheckExpectedState( strcmp( pcStringToSend, pcStringReceived ) == 0 ); - - /* Maintain a count of the number of times this code executes so a - * check task can determine if this task is still functioning as - * expected or not. As there are two client tasks, and the priorities - * used are 0 and 1, the task's priority is used as an index into the - * loop count array. */ - ulEchoLoopCounters[ uxIndex ]++; - - /* This stream buffer is just created and deleted to ensure no memory - * leaks. */ - xTempStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 ); - vStreamBufferDelete( xTempStreamBuffer ); - - /* The following are tests for a stream buffer of size one. */ - /* Create a buffer of size one. */ - xTempStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_ONE, sbTRIGGER_LEVEL_1 ); - /* Ensure that the buffer was created successfully. */ - configASSERT( xTempStreamBuffer ); - - /* Send one byte to the buffer. */ - ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 1, sbDONT_BLOCK ); - /* Ensure that the byte was sent successfully. */ - configASSERT( ux == 1 ); - /* Try sending another byte to the buffer. */ - ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 1, sbDONT_BLOCK ); - /* Make sure that send failed as the buffer is full. */ - configASSERT( ux == 0 ); - - /* Receive one byte from the buffer. */ - memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); - ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 1, sbDONT_BLOCK ); - /* Ensure that the receive was successful. */ - configASSERT( ux == 1 ); - /* Ensure that the correct data was received. */ - configASSERT( pcStringToSend[ 0 ] == pcStringReceived[ 0 ] ); - /* Try receiving another byte from the buffer. */ - ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 1, sbDONT_BLOCK ); - /* Ensure that the receive failed as the buffer is empty. */ - configASSERT( ux == 0 ); - - /* Try sending two bytes to the buffer. Since the size of the - * buffer is one, we must not be able to send more than one. */ - ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 2, sbDONT_BLOCK ); - /* Ensure that only one byte was sent. */ - configASSERT( ux == 1 ); - - /* Try receiving two bytes from the buffer. Since the size of the - * buffer is one, we must not be able to get more than one. */ - memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); - ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 2, sbDONT_BLOCK ); - /* Ensure that only one byte was received. */ - configASSERT( ux == 1 ); - /* Ensure that the correct data was received. */ - configASSERT( pcStringToSend[ 0 ] == pcStringReceived[ 0 ] ); - - /* Delete the buffer. */ - vStreamBufferDelete( xTempStreamBuffer ); - } -} -/*-----------------------------------------------------------*/ - -static void prvEchoServer( void * pvParameters ) -{ - size_t xReceivedLength; - char * pcReceivedString; - EchoStreamBuffers_t xStreamBuffers; - TickType_t xTimeOnEntering; - const TickType_t xTicksToBlock = pdMS_TO_TICKS( 350UL ); - - /* Prevent compiler warnings about unused parameters. */ - ( void ) pvParameters; - - /* Create the stream buffer used to send data from the client to the server, - * and the stream buffer used to echo the data from the server back to the - * client. */ - xStreamBuffers.xEchoClientBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 ); - xStreamBuffers.xEchoServerBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 ); - configASSERT( xStreamBuffers.xEchoClientBuffer ); - configASSERT( xStreamBuffers.xEchoServerBuffer ); - - /* Create the buffer into which received strings will be copied. */ - pcReceivedString = ( char * ) pvPortMalloc( sbSTREAM_BUFFER_LENGTH_BYTES ); - configASSERT( pcReceivedString ); - - /* Don't expect to receive anything yet! */ - xTimeOnEntering = xTaskGetTickCount(); - xReceivedLength = xStreamBufferReceive( xStreamBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, sbSTREAM_BUFFER_LENGTH_BYTES, xTicksToBlock ); - prvCheckExpectedState( ( ( TickType_t ) ( xTaskGetTickCount() - xTimeOnEntering ) ) >= xTicksToBlock ); - prvCheckExpectedState( xReceivedLength == 0 ); - - /* Now the stream buffers have been created the echo client task can be - * created. If this server task has the higher priority then the client task - * is created at the lower priority - if this server task has the lower - * priority then the client task is created at the higher priority. */ - if( uxTaskPriorityGet( NULL ) == sbLOWER_PRIORITY ) - { - xTaskCreate( prvEchoClient, "EchoClient", sbSMALLER_STACK_SIZE, ( void * ) &xStreamBuffers, sbHIGHER_PRIORITY, NULL ); - } - else - { - /* Here prvSingleTaskTests() performs various tests on a stream buffer - * that was created dynamically. */ - prvSingleTaskTests( xStreamBuffers.xEchoClientBuffer ); - xTaskCreate( prvEchoClient, "EchoClient", sbSMALLER_STACK_SIZE, ( void * ) &xStreamBuffers, sbLOWER_PRIORITY, NULL ); - } - - for( ; ; ) - { - memset( pcReceivedString, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); - - /* Has any data been sent by the client? */ - xReceivedLength = xStreamBufferReceive( xStreamBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, sbSTREAM_BUFFER_LENGTH_BYTES, portMAX_DELAY ); - - /* Should always receive data as max delay was used. */ - prvCheckExpectedState( xReceivedLength > 0 ); - - /* Echo the received data back to the client. */ - xStreamBufferSend( xStreamBuffers.xEchoServerBuffer, ( void * ) pcReceivedString, xReceivedLength, portMAX_DELAY ); - } -} -/*-----------------------------------------------------------*/ - -void vPeriodicStreamBufferProcessing( void ) -{ - static size_t xNextChar = 0; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - - /* Called from the tick interrupt hook. If the global stream buffer - * variable is not NULL then the prvInterruptTriggerTest() task expects a byte - * to be sent to the stream buffer on each tick interrupt. */ - if( xInterruptStreamBuffer != NULL ) - { - /* One character from the pcDataSentFromInterrupt string is sent on each - * interrupt. The task blocked on the stream buffer should not be - * unblocked until the defined trigger level is hit. */ - xStreamBufferSendFromISR( xInterruptStreamBuffer, ( const void * ) &( pcDataSentFromInterrupt[ xNextChar ] ), sizeof( char ), &xHigherPriorityTaskWoken ); - - if( xNextChar < strlen( pcDataSentFromInterrupt ) ) - { - xNextChar++; - } - } - else - { - /* Start at the beginning of the string being sent again. */ - xNextChar = 0; - } -} -/*-----------------------------------------------------------*/ - -static void prvInterruptTriggerLevelTest( void * pvParameters ) -{ - StreamBufferHandle_t xStreamBuffer; - size_t xTriggerLevel = 1, xBytesReceived; - const size_t xStreamBufferSizeBytes = ( size_t ) 9, xMaxTriggerLevel = ( size_t ) 7, xMinTriggerLevel = ( size_t ) 2; - const TickType_t xReadBlockTime = 5, xCycleBlockTime = pdMS_TO_TICKS( 100 ); - uint8_t ucRxData[ 9 ]; - BaseType_t xErrorDetected = pdFALSE; - - #ifndef configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN - const size_t xAllowableMargin = ( size_t ) 0; - #else - const size_t xAllowableMargin = ( size_t ) configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN; - #endif - - /* Remove compiler warning about unused parameter. */ - ( void ) pvParameters; - - for( ; ; ) - { - for( xTriggerLevel = xMinTriggerLevel; xTriggerLevel < xMaxTriggerLevel; xTriggerLevel++ ) - { - /* This test is very time sensitive so delay at the beginning to ensure - * the rest of the system is up and running before starting. Delay between - * each loop to ensure the interrupt that sends to the stream buffer - * detects it needs to start sending from the start of the strin again.. */ - vTaskDelay( xCycleBlockTime ); - - /* Create the stream buffer that will be used from inside the tick - * interrupt. */ - memset( ucRxData, 0x00, sizeof( ucRxData ) ); - xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel ); - configASSERT( xStreamBuffer ); - - /* Now the stream buffer has been created it can be assigned to the - * file scope variable, which will allow the tick interrupt to start - * using it. */ - taskENTER_CRITICAL(); - { - xInterruptStreamBuffer = xStreamBuffer; - } - taskEXIT_CRITICAL(); - - xBytesReceived = xStreamBufferReceive( xStreamBuffer, ( void * ) ucRxData, sizeof( ucRxData ), xReadBlockTime ); - - /* Set the file scope variable back to NULL so the interrupt doesn't - * try to use it again. */ - taskENTER_CRITICAL(); - { - xInterruptStreamBuffer = NULL; - } - taskEXIT_CRITICAL(); - - /* Now check the number of bytes received equals the trigger level, - * except in the case that the read timed out before the trigger level - * was reached. */ - if( xTriggerLevel > xReadBlockTime ) - { - /* Trigger level was greater than the block time so expect to - * time out having received xReadBlockTime bytes. */ - if( xBytesReceived > xReadBlockTime ) - { - /* Received more bytes than expected. That could happen if - * this task unblocked at the right time, but an interrupt - * added another byte to the stream buffer before this task was - * able to run. */ - if( ( xBytesReceived - xReadBlockTime ) > xAllowableMargin ) - { - xErrorDetected = pdTRUE; - } - } - else if( xReadBlockTime != xBytesReceived ) - { - /* It is possible the interrupt placed an item in the stream - * buffer before this task called xStreamBufferReceive(), but - * if that is the case then xBytesReceived will only every be - * 0 as the interrupt will only have executed once. */ - if( xBytesReceived != 1 ) - { - xErrorDetected = pdTRUE; - } - } - } - else if( xTriggerLevel < xReadBlockTime ) - { - /* Trigger level was less than the block time so we expect to - * have received the trigger level number of bytes - could be more - * though depending on other activity between the task being - * unblocked and the task reading the number of bytes received. It - * could also be less if the interrupt already put something in the - * stream buffer before this task attempted to read it - in which - * case the task would have returned the available bytes immediately - * without ever blocking - in that case the bytes received will - * only ever be 1 as the interrupt would not have executed more - * than one in that time unless this task has too low a priority. */ - if( xBytesReceived < xTriggerLevel ) - { - if( xBytesReceived != 1 ) - { - xErrorDetected = pdTRUE; - } - } - else if( ( xBytesReceived - xTriggerLevel ) > xAllowableMargin ) - { - xErrorDetected = pdTRUE; - } - } - else - { - /* The trigger level equalled the block time, so expect to - * receive no greater than the block time. It could also be less - * if the interrupt already put something in the stream buffer - * before this task attempted to read it - in which case the task - * would have returned the available bytes immediately without ever - * blocking - in that case the bytes received would only ever be 1 - * because the interrupt is not going to execute twice in that time - * unless this task is running a too low a priority. */ - if( xBytesReceived < xReadBlockTime ) - { - if( xBytesReceived != 1 ) - { - xErrorDetected = pdTRUE; - } - } - else if( ( xBytesReceived - xReadBlockTime ) > xAllowableMargin ) - { - xErrorDetected = pdTRUE; - } - } - - if( xBytesReceived > sizeof( ucRxData ) ) - { - xErrorDetected = pdTRUE; - } - else if( memcmp( ( void * ) ucRxData, ( const void * ) pcDataSentFromInterrupt, xBytesReceived ) != 0 ) - { - /* Received data didn't match that expected. */ - xErrorDetected = pdTRUE; - } - - if( xErrorDetected == pdFALSE ) - { - /* Increment the cycle counter so the 'check' task knows this test - * is still running without error. */ - ulInterruptTriggerCounter++; - } - - /* Tidy up ready for the next loop. */ - vStreamBufferDelete( xStreamBuffer ); - } - } -} -/*-----------------------------------------------------------*/ - -BaseType_t xAreStreamBufferTasksStillRunning( void ) -{ - static uint32_t ulLastEchoLoopCounters[ sbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; - static uint32_t ulLastNonBlockingRxCounter = 0; - static uint32_t ulLastInterruptTriggerCounter = 0; - BaseType_t x; - - for( x = 0; x < sbNUMBER_OF_ECHO_CLIENTS; x++ ) - { - if( ulLastEchoLoopCounters[ x ] == ulEchoLoopCounters[ x ] ) - { - xErrorStatus = pdFAIL; - } - else - { - ulLastEchoLoopCounters[ x ] = ulEchoLoopCounters[ x ]; - } - } - - if( ulNonBlockingRxCounter == ulLastNonBlockingRxCounter ) - { - xErrorStatus = pdFAIL; - } - else - { - ulLastNonBlockingRxCounter = ulNonBlockingRxCounter; - } - - if( ulLastInterruptTriggerCounter == ulInterruptTriggerCounter ) - { - xErrorStatus = pdFAIL; - } - else - { - ulLastInterruptTriggerCounter = ulInterruptTriggerCounter; - } - - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - { - static uint32_t ulLastSenderLoopCounters[ sbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; - - for( x = 0; x < sbNUMBER_OF_SENDER_TASKS; x++ ) - { - if( ulLastSenderLoopCounters[ x ] == ulSenderLoopCounters[ x ] ) - { - xErrorStatus = pdFAIL; - } - else - { - ulLastSenderLoopCounters[ x ] = ulSenderLoopCounters[ x ]; - } - } - } - #endif /* configSUPPORT_STATIC_ALLOCATION */ - - return xErrorStatus; -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include "stdio.h" +#include "string.h" + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "stream_buffer.h" + +/* Demo app includes. */ +#include "StreamBufferDemo.h" + +/* The number of bytes of storage in the stream buffers used in this test. */ +#define sbSTREAM_BUFFER_LENGTH_BYTES ( ( size_t ) 30 ) + +/* Stream buffer length one. */ +#define sbSTREAM_BUFFER_LENGTH_ONE ( ( size_t ) 1 ) + +/* Start and end ASCII characters used in data sent to the buffers. */ +#define sbASCII_SPACE 32 +#define sbASCII_TILDA 126 + +/* Defines the number of tasks to create in this test and demo. */ +#define sbNUMBER_OF_ECHO_CLIENTS ( 2 ) +#define sbNUMBER_OF_SENDER_TASKS ( 2 ) + +/* Priority of the test tasks. The send and receive go from low to high + * priority tasks, and from high to low priority tasks. */ +#define sbLOWER_PRIORITY ( tskIDLE_PRIORITY ) +#define sbHIGHER_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* Block times used when sending and receiving from the stream buffers. */ +#define sbRX_TX_BLOCK_TIME pdMS_TO_TICKS( 125UL ) + +/* A block time of 0 means "don't block". */ +#define sbDONT_BLOCK ( 0 ) + +/* The trigger level sets the number of bytes that must be present in the + * stream buffer before a task that is blocked on the stream buffer is moved out of + * the Blocked state so it can read the bytes. */ +#define sbTRIGGER_LEVEL_1 ( 1 ) + +/* The size of the stack allocated to the tasks that run as part of this demo/ + * test. The stack size is over generous in most cases. */ +#ifndef configSTREAM_BUFFER_SENDER_TASK_STACK_SIZE + #define sbSTACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) +#else + #define sbSTACK_SIZE configSTREAM_BUFFER_SENDER_TASK_STACK_SIZE +#endif + +#ifndef configSTREAM_BUFFER_SMALLER_TASK_STACK_SIZE + #define sbSMALLER_STACK_SIZE sbSTACK_SIZE +#else + #define sbSMALLER_STACK_SIZE configSTREAM_BUFFER_SMALLER_TASK_STACK_SIZE +#endif + +/*-----------------------------------------------------------*/ + +/* + * Performs various tests that do not require multiple tasks to interact. + */ +static void prvSingleTaskTests( StreamBufferHandle_t xStreamBuffer ); + +/* + * Tests sending and receiving various lengths of data via a stream buffer. + * The echo client sends the data to the echo server, which then sends the + * data back to the echo client, which checks it receives exactly what it + * sent. + */ +static void prvEchoClient( void * pvParameters ); +static void prvEchoServer( void * pvParameters ); + +/* + * Tasks that send and receive to a stream buffer at a low priority and without + * blocking, so the send and receive functions interleave in time as the tasks + * are switched in and out. + */ +static void prvNonBlockingReceiverTask( void * pvParameters ); +static void prvNonBlockingSenderTask( void * pvParameters ); + +/* Performs an assert() like check in a way that won't get removed when + * performing a code coverage analysis. */ +static void prvCheckExpectedState( BaseType_t xState ); + +/* + * A task that creates a stream buffer with a specific trigger level, then + * receives a string from an interrupt (the RTOS tick hook) byte by byte to + * check it is only unblocked when the specified trigger level is reached. + */ +static void prvInterruptTriggerLevelTest( void * pvParameters ); + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + +/* This file tests both statically and dynamically allocated stream buffers. + * Allocate the structures and buffers to be used by the statically allocated + * objects, which get used in the echo tests. */ + static void prvReceiverTask( void * pvParameters ); + static void prvSenderTask( void * pvParameters ); + + static StaticStreamBuffer_t xStaticStreamBuffers[ sbNUMBER_OF_ECHO_CLIENTS ]; + static uint32_t ulSenderLoopCounters[ sbNUMBER_OF_SENDER_TASKS ] = { 0 }; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/* The +1 is to make the test logic easier as the function that calculates the + * free space will return one less than the actual free space - adding a 1 to the + * actual length makes it appear to the tests as if the free space is returned as + * it might logically be expected. Returning 1 less than the actual free space is + * fine as it can never result in an overrun. */ +static uint8_t ucBufferStorage[ sbNUMBER_OF_SENDER_TASKS ][ sbSTREAM_BUFFER_LENGTH_BYTES + 1 ]; + +/*-----------------------------------------------------------*/ + +/* The buffers used by the echo client and server tasks. */ +typedef struct ECHO_STREAM_BUFFERS +{ + /* Handles to the data structures that describe the stream buffers. */ + StreamBufferHandle_t xEchoClientBuffer; + StreamBufferHandle_t xEchoServerBuffer; +} EchoStreamBuffers_t; +static volatile uint32_t ulEchoLoopCounters[ sbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; + +/* The non-blocking tasks monitor their operation, and if no errors have been + * found, increment ulNonBlockingRxCounter. xAreStreamBufferTasksStillRunning() + * then checks ulNonBlockingRxCounter and only returns pdPASS if + * ulNonBlockingRxCounter is still incrementing. */ +static volatile uint32_t ulNonBlockingRxCounter = 0; + +/* The task that receives characters from the tick interrupt in order to test + * different trigger levels monitors its own behaviour. If it has not detected any + * error then it increments ulInterruptTriggerCounter to indicate to the check task + * that it is still operating correctly. */ +static volatile uint32_t ulInterruptTriggerCounter = 0UL; + +/* The stream buffer used from the tick interrupt. This sends one byte at a time + * to a test task to test the trigger level operation. The variable is set to NULL + * in between test runs. */ +static volatile StreamBufferHandle_t xInterruptStreamBuffer = NULL; + +/* The data sent from the tick interrupt to the task that tests the trigger + * level functionality. */ +static const char * pcDataSentFromInterrupt = "0123456789"; + +/* Data that is longer than the buffer that is sent to the buffers as a stream + * of bytes. Parts of which are written to the stream buffer to test writing + * different lengths at different offsets, to many bytes, part streams, streams + * that wrap, etc.. Two messages are defined to ensure left over data is not + * accidentally read out of the buffer. */ +static const char * pc55ByteString = "One two three four five six seven eight nine ten eleven"; +static const char * pc54ByteString = "01234567891abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ"; + +/* Used to log the status of the tests contained within this file for reporting + * to a monitoring task ('check' task). */ +static BaseType_t xErrorStatus = pdPASS; + +/*-----------------------------------------------------------*/ + +void vStartStreamBufferTasks( void ) +{ + StreamBufferHandle_t xStreamBuffer; + + /* The echo servers sets up the stream buffers before creating the echo + * client tasks. One set of tasks has the server as the higher priority, and + * the other has the client as the higher priority. */ + xTaskCreate( prvEchoServer, "1StrEchoServer", sbSMALLER_STACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL ); + xTaskCreate( prvEchoServer, "2StrEchoServer", sbSMALLER_STACK_SIZE, NULL, sbLOWER_PRIORITY, NULL ); + + /* The non blocking tasks run continuously and will interleave with each + * other, so must be created at the lowest priority. The stream buffer they + * use is created and passed in using the task's parameter. */ + xStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 ); + xTaskCreate( prvNonBlockingReceiverTask, "StrNonBlkRx", configMINIMAL_STACK_SIZE, ( void * ) xStreamBuffer, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvNonBlockingSenderTask, "StrNonBlkTx", configMINIMAL_STACK_SIZE, ( void * ) xStreamBuffer, tskIDLE_PRIORITY, NULL ); + + /* The task that receives bytes from an interrupt to test that it unblocks + * at a specific trigger level must run at a high priority to minimise the risk + * of it receiving more characters before it can execute again after being + * unblocked. */ + xTaskCreate( prvInterruptTriggerLevelTest, "StrTrig", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL ); + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* The sender tasks set up the stream buffers before creating the + * receiver tasks. Priorities must be 0 and 1 as the priority is used to + * index into the xStaticStreamBuffers and ucBufferStorage arrays. */ + xTaskCreate( prvSenderTask, "Str1Sender", sbSMALLER_STACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL ); + xTaskCreate( prvSenderTask, "Str2Sender", sbSMALLER_STACK_SIZE, NULL, sbLOWER_PRIORITY, NULL ); + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ +} +/*-----------------------------------------------------------*/ + +static void prvCheckExpectedState( BaseType_t xState ) +{ + configASSERT( xState ); + + if( xState == pdFAIL ) + { + xErrorStatus = pdFAIL; + } +} +/*-----------------------------------------------------------*/ + +static void prvSingleTaskTests( StreamBufferHandle_t xStreamBuffer ) +{ + size_t xReturned, xItem, xExpected, xExpectedSpaces, xExpectedBytes; + const size_t xMax6ByteMessages = sbSTREAM_BUFFER_LENGTH_BYTES / 6; + const size_t xTrueSize = ( sizeof( ucBufferStorage ) / sbNUMBER_OF_SENDER_TASKS ); + const size_t x6ByteLength = 6, x17ByteLength = 17, xFullBufferSize = sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2; + uint8_t * pucFullBuffer, * pucData, * pucReadData; + TickType_t xTimeBeforeCall, xTimeAfterCall; + const TickType_t xBlockTime = pdMS_TO_TICKS( 15 ), xAllowableMargin = pdMS_TO_TICKS( 3 ), xMinimalBlockTime = 2; + UBaseType_t uxOriginalPriority; + + /* Remove warning in case configASSERT() is not defined. */ + ( void ) xAllowableMargin; + + /* To minimise stack and heap usage a full size buffer is allocated from the + * heap, then buffers which hold smaller amounts of data are overlayed with the + * larger buffer - just make sure not to use both at once! */ + pucFullBuffer = pvPortMalloc( xFullBufferSize ); + configASSERT( pucFullBuffer ); + + pucData = pucFullBuffer; + pucReadData = pucData + x17ByteLength; + + /* Nothing has been added or removed yet, so expect the free space to be + * exactly as created. Head and tail are both at 0. */ + xExpectedSpaces = sbSTREAM_BUFFER_LENGTH_BYTES; + xExpectedBytes = 0; + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedSpaces ); + xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedBytes ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + + /* Add a single item - number of bytes available should go up by one and spaces + * available down by one. Head is in front of tail. */ + xExpectedSpaces--; + xExpectedBytes++; + xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); + prvCheckExpectedState( xReturned == sizeof( *pucData ) ); + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedSpaces ); + xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedBytes ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + + /* Now fill the buffer by adding another 29 bytes. Head is 30 tail is at 0. */ + xExpectedSpaces -= 29; + xExpectedBytes += 29; + xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, ( sbSTREAM_BUFFER_LENGTH_BYTES - 1 ), ( TickType_t ) 0 ); + prvCheckExpectedState( xReturned == ( sbSTREAM_BUFFER_LENGTH_BYTES - 1 ) ); + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedSpaces ); + xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedBytes ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); + + /* Should not be able to add another byte now. */ + xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); + prvCheckExpectedState( xReturned == ( size_t ) 0 ); + + /* Remove a byte so the tail pointer moves off 0. Head pointer remains at the + * end of the buffer. */ + xExpectedSpaces += 1; + xExpectedBytes -= 1; + xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); + prvCheckExpectedState( xReturned == sizeof( *pucData ) ); + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedSpaces ); + xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedBytes ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + + /* Should be able to add another byte to fill the buffer again now. */ + xExpectedSpaces -= 1; + xExpectedBytes += 1; + xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); + prvCheckExpectedState( xReturned == sizeof( *pucData ) ); + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedSpaces ); + xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedBytes ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); + + /* Now the head pointer is behind the tail pointer. Read another 29 bytes so + * the tail pointer moves to the end of the buffer. */ + xExpectedSpaces += 29; + xExpectedBytes -= 29; + xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucData, ( size_t ) 29, ( TickType_t ) 0 ); + prvCheckExpectedState( xReturned == ( size_t ) 29 ); + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedSpaces ); + xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedBytes ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + + /* Read out one more byte to wrap the tail back around to the start, to get back + * to where we started. */ + xExpectedSpaces += 1; + xExpectedBytes -= 1; + xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucData, sizeof( *pucData ), ( TickType_t ) 0 ); + prvCheckExpectedState( xReturned == sizeof( *pucData ) ); + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedSpaces ); + xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedBytes ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + + /* Try filling the message buffer in one write, blocking indefinitely. Expect to + * have written one byte less. */ + xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, xTrueSize, portMAX_DELAY ); + xExpectedSpaces = ( size_t ) 0; + prvCheckExpectedState( xReturned == ( xTrueSize - ( size_t ) 1 ) ); + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == xExpectedSpaces ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); + + /* Empty the buffer again ready for the rest of the tests. Again block + * indefinitely to ensure reading more than there can possible be won't lock this + * task up, so expect to actually receive one byte less than requested. */ + xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucData, xTrueSize, portMAX_DELAY ); + prvCheckExpectedState( xReturned == ( xTrueSize - ( size_t ) 1 ) ); + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == sbSTREAM_BUFFER_LENGTH_BYTES ); + xExpected = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == ( size_t ) 0 ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + + + /* The buffer is 30 bytes long. 6 5 byte messages should fit before the + * buffer is completely full. */ + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + + for( xItem = 0; xItem < xMax6ByteMessages; xItem++ ) + { + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + + /* Generate recognizable data to write to the buffer. This is just + * ascii characters that shows which loop iteration the data was written + * in. The 'FromISR' version is used to give it some exercise as a block + * time is not used, so the call must be inside a critical section so it + * runs with ports that don't support interrupt nesting (and therefore + * don't have interrupt safe critical sections). */ + memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength ); + taskENTER_CRITICAL(); + { + xReturned = xStreamBufferSendFromISR( xStreamBuffer, ( void * ) pucData, x6ByteLength, NULL ); + } + taskEXIT_CRITICAL(); + prvCheckExpectedState( xReturned == x6ByteLength ); + + /* The space in the buffer will have reduced by the amount of user data + * written into the buffer. */ + xExpected -= x6ByteLength; + xReturned = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xReturned == xExpected ); + xReturned = xStreamBufferBytesAvailable( xStreamBuffer ); + /* +1 as it is zero indexed. */ + prvCheckExpectedState( xReturned == ( ( xItem + 1 ) * x6ByteLength ) ); + } + + /* Now the buffer should be full, and attempting to add anything should fail. */ + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); + xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), sbDONT_BLOCK ); + prvCheckExpectedState( xReturned == 0 ); + + /* Adding with a timeout should also fail after the appropriate time. The + * priority is temporarily boosted in this part of the test to keep the + * allowable margin to a minimum. */ + uxOriginalPriority = uxTaskPriorityGet( NULL ); + vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); + xTimeBeforeCall = xTaskGetTickCount(); + xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, sizeof( pucData[ 0 ] ), xBlockTime ); + xTimeAfterCall = xTaskGetTickCount(); + vTaskPrioritySet( NULL, uxOriginalPriority ); + prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) >= xBlockTime ); + prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) < ( xBlockTime + xAllowableMargin ) ); + prvCheckExpectedState( xReturned == 0 ); + + /* The buffer is now full of data in the form "000000", "111111", etc. Make + * sure the data is read out as expected. */ + for( xItem = 0; xItem < xMax6ByteMessages; xItem++ ) + { + /* Generate the data that is expected to be read out for this loop + * iteration. */ + memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x6ByteLength ); + + /* Read the next 6 bytes out. The 'FromISR' version is used to give it + * some exercise as a block time is not used, so a it must be called from + * a critical section so this will work on ports that don't support + * interrupt nesting (so don't have interrupt safe critical sections). */ + taskENTER_CRITICAL(); + { + xReturned = xStreamBufferReceiveFromISR( xStreamBuffer, ( void * ) pucReadData, x6ByteLength, NULL ); + } + taskEXIT_CRITICAL(); + prvCheckExpectedState( xReturned == x6ByteLength ); + + /* Does the data read out match that expected? */ + prvCheckExpectedState( memcmp( ( void * ) pucData, ( void * ) pucReadData, x6ByteLength ) == 0 ); + + /* The space in the buffer will have increased by the amount of user + * data removed from the buffer. */ + xExpected += x6ByteLength; + xReturned = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xReturned == xExpected ); + xReturned = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xReturned == ( sbSTREAM_BUFFER_LENGTH_BYTES - xExpected ) ); + } + + /* The buffer should be empty again. */ + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); + xExpected = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xExpected == sbSTREAM_BUFFER_LENGTH_BYTES ); + + /* Reading with a timeout should also fail after the appropriate time. The + * priority is temporarily boosted in this part of the test to keep the + * allowable margin to a minimum. */ + vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); + xTimeBeforeCall = xTaskGetTickCount(); + xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucReadData, x6ByteLength, xBlockTime ); + xTimeAfterCall = xTaskGetTickCount(); + vTaskPrioritySet( NULL, uxOriginalPriority ); + prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) >= xBlockTime ); + prvCheckExpectedState( ( ( TickType_t ) ( xTimeAfterCall - xTimeBeforeCall ) ) < ( xBlockTime + xAllowableMargin ) ); + prvCheckExpectedState( xReturned == 0 ); + + + /* In the next loop 17 bytes are written to then read out on each + * iteration. As 30 is not divisible by 17 the data will wrap around. */ + xExpected = sbSTREAM_BUFFER_LENGTH_BYTES - x17ByteLength; + + for( xItem = 0; xItem < 100; xItem++ ) + { + /* Generate recognizable data to write to the queue. This is just + * ascii characters that shows which loop iteration the data was written + * in. */ + memset( ( void * ) pucData, ( ( int ) '0' ) + ( int ) xItem, x17ByteLength ); + xReturned = xStreamBufferSend( xStreamBuffer, ( void * ) pucData, x17ByteLength, sbDONT_BLOCK ); + prvCheckExpectedState( xReturned == x17ByteLength ); + + /* The space in the buffer will have reduced by the amount of user data + * written into the buffer. */ + xReturned = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xReturned == xExpected ); + xReturned = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xReturned == x17ByteLength ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); + + /* Read the 17 bytes out again. */ + xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucReadData, x17ByteLength, sbDONT_BLOCK ); + prvCheckExpectedState( xReturned == x17ByteLength ); + + /* Does the data read out match that expected? */ + prvCheckExpectedState( memcmp( ( void * ) pucData, ( void * ) pucReadData, x17ByteLength ) == 0 ); + + /* Full buffer space available again. */ + xReturned = xStreamBufferSpacesAvailable( xStreamBuffer ); + prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES ); + xReturned = xStreamBufferBytesAvailable( xStreamBuffer ); + prvCheckExpectedState( xReturned == 0 ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); + } + + /* Fill the buffer with one message, check it is full, then read it back + * again and check the correct data is received. */ + xStreamBufferSend( xStreamBuffer, ( const void * ) pc55ByteString, sbSTREAM_BUFFER_LENGTH_BYTES, sbDONT_BLOCK ); + xStreamBufferReceive( xStreamBuffer, ( void * ) pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES, sbDONT_BLOCK ); + prvCheckExpectedState( memcmp( pc55ByteString, pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES ) == 0 ); + + /* Fill the buffer one bytes at a time. */ + for( xItem = 0; xItem < sbSTREAM_BUFFER_LENGTH_BYTES; xItem++ ) + { + /* Block time is only for test coverage, the task should never actually + * block here. */ + xStreamBufferSend( xStreamBuffer, ( const void * ) &( pc54ByteString[ xItem ] ), sizeof( char ), sbRX_TX_BLOCK_TIME ); + } + + /* The buffer should now be full. */ + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); + + /* Read the message out in one go, even though it was written in individual + * bytes. Try reading much more data than is actually available to ensure only + * the available bytes are returned (otherwise this read will write outside of + * the memory allocated anyway!). */ + xReturned = xStreamBufferReceive( xStreamBuffer, pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2, sbRX_TX_BLOCK_TIME ); + prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES ); + prvCheckExpectedState( memcmp( ( const void * ) pc54ByteString, ( const void * ) pucFullBuffer, sbSTREAM_BUFFER_LENGTH_BYTES ) == 0 ); + + /* Now do the opposite, write in one go and read out in single bytes. */ + xReturned = xStreamBufferSend( xStreamBuffer, ( const void * ) pc55ByteString, sbSTREAM_BUFFER_LENGTH_BYTES, sbRX_TX_BLOCK_TIME ); + prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferBytesAvailable( xStreamBuffer ) == sbSTREAM_BUFFER_LENGTH_BYTES ); + prvCheckExpectedState( xStreamBufferSpacesAvailable( xStreamBuffer ) == 0 ); + + /* Read from the buffer one byte at a time. */ + for( xItem = 0; xItem < sbSTREAM_BUFFER_LENGTH_BYTES; xItem++ ) + { + /* Block time is only for test coverage, the task should never actually + * block here. */ + xStreamBufferReceive( xStreamBuffer, ( void * ) pucFullBuffer, sizeof( char ), sbRX_TX_BLOCK_TIME ); + prvCheckExpectedState( pc55ByteString[ xItem ] == pucFullBuffer[ 0 ] ); + } + + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + + /* Try writing more bytes than there is space. */ + vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); + xReturned = xStreamBufferSend( xStreamBuffer, ( const void * ) pc54ByteString, sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2, xMinimalBlockTime ); + vTaskPrioritySet( NULL, uxOriginalPriority ); + prvCheckExpectedState( xReturned == sbSTREAM_BUFFER_LENGTH_BYTES ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdTRUE ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdFALSE ); + + /* No space now though. */ + xReturned = xStreamBufferSend( xStreamBuffer, ( const void * ) pc54ByteString, sbSTREAM_BUFFER_LENGTH_BYTES * ( size_t ) 2, xMinimalBlockTime ); + prvCheckExpectedState( xReturned == 0 ); + + /* Ensure data was written as expected even when there was an attempt to + * write more than was available. This also tries to read more bytes than are + * available. */ + xReturned = xStreamBufferReceive( xStreamBuffer, ( void * ) pucFullBuffer, xFullBufferSize, xMinimalBlockTime ); + prvCheckExpectedState( memcmp( ( const void * ) pucFullBuffer, ( const void * ) pc54ByteString, sbSTREAM_BUFFER_LENGTH_BYTES ) == 0 ); + prvCheckExpectedState( xStreamBufferIsFull( xStreamBuffer ) == pdFALSE ); + prvCheckExpectedState( xStreamBufferIsEmpty( xStreamBuffer ) == pdTRUE ); + + /* Clean up with data in the buffer to ensure the tests that follow don't + * see the data (the data should be discarded). */ + ( void ) xStreamBufferSend( xStreamBuffer, ( const void * ) pc55ByteString, sbSTREAM_BUFFER_LENGTH_BYTES / ( size_t ) 2, sbDONT_BLOCK ); + vPortFree( pucFullBuffer ); + xStreamBufferReset( xStreamBuffer ); +} +/*-----------------------------------------------------------*/ + +static void prvNonBlockingSenderTask( void * pvParameters ) +{ + StreamBufferHandle_t xStreamBuffer; + size_t xNextChar = 0, xBytesToSend, xBytesActuallySent; + const size_t xStringLength = strlen( pc54ByteString ); + + /* In this case the stream buffer has already been created and is passed + * into the task using the task's parameter. */ + xStreamBuffer = ( StreamBufferHandle_t ) pvParameters; + + /* Keep sending the string to the stream buffer as many bytes as possible in + * each go. Doesn't block so calls can interleave with the non-blocking + * receives performed by prvNonBlockingReceiverTask(). */ + for( ; ; ) + { + /* The whole string cannot be sent at once, so xNextChar is an index to + * the position within the string that has been sent so far. How many + * bytes are there left to send before the end of the string? */ + xBytesToSend = xStringLength - xNextChar; + + /* Attempt to send right up to the end of the string. */ + xBytesActuallySent = xStreamBufferSend( xStreamBuffer, ( const void * ) &( pc54ByteString[ xNextChar ] ), xBytesToSend, sbDONT_BLOCK ); + prvCheckExpectedState( xBytesActuallySent <= xBytesToSend ); + + /* Move the index up the string to the next character to be sent, + * wrapping if the end of the string has been reached. */ + xNextChar += xBytesActuallySent; + prvCheckExpectedState( xNextChar <= xStringLength ); + + if( xNextChar == xStringLength ) + { + xNextChar = 0; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvNonBlockingReceiverTask( void * pvParameters ) +{ + StreamBufferHandle_t xStreamBuffer; + size_t xNextChar = 0, xReceiveLength, xBytesToTest, xStartIndex; + const size_t xStringLength = strlen( pc54ByteString ); + char cRxString[ 12 ]; /* Holds received characters. */ + BaseType_t xNonBlockingReceiveError = pdFALSE; + + /* In this case the stream buffer has already been created and is passed + * into the task using the task's parameter. */ + xStreamBuffer = ( StreamBufferHandle_t ) pvParameters; + + /* Expects to receive the pc54ByteString over and over again. Sends and + * receives are not blocking so will interleave. */ + for( ; ; ) + { + /* Attempt to receive as many bytes as possible, up to the limit of the + * Rx buffer size. */ + xReceiveLength = xStreamBufferReceive( xStreamBuffer, ( void * ) cRxString, sizeof( cRxString ), sbDONT_BLOCK ); + + if( xReceiveLength > 0 ) + { + /* xNextChar is the index into pc54ByteString that has been received + * already. If xReceiveLength bytes are added to that, will it go off + * the end of the string? If so, then first test up to the end of the + * string, then go back to the start of pc54ByteString to test the + * remains of the received data. */ + xBytesToTest = xReceiveLength; + + if( ( xNextChar + xBytesToTest ) > xStringLength ) + { + /* Cap to test the received data to the end of the string. */ + xBytesToTest = xStringLength - xNextChar; + + if( memcmp( ( const void * ) &( pc54ByteString[ xNextChar ] ), ( const void * ) cRxString, xBytesToTest ) != 0 ) + { + xNonBlockingReceiveError = pdTRUE; + } + + /* Then move back to the start of the string to test the + * remaining received bytes. */ + xNextChar = 0; + xStartIndex = xBytesToTest; + xBytesToTest = xReceiveLength - xBytesToTest; + } + else + { + /* The string didn't wrap in the buffer, so start comparing from + * the start of the received data. */ + xStartIndex = 0; + } + + /* Test the received bytes are as expected, then move the index + * along the string to the next expected char to receive. */ + if( memcmp( ( const void * ) &( pc54ByteString[ xNextChar ] ), ( const void * ) &( cRxString[ xStartIndex ] ), xBytesToTest ) != 0 ) + { + xNonBlockingReceiveError = pdTRUE; + } + + if( xNonBlockingReceiveError == pdFALSE ) + { + /* No errors detected so increment the counter that lets the + * check task know this test is still functioning correctly. */ + ulNonBlockingRxCounter++; + } + + xNextChar += xBytesToTest; + + if( xNextChar >= xStringLength ) + { + xNextChar = 0; + } + } + } +} +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + static void prvSenderTask( void * pvParameters ) + { + StreamBufferHandle_t xStreamBuffer, xTempStreamBuffer; + static uint8_t ucTempBuffer[ 10 ]; /* Just used to exercise stream buffer creating and deletion. */ + const TickType_t xTicksToWait = sbRX_TX_BLOCK_TIME, xShortDelay = pdMS_TO_TICKS( 50 ); + StaticStreamBuffer_t xStaticStreamBuffer; + size_t xNextChar = 0, xBytesToSend, xBytesActuallySent; + const size_t xStringLength = strlen( pc55ByteString ); + + /* The task's priority is used as an index into the loop counters used to + * indicate this task is still running. */ + UBaseType_t uxIndex = uxTaskPriorityGet( NULL ); + + /* Make sure a change in priority does not inadvertently result in an + * invalid array index. */ + prvCheckExpectedState( uxIndex < sbNUMBER_OF_ECHO_CLIENTS ); + + /* Avoid compiler warnings about unused parameters. */ + ( void ) pvParameters; + + xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ) / sbNUMBER_OF_SENDER_TASKS, /* The number of bytes in each buffer in the array. */ + sbTRIGGER_LEVEL_1, /* The number of bytes to be in the buffer before a task blocked to wait for data is unblocked. */ + &( ucBufferStorage[ uxIndex ][ 0 ] ), /* The address of the buffer to use within the array. */ + &( xStaticStreamBuffers[ uxIndex ] ) ); /* The static stream buffer structure to use within the array. */ + + /* Now the stream buffer has been created the receiver task can be + * created. If this sender task has the higher priority then the receiver + * task is created at the lower priority - if this sender task has the + * lower priority then the receiver task is created at the higher + * priority. */ + if( uxTaskPriorityGet( NULL ) == sbLOWER_PRIORITY ) + { + /* Here prvSingleTaskTests() performs various tests on a stream buffer + * that was created statically. */ + prvSingleTaskTests( xStreamBuffer ); + xTaskCreate( prvReceiverTask, "StrReceiver", sbSMALLER_STACK_SIZE, ( void * ) xStreamBuffer, sbHIGHER_PRIORITY, NULL ); + } + else + { + xTaskCreate( prvReceiverTask, "StrReceiver", sbSMALLER_STACK_SIZE, ( void * ) xStreamBuffer, sbLOWER_PRIORITY, NULL ); + } + + for( ; ; ) + { + /* The whole string cannot be sent at once, so xNextChar is an index + * to the position within the string that has been sent so far. How + * many bytes are there left to send before the end of the string? */ + xBytesToSend = xStringLength - xNextChar; + + /* Attempt to send right up to the end of the string. */ + xBytesActuallySent = xStreamBufferSend( xStreamBuffer, ( const void * ) &( pc55ByteString[ xNextChar ] ), xBytesToSend, xTicksToWait ); + prvCheckExpectedState( xBytesActuallySent <= xBytesToSend ); + + /* Move the index up the string to the next character to be sent, + * wrapping if the end of the string has been reached. */ + xNextChar += xBytesActuallySent; + prvCheckExpectedState( xNextChar <= xStringLength ); + + if( xNextChar == xStringLength ) + { + xNextChar = 0; + } + + /* Increment a loop counter so a check task can tell this task is + * still running as expected. */ + ulSenderLoopCounters[ uxIndex ]++; + + if( uxTaskPriorityGet( NULL ) == sbHIGHER_PRIORITY ) + { + /* Allow other tasks to run. */ + vTaskDelay( xShortDelay ); + } + + /* This stream buffer is just created and deleted to ensure no + * issues when attempting to delete a stream buffer that was + * created using statically allocated memory. To save stack space + * the buffer is set to point to the pc55ByteString, which is a const + * string, but no data is written into the buffer so any valid address + * will do. */ + xTempStreamBuffer = xStreamBufferCreateStatic( sizeof( ucTempBuffer ), sbTRIGGER_LEVEL_1, ucTempBuffer, &xStaticStreamBuffer ); + xStreamBufferReset( xTempStreamBuffer ); + vStreamBufferDelete( xTempStreamBuffer ); + } + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + static void prvReceiverTask( void * pvParameters ) + { + StreamBufferHandle_t const pxStreamBuffer = ( StreamBufferHandle_t ) pvParameters; + char cRxString[ 12 ]; /* Large enough to hold a 32-bit number in ASCII. */ + const TickType_t xTicksToWait = pdMS_TO_TICKS( 5UL ); + const size_t xStringLength = strlen( pc55ByteString ); + size_t xNextChar = 0, xReceivedLength, xBytesToReceive; + + for( ; ; ) + { + /* Attempt to receive the number of bytes to the end of the string, + * or the number of byte that can be placed into the rx buffer, + * whichever is smallest. */ + xBytesToReceive = configMIN( ( xStringLength - xNextChar ), sizeof( cRxString ) ); + + do + { + xReceivedLength = xStreamBufferReceive( pxStreamBuffer, ( void * ) cRxString, xBytesToReceive, xTicksToWait ); + } while( xReceivedLength == 0 ); + + /* Ensure the received string matches the expected string. */ + prvCheckExpectedState( memcmp( ( void * ) cRxString, ( const void * ) &( pc55ByteString[ xNextChar ] ), xReceivedLength ) == 0 ); + + /* Move the index into the string up to the end of the bytes + * received so far - wrapping if the end of the string has been + * reached. */ + xNextChar += xReceivedLength; + + if( xNextChar >= xStringLength ) + { + xNextChar = 0; + } + } + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvEchoClient( void * pvParameters ) +{ + size_t xSendLength = 0, ux; + char * pcStringToSend, * pcStringReceived, cNextChar = sbASCII_SPACE; + const TickType_t xTicksToWait = pdMS_TO_TICKS( 50 ); + StreamBufferHandle_t xTempStreamBuffer; + +/* The task's priority is used as an index into the loop counters used to + * indicate this task is still running. */ + UBaseType_t uxIndex = uxTaskPriorityGet( NULL ); + +/* Pointers to the client and server stream buffers are passed into this task + * using the task's parameter. */ + EchoStreamBuffers_t * pxStreamBuffers = ( EchoStreamBuffers_t * ) pvParameters; + + /* Prevent compiler warnings. */ + ( void ) pvParameters; + + /* Create the buffer into which strings to send to the server will be + * created, and the buffer into which strings echoed back from the server will + * be copied. */ + pcStringToSend = ( char * ) pvPortMalloc( sbSTREAM_BUFFER_LENGTH_BYTES ); + pcStringReceived = ( char * ) pvPortMalloc( sbSTREAM_BUFFER_LENGTH_BYTES ); + + configASSERT( pcStringToSend ); + configASSERT( pcStringReceived ); + + for( ; ; ) + { + /* Generate the length of the next string to send. */ + xSendLength++; + + /* The stream buffer is being used to hold variable length data, so + * each data item requires sizeof( size_t ) bytes to hold the data's + * length, hence the sizeof() in the if() condition below. */ + if( xSendLength > ( sbSTREAM_BUFFER_LENGTH_BYTES - sizeof( size_t ) ) ) + { + /* Back to a string length of 1. */ + xSendLength = sizeof( char ); + } + + memset( pcStringToSend, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); + + for( ux = 0; ux < xSendLength; ux++ ) + { + pcStringToSend[ ux ] = cNextChar; + + cNextChar++; + + if( cNextChar > sbASCII_TILDA ) + { + cNextChar = sbASCII_SPACE; + } + } + + /* Send the generated string to the buffer. */ + do + { + ux = xStreamBufferSend( pxStreamBuffers->xEchoClientBuffer, ( void * ) pcStringToSend, xSendLength, xTicksToWait ); + } while( ux == 0 ); + + /* Wait for the string to be echoed back. */ + memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); + xStreamBufferReceive( pxStreamBuffers->xEchoServerBuffer, ( void * ) pcStringReceived, xSendLength, portMAX_DELAY ); + + prvCheckExpectedState( strcmp( pcStringToSend, pcStringReceived ) == 0 ); + + /* Maintain a count of the number of times this code executes so a + * check task can determine if this task is still functioning as + * expected or not. As there are two client tasks, and the priorities + * used are 0 and 1, the task's priority is used as an index into the + * loop count array. */ + ulEchoLoopCounters[ uxIndex ]++; + + /* This stream buffer is just created and deleted to ensure no memory + * leaks. */ + xTempStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 ); + vStreamBufferDelete( xTempStreamBuffer ); + + /* The following are tests for a stream buffer of size one. */ + /* Create a buffer of size one. */ + xTempStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_ONE, sbTRIGGER_LEVEL_1 ); + /* Ensure that the buffer was created successfully. */ + configASSERT( xTempStreamBuffer ); + + /* Send one byte to the buffer. */ + ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 1, sbDONT_BLOCK ); + /* Ensure that the byte was sent successfully. */ + configASSERT( ux == 1 ); + /* Try sending another byte to the buffer. */ + ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 1, sbDONT_BLOCK ); + /* Make sure that send failed as the buffer is full. */ + configASSERT( ux == 0 ); + + /* Receive one byte from the buffer. */ + memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); + ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 1, sbDONT_BLOCK ); + /* Ensure that the receive was successful. */ + configASSERT( ux == 1 ); + /* Ensure that the correct data was received. */ + configASSERT( pcStringToSend[ 0 ] == pcStringReceived[ 0 ] ); + /* Try receiving another byte from the buffer. */ + ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 1, sbDONT_BLOCK ); + /* Ensure that the receive failed as the buffer is empty. */ + configASSERT( ux == 0 ); + + /* Try sending two bytes to the buffer. Since the size of the + * buffer is one, we must not be able to send more than one. */ + ux = xStreamBufferSend( xTempStreamBuffer, ( void * ) pcStringToSend, ( size_t ) 2, sbDONT_BLOCK ); + /* Ensure that only one byte was sent. */ + configASSERT( ux == 1 ); + + /* Try receiving two bytes from the buffer. Since the size of the + * buffer is one, we must not be able to get more than one. */ + memset( pcStringReceived, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); + ux = xStreamBufferReceive( xTempStreamBuffer, ( void * ) pcStringReceived, ( size_t ) 2, sbDONT_BLOCK ); + /* Ensure that only one byte was received. */ + configASSERT( ux == 1 ); + /* Ensure that the correct data was received. */ + configASSERT( pcStringToSend[ 0 ] == pcStringReceived[ 0 ] ); + + /* Delete the buffer. */ + vStreamBufferDelete( xTempStreamBuffer ); + } +} +/*-----------------------------------------------------------*/ + +static void prvEchoServer( void * pvParameters ) +{ + size_t xReceivedLength; + char * pcReceivedString; + EchoStreamBuffers_t xStreamBuffers; + TickType_t xTimeOnEntering; + const TickType_t xTicksToBlock = pdMS_TO_TICKS( 350UL ); + + /* Prevent compiler warnings about unused parameters. */ + ( void ) pvParameters; + + /* Create the stream buffer used to send data from the client to the server, + * and the stream buffer used to echo the data from the server back to the + * client. */ + xStreamBuffers.xEchoClientBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 ); + xStreamBuffers.xEchoServerBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 ); + configASSERT( xStreamBuffers.xEchoClientBuffer ); + configASSERT( xStreamBuffers.xEchoServerBuffer ); + + /* Create the buffer into which received strings will be copied. */ + pcReceivedString = ( char * ) pvPortMalloc( sbSTREAM_BUFFER_LENGTH_BYTES ); + configASSERT( pcReceivedString ); + + /* Don't expect to receive anything yet! */ + xTimeOnEntering = xTaskGetTickCount(); + xReceivedLength = xStreamBufferReceive( xStreamBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, sbSTREAM_BUFFER_LENGTH_BYTES, xTicksToBlock ); + prvCheckExpectedState( ( ( TickType_t ) ( xTaskGetTickCount() - xTimeOnEntering ) ) >= xTicksToBlock ); + prvCheckExpectedState( xReceivedLength == 0 ); + + /* Now the stream buffers have been created the echo client task can be + * created. If this server task has the higher priority then the client task + * is created at the lower priority - if this server task has the lower + * priority then the client task is created at the higher priority. */ + if( uxTaskPriorityGet( NULL ) == sbLOWER_PRIORITY ) + { + xTaskCreate( prvEchoClient, "EchoClient", sbSMALLER_STACK_SIZE, ( void * ) &xStreamBuffers, sbHIGHER_PRIORITY, NULL ); + } + else + { + /* Here prvSingleTaskTests() performs various tests on a stream buffer + * that was created dynamically. */ + prvSingleTaskTests( xStreamBuffers.xEchoClientBuffer ); + xTaskCreate( prvEchoClient, "EchoClient", sbSMALLER_STACK_SIZE, ( void * ) &xStreamBuffers, sbLOWER_PRIORITY, NULL ); + } + + for( ; ; ) + { + memset( pcReceivedString, 0x00, sbSTREAM_BUFFER_LENGTH_BYTES ); + + /* Has any data been sent by the client? */ + xReceivedLength = xStreamBufferReceive( xStreamBuffers.xEchoClientBuffer, ( void * ) pcReceivedString, sbSTREAM_BUFFER_LENGTH_BYTES, portMAX_DELAY ); + + /* Should always receive data as max delay was used. */ + prvCheckExpectedState( xReceivedLength > 0 ); + + /* Echo the received data back to the client. */ + xStreamBufferSend( xStreamBuffers.xEchoServerBuffer, ( void * ) pcReceivedString, xReceivedLength, portMAX_DELAY ); + } +} +/*-----------------------------------------------------------*/ + +void vPeriodicStreamBufferProcessing( void ) +{ + static size_t xNextChar = 0; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + /* Called from the tick interrupt hook. If the global stream buffer + * variable is not NULL then the prvInterruptTriggerTest() task expects a byte + * to be sent to the stream buffer on each tick interrupt. */ + if( xInterruptStreamBuffer != NULL ) + { + /* One character from the pcDataSentFromInterrupt string is sent on each + * interrupt. The task blocked on the stream buffer should not be + * unblocked until the defined trigger level is hit. */ + xStreamBufferSendFromISR( xInterruptStreamBuffer, ( const void * ) &( pcDataSentFromInterrupt[ xNextChar ] ), sizeof( char ), &xHigherPriorityTaskWoken ); + + if( xNextChar < strlen( pcDataSentFromInterrupt ) ) + { + xNextChar++; + } + } + else + { + /* Start at the beginning of the string being sent again. */ + xNextChar = 0; + } +} +/*-----------------------------------------------------------*/ + +static void prvInterruptTriggerLevelTest( void * pvParameters ) +{ + StreamBufferHandle_t xStreamBuffer; + size_t xTriggerLevel = 1, xBytesReceived; + const size_t xStreamBufferSizeBytes = ( size_t ) 9, xMaxTriggerLevel = ( size_t ) 7, xMinTriggerLevel = ( size_t ) 2; + const TickType_t xReadBlockTime = 5, xCycleBlockTime = pdMS_TO_TICKS( 100 ); + uint8_t ucRxData[ 9 ]; + BaseType_t xErrorDetected = pdFALSE; + + #ifndef configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN + const size_t xAllowableMargin = ( size_t ) 0; + #else + const size_t xAllowableMargin = ( size_t ) configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN; + #endif + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + for( ; ; ) + { + for( xTriggerLevel = xMinTriggerLevel; xTriggerLevel < xMaxTriggerLevel; xTriggerLevel++ ) + { + /* This test is very time sensitive so delay at the beginning to ensure + * the rest of the system is up and running before starting. Delay between + * each loop to ensure the interrupt that sends to the stream buffer + * detects it needs to start sending from the start of the string again.. */ + vTaskDelay( xCycleBlockTime ); + + /* Create the stream buffer that will be used from inside the tick + * interrupt. */ + memset( ucRxData, 0x00, sizeof( ucRxData ) ); + xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel ); + configASSERT( xStreamBuffer ); + + /* Now the stream buffer has been created it can be assigned to the + * file scope variable, which will allow the tick interrupt to start + * using it. */ + taskENTER_CRITICAL(); + { + xInterruptStreamBuffer = xStreamBuffer; + } + taskEXIT_CRITICAL(); + + xBytesReceived = xStreamBufferReceive( xStreamBuffer, ( void * ) ucRxData, sizeof( ucRxData ), xReadBlockTime ); + + /* Set the file scope variable back to NULL so the interrupt doesn't + * try to use it again. */ + taskENTER_CRITICAL(); + { + xInterruptStreamBuffer = NULL; + } + taskEXIT_CRITICAL(); + + /* Now check the number of bytes received equals the trigger level, + * except in the case that the read timed out before the trigger level + * was reached. */ + if( xTriggerLevel > xReadBlockTime ) + { + /* Trigger level was greater than the block time so expect to + * time out having received xReadBlockTime bytes. */ + if( xBytesReceived > xReadBlockTime ) + { + /* Received more bytes than expected. That could happen if + * this task unblocked at the right time, but an interrupt + * added another byte to the stream buffer before this task was + * able to run. */ + if( ( xBytesReceived - xReadBlockTime ) > xAllowableMargin ) + { + xErrorDetected = pdTRUE; + } + } + else if( xReadBlockTime != xBytesReceived ) + { + /* It is possible the interrupt placed an item in the stream + * buffer before this task called xStreamBufferReceive(), but + * if that is the case then xBytesReceived will only every be + * 0 as the interrupt will only have executed once. */ + if( xBytesReceived != 1 ) + { + xErrorDetected = pdTRUE; + } + } + } + else if( xTriggerLevel < xReadBlockTime ) + { + /* Trigger level was less than the block time so we expect to + * have received the trigger level number of bytes - could be more + * though depending on other activity between the task being + * unblocked and the task reading the number of bytes received. It + * could also be less if the interrupt already put something in the + * stream buffer before this task attempted to read it - in which + * case the task would have returned the available bytes immediately + * without ever blocking - in that case the bytes received will + * only ever be 1 as the interrupt would not have executed more + * than one in that time unless this task has too low a priority. */ + if( xBytesReceived < xTriggerLevel ) + { + if( xBytesReceived != 1 ) + { + xErrorDetected = pdTRUE; + } + } + else if( ( xBytesReceived - xTriggerLevel ) > xAllowableMargin ) + { + xErrorDetected = pdTRUE; + } + } + else + { + /* The trigger level equalled the block time, so expect to + * receive no greater than the block time. It could also be less + * if the interrupt already put something in the stream buffer + * before this task attempted to read it - in which case the task + * would have returned the available bytes immediately without ever + * blocking - in that case the bytes received would only ever be 1 + * because the interrupt is not going to execute twice in that time + * unless this task is running a too low a priority. */ + if( xBytesReceived < xReadBlockTime ) + { + if( xBytesReceived != 1 ) + { + xErrorDetected = pdTRUE; + } + } + else if( ( xBytesReceived - xReadBlockTime ) > xAllowableMargin ) + { + xErrorDetected = pdTRUE; + } + } + + if( xBytesReceived > sizeof( ucRxData ) ) + { + xErrorDetected = pdTRUE; + } + else if( memcmp( ( void * ) ucRxData, ( const void * ) pcDataSentFromInterrupt, xBytesReceived ) != 0 ) + { + /* Received data didn't match that expected. */ + xErrorDetected = pdTRUE; + } + + if( xErrorDetected == pdFALSE ) + { + /* Increment the cycle counter so the 'check' task knows this test + * is still running without error. */ + ulInterruptTriggerCounter++; + } + + /* Tidy up ready for the next loop. */ + vStreamBufferDelete( xStreamBuffer ); + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreStreamBufferTasksStillRunning( void ) +{ + static uint32_t ulLastEchoLoopCounters[ sbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; + static uint32_t ulLastNonBlockingRxCounter = 0; + static uint32_t ulLastInterruptTriggerCounter = 0; + BaseType_t x; + + for( x = 0; x < sbNUMBER_OF_ECHO_CLIENTS; x++ ) + { + if( ulLastEchoLoopCounters[ x ] == ulEchoLoopCounters[ x ] ) + { + xErrorStatus = pdFAIL; + } + else + { + ulLastEchoLoopCounters[ x ] = ulEchoLoopCounters[ x ]; + } + } + + if( ulNonBlockingRxCounter == ulLastNonBlockingRxCounter ) + { + xErrorStatus = pdFAIL; + } + else + { + ulLastNonBlockingRxCounter = ulNonBlockingRxCounter; + } + + if( ulLastInterruptTriggerCounter == ulInterruptTriggerCounter ) + { + xErrorStatus = pdFAIL; + } + else + { + ulLastInterruptTriggerCounter = ulInterruptTriggerCounter; + } + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + static uint32_t ulLastSenderLoopCounters[ sbNUMBER_OF_ECHO_CLIENTS ] = { 0 }; + + for( x = 0; x < sbNUMBER_OF_SENDER_TASKS; x++ ) + { + if( ulLastSenderLoopCounters[ x ] == ulSenderLoopCounters[ x ] ) + { + xErrorStatus = pdFAIL; + } + else + { + ulLastSenderLoopCounters[ x ] = ulSenderLoopCounters[ x ]; + } + } + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + return xErrorStatus; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c b/FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c index ce680e08a..b974ffe75 100644 --- a/FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c +++ b/FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c @@ -1,228 +1,228 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * A simple example that shows a stream buffer being used to pass data from an - * interrupt to a task. - * - * There are two strings, pcStringToSend and pcStringToReceive, where - * pcStringToReceive is a substring of pcStringToSend. The interrupt sends - * a few bytes of pcStringToSend to a stream buffer ever few times that it - * executes. A task reads the bytes from the stream buffer, looking for the - * substring, and flagging an error if the received data is invalid. - */ - -/* Standard includes. */ -#include "stdio.h" -#include "string.h" - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "stream_buffer.h" - -/* Demo app includes. */ -#include "StreamBufferInterrupt.h" - -#define sbiSTREAM_BUFFER_LENGTH_BYTES ( ( size_t ) 100 ) -#define sbiSTREAM_BUFFER_TRIGGER_LEVEL_10 ( ( BaseType_t ) 10 ) - -/*-----------------------------------------------------------*/ - -/* Implements the task that receives a stream of bytes from the interrupt. */ -static void prvReceivingTask( void * pvParameters ); - -/*-----------------------------------------------------------*/ - -/* The stream buffer that is used to send data from an interrupt to the task. */ -static StreamBufferHandle_t xStreamBuffer = NULL; - -/* The string that is sent from the interrupt to the task four bytes at a - * time. Must be multiple of 4 bytes long as the ISR sends 4 bytes at a time*/ -static const char * pcStringToSend = "_____Hello FreeRTOS_____"; - -/* The string to task is looking for, which must be a substring of - * pcStringToSend. */ -static const char * pcStringToReceive = "Hello FreeRTOS"; - -/* Set to pdFAIL if anything unexpected happens. */ -static BaseType_t xDemoStatus = pdPASS; - -/* Incremented each time pcStringToReceive is correctly received, provided no - * errors have occurred. Used so the check task can check this task is still - * running as expected. */ -static uint32_t ulCycleCount = 0; - -/*-----------------------------------------------------------*/ - -void vStartStreamBufferInterruptDemo( void ) -{ - /* Create the stream buffer that sends data from the interrupt to the - * task, and create the task. */ - xStreamBuffer = xStreamBufferCreate( /* The buffer length in bytes. */ - sbiSTREAM_BUFFER_LENGTH_BYTES, - /* The stream buffer's trigger level. */ - sbiSTREAM_BUFFER_TRIGGER_LEVEL_10 ); - - xTaskCreate( prvReceivingTask, /* The function that implements the task. */ - "StrIntRx", /* Human readable name for the task. */ - configMINIMAL_STACK_SIZE, /* Stack size (in words!). */ - NULL, /* Task parameter is not used. */ - tskIDLE_PRIORITY + 2, /* The priority at which the task is created. */ - NULL ); /* No use for the task handle. */ -} -/*-----------------------------------------------------------*/ - -static void prvReceivingTask( void * pvParameters ) -{ - char cRxBuffer[ 20 ]; - BaseType_t xNextByte = 0; - - /* Remove warning about unused parameters. */ - ( void ) pvParameters; - - /* Make sure the string will fit in the Rx buffer, including the NULL - * terminator. */ - configASSERT( sizeof( cRxBuffer ) > strlen( pcStringToReceive ) ); - - /* Make sure the stream buffer has been created. */ - configASSERT( xStreamBuffer != NULL ); - - /* Start with the Rx buffer in a known state. */ - memset( cRxBuffer, 0x00, sizeof( cRxBuffer ) ); - - for( ; ; ) - { - /* Keep receiving characters until the end of the string is received. - * Note: An infinite block time is used to simplify the example. Infinite - * block times are not recommended in production code as they do not allow - * for error recovery. */ - xStreamBufferReceive( /* The stream buffer data is being received from. */ - xStreamBuffer, - /* Where to place received data. */ - ( void * ) &( cRxBuffer[ xNextByte ] ), - /* The number of bytes to receive. */ - sizeof( char ), - - /* The time to wait for the next data if the buffer - * is empty. */ - portMAX_DELAY ); - - /* If xNextByte is 0 then this task is looking for the start of the - * string, which is 'H'. */ - if( xNextByte == 0 ) - { - if( cRxBuffer[ xNextByte ] == 'H' ) - { - /* The start of the string has been found. Now receive - * characters until the end of the string is found. */ - xNextByte++; - } - } - else - { - /* Receiving characters while looking for the end of the string, - * which is an 'S'. */ - if( cRxBuffer[ xNextByte ] == 'S' ) - { - /* The string has now been received. Check its validity. */ - if( strcmp( cRxBuffer, pcStringToReceive ) != 0 ) - { - xDemoStatus = pdFAIL; - } - - /* Return to start looking for the beginning of the string - * again. */ - memset( cRxBuffer, 0x00, sizeof( cRxBuffer ) ); - xNextByte = 0; - - /* Increment the cycle count as an indication to the check task - * that this demo is still running. */ - if( xDemoStatus == pdPASS ) - { - ulCycleCount++; - } - } - else - { - /* Receive the next character the next time around, while - * continuing to look for the end of the string. */ - xNextByte++; - - configASSERT( ( size_t ) xNextByte < sizeof( cRxBuffer ) ); - } - } - } -} -/*-----------------------------------------------------------*/ - -void vBasicStreamBufferSendFromISR( void ) -{ - static size_t xNextByteToSend = 0; - const BaseType_t xCallsBetweenSends = 100, xBytesToSend = 4; - static BaseType_t xCallCount = 0; - - /* Is it time to write to the stream buffer again? */ - xCallCount++; - - if( xCallCount > xCallsBetweenSends ) - { - xCallCount = 0; - - /* Send the next four bytes to the stream buffer. */ - xStreamBufferSendFromISR( xStreamBuffer, - ( const void * ) ( pcStringToSend + xNextByteToSend ), - xBytesToSend, - NULL ); - - /* Send the next four bytes the next time around, wrapping to the start - * of the string if necessary. */ - xNextByteToSend += xBytesToSend; - - if( xNextByteToSend >= strlen( pcStringToSend ) ) - { - xNextByteToSend = 0; - } - } -} -/*-----------------------------------------------------------*/ - -BaseType_t xIsInterruptStreamBufferDemoStillRunning( void ) -{ - uint32_t ulLastCycleCount = 0; - - /* Check the demo is still running. */ - if( ulLastCycleCount == ulCycleCount ) - { - xDemoStatus = pdFAIL; - } - else - { - ulLastCycleCount = ulCycleCount; - } - - return xDemoStatus; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * A simple example that shows a stream buffer being used to pass data from an + * interrupt to a task. + * + * There are two strings, pcStringToSend and pcStringToReceive, where + * pcStringToReceive is a substring of pcStringToSend. The interrupt sends + * a few bytes of pcStringToSend to a stream buffer ever few times that it + * executes. A task reads the bytes from the stream buffer, looking for the + * substring, and flagging an error if the received data is invalid. + */ + +/* Standard includes. */ +#include "stdio.h" +#include "string.h" + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "stream_buffer.h" + +/* Demo app includes. */ +#include "StreamBufferInterrupt.h" + +#define sbiSTREAM_BUFFER_LENGTH_BYTES ( ( size_t ) 100 ) +#define sbiSTREAM_BUFFER_TRIGGER_LEVEL_10 ( ( BaseType_t ) 10 ) + +/*-----------------------------------------------------------*/ + +/* Implements the task that receives a stream of bytes from the interrupt. */ +static void prvReceivingTask( void * pvParameters ); + +/*-----------------------------------------------------------*/ + +/* The stream buffer that is used to send data from an interrupt to the task. */ +static StreamBufferHandle_t xStreamBuffer = NULL; + +/* The string that is sent from the interrupt to the task four bytes at a + * time. Must be multiple of 4 bytes long as the ISR sends 4 bytes at a time*/ +static const char * pcStringToSend = "_____Hello FreeRTOS_____"; + +/* The string to task is looking for, which must be a substring of + * pcStringToSend. */ +static const char * pcStringToReceive = "Hello FreeRTOS"; + +/* Set to pdFAIL if anything unexpected happens. */ +static BaseType_t xDemoStatus = pdPASS; + +/* Incremented each time pcStringToReceive is correctly received, provided no + * errors have occurred. Used so the check task can check this task is still + * running as expected. */ +static uint32_t ulCycleCount = 0; + +/*-----------------------------------------------------------*/ + +void vStartStreamBufferInterruptDemo( void ) +{ + /* Create the stream buffer that sends data from the interrupt to the + * task, and create the task. */ + xStreamBuffer = xStreamBufferCreate( /* The buffer length in bytes. */ + sbiSTREAM_BUFFER_LENGTH_BYTES, + /* The stream buffer's trigger level. */ + sbiSTREAM_BUFFER_TRIGGER_LEVEL_10 ); + + xTaskCreate( prvReceivingTask, /* The function that implements the task. */ + "StrIntRx", /* Human readable name for the task. */ + configMINIMAL_STACK_SIZE, /* Stack size (in words!). */ + NULL, /* Task parameter is not used. */ + tskIDLE_PRIORITY + 2, /* The priority at which the task is created. */ + NULL ); /* No use for the task handle. */ +} +/*-----------------------------------------------------------*/ + +static void prvReceivingTask( void * pvParameters ) +{ + char cRxBuffer[ 20 ]; + BaseType_t xNextByte = 0; + + /* Remove warning about unused parameters. */ + ( void ) pvParameters; + + /* Make sure the string will fit in the Rx buffer, including the NULL + * terminator. */ + configASSERT( sizeof( cRxBuffer ) > strlen( pcStringToReceive ) ); + + /* Make sure the stream buffer has been created. */ + configASSERT( xStreamBuffer != NULL ); + + /* Start with the Rx buffer in a known state. */ + memset( cRxBuffer, 0x00, sizeof( cRxBuffer ) ); + + for( ; ; ) + { + /* Keep receiving characters until the end of the string is received. + * Note: An infinite block time is used to simplify the example. Infinite + * block times are not recommended in production code as they do not allow + * for error recovery. */ + xStreamBufferReceive( /* The stream buffer data is being received from. */ + xStreamBuffer, + /* Where to place received data. */ + ( void * ) &( cRxBuffer[ xNextByte ] ), + /* The number of bytes to receive. */ + sizeof( char ), + + /* The time to wait for the next data if the buffer + * is empty. */ + portMAX_DELAY ); + + /* If xNextByte is 0 then this task is looking for the start of the + * string, which is 'H'. */ + if( xNextByte == 0 ) + { + if( cRxBuffer[ xNextByte ] == 'H' ) + { + /* The start of the string has been found. Now receive + * characters until the end of the string is found. */ + xNextByte++; + } + } + else + { + /* Receiving characters while looking for the end of the string, + * which is an 'S'. */ + if( cRxBuffer[ xNextByte ] == 'S' ) + { + /* The string has now been received. Check its validity. */ + if( strcmp( cRxBuffer, pcStringToReceive ) != 0 ) + { + xDemoStatus = pdFAIL; + } + + /* Return to start looking for the beginning of the string + * again. */ + memset( cRxBuffer, 0x00, sizeof( cRxBuffer ) ); + xNextByte = 0; + + /* Increment the cycle count as an indication to the check task + * that this demo is still running. */ + if( xDemoStatus == pdPASS ) + { + ulCycleCount++; + } + } + else + { + /* Receive the next character the next time around, while + * continuing to look for the end of the string. */ + xNextByte++; + + configASSERT( ( size_t ) xNextByte < sizeof( cRxBuffer ) ); + } + } + } +} +/*-----------------------------------------------------------*/ + +void vBasicStreamBufferSendFromISR( void ) +{ + static size_t xNextByteToSend = 0; + const BaseType_t xCallsBetweenSends = 100, xBytesToSend = 4; + static BaseType_t xCallCount = 0; + + /* Is it time to write to the stream buffer again? */ + xCallCount++; + + if( xCallCount > xCallsBetweenSends ) + { + xCallCount = 0; + + /* Send the next four bytes to the stream buffer. */ + xStreamBufferSendFromISR( xStreamBuffer, + ( const void * ) ( pcStringToSend + xNextByteToSend ), + xBytesToSend, + NULL ); + + /* Send the next four bytes the next time around, wrapping to the start + * of the string if necessary. */ + xNextByteToSend += xBytesToSend; + + if( xNextByteToSend >= strlen( pcStringToSend ) ) + { + xNextByteToSend = 0; + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xIsInterruptStreamBufferDemoStillRunning( void ) +{ + uint32_t ulLastCycleCount = 0; + + /* Check the demo is still running. */ + if( ulLastCycleCount == ulCycleCount ) + { + xDemoStatus = pdFAIL; + } + else + { + ulLastCycleCount = ulCycleCount; + } + + return xDemoStatus; +} diff --git a/FreeRTOS/Demo/Common/Minimal/TaskNotify.c b/FreeRTOS/Demo/Common/Minimal/TaskNotify.c index a2facda9a..b87c9d646 100644 --- a/FreeRTOS/Demo/Common/Minimal/TaskNotify.c +++ b/FreeRTOS/Demo/Common/Minimal/TaskNotify.c @@ -1,720 +1,720 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* - * Tests the behaviour of direct task notifications. - */ - -/* Standard includes. */ -#include - -/* Scheduler include files. */ -#include "FreeRTOS.h" -#include "task.h" -#include "timers.h" - -/* Demo program include files. */ -#include "TaskNotify.h" - -/* Allow parameters to be overridden on a demo by demo basis. */ -#ifndef notifyNOTIFIED_TASK_STACK_SIZE - #define notifyNOTIFIED_TASK_STACK_SIZE configMINIMAL_STACK_SIZE -#endif - -#define notifyTASK_PRIORITY ( tskIDLE_PRIORITY ) - -/* Constants used in tests when setting/clearing bits. */ -#define notifyUINT32_MAX ( ( uint32_t ) 0xffffffff ) -#define notifyUINT32_HIGH_BYTE ( ( uint32_t ) 0xff000000 ) -#define notifyUINT32_LOW_BYTE ( ( uint32_t ) 0x000000ff ) - -#define notifySUSPENDED_TEST_TIMER_PERIOD pdMS_TO_TICKS( 50 ) - -/*-----------------------------------------------------------*/ - -/* - * 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 ); - -/* - * Callback for a timer that is used during preliminary testing. The timer - * tests the behaviour when 1: a task waiting for a notification is suspended - * and then resumed without ever receiving a notification, and 2: when a task - * waiting for a notification receives a notification while it is suspended. - */ -static void prvSuspendedTaskTimerTestCallback( TimerHandle_t xExpiredTimer ); - -/*-----------------------------------------------------------*/ - -/* 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, /* Function that implements the task. */ - "Notified", /* Text name for the task - for debugging only - not used by the kernel. */ - notifyNOTIFIED_TASK_STACK_SIZE, /* Task's stack size in words, not bytes!. */ - NULL, /* Task parameter, not used in this case. */ - notifyTASK_PRIORITY, /* Task priority, 0 is the lowest. */ - &xTaskToNotify ); /* Used to pass a handle to the task out is needed, otherwise set to NULL. */ - - /* 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; - TimerHandle_t xSingleTaskTimer; - - - /* ------------------------------------------------------------------------ - * Check blocking when there are no notifications. */ - xTimeOnEntering = xTaskGetTickCount(); - xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, xTicksToWait ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* Should have blocked for the entire block time. */ - if( ( xTaskGetTickCount() - xTimeOnEntering ) < xTicksToWait ) - { - xErrorStatus = pdFAIL; - } - - configASSERT( xReturned == pdFAIL ); - configASSERT( ulNotifiedValue == 0UL ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - ( void ) ulNotifiedValue; - - - - /* ------------------------------------------------------------------------ - * 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 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* No bits should have been pending previously. */ - configASSERT( ulPreviousValue == 0 ); - ( void ) ulPreviousValue; - - /* 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 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - ( void ) ulNotifiedValue; - - /* 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 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithoutOverwrite ); - configASSERT( xReturned == pdFAIL ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* 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 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - ( void ) ulNotifiedValue; - - - - /*------------------------------------------------------------------------- - * 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 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithOverwrite ); - configASSERT( xReturned == pdPASS ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); - configASSERT( xReturned == pdPASS ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst ); - ( void ) ulNotifiedValue; - - - - /*------------------------------------------------------------------------- - * 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 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); - configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst ); - ( void ) ulNotifiedValue; /* In case configASSERT() is not defined. */ - - /*------------------------------------------------------------------------- - * 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 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - } - - xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); - configASSERT( xReturned == pdPASS ); - configASSERT( ulNotifiedValue == ( ulSecondNotifiedValueConst + ulMaxLoops ) ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - ( void ) ulNotifiedValue; - - /* Should not be any notifications pending now. */ - xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 ); - configASSERT( xReturned == pdFAIL ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - ( void ) ulNotifiedValue; - - - - /*------------------------------------------------------------------------- - * 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 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - 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 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* 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 ) ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - - - /*------------------------------------------------------------------------- - * 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 ) ) ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - - - /*------------------------------------------------------------------------- - * Now try querying the previous 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 ); - - - - /* ------------------------------------------------------------------------ - * Clear bits in the notification value. */ - - /* Get the task to set all bits its own notification value. This is not a - * normal thing to do, and is only done here for test purposes. */ - xTaskNotify( xTaskToNotify, notifyUINT32_MAX, eSetBits ); - - /* Now clear the top bytes - the returned value from the first call should - * indicate that previously all bits were set. */ - configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_HIGH_BYTE ) == notifyUINT32_MAX ); - - /* Next clear the bottom bytes - the returned value this time should indicate - * that the top byte was clear (before the bottom byte was cleared. */ - configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_LOW_BYTE ) == ( notifyUINT32_MAX & ~notifyUINT32_HIGH_BYTE ) ); - - /* Next clear all bytes - the returned value should indicate that previously the - * high and low bytes were clear. */ - configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_MAX ) == ( notifyUINT32_MAX & ~notifyUINT32_HIGH_BYTE & ~notifyUINT32_LOW_BYTE ) ); - - /* Now all bits should be clear. */ - configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_MAX ) == 0 ); - configASSERT( ulTaskNotifyValueClear( xTaskToNotify, 0UL ) == 0 ); - configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_MAX ) == 0 ); - - /* 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 ); - - - - /* ------------------------------------------------------------------------ - * Create a timer that will try notifying this task while it is suspended. */ - xSingleTaskTimer = xTimerCreate( "SingleNotify", notifySUSPENDED_TEST_TIMER_PERIOD, pdFALSE, NULL, prvSuspendedTaskTimerTestCallback ); - configASSERT( xSingleTaskTimer ); - - /* Incremented to show the task is still running. */ - ulNotifyCycleCount++; - - /* Ensure no notifications are pending. */ - xTaskNotifyWait( notifyUINT32_MAX, 0, NULL, 0 ); - - /* Raise the task's priority so it can suspend itself before the timer - * expires. */ - vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); - - /* Start the timer that will try notifying this task while it is - * suspended, then wait for a notification. The first time the callback - * executes the timer will suspend the task, then resume the task, without - * ever sending a notification to the task. */ - ulNotifiedValue = 0; - xTimerStart( xSingleTaskTimer, portMAX_DELAY ); - - /* Check a notification is not received. */ - xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, portMAX_DELAY ); - configASSERT( xReturned == pdFALSE ); - configASSERT( ulNotifiedValue == 0 ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - - /* Incremented to show the task is still running. */ - ulNotifyCycleCount++; - - /* Start the timer that will try notifying this task while it is - * suspended, then wait for a notification. The second time the callback - * executes the timer will suspend the task, notify the task, then resume the - * task (previously it was suspended and resumed without being notified). */ - xTimerStart( xSingleTaskTimer, portMAX_DELAY ); - - /* Check a notification is received. */ - xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, portMAX_DELAY ); - configASSERT( xReturned == pdPASS ); - ( void ) xReturned; /* In case configASSERT() is not defined. */ - configASSERT( ulNotifiedValue != 0 ); - - /* Return the task to its proper priority and delete the timer as it is - * not used again. */ - vTaskPrioritySet( NULL, notifyTASK_PRIORITY ); - xTimerDelete( xSingleTaskTimer, portMAX_DELAY ); - - /* Incremented to show the task is still running. */ - ulNotifyCycleCount++; - - /* Leave all bits cleared. */ - xTaskNotifyWait( notifyUINT32_MAX, 0, NULL, 0 ); -} -/*-----------------------------------------------------------*/ - -static void prvSuspendedTaskTimerTestCallback( TimerHandle_t xExpiredTimer ) -{ - static uint32_t ulCallCount = 0; - - /* Remove compiler warnings about unused parameters. */ - ( void ) xExpiredTimer; - - /* Callback for a timer that is used during preliminary testing. The timer - * tests the behaviour when 1: a task waiting for a notification is suspended - * and then resumed without ever receiving a notification, and 2: when a task - * waiting for a notification receives a notification while it is suspended. */ - - if( ulCallCount == 0 ) - { - vTaskSuspend( xTaskToNotify ); - configASSERT( eTaskGetState( xTaskToNotify ) == eSuspended ); - vTaskResume( xTaskToNotify ); - } - else - { - vTaskSuspend( xTaskToNotify ); - - /* Sending a notification while the task is suspended should pass, but - * not cause the task to resume. ulCallCount is just used as a convenient - * non-zero value. */ - xTaskNotify( xTaskToNotify, ulCallCount, eSetValueWithOverwrite ); - - /* Make sure giving the notification didn't resume the task. */ - configASSERT( eTaskGetState( xTaskToNotify ) == eSuspended ); - - vTaskResume( xTaskToNotify ); - } - - ulCallCount++; -} -/*-----------------------------------------------------------*/ - -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 task's block time, sometimes it will be lower - * than the task's 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 task's block time, - * sometimes it will be lower than the task's 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; - - /* Check the task notification demo tasks were actually created. */ - configASSERT( xTaskToNotify ); - - /* 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 ) ); -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * Tests the behaviour of direct task notifications. + */ + +/* Standard includes. */ +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" + +/* Demo program include files. */ +#include "TaskNotify.h" + +/* Allow parameters to be overridden on a demo by demo basis. */ +#ifndef notifyNOTIFIED_TASK_STACK_SIZE + #define notifyNOTIFIED_TASK_STACK_SIZE configMINIMAL_STACK_SIZE +#endif + +#define notifyTASK_PRIORITY ( tskIDLE_PRIORITY ) + +/* Constants used in tests when setting/clearing bits. */ +#define notifyUINT32_MAX ( ( uint32_t ) 0xffffffff ) +#define notifyUINT32_HIGH_BYTE ( ( uint32_t ) 0xff000000 ) +#define notifyUINT32_LOW_BYTE ( ( uint32_t ) 0x000000ff ) + +#define notifySUSPENDED_TEST_TIMER_PERIOD pdMS_TO_TICKS( 50 ) + +/*-----------------------------------------------------------*/ + +/* + * 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 ); + +/* + * Callback for a timer that is used during preliminary testing. The timer + * tests the behaviour when 1: a task waiting for a notification is suspended + * and then resumed without ever receiving a notification, and 2: when a task + * waiting for a notification receives a notification while it is suspended. + */ +static void prvSuspendedTaskTimerTestCallback( TimerHandle_t xExpiredTimer ); + +/*-----------------------------------------------------------*/ + +/* 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, /* Function that implements the task. */ + "Notified", /* Text name for the task - for debugging only - not used by the kernel. */ + notifyNOTIFIED_TASK_STACK_SIZE, /* Task's stack size in words, not bytes!. */ + NULL, /* Task parameter, not used in this case. */ + notifyTASK_PRIORITY, /* Task priority, 0 is the lowest. */ + &xTaskToNotify ); /* Used to pass a handle to the task out is needed, otherwise set to NULL. */ + + /* 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; + TimerHandle_t xSingleTaskTimer; + + + /* ------------------------------------------------------------------------ + * Check blocking when there are no notifications. */ + xTimeOnEntering = xTaskGetTickCount(); + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, xTicksToWait ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* Should have blocked for the entire block time. */ + if( ( xTaskGetTickCount() - xTimeOnEntering ) < xTicksToWait ) + { + xErrorStatus = pdFAIL; + } + + configASSERT( xReturned == pdFAIL ); + configASSERT( ulNotifiedValue == 0UL ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + ( void ) ulNotifiedValue; + + + + /* ------------------------------------------------------------------------ + * 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 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* No bits should have been pending previously. */ + configASSERT( ulPreviousValue == 0 ); + ( void ) ulPreviousValue; + + /* 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 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + ( void ) ulNotifiedValue; + + /* 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 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithoutOverwrite ); + configASSERT( xReturned == pdFAIL ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* 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 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + ( void ) ulNotifiedValue; + + + + /*------------------------------------------------------------------------- + * 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 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithOverwrite ); + configASSERT( xReturned == pdPASS ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); + configASSERT( xReturned == pdPASS ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst ); + ( void ) ulNotifiedValue; + + + + /*------------------------------------------------------------------------- + * 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 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); + configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst ); + ( void ) ulNotifiedValue; /* In case configASSERT() is not defined. */ + + /*------------------------------------------------------------------------- + * 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 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + } + + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); + configASSERT( xReturned == pdPASS ); + configASSERT( ulNotifiedValue == ( ulSecondNotifiedValueConst + ulMaxLoops ) ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + ( void ) ulNotifiedValue; + + /* Should not be any notifications pending now. */ + xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 ); + configASSERT( xReturned == pdFAIL ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + ( void ) ulNotifiedValue; + + + + /*------------------------------------------------------------------------- + * 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 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + 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 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* 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 ) ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + + + /*------------------------------------------------------------------------- + * 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 ) ) ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + + + /*------------------------------------------------------------------------- + * Now try querying the previous 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 ); + + + + /* ------------------------------------------------------------------------ + * Clear bits in the notification value. */ + + /* Get the task to set all bits its own notification value. This is not a + * normal thing to do, and is only done here for test purposes. */ + xTaskNotify( xTaskToNotify, notifyUINT32_MAX, eSetBits ); + + /* Now clear the top bytes - the returned value from the first call should + * indicate that previously all bits were set. */ + configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_HIGH_BYTE ) == notifyUINT32_MAX ); + + /* Next clear the bottom bytes - the returned value this time should indicate + * that the top byte was clear (before the bottom byte was cleared. */ + configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_LOW_BYTE ) == ( notifyUINT32_MAX & ~notifyUINT32_HIGH_BYTE ) ); + + /* Next clear all bytes - the returned value should indicate that previously the + * high and low bytes were clear. */ + configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_MAX ) == ( notifyUINT32_MAX & ~notifyUINT32_HIGH_BYTE & ~notifyUINT32_LOW_BYTE ) ); + + /* Now all bits should be clear. */ + configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_MAX ) == 0 ); + configASSERT( ulTaskNotifyValueClear( xTaskToNotify, 0UL ) == 0 ); + configASSERT( ulTaskNotifyValueClear( xTaskToNotify, notifyUINT32_MAX ) == 0 ); + + /* 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 ); + + + + /* ------------------------------------------------------------------------ + * Create a timer that will try notifying this task while it is suspended. */ + xSingleTaskTimer = xTimerCreate( "SingleNotify", notifySUSPENDED_TEST_TIMER_PERIOD, pdFALSE, NULL, prvSuspendedTaskTimerTestCallback ); + configASSERT( xSingleTaskTimer ); + + /* Incremented to show the task is still running. */ + ulNotifyCycleCount++; + + /* Ensure no notifications are pending. */ + xTaskNotifyWait( notifyUINT32_MAX, 0, NULL, 0 ); + + /* Raise the task's priority so it can suspend itself before the timer + * expires. */ + vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); + + /* Start the timer that will try notifying this task while it is + * suspended, then wait for a notification. The first time the callback + * executes the timer will suspend the task, then resume the task, without + * ever sending a notification to the task. */ + ulNotifiedValue = 0; + xTimerStart( xSingleTaskTimer, portMAX_DELAY ); + + /* Check a notification is not received. */ + xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, portMAX_DELAY ); + configASSERT( xReturned == pdFALSE ); + configASSERT( ulNotifiedValue == 0 ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + + /* Incremented to show the task is still running. */ + ulNotifyCycleCount++; + + /* Start the timer that will try notifying this task while it is + * suspended, then wait for a notification. The second time the callback + * executes the timer will suspend the task, notify the task, then resume the + * task (previously it was suspended and resumed without being notified). */ + xTimerStart( xSingleTaskTimer, portMAX_DELAY ); + + /* Check a notification is received. */ + xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, portMAX_DELAY ); + configASSERT( xReturned == pdPASS ); + ( void ) xReturned; /* In case configASSERT() is not defined. */ + configASSERT( ulNotifiedValue != 0 ); + + /* Return the task to its proper priority and delete the timer as it is + * not used again. */ + vTaskPrioritySet( NULL, notifyTASK_PRIORITY ); + xTimerDelete( xSingleTaskTimer, portMAX_DELAY ); + + /* Incremented to show the task is still running. */ + ulNotifyCycleCount++; + + /* Leave all bits cleared. */ + xTaskNotifyWait( notifyUINT32_MAX, 0, NULL, 0 ); +} +/*-----------------------------------------------------------*/ + +static void prvSuspendedTaskTimerTestCallback( TimerHandle_t xExpiredTimer ) +{ + static uint32_t ulCallCount = 0; + + /* Remove compiler warnings about unused parameters. */ + ( void ) xExpiredTimer; + + /* Callback for a timer that is used during preliminary testing. The timer + * tests the behaviour when 1: a task waiting for a notification is suspended + * and then resumed without ever receiving a notification, and 2: when a task + * waiting for a notification receives a notification while it is suspended. */ + + if( ulCallCount == 0 ) + { + vTaskSuspend( xTaskToNotify ); + configASSERT( eTaskGetState( xTaskToNotify ) == eSuspended ); + vTaskResume( xTaskToNotify ); + } + else + { + vTaskSuspend( xTaskToNotify ); + + /* Sending a notification while the task is suspended should pass, but + * not cause the task to resume. ulCallCount is just used as a convenient + * non-zero value. */ + xTaskNotify( xTaskToNotify, ulCallCount, eSetValueWithOverwrite ); + + /* Make sure giving the notification didn't resume the task. */ + configASSERT( eTaskGetState( xTaskToNotify ) == eSuspended ); + + vTaskResume( xTaskToNotify ); + } + + ulCallCount++; +} +/*-----------------------------------------------------------*/ + +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 task's block time, sometimes it will be lower + * than the task's 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 task's block time, + * sometimes it will be lower than the task's 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; + + /* Check the task notification demo tasks were actually created. */ + configASSERT( xTaskToNotify ); + + /* 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 ) ); +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/Common/Minimal/TaskNotifyArray.c b/FreeRTOS/Demo/Common/Minimal/TaskNotifyArray.c index aedd439e3..1a136fabc 100644 --- a/FreeRTOS/Demo/Common/Minimal/TaskNotifyArray.c +++ b/FreeRTOS/Demo/Common/Minimal/TaskNotifyArray.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -159,7 +159,7 @@ void vStartTaskNotifyArrayTask( 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, /* Function that implements the task. */ - "ArrayNotifed", /* Text name for the task - for debugging only - not used by the kernel. */ + "ArrayNotified", /* Text name for the task - for debugging only - not used by the kernel. */ notifyNOTIFY_ARRAY_TASK_STACK_SIZE, /* Task's stack size in words, not bytes!. */ NULL, /* Task parameter, not used in this case. */ notifyTASK_PRIORITY, /* Task priority, 0 is the lowest. */ @@ -917,7 +917,7 @@ static void prvBlockOnTheNotifiedIndexed( void ) xTaskNotifyStateClearIndexed( xTaskToNotify, uxIndex ); } - /* Peform the test on each task notification within the array of task + /* Perform the test on each task notification within the array of task * notifications. */ for( uxIndexToNotify = 0; uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES; uxIndexToNotify++ ) { diff --git a/FreeRTOS/Demo/Common/Minimal/TimerDemo.c b/FreeRTOS/Demo/Common/Minimal/TimerDemo.c index 05a8450fb..be3002aaa 100644 --- a/FreeRTOS/Demo/Common/Minimal/TimerDemo.c +++ b/FreeRTOS/Demo/Common/Minimal/TimerDemo.c @@ -1,1224 +1,1224 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* - * Tests the behaviour of timers. Some timers are created before the scheduler - * is started, and some after. - */ - -/* Standard includes. */ -#include - -/* Scheduler include files. */ -#include "FreeRTOS.h" -#include "task.h" -#include "timers.h" - -/* Demo program include files. */ -#include "TimerDemo.h" - -#if ( configTIMER_TASK_PRIORITY < 1 ) - #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly. -#endif - -#define tmrdemoDONT_BLOCK ( ( TickType_t ) 0 ) -#define tmrdemoONE_SHOT_TIMER_PERIOD ( xBasePeriod * ( TickType_t ) 3 ) -#define tmrdemoNUM_TIMER_RESETS ( ( uint8_t ) 10 ) - -#ifndef tmrTIMER_TEST_TASK_STACK_SIZE - #define tmrTIMER_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE -#endif - -/*-----------------------------------------------------------*/ - -/* The callback functions used by the timers. These each increment a counter - * to indicate which timer has expired. The auto-reload timers that are used by - * the test task (as opposed to being used from an ISR) all share the same - * prvAutoReloadTimerCallback() callback function, and use the ID of the - * pxExpiredTimer parameter passed into that function to know which counter to - * increment. The other timers all have their own unique callback function and - * simply increment their counters without using the callback function parameter. */ -static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ); -static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer ); -static void prvTimerTestTask( void * pvParameters ); -static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ); -static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer ); - -/* The test functions used by the timer test task. These manipulate the auto - * reload and one-shot timers in various ways, then delay, then inspect the timers - * to ensure they have behaved as expected. */ -static void prvTest1_CreateTimersWithoutSchedulerRunning( void ); -static void prvTest2_CheckTaskAndTimersInitialState( void ); -static void prvTest3_CheckAutoReloadExpireRates( void ); -static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ); -static void prvTest5_CheckBasicOneShotTimerBehaviour( void ); -static void prvTest6_CheckAutoReloadResetBehaviour( void ); -static void prvTest7_CheckBacklogBehaviour( void ); -static void prvResetStartConditionsForNextIteration( void ); - -/*-----------------------------------------------------------*/ - -/* Flag that will be latched to pdFAIL should any unexpected behaviour be - * detected in any of the demo tests. */ -static volatile BaseType_t xTestStatus = pdPASS; - -/* Flag indicating whether the testing includes the backlog demo. The backlog - * demo can be disruptive to other demos because the timer backlog is created by - * calling xTaskCatchUpTicks(). */ -static uint8_t ucIsBacklogDemoEnabled = ( uint8_t ) 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; - -/* A set of auto-reload timers - each of which use the same callback function. - * The callback function uses the timer ID to index into, and then increment, a - * counter in the ucAutoReloadTimerCounters[] array. The callback function stops - * xAutoReloadTimers[0] during its callback if ucIsStopNeededInTimerZeroCallback is - * pdTRUE. The auto-reload timers referenced from xAutoReloadTimers[] are used by - * the prvTimerTestTask task. */ -static TimerHandle_t xAutoReloadTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; -static uint8_t ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; -static uint8_t ucIsStopNeededInTimerZeroCallback = ( uint8_t ) pdFALSE; - -/* The one-shot timer is configured to use a callback function that increments - * ucOneShotTimerCounter each time it gets called. */ -static TimerHandle_t xOneShotTimer = NULL; -static uint8_t ucOneShotTimerCounter = ( uint8_t ) 0; - -/* The ISR reload timer is controlled from the tick hook to exercise the timer - * API functions that can be used from an ISR. It is configured to increment - * ucISRReloadTimerCounter each time its callback function is executed. */ -static TimerHandle_t xISRAutoReloadTimer = NULL; -static uint8_t ucISRAutoReloadTimerCounter = ( uint8_t ) 0; - -/* The ISR one-shot timer is controlled from the tick hook to exercise the timer - * API functions that can be used from an ISR. It is configured to increment - * ucISRReloadTimerCounter each time its callback function is executed. */ -static TimerHandle_t xISROneShotTimer = NULL; -static uint8_t ucISROneShotTimerCounter = ( uint8_t ) 0; - -/* The period of all the timers are a multiple of the base period. The base - * period is configured by the parameter to vStartTimerDemoTask(). */ -static TickType_t xBasePeriod = 0; - -/*-----------------------------------------------------------*/ - -void vStartTimerDemoTask( TickType_t xBasePeriodIn ) -{ - /* Start with the timer and counter arrays clear - this is only necessary - * where the compiler does not clear them automatically on start up. */ - memset( ucAutoReloadTimerCounters, 0x00, sizeof( ucAutoReloadTimerCounters ) ); - memset( xAutoReloadTimers, 0x00, sizeof( xAutoReloadTimers ) ); - - /* Store the period from which all the timer periods will be generated from - * (multiples of). */ - xBasePeriod = xBasePeriodIn; - - /* Create a set of timers for use by this demo/test. */ - prvTest1_CreateTimersWithoutSchedulerRunning(); - - /* Create the task that will control and monitor the timers. This is - * created at a lower priority than the timer service task to ensure, as - * far as it is concerned, commands on timers are acted on immediately - * (sending a command to the timer service task will unblock the timer service - * task, which will then preempt this task). */ - if( xTestStatus != pdFAIL ) - { - xTaskCreate( prvTimerTestTask, "Tmr Tst", tmrTIMER_TEST_TASK_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL ); - } -} -/*-----------------------------------------------------------*/ - -void vTimerDemoIncludeBacklogTests( BaseType_t includeBacklogTests ) -{ - ucIsBacklogDemoEnabled = ( uint8_t ) includeBacklogTests; -} -/*-----------------------------------------------------------*/ - -static void prvTimerTestTask( void * pvParameters ) -{ - ( void ) pvParameters; - - /* Create a one-shot timer for use later on in this test. For test purposes it - * is created as an auto-reload timer then converted to a one-shot timer. */ - xOneShotTimer = xTimerCreate( "Oneshot Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ - tmrdemoONE_SHOT_TIMER_PERIOD, /* The period for the timer. */ - pdFALSE, /* Autoreload is false, so created as a one-shot timer. */ - ( void * ) 0, /* The timer identifier. Initialise to 0, then increment each time it is called. */ - prvOneShotTimerCallback ); /* The callback to be called when the timer expires. */ - - if( xOneShotTimer == NULL ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Purely for test coverage purposes - change and query the reload mode to - * auto-reload then back to one-shot. */ - - /* Change timer to auto-reload. */ - vTimerSetReloadMode( xOneShotTimer, pdTRUE ); - - /* Timer should now be auto-reload. */ - configASSERT( uxTimerGetReloadMode( xOneShotTimer ) == pdTRUE ); - - /* Change timer to one-shot, which is what is needed for this test. */ - vTimerSetReloadMode( xOneShotTimer, pdFALSE ); - - /* Check change to one-shot was successful. */ - configASSERT( uxTimerGetReloadMode( xOneShotTimer ) == pdFALSE ); - - /* Ensure all the timers are in their expected initial state. This - * depends on the timer service task having a higher priority than this task. */ - prvTest2_CheckTaskAndTimersInitialState(); - - for( ; ; ) - { - /* Check the auto-reload timers expire at the expected/correct rates. */ - prvTest3_CheckAutoReloadExpireRates(); - - /* Check the auto-reload timers can be stopped correctly, and correctly - * report their state. */ - prvTest4_CheckAutoReloadTimersCanBeStopped(); - - /* Check the one-shot timer only calls its callback once after it has been - * started, and that it reports its state correctly. */ - prvTest5_CheckBasicOneShotTimerBehaviour(); - - /* Check timer reset behaviour. */ - prvTest6_CheckAutoReloadResetBehaviour(); - - /* Check timer behaviour when the timer task gets behind in its work. */ - if( ucIsBacklogDemoEnabled == ( uint8_t ) pdTRUE ) - { - prvTest7_CheckBacklogBehaviour(); - } - - /* Start the timers again to restart all the tests over again. */ - prvResetStartConditionsForNextIteration(); - } -} -/*-----------------------------------------------------------*/ - -/* This is called to check that the created task is still running and has not - * detected any errors. */ -BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency ) -{ - static uint32_t ulLastLoopCounter = 0UL; - TickType_t xMaxBlockTimeUsedByTheseTests, xLoopCounterIncrementTimeMax; - static TickType_t xIterationsWithoutCounterIncrement = ( TickType_t ) 0, xLastCycleFrequency; - - if( xLastCycleFrequency != xCycleFrequency ) - { - /* The cycle frequency has probably become much faster due to an error - * elsewhere. Start counting Iterations again. */ - xIterationsWithoutCounterIncrement = ( TickType_t ) 0; - xLastCycleFrequency = xCycleFrequency; - } - - /* Calculate the maximum number of times that it is permissible for this - * function to be called without ulLoopCounter being incremented. This is - * necessary because the tests in this file block for extended periods, and the - * block period might be longer than the time between calls to this function. */ - xMaxBlockTimeUsedByTheseTests = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod; - xLoopCounterIncrementTimeMax = ( xMaxBlockTimeUsedByTheseTests / xCycleFrequency ) + 1; - - /* If the demo task is still running then the loop counter is expected to - * have incremented every xLoopCounterIncrementTimeMax calls. */ - if( ulLastLoopCounter == ulLoopCounter ) - { - xIterationsWithoutCounterIncrement++; - - if( xIterationsWithoutCounterIncrement > xLoopCounterIncrementTimeMax ) - { - /* The tests appear to be no longer running (stalled). */ - xTestStatus = pdFAIL; - } - } - else - { - /* ulLoopCounter changed, so the count of times this function was called - * without a change can be reset to zero. */ - xIterationsWithoutCounterIncrement = ( TickType_t ) 0; - } - - ulLastLoopCounter = ulLoopCounter; - - /* Errors detected in the task itself will have latched xTestStatus - * to pdFAIL. */ - - return xTestStatus; -} -/*-----------------------------------------------------------*/ - -static void prvTest1_CreateTimersWithoutSchedulerRunning( void ) -{ - TickType_t xTimer; - - for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ ) - { - /* As the timer queue is not yet full, it should be possible to both - * create and start a timer. These timers are being started before the - * scheduler has been started, so their block times should get set to zero - * within the timer API itself. */ - xAutoReloadTimers[ xTimer ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ - ( ( xTimer + ( TickType_t ) 1 ) * xBasePeriod ), /* The period for the timer. The plus 1 ensures a period of zero is not specified. */ - pdTRUE, /* Auto-reload is set to true. */ - ( void * ) xTimer, /* An identifier for the timer as all the auto-reload timers use the same callback. */ - prvAutoReloadTimerCallback ); /* The callback to be called when the timer expires. */ - - if( xAutoReloadTimers[ xTimer ] == NULL ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - else - { - configASSERT( strcmp( pcTimerGetName( xAutoReloadTimers[ xTimer ] ), "FR Timer" ) == 0 ); - - /* The scheduler has not yet started, so the block period of - * portMAX_DELAY should just get set to zero in xTimerStart(). Also, - * the timer queue is not yet full so xTimerStart() should return - * pdPASS. */ - if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) != pdPASS ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - } - - /* The timers queue should now be full, so it should be possible to create - * another timer, but not possible to start it (the timer queue will not get - * drained until the scheduler has been started. */ - xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ - ( configTIMER_QUEUE_LENGTH * xBasePeriod ), /* The period for the timer. */ - pdTRUE, /* Auto-reload is set to true. */ - ( void * ) xTimer, /* An identifier for the timer as all the auto-reload timers use the same callback. */ - prvAutoReloadTimerCallback ); /* The callback executed when the timer expires. */ - - if( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] == NULL ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - else - { - if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) == pdPASS ) - { - /* This time it would not be expected that the timer could be - * started at this point. */ - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - - /* Create the timers that are used from the tick interrupt to test the timer - * API functions that can be called from an ISR. */ - xISRAutoReloadTimer = xTimerCreate( "ISR AR", /* The text name given to the timer. */ - 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */ - pdTRUE, /* This is an auto-reload timer. */ - ( void * ) NULL, /* The identifier is not required. */ - prvISRAutoReloadTimerCallback ); /* The callback that is executed when the timer expires. */ - - xISROneShotTimer = xTimerCreate( "ISR OS", /* The text name given to the timer. */ - 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */ - pdFALSE, /* This is a one-shot timer. */ - ( void * ) NULL, /* The identifier is not required. */ - prvISROneShotTimerCallback ); /* The callback that is executed when the timer expires. */ - - if( ( xISRAutoReloadTimer == NULL ) || ( xISROneShotTimer == NULL ) ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } -} -/*-----------------------------------------------------------*/ - -static void prvTest2_CheckTaskAndTimersInitialState( void ) -{ - uint8_t ucTimer; - - /* Ensure all the timers are in their expected initial state. This depends - * on the timer service task having a higher priority than this task. - * - * auto-reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active, - * and auto-reload timer configTIMER_QUEUE_LENGTH should not yet be active (it - * could not be started prior to the scheduler being started when it was - * created). */ - for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) - { - if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - - if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } -} -/*-----------------------------------------------------------*/ - -static void prvTest3_CheckAutoReloadExpireRates( void ) -{ - uint8_t ucMaxAllowableValue, ucMinAllowableValue, ucTimer; - TickType_t xBlockPeriod, xTimerPeriod, xExpectedNumber; - UBaseType_t uxOriginalPriority; - - /* Check the auto-reload timers expire at the expected rates. Do this at a - * high priority for maximum accuracy. This is ok as most of the time is spent - * in the Blocked state. */ - uxOriginalPriority = uxTaskPriorityGet( NULL ); - vTaskPrioritySet( NULL, ( configMAX_PRIORITIES - 1 ) ); - - /* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow - * all the auto-reload timers to expire at least once. */ - xBlockPeriod = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod; - vTaskDelay( xBlockPeriod ); - - /* Check that all the auto-reload timers have called their callback - * function the expected number of times. */ - for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) - { - /* The expected number of expires is equal to the block period divided - * by the timer period. */ - xTimerPeriod = ( ( ( TickType_t ) ucTimer + ( TickType_t ) 1 ) * xBasePeriod ); - xExpectedNumber = xBlockPeriod / xTimerPeriod; - - ucMaxAllowableValue = ( ( uint8_t ) xExpectedNumber ); - ucMinAllowableValue = ( uint8_t ) ( ( uint8_t ) xExpectedNumber - ( uint8_t ) 1 ); /* Weird casting to try and please all compilers. */ - - if( ( ucAutoReloadTimerCounters[ ucTimer ] < ucMinAllowableValue ) || - ( ucAutoReloadTimerCounters[ ucTimer ] > ucMaxAllowableValue ) - ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - - /* Return to the original priority. */ - vTaskPrioritySet( NULL, uxOriginalPriority ); - - if( xTestStatus == pdPASS ) - { - /* No errors have been reported so increment the loop counter so the - * check task knows this task is still running. */ - ulLoopCounter++; - } -} -/*-----------------------------------------------------------*/ - -static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ) -{ - uint8_t ucTimer; - - /* Check the auto-reload timers can be stopped correctly, and correctly - * report their state. */ - - /* Stop all the active timers. */ - for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) - { - /* The timer has not been stopped yet! */ - if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Now stop the timer. This will appear to happen immediately to - * this task because this task is running at a priority below the - * timer service task. */ - xTimerStop( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); - - /* The timer should now be inactive. */ - if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - - taskENTER_CRITICAL(); - { - /* The timer in array position configTIMER_QUEUE_LENGTH should not - * be active. The critical section is used to ensure the timer does - * not call its callback between the next line running and the array - * being cleared back to zero, as that would mask an error condition. */ - if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( uint8_t ) 0 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Clear the timer callback count. */ - memset( ( void * ) ucAutoReloadTimerCounters, 0, sizeof( ucAutoReloadTimerCounters ) ); - } - taskEXIT_CRITICAL(); - - /* The timers are now all inactive, so this time, after delaying, none - * of the callback counters should have incremented. */ - vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); - - for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) - { - if( ucAutoReloadTimerCounters[ ucTimer ] != ( uint8_t ) 0 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - - if( xTestStatus == pdPASS ) - { - /* No errors have been reported so increment the loop counter so - * the check task knows this task is still running. */ - ulLoopCounter++; - } -} -/*-----------------------------------------------------------*/ - -static void prvTest5_CheckBasicOneShotTimerBehaviour( void ) -{ - /* Check the one-shot timer only calls its callback once after it has been - * started, and that it reports its state correctly. */ - - /* The one-shot timer should not be active yet. */ - if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucOneShotTimerCounter != ( uint8_t ) 0 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Start the one-shot timer and check that it reports its state correctly. */ - xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); - - if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Delay for three times as long as the one-shot timer period, then check - * to ensure it has only called its callback once, and is now not in the - * active state. */ - vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD * ( TickType_t ) 3 ); - - if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucOneShotTimerCounter != ( uint8_t ) 1 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - else - { - /* Reset the one-shot timer callback count. */ - ucOneShotTimerCounter = ( uint8_t ) 0; - } - - if( xTestStatus == pdPASS ) - { - /* No errors have been reported so increment the loop counter so the - * check task knows this task is still running. */ - ulLoopCounter++; - } -} -/*-----------------------------------------------------------*/ - -static void prvTest6_CheckAutoReloadResetBehaviour( void ) -{ - uint8_t ucTimer; - - /* Check timer reset behaviour. */ - - /* Restart the one-shot timer and check it reports its status correctly. */ - xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); - - if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Restart one of the auto-reload timers and check that it reports its - * status correctly. */ - xTimerStart( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); - - if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - for( ucTimer = 0; ucTimer < tmrdemoNUM_TIMER_RESETS; ucTimer++ ) - { - /* Delay for half as long as the one-shot timer period, then reset it. - * It should never expire while this is done, so its callback count should - * never increment. */ - vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD / 2 ); - - /* Check both running timers are still active, but have not called their - * callback functions. */ - if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucOneShotTimerCounter != ( uint8_t ) 0 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( uint8_t ) 0 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Reset both running timers. */ - xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK ); - xTimerReset( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); - - if( xTestStatus == pdPASS ) - { - /* No errors have been reported so increment the loop counter so - * the check task knows this task is still running. */ - ulLoopCounter++; - } - } - - /* Finally delay long enough for both running timers to expire. */ - vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); - - /* The timers were not reset during the above delay period so should now - * both have called their callback functions. */ - if( ucOneShotTimerCounter != ( uint8_t ) 1 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* The one-shot timer should no longer be active, while the auto-reload - * timer should still be active. */ - if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Stop the auto-reload timer again. */ - xTimerStop( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); - - if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Clear the timer callback counts, ready for another iteration of these - * tests. */ - ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( uint8_t ) 0; - ucOneShotTimerCounter = ( uint8_t ) 0; - - if( xTestStatus == pdPASS ) - { - /* No errors have been reported so increment the loop counter so the check - * task knows this task is still running. */ - ulLoopCounter++; - } -} -/*-----------------------------------------------------------*/ - -static void prvTest7_CheckBacklogBehaviour( void ) -{ - UBaseType_t uxOriginalPriority; - - /* Use the first auto-reload timer to test stopping a timer from a - * backlogged callback. */ - - /* The timer has not been started yet! */ - if( xTimerIsTimerActive( xAutoReloadTimers[ 0 ] ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Prompt the callback function to stop the timer. */ - ucIsStopNeededInTimerZeroCallback = ( uint8_t ) pdTRUE; - - /* Now start the timer. This will appear to happen immediately to - * this task because this task is running at a priority below the timer - * service task. Use a timer period of one tick so the call to - * xTaskCatchUpTicks() below has minimal impact on other tests that might - * be running. */ -#define tmrdemoBACKLOG_TIMER_PERIOD ( ( TickType_t ) 1 ) - xTimerChangePeriod( xAutoReloadTimers[ 0 ], tmrdemoBACKLOG_TIMER_PERIOD, tmrdemoDONT_BLOCK ); - - /* The timer should now be active. */ - if( xTimerIsTimerActive( xAutoReloadTimers[ 0 ] ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Arrange for the callback to execute late enough that it will execute - * twice, back-to-back. The timer must handle the stop request properly - * in spite of the backlog of callbacks. */ -#define tmrdemoEXPECTED_BACKLOG_EXPIRES ( ( TickType_t ) 2 ) - xTaskCatchUpTicks( tmrdemoBACKLOG_TIMER_PERIOD * tmrdemoEXPECTED_BACKLOG_EXPIRES ); - - /* The timer should now be inactive. */ - if( xTimerIsTimerActive( xAutoReloadTimers[ 0 ] ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Restore the standard timer period, and leave the timer inactive. */ - xTimerChangePeriod( xAutoReloadTimers[ 0 ], xBasePeriod, tmrdemoDONT_BLOCK ); - xTimerStop( xAutoReloadTimers[ 0 ], tmrdemoDONT_BLOCK ); - - /* Clear the reload count for the timer used in this test. */ - ucAutoReloadTimerCounters[ 0 ] = ( uint8_t ) 0; - - - /* Verify a one-shot timer is marked as inactive if the timer task processes - * the start or reset request after the expiration time has passed. */ - - /* The timer has not been started yet! */ - if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Use the timer period specific to backlogged timers because it reduces - * the impact on other tests that might be running when xTaskCatchUpTicks() - * creates the backlog, below. */ - xTimerChangePeriod( xOneShotTimer, tmrdemoBACKLOG_TIMER_PERIOD, tmrdemoDONT_BLOCK ); - - /* Temporarily give this task maximum priority so it can cause the timer - * task to delay its processing of the reset request below. */ - uxOriginalPriority = uxTaskPriorityGet( NULL ); - vTaskPrioritySet( NULL, ( configMAX_PRIORITIES - 1 ) ); - - /* Reset the timer. The timer service won't process this request right - * away as noted above. */ - xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK ); - - /* Cause the timer period to elapse without giving an opportunity for the - * timer service task to process the reset request. */ - xTaskCatchUpTicks( tmrdemoBACKLOG_TIMER_PERIOD ); - - /* Return this task to its original priority. The timer service task will - * process the reset request immediately. The timer task must handle the reset - * request as if it were processed at the time of the request even though in - * this test the processing occurs after the intended expiration time. */ - vTaskPrioritySet( NULL, uxOriginalPriority ); - - /* The timer should now be inactive. */ - if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Restore the standard timer period, and leave the timer inactive. */ - xTimerChangePeriod( xOneShotTimer, tmrdemoONE_SHOT_TIMER_PERIOD, tmrdemoDONT_BLOCK ); - xTimerStop( xOneShotTimer, tmrdemoDONT_BLOCK ); - - /* Clear the counter for the timer used in this test. */ - ucOneShotTimerCounter = ( uint8_t ) 0; - - if( xTestStatus == pdPASS ) - { - /* No errors have been reported so increment the loop counter so the check - * task knows this task is still running. */ - ulLoopCounter++; - } -} -/*-----------------------------------------------------------*/ - -static void prvResetStartConditionsForNextIteration( void ) -{ - uint8_t ucTimer; - - /* Start the timers again to start all the tests over again. */ - - /* Start the timers again. */ - for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) - { - /* The timer has not been started yet! */ - if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Now start the timer. This will appear to happen immediately to - * this task because this task is running at a priority below the timer - * service task. */ - xTimerStart( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); - - /* The timer should now be active. */ - if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - - if( xTestStatus == pdPASS ) - { - /* No errors have been reported so increment the loop counter so the - * check task knows this task is still running. */ - ulLoopCounter++; - } -} -/*-----------------------------------------------------------*/ - -void vTimerPeriodicISRTests( void ) -{ - static TickType_t uxTick = ( TickType_t ) -1; - - #if ( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) ) - - /* The timer service task is not the highest priority task, so it cannot - * be assumed that timings will be exact. Timers should never call their - * callback before their expiry time, but a margin is permissible for calling - * their callback after their expiry time. If exact timing is required then - * configTIMER_TASK_PRIORITY must be set to ensure the timer service task - * is the highest priority task in the system. - * - * This function is called from the tick hook. The tick hook is called - * even when the scheduler is suspended. Therefore it is possible that the - * uxTick count maintained in this function is temporarily ahead of the tick - * count maintained by the kernel. When this is the case a message posted from - * this function will assume a time stamp in advance of the real time stamp, - * which can result in a timer being processed before this function expects it - * to. For example, if the kernel's tick count was 100, and uxTick was 102, - * then this function will not expect the timer to have expired until the - * kernel's tick count is (102 + xBasePeriod), whereas in reality the timer - * will expire when the kernel's tick count is (100 + xBasePeriod). For this - * reason xMargin is used as an allowable margin for premature timer expires - * as well as late timer expires. */ - #ifdef _WINDOWS_ - /* Windows is not real real time. */ - const TickType_t xMargin = 20; - #else - const TickType_t xMargin = 6; - #endif /* _WINDOWS_ */ - #else - #ifdef _WINDOWS_ - /* Windows is not real real time. */ - const TickType_t xMargin = 20; - #else - const TickType_t xMargin = 4; - #endif /* _WINDOWS_ */ - #endif /* if ( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) ) */ - - - uxTick++; - - if( uxTick == 0 ) - { - /* The timers will have been created, but not started. Start them now - * by setting their period. */ - ucISRAutoReloadTimerCounter = 0; - ucISROneShotTimerCounter = 0; - - /* It is possible that the timer task has not yet made room in the - * timer queue. If the timers cannot be started then reset uxTick so - * another attempt is made later. */ - uxTick = ( TickType_t ) -1; - - /* Try starting first timer. */ - if( xTimerChangePeriodFromISR( xISRAutoReloadTimer, xBasePeriod, NULL ) == pdPASS ) - { - /* First timer was started, try starting the second timer. */ - if( xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, NULL ) == pdPASS ) - { - /* Both timers were started, so set the uxTick back to its - * proper value. */ - uxTick = 0; - } - else - { - /* Second timer could not be started, so stop the first one - * again. */ - xTimerStopFromISR( xISRAutoReloadTimer, NULL ); - } - } - } - else if( uxTick == ( xBasePeriod - xMargin ) ) - { - /* Neither timer should have expired yet. */ - if( ( ucISRAutoReloadTimerCounter != 0 ) || ( ucISROneShotTimerCounter != 0 ) ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - else if( uxTick == ( xBasePeriod + xMargin ) ) - { - /* Both timers should now have expired once. The auto-reload timer will - * still be active, but the one-shot timer should now have stopped. */ - if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - else if( uxTick == ( ( 2 * xBasePeriod ) - xMargin ) ) - { - /* The auto-reload timer will still be active, but the one-shot timer - * should now have stopped - however, at this time neither of the timers - * should have expired again since the last test. */ - if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - else if( uxTick == ( ( 2 * xBasePeriod ) + xMargin ) ) - { - /* The auto-reload timer will still be active, but the one-shot timer - * should now have stopped. At this time the auto-reload timer should have - * expired again, but the one-shot timer count should not have changed. */ - if( ucISRAutoReloadTimerCounter != 2 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 1 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - else if( uxTick == ( ( 2 * xBasePeriod ) + ( xBasePeriod >> ( TickType_t ) 2U ) ) ) - { - /* The auto-reload timer will still be active, but the one-shot timer - * should now have stopped. Again though, at this time, neither timer call - * back should have been called since the last test. */ - if( ucISRAutoReloadTimerCounter != 2 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 1 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - else if( uxTick == ( 3 * xBasePeriod ) ) - { - /* Start the one-shot timer again. */ - xTimerStartFromISR( xISROneShotTimer, NULL ); - } - else if( uxTick == ( ( 3 * xBasePeriod ) + xMargin ) ) - { - /* The auto-reload timer and one-shot timer will be active. At - * this time the auto-reload timer should have expired again, but the one - * shot timer count should not have changed yet. */ - if( ucISRAutoReloadTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 1 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Now stop the auto-reload timer. The one-shot timer was started - * a few ticks ago. */ - xTimerStopFromISR( xISRAutoReloadTimer, NULL ); - } - else if( uxTick == ( 4 * ( xBasePeriod - xMargin ) ) ) - { - /* The auto-reload timer is now stopped, and the one-shot timer is - * active, but at this time neither timer should have expired since the - * last test. */ - if( ucISRAutoReloadTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 1 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - else if( uxTick == ( ( 4 * xBasePeriod ) + xMargin ) ) - { - /* The auto-reload timer is now stopped, and the one-shot timer is - * active. The one-shot timer should have expired again, but the auto - * reload timer should not have executed its callback. */ - if( ucISRAutoReloadTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 2 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - else if( uxTick == ( 8 * xBasePeriod ) ) - { - /* The auto-reload timer is now stopped, and the one-shot timer has - * already expired and then stopped itself. Both callback counters should - * not have incremented since the last test. */ - if( ucISRAutoReloadTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 2 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - /* Now reset the one-shot timer. */ - xTimerResetFromISR( xISROneShotTimer, NULL ); - } - else if( uxTick == ( ( 9 * xBasePeriod ) - xMargin ) ) - { - /* Only the one-shot timer should be running, but it should not have - * expired since the last test. Check the callback counters have not - * incremented, then reset the one-shot timer again. */ - if( ucISRAutoReloadTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 2 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - xTimerResetFromISR( xISROneShotTimer, NULL ); - } - else if( uxTick == ( ( 10 * xBasePeriod ) - ( 2 * xMargin ) ) ) - { - /* Only the one-shot timer should be running, but it should not have - * expired since the last test. Check the callback counters have not - * incremented, then reset the one-shot timer again. */ - if( ucISRAutoReloadTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 2 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - xTimerResetFromISR( xISROneShotTimer, NULL ); - } - else if( uxTick == ( ( 11 * xBasePeriod ) - ( 3 * xMargin ) ) ) - { - /* Only the one-shot timer should be running, but it should not have - * expired since the last test. Check the callback counters have not - * incremented, then reset the one-shot timer once again. */ - if( ucISRAutoReloadTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 2 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - xTimerResetFromISR( xISROneShotTimer, NULL ); - } - else if( uxTick == ( ( 12 * xBasePeriod ) - ( 2 * xMargin ) ) ) - { - /* Only the one-shot timer should have been running and this time it - * should have expired. Check its callback count has been incremented. - * The auto-reload timer is still not running so should still have the same - * count value. This time the one-shot timer is not reset so should not - * restart from its expiry period again. */ - if( ucISRAutoReloadTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - } - else if( uxTick == ( 15 * xBasePeriod ) ) - { - /* Neither timer should be running now. Check neither callback count - * has incremented, then go back to the start to run these tests all - * over again. */ - if( ucISRAutoReloadTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - if( ucISROneShotTimerCounter != 3 ) - { - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } - - uxTick = ( TickType_t ) -1; - } -} -/*-----------------------------------------------------------*/ - -/*** Timer callback functions are defined below here. ***/ - -static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ) -{ - size_t uxTimerID; - - uxTimerID = ( size_t ) pvTimerGetTimerID( pxExpiredTimer ); - - if( uxTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) ) - { - ( ucAutoReloadTimerCounters[ uxTimerID ] )++; - - /* Stop timer ID 0 if requested. */ - if( ( uxTimerID == ( size_t ) 0 ) && ( ucIsStopNeededInTimerZeroCallback == ( uint8_t ) pdTRUE ) ) - { - xTimerStop( pxExpiredTimer, tmrdemoDONT_BLOCK ); - ucIsStopNeededInTimerZeroCallback = ( uint8_t ) pdFALSE; - } - } - else - { - /* The timer ID appears to be unexpected (invalid). */ - xTestStatus = pdFAIL; - configASSERT( xTestStatus ); - } -} -/*-----------------------------------------------------------*/ - -static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer ) -{ -/* A count is kept of the number of times this callback function is executed. - * The count is stored as the timer's ID. This is only done to test the - * vTimerSetTimerID() function. */ - static size_t uxCallCount = 0; - size_t uxLastCallCount; - - /* Obtain the timer's ID, which should be a count of the number of times - * this callback function has been executed. */ - uxLastCallCount = ( size_t ) pvTimerGetTimerID( pxExpiredTimer ); - configASSERT( uxLastCallCount == uxCallCount ); - - /* Increment the call count, then save it back as the timer's ID. This is - * only done to test the vTimerSetTimerID() API function. */ - uxLastCallCount++; - vTimerSetTimerID( pxExpiredTimer, ( void * ) uxLastCallCount ); - uxCallCount++; - - ucOneShotTimerCounter++; -} -/*-----------------------------------------------------------*/ - -static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ) -{ - /* The parameter is not used in this case as only one timer uses this - * callback function. */ - ( void ) pxExpiredTimer; - - ucISRAutoReloadTimerCounter++; -} -/*-----------------------------------------------------------*/ - -static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer ) -{ - /* The parameter is not used in this case as only one timer uses this - * callback function. */ - ( void ) pxExpiredTimer; - - ucISROneShotTimerCounter++; -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * Tests the behaviour of timers. Some timers are created before the scheduler + * is started, and some after. + */ + +/* Standard includes. */ +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" + +/* Demo program include files. */ +#include "TimerDemo.h" + +#if ( configTIMER_TASK_PRIORITY < 1 ) + #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly. +#endif + +#define tmrdemoDONT_BLOCK ( ( TickType_t ) 0 ) +#define tmrdemoONE_SHOT_TIMER_PERIOD ( xBasePeriod * ( TickType_t ) 3 ) +#define tmrdemoNUM_TIMER_RESETS ( ( uint8_t ) 10 ) + +#ifndef tmrTIMER_TEST_TASK_STACK_SIZE + #define tmrTIMER_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE +#endif + +/*-----------------------------------------------------------*/ + +/* The callback functions used by the timers. These each increment a counter + * to indicate which timer has expired. The auto-reload timers that are used by + * the test task (as opposed to being used from an ISR) all share the same + * prvAutoReloadTimerCallback() callback function, and use the ID of the + * pxExpiredTimer parameter passed into that function to know which counter to + * increment. The other timers all have their own unique callback function and + * simply increment their counters without using the callback function parameter. */ +static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ); +static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer ); +static void prvTimerTestTask( void * pvParameters ); +static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ); +static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer ); + +/* The test functions used by the timer test task. These manipulate the auto + * reload and one-shot timers in various ways, then delay, then inspect the timers + * to ensure they have behaved as expected. */ +static void prvTest1_CreateTimersWithoutSchedulerRunning( void ); +static void prvTest2_CheckTaskAndTimersInitialState( void ); +static void prvTest3_CheckAutoReloadExpireRates( void ); +static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ); +static void prvTest5_CheckBasicOneShotTimerBehaviour( void ); +static void prvTest6_CheckAutoReloadResetBehaviour( void ); +static void prvTest7_CheckBacklogBehaviour( void ); +static void prvResetStartConditionsForNextIteration( void ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdFAIL should any unexpected behaviour be + * detected in any of the demo tests. */ +static volatile BaseType_t xTestStatus = pdPASS; + +/* Flag indicating whether the testing includes the backlog demo. The backlog + * demo can be disruptive to other demos because the timer backlog is created by + * calling xTaskCatchUpTicks(). */ +static uint8_t ucIsBacklogDemoEnabled = ( uint8_t ) 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; + +/* A set of auto-reload timers - each of which use the same callback function. + * The callback function uses the timer ID to index into, and then increment, a + * counter in the ucAutoReloadTimerCounters[] array. The callback function stops + * xAutoReloadTimers[0] during its callback if ucIsStopNeededInTimerZeroCallback is + * pdTRUE. The auto-reload timers referenced from xAutoReloadTimers[] are used by + * the prvTimerTestTask task. */ +static TimerHandle_t xAutoReloadTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; +static uint8_t ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; +static uint8_t ucIsStopNeededInTimerZeroCallback = ( uint8_t ) pdFALSE; + +/* The one-shot timer is configured to use a callback function that increments + * ucOneShotTimerCounter each time it gets called. */ +static TimerHandle_t xOneShotTimer = NULL; +static uint8_t ucOneShotTimerCounter = ( uint8_t ) 0; + +/* The ISR reload timer is controlled from the tick hook to exercise the timer + * API functions that can be used from an ISR. It is configured to increment + * ucISRReloadTimerCounter each time its callback function is executed. */ +static TimerHandle_t xISRAutoReloadTimer = NULL; +static uint8_t ucISRAutoReloadTimerCounter = ( uint8_t ) 0; + +/* The ISR one-shot timer is controlled from the tick hook to exercise the timer + * API functions that can be used from an ISR. It is configured to increment + * ucISRReloadTimerCounter each time its callback function is executed. */ +static TimerHandle_t xISROneShotTimer = NULL; +static uint8_t ucISROneShotTimerCounter = ( uint8_t ) 0; + +/* The period of all the timers are a multiple of the base period. The base + * period is configured by the parameter to vStartTimerDemoTask(). */ +static TickType_t xBasePeriod = 0; + +/*-----------------------------------------------------------*/ + +void vStartTimerDemoTask( TickType_t xBasePeriodIn ) +{ + /* Start with the timer and counter arrays clear - this is only necessary + * where the compiler does not clear them automatically on start up. */ + memset( ucAutoReloadTimerCounters, 0x00, sizeof( ucAutoReloadTimerCounters ) ); + memset( xAutoReloadTimers, 0x00, sizeof( xAutoReloadTimers ) ); + + /* Store the period from which all the timer periods will be generated from + * (multiples of). */ + xBasePeriod = xBasePeriodIn; + + /* Create a set of timers for use by this demo/test. */ + prvTest1_CreateTimersWithoutSchedulerRunning(); + + /* Create the task that will control and monitor the timers. This is + * created at a lower priority than the timer service task to ensure, as + * far as it is concerned, commands on timers are acted on immediately + * (sending a command to the timer service task will unblock the timer service + * task, which will then preempt this task). */ + if( xTestStatus != pdFAIL ) + { + xTaskCreate( prvTimerTestTask, "Tmr Tst", tmrTIMER_TEST_TASK_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL ); + } +} +/*-----------------------------------------------------------*/ + +void vTimerDemoIncludeBacklogTests( BaseType_t includeBacklogTests ) +{ + ucIsBacklogDemoEnabled = ( uint8_t ) includeBacklogTests; +} +/*-----------------------------------------------------------*/ + +static void prvTimerTestTask( void * pvParameters ) +{ + ( void ) pvParameters; + + /* Create a one-shot timer for use later on in this test. For test purposes it + * is created as an auto-reload timer then converted to a one-shot timer. */ + xOneShotTimer = xTimerCreate( "Oneshot Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ + tmrdemoONE_SHOT_TIMER_PERIOD, /* The period for the timer. */ + pdFALSE, /* Autoreload is false, so created as a one-shot timer. */ + ( void * ) 0, /* The timer identifier. Initialise to 0, then increment each time it is called. */ + prvOneShotTimerCallback ); /* The callback to be called when the timer expires. */ + + if( xOneShotTimer == NULL ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Purely for test coverage purposes - change and query the reload mode to + * auto-reload then back to one-shot. */ + + /* Change timer to auto-reload. */ + vTimerSetReloadMode( xOneShotTimer, pdTRUE ); + + /* Timer should now be auto-reload. */ + configASSERT( uxTimerGetReloadMode( xOneShotTimer ) == pdTRUE ); + + /* Change timer to one-shot, which is what is needed for this test. */ + vTimerSetReloadMode( xOneShotTimer, pdFALSE ); + + /* Check change to one-shot was successful. */ + configASSERT( uxTimerGetReloadMode( xOneShotTimer ) == pdFALSE ); + + /* Ensure all the timers are in their expected initial state. This + * depends on the timer service task having a higher priority than this task. */ + prvTest2_CheckTaskAndTimersInitialState(); + + for( ; ; ) + { + /* Check the auto-reload timers expire at the expected/correct rates. */ + prvTest3_CheckAutoReloadExpireRates(); + + /* Check the auto-reload timers can be stopped correctly, and correctly + * report their state. */ + prvTest4_CheckAutoReloadTimersCanBeStopped(); + + /* Check the one-shot timer only calls its callback once after it has been + * started, and that it reports its state correctly. */ + prvTest5_CheckBasicOneShotTimerBehaviour(); + + /* Check timer reset behaviour. */ + prvTest6_CheckAutoReloadResetBehaviour(); + + /* Check timer behaviour when the timer task gets behind in its work. */ + if( ucIsBacklogDemoEnabled == ( uint8_t ) pdTRUE ) + { + prvTest7_CheckBacklogBehaviour(); + } + + /* Start the timers again to restart all the tests over again. */ + prvResetStartConditionsForNextIteration(); + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that the created task is still running and has not + * detected any errors. */ +BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency ) +{ + static uint32_t ulLastLoopCounter = 0UL; + TickType_t xMaxBlockTimeUsedByTheseTests, xLoopCounterIncrementTimeMax; + static TickType_t xIterationsWithoutCounterIncrement = ( TickType_t ) 0, xLastCycleFrequency; + + if( xLastCycleFrequency != xCycleFrequency ) + { + /* The cycle frequency has probably become much faster due to an error + * elsewhere. Start counting Iterations again. */ + xIterationsWithoutCounterIncrement = ( TickType_t ) 0; + xLastCycleFrequency = xCycleFrequency; + } + + /* Calculate the maximum number of times that it is permissible for this + * function to be called without ulLoopCounter being incremented. This is + * necessary because the tests in this file block for extended periods, and the + * block period might be longer than the time between calls to this function. */ + xMaxBlockTimeUsedByTheseTests = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod; + xLoopCounterIncrementTimeMax = ( xMaxBlockTimeUsedByTheseTests / xCycleFrequency ) + 1; + + /* If the demo task is still running then the loop counter is expected to + * have incremented every xLoopCounterIncrementTimeMax calls. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xIterationsWithoutCounterIncrement++; + + if( xIterationsWithoutCounterIncrement > xLoopCounterIncrementTimeMax ) + { + /* The tests appear to be no longer running (stalled). */ + xTestStatus = pdFAIL; + } + } + else + { + /* ulLoopCounter changed, so the count of times this function was called + * without a change can be reset to zero. */ + xIterationsWithoutCounterIncrement = ( TickType_t ) 0; + } + + ulLastLoopCounter = ulLoopCounter; + + /* Errors detected in the task itself will have latched xTestStatus + * to pdFAIL. */ + + return xTestStatus; +} +/*-----------------------------------------------------------*/ + +static void prvTest1_CreateTimersWithoutSchedulerRunning( void ) +{ + TickType_t xTimer; + + for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ ) + { + /* As the timer queue is not yet full, it should be possible to both + * create and start a timer. These timers are being started before the + * scheduler has been started, so their block times should get set to zero + * within the timer API itself. */ + xAutoReloadTimers[ xTimer ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ + ( ( xTimer + ( TickType_t ) 1 ) * xBasePeriod ), /* The period for the timer. The plus 1 ensures a period of zero is not specified. */ + pdTRUE, /* Auto-reload is set to true. */ + ( void * ) xTimer, /* An identifier for the timer as all the auto-reload timers use the same callback. */ + prvAutoReloadTimerCallback ); /* The callback to be called when the timer expires. */ + + if( xAutoReloadTimers[ xTimer ] == NULL ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + else + { + configASSERT( strcmp( pcTimerGetName( xAutoReloadTimers[ xTimer ] ), "FR Timer" ) == 0 ); + + /* The scheduler has not yet started, so the block period of + * portMAX_DELAY should just get set to zero in xTimerStart(). Also, + * the timer queue is not yet full so xTimerStart() should return + * pdPASS. */ + if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) != pdPASS ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + } + + /* The timers queue should now be full, so it should be possible to create + * another timer, but not possible to start it (the timer queue will not get + * drained until the scheduler has been started. */ + xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ + ( configTIMER_QUEUE_LENGTH * xBasePeriod ), /* The period for the timer. */ + pdTRUE, /* Auto-reload is set to true. */ + ( void * ) xTimer, /* An identifier for the timer as all the auto-reload timers use the same callback. */ + prvAutoReloadTimerCallback ); /* The callback executed when the timer expires. */ + + if( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] == NULL ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + else + { + if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) == pdPASS ) + { + /* This time it would not be expected that the timer could be + * started at this point. */ + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + /* Create the timers that are used from the tick interrupt to test the timer + * API functions that can be called from an ISR. */ + xISRAutoReloadTimer = xTimerCreate( "ISR AR", /* The text name given to the timer. */ + 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */ + pdTRUE, /* This is an auto-reload timer. */ + ( void * ) NULL, /* The identifier is not required. */ + prvISRAutoReloadTimerCallback ); /* The callback that is executed when the timer expires. */ + + xISROneShotTimer = xTimerCreate( "ISR OS", /* The text name given to the timer. */ + 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */ + pdFALSE, /* This is a one-shot timer. */ + ( void * ) NULL, /* The identifier is not required. */ + prvISROneShotTimerCallback ); /* The callback that is executed when the timer expires. */ + + if( ( xISRAutoReloadTimer == NULL ) || ( xISROneShotTimer == NULL ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTest2_CheckTaskAndTimersInitialState( void ) +{ + uint8_t ucTimer; + + /* Ensure all the timers are in their expected initial state. This depends + * on the timer service task having a higher priority than this task. + * + * auto-reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active, + * and auto-reload timer configTIMER_QUEUE_LENGTH should not yet be active (it + * could not be started prior to the scheduler being started when it was + * created). */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTest3_CheckAutoReloadExpireRates( void ) +{ + uint8_t ucMaxAllowableValue, ucMinAllowableValue, ucTimer; + TickType_t xBlockPeriod, xTimerPeriod, xExpectedNumber; + UBaseType_t uxOriginalPriority; + + /* Check the auto-reload timers expire at the expected rates. Do this at a + * high priority for maximum accuracy. This is ok as most of the time is spent + * in the Blocked state. */ + uxOriginalPriority = uxTaskPriorityGet( NULL ); + vTaskPrioritySet( NULL, ( configMAX_PRIORITIES - 1 ) ); + + /* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow + * all the auto-reload timers to expire at least once. */ + xBlockPeriod = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod; + vTaskDelay( xBlockPeriod ); + + /* Check that all the auto-reload timers have called their callback + * function the expected number of times. */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + /* The expected number of expires is equal to the block period divided + * by the timer period. */ + xTimerPeriod = ( ( ( TickType_t ) ucTimer + ( TickType_t ) 1 ) * xBasePeriod ); + xExpectedNumber = xBlockPeriod / xTimerPeriod; + + ucMaxAllowableValue = ( ( uint8_t ) xExpectedNumber ); + ucMinAllowableValue = ( uint8_t ) ( ( uint8_t ) xExpectedNumber - ( uint8_t ) 1 ); /* Weird casting to try and please all compilers. */ + + if( ( ucAutoReloadTimerCounters[ ucTimer ] < ucMinAllowableValue ) || + ( ucAutoReloadTimerCounters[ ucTimer ] > ucMaxAllowableValue ) + ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + /* Return to the original priority. */ + vTaskPrioritySet( NULL, uxOriginalPriority ); + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the + * check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ) +{ + uint8_t ucTimer; + + /* Check the auto-reload timers can be stopped correctly, and correctly + * report their state. */ + + /* Stop all the active timers. */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + /* The timer has not been stopped yet! */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now stop the timer. This will appear to happen immediately to + * this task because this task is running at a priority below the + * timer service task. */ + xTimerStop( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); + + /* The timer should now be inactive. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + taskENTER_CRITICAL(); + { + /* The timer in array position configTIMER_QUEUE_LENGTH should not + * be active. The critical section is used to ensure the timer does + * not call its callback between the next line running and the array + * being cleared back to zero, as that would mask an error condition. */ + if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Clear the timer callback count. */ + memset( ( void * ) ucAutoReloadTimerCounters, 0, sizeof( ucAutoReloadTimerCounters ) ); + } + taskEXIT_CRITICAL(); + + /* The timers are now all inactive, so this time, after delaying, none + * of the callback counters should have incremented. */ + vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); + + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + if( ucAutoReloadTimerCounters[ ucTimer ] != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so + * the check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest5_CheckBasicOneShotTimerBehaviour( void ) +{ + /* Check the one-shot timer only calls its callback once after it has been + * started, and that it reports its state correctly. */ + + /* The one-shot timer should not be active yet. */ + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucOneShotTimerCounter != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Start the one-shot timer and check that it reports its state correctly. */ + xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); + + if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Delay for three times as long as the one-shot timer period, then check + * to ensure it has only called its callback once, and is now not in the + * active state. */ + vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD * ( TickType_t ) 3 ); + + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucOneShotTimerCounter != ( uint8_t ) 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + else + { + /* Reset the one-shot timer callback count. */ + ucOneShotTimerCounter = ( uint8_t ) 0; + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the + * check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest6_CheckAutoReloadResetBehaviour( void ) +{ + uint8_t ucTimer; + + /* Check timer reset behaviour. */ + + /* Restart the one-shot timer and check it reports its status correctly. */ + xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); + + if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Restart one of the auto-reload timers and check that it reports its + * status correctly. */ + xTimerStart( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + for( ucTimer = 0; ucTimer < tmrdemoNUM_TIMER_RESETS; ucTimer++ ) + { + /* Delay for half as long as the one-shot timer period, then reset it. + * It should never expire while this is done, so its callback count should + * never increment. */ + vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD / 2 ); + + /* Check both running timers are still active, but have not called their + * callback functions. */ + if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucOneShotTimerCounter != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Reset both running timers. */ + xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK ); + xTimerReset( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so + * the check task knows this task is still running. */ + ulLoopCounter++; + } + } + + /* Finally delay long enough for both running timers to expire. */ + vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); + + /* The timers were not reset during the above delay period so should now + * both have called their callback functions. */ + if( ucOneShotTimerCounter != ( uint8_t ) 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* The one-shot timer should no longer be active, while the auto-reload + * timer should still be active. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Stop the auto-reload timer again. */ + xTimerStop( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Clear the timer callback counts, ready for another iteration of these + * tests. */ + ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( uint8_t ) 0; + ucOneShotTimerCounter = ( uint8_t ) 0; + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the check + * task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest7_CheckBacklogBehaviour( void ) +{ + UBaseType_t uxOriginalPriority; + + /* Use the first auto-reload timer to test stopping a timer from a + * backlogged callback. */ + + /* The timer has not been started yet! */ + if( xTimerIsTimerActive( xAutoReloadTimers[ 0 ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Prompt the callback function to stop the timer. */ + ucIsStopNeededInTimerZeroCallback = ( uint8_t ) pdTRUE; + + /* Now start the timer. This will appear to happen immediately to + * this task because this task is running at a priority below the timer + * service task. Use a timer period of one tick so the call to + * xTaskCatchUpTicks() below has minimal impact on other tests that might + * be running. */ +#define tmrdemoBACKLOG_TIMER_PERIOD ( ( TickType_t ) 1 ) + xTimerChangePeriod( xAutoReloadTimers[ 0 ], tmrdemoBACKLOG_TIMER_PERIOD, tmrdemoDONT_BLOCK ); + + /* The timer should now be active. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ 0 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Arrange for the callback to execute late enough that it will execute + * twice, back-to-back. The timer must handle the stop request properly + * in spite of the backlog of callbacks. */ +#define tmrdemoEXPECTED_BACKLOG_EXPIRES ( ( TickType_t ) 2 ) + xTaskCatchUpTicks( tmrdemoBACKLOG_TIMER_PERIOD * tmrdemoEXPECTED_BACKLOG_EXPIRES ); + + /* The timer should now be inactive. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ 0 ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Restore the standard timer period, and leave the timer inactive. */ + xTimerChangePeriod( xAutoReloadTimers[ 0 ], xBasePeriod, tmrdemoDONT_BLOCK ); + xTimerStop( xAutoReloadTimers[ 0 ], tmrdemoDONT_BLOCK ); + + /* Clear the reload count for the timer used in this test. */ + ucAutoReloadTimerCounters[ 0 ] = ( uint8_t ) 0; + + + /* Verify a one-shot timer is marked as inactive if the timer task processes + * the start or reset request after the expiration time has passed. */ + + /* The timer has not been started yet! */ + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Use the timer period specific to backlogged timers because it reduces + * the impact on other tests that might be running when xTaskCatchUpTicks() + * creates the backlog, below. */ + xTimerChangePeriod( xOneShotTimer, tmrdemoBACKLOG_TIMER_PERIOD, tmrdemoDONT_BLOCK ); + + /* Temporarily give this task maximum priority so it can cause the timer + * task to delay its processing of the reset request below. */ + uxOriginalPriority = uxTaskPriorityGet( NULL ); + vTaskPrioritySet( NULL, ( configMAX_PRIORITIES - 1 ) ); + + /* Reset the timer. The timer service won't process this request right + * away as noted above. */ + xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK ); + + /* Cause the timer period to elapse without giving an opportunity for the + * timer service task to process the reset request. */ + xTaskCatchUpTicks( tmrdemoBACKLOG_TIMER_PERIOD ); + + /* Return this task to its original priority. The timer service task will + * process the reset request immediately. The timer task must handle the reset + * request as if it were processed at the time of the request even though in + * this test the processing occurs after the intended expiration time. */ + vTaskPrioritySet( NULL, uxOriginalPriority ); + + /* The timer should now be inactive. */ + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Restore the standard timer period, and leave the timer inactive. */ + xTimerChangePeriod( xOneShotTimer, tmrdemoONE_SHOT_TIMER_PERIOD, tmrdemoDONT_BLOCK ); + xTimerStop( xOneShotTimer, tmrdemoDONT_BLOCK ); + + /* Clear the counter for the timer used in this test. */ + ucOneShotTimerCounter = ( uint8_t ) 0; + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the check + * task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvResetStartConditionsForNextIteration( void ) +{ + uint8_t ucTimer; + + /* Start the timers again to start all the tests over again. */ + + /* Start the timers again. */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + /* The timer has not been started yet! */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now start the timer. This will appear to happen immediately to + * this task because this task is running at a priority below the timer + * service task. */ + xTimerStart( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); + + /* The timer should now be active. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the + * check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +void vTimerPeriodicISRTests( void ) +{ + static TickType_t uxTick = ( TickType_t ) -1; + + #if ( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) ) + + /* The timer service task is not the highest priority task, so it cannot + * be assumed that timings will be exact. Timers should never call their + * callback before their expiry time, but a margin is permissible for calling + * their callback after their expiry time. If exact timing is required then + * configTIMER_TASK_PRIORITY must be set to ensure the timer service task + * is the highest priority task in the system. + * + * This function is called from the tick hook. The tick hook is called + * even when the scheduler is suspended. Therefore it is possible that the + * uxTick count maintained in this function is temporarily ahead of the tick + * count maintained by the kernel. When this is the case a message posted from + * this function will assume a time stamp in advance of the real time stamp, + * which can result in a timer being processed before this function expects it + * to. For example, if the kernel's tick count was 100, and uxTick was 102, + * then this function will not expect the timer to have expired until the + * kernel's tick count is (102 + xBasePeriod), whereas in reality the timer + * will expire when the kernel's tick count is (100 + xBasePeriod). For this + * reason xMargin is used as an allowable margin for premature timer expires + * as well as late timer expires. */ + #ifdef _WINDOWS_ + /* Windows is not real real time. */ + const TickType_t xMargin = 20; + #else + const TickType_t xMargin = 6; + #endif /* _WINDOWS_ */ + #else + #ifdef _WINDOWS_ + /* Windows is not real real time. */ + const TickType_t xMargin = 20; + #else + const TickType_t xMargin = 4; + #endif /* _WINDOWS_ */ + #endif /* if ( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) ) */ + + + uxTick++; + + if( uxTick == 0 ) + { + /* The timers will have been created, but not started. Start them now + * by setting their period. */ + ucISRAutoReloadTimerCounter = 0; + ucISROneShotTimerCounter = 0; + + /* It is possible that the timer task has not yet made room in the + * timer queue. If the timers cannot be started then reset uxTick so + * another attempt is made later. */ + uxTick = ( TickType_t ) -1; + + /* Try starting first timer. */ + if( xTimerChangePeriodFromISR( xISRAutoReloadTimer, xBasePeriod, NULL ) == pdPASS ) + { + /* First timer was started, try starting the second timer. */ + if( xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, NULL ) == pdPASS ) + { + /* Both timers were started, so set the uxTick back to its + * proper value. */ + uxTick = 0; + } + else + { + /* Second timer could not be started, so stop the first one + * again. */ + xTimerStopFromISR( xISRAutoReloadTimer, NULL ); + } + } + } + else if( uxTick == ( xBasePeriod - xMargin ) ) + { + /* Neither timer should have expired yet. */ + if( ( ucISRAutoReloadTimerCounter != 0 ) || ( ucISROneShotTimerCounter != 0 ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( xBasePeriod + xMargin ) ) + { + /* Both timers should now have expired once. The auto-reload timer will + * still be active, but the one-shot timer should now have stopped. */ + if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 2 * xBasePeriod ) - xMargin ) ) + { + /* The auto-reload timer will still be active, but the one-shot timer + * should now have stopped - however, at this time neither of the timers + * should have expired again since the last test. */ + if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 2 * xBasePeriod ) + xMargin ) ) + { + /* The auto-reload timer will still be active, but the one-shot timer + * should now have stopped. At this time the auto-reload timer should have + * expired again, but the one-shot timer count should not have changed. */ + if( ucISRAutoReloadTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 2 * xBasePeriod ) + ( xBasePeriod >> ( TickType_t ) 2U ) ) ) + { + /* The auto-reload timer will still be active, but the one-shot timer + * should now have stopped. Again though, at this time, neither timer call + * back should have been called since the last test. */ + if( ucISRAutoReloadTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( 3 * xBasePeriod ) ) + { + /* Start the one-shot timer again. */ + xTimerStartFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 3 * xBasePeriod ) + xMargin ) ) + { + /* The auto-reload timer and one-shot timer will be active. At + * this time the auto-reload timer should have expired again, but the one + * shot timer count should not have changed yet. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now stop the auto-reload timer. The one-shot timer was started + * a few ticks ago. */ + xTimerStopFromISR( xISRAutoReloadTimer, NULL ); + } + else if( uxTick == ( 4 * ( xBasePeriod - xMargin ) ) ) + { + /* The auto-reload timer is now stopped, and the one-shot timer is + * active, but at this time neither timer should have expired since the + * last test. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 4 * xBasePeriod ) + xMargin ) ) + { + /* The auto-reload timer is now stopped, and the one-shot timer is + * active. The one-shot timer should have expired again, but the auto + * reload timer should not have executed its callback. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( 8 * xBasePeriod ) ) + { + /* The auto-reload timer is now stopped, and the one-shot timer has + * already expired and then stopped itself. Both callback counters should + * not have incremented since the last test. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now reset the one-shot timer. */ + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 9 * xBasePeriod ) - xMargin ) ) + { + /* Only the one-shot timer should be running, but it should not have + * expired since the last test. Check the callback counters have not + * incremented, then reset the one-shot timer again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 10 * xBasePeriod ) - ( 2 * xMargin ) ) ) + { + /* Only the one-shot timer should be running, but it should not have + * expired since the last test. Check the callback counters have not + * incremented, then reset the one-shot timer again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 11 * xBasePeriod ) - ( 3 * xMargin ) ) ) + { + /* Only the one-shot timer should be running, but it should not have + * expired since the last test. Check the callback counters have not + * incremented, then reset the one-shot timer once again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 12 * xBasePeriod ) - ( 2 * xMargin ) ) ) + { + /* Only the one-shot timer should have been running and this time it + * should have expired. Check its callback count has been incremented. + * The auto-reload timer is still not running so should still have the same + * count value. This time the one-shot timer is not reset so should not + * restart from its expiry period again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( 15 * xBasePeriod ) ) + { + /* Neither timer should be running now. Check neither callback count + * has incremented, then go back to the start to run these tests all + * over again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + uxTick = ( TickType_t ) -1; + } +} +/*-----------------------------------------------------------*/ + +/*** Timer callback functions are defined below here. ***/ + +static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ) +{ + size_t uxTimerID; + + uxTimerID = ( size_t ) pvTimerGetTimerID( pxExpiredTimer ); + + if( uxTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) ) + { + ( ucAutoReloadTimerCounters[ uxTimerID ] )++; + + /* Stop timer ID 0 if requested. */ + if( ( uxTimerID == ( size_t ) 0 ) && ( ucIsStopNeededInTimerZeroCallback == ( uint8_t ) pdTRUE ) ) + { + xTimerStop( pxExpiredTimer, tmrdemoDONT_BLOCK ); + ucIsStopNeededInTimerZeroCallback = ( uint8_t ) pdFALSE; + } + } + else + { + /* The timer ID appears to be unexpected (invalid). */ + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } +} +/*-----------------------------------------------------------*/ + +static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer ) +{ +/* A count is kept of the number of times this callback function is executed. + * The count is stored as the timer's ID. This is only done to test the + * vTimerSetTimerID() function. */ + static size_t uxCallCount = 0; + size_t uxLastCallCount; + + /* Obtain the timer's ID, which should be a count of the number of times + * this callback function has been executed. */ + uxLastCallCount = ( size_t ) pvTimerGetTimerID( pxExpiredTimer ); + configASSERT( uxLastCallCount == uxCallCount ); + + /* Increment the call count, then save it back as the timer's ID. This is + * only done to test the vTimerSetTimerID() API function. */ + uxLastCallCount++; + vTimerSetTimerID( pxExpiredTimer, ( void * ) uxLastCallCount ); + uxCallCount++; + + ucOneShotTimerCounter++; +} +/*-----------------------------------------------------------*/ + +static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ) +{ + /* The parameter is not used in this case as only one timer uses this + * callback function. */ + ( void ) pxExpiredTimer; + + ucISRAutoReloadTimerCounter++; +} +/*-----------------------------------------------------------*/ + +static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer ) +{ + /* The parameter is not used in this case as only one timer uses this + * callback function. */ + ( void ) pxExpiredTimer; + + ucISROneShotTimerCounter++; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/Common/Minimal/blocktim.c b/FreeRTOS/Demo/Common/Minimal/blocktim.c index fbd8a44e8..f5e8ef2b7 100644 --- a/FreeRTOS/Demo/Common/Minimal/blocktim.c +++ b/FreeRTOS/Demo/Common/Minimal/blocktim.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -290,7 +290,7 @@ static void vPrimaryBlockTimeTestTask( void * pvParameters ) vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); } - /* Let the other task timeout. When it unblockes it will check that it + /* Let the other task timeout. When it unblocks it will check that it * unblocked at the correct time, then suspend itself. */ while( xRunIndicator != bktRUN_INDICATOR ) { @@ -367,7 +367,7 @@ static void vPrimaryBlockTimeTestTask( void * pvParameters ) vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); } - /* Let the other task timeout. When it unblockes it will check that it + /* Let the other task timeout. When it unblocks it will check that it * unblocked at the correct time, then suspend itself. */ while( xRunIndicator != bktRUN_INDICATOR ) { diff --git a/FreeRTOS/Demo/Common/Minimal/comtest.c b/FreeRTOS/Demo/Common/Minimal/comtest.c index 4b211daa9..8611d0429 100644 --- a/FreeRTOS/Demo/Common/Minimal/comtest.c +++ b/FreeRTOS/Demo/Common/Minimal/comtest.c @@ -1,265 +1,265 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* - * 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 -#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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * 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 +#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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/comtest_strings.c b/FreeRTOS/Demo/Common/Minimal/comtest_strings.c index 757387fc9..b6c04250c 100644 --- a/FreeRTOS/Demo/Common/Minimal/comtest_strings.c +++ b/FreeRTOS/Demo/Common/Minimal/comtest_strings.c @@ -1,316 +1,316 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* - * 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 -#include -#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 declaration 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * 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 +#include +#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 declaration 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/countsem.c b/FreeRTOS/Demo/Common/Minimal/countsem.c index d0c6a0eda..791b4b42a 100644 --- a/FreeRTOS/Demo/Common/Minimal/countsem.c +++ b/FreeRTOS/Demo/Common/Minimal/countsem.c @@ -1,290 +1,290 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - -/* - * 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, - volatile UBaseType_t * puxLoopCounter ); - -/* - * Utility function to decrement the semaphore count value up from - * countMAX_COUNT_VALUE to zero. - */ -static void prvDecrementSemaphoreCount( SemaphoreHandle_t xSemaphore, - volatile 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. */ - volatile UBaseType_t uxLoopCounter; -} xCountSemStruct; - -/* Two structures are defined, one is passed to each test task. */ -static 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, - volatile 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, - volatile 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * 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, + volatile UBaseType_t * puxLoopCounter ); + +/* + * Utility function to decrement the semaphore count value up from + * countMAX_COUNT_VALUE to zero. + */ +static void prvDecrementSemaphoreCount( SemaphoreHandle_t xSemaphore, + volatile 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. */ + volatile UBaseType_t uxLoopCounter; +} xCountSemStruct; + +/* Two structures are defined, one is passed to each test task. */ +static 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, + volatile 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, + volatile 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/crflash.c b/FreeRTOS/Demo/Common/Minimal/crflash.c index 099867ae3..1ce0e162f 100644 --- a/FreeRTOS/Demo/Common/Minimal/crflash.c +++ b/FreeRTOS/Demo/Common/Minimal/crflash.c @@ -1,218 +1,218 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 - -#if ( configUSE_CO_ROUTINES == 1 ) - -/* - * 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; - } - -#endif /* if ( configUSE_CO_ROUTINES == 1 ) */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 + +#if ( configUSE_CO_ROUTINES == 1 ) + +/* + * 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; + } + +#endif /* if ( configUSE_CO_ROUTINES == 1 ) */ diff --git a/FreeRTOS/Demo/Common/Minimal/crhook.c b/FreeRTOS/Demo/Common/Minimal/crhook.c index 764099d1b..cb8d46433 100644 --- a/FreeRTOS/Demo/Common/Minimal/crhook.c +++ b/FreeRTOS/Demo/Common/Minimal/crhook.c @@ -1,236 +1,236 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 ) -/*-----------------------------------------------------------*/ -#if ( configUSE_CO_ROUTINES == 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; - } - } - -#endif /* if ( configUSE_CO_ROUTINES == 1 ) */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 ) +/*-----------------------------------------------------------*/ +#if ( configUSE_CO_ROUTINES == 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; + } + } + +#endif /* if ( configUSE_CO_ROUTINES == 1 ) */ diff --git a/FreeRTOS/Demo/Common/Minimal/death.c b/FreeRTOS/Demo/Common/Minimal/death.c index 214d400bb..1b195d1a4 100644 --- a/FreeRTOS/Demo/Common/Minimal/death.c +++ b/FreeRTOS/Demo/Common/Minimal/death.c @@ -1,200 +1,200 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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 - *
- */ - - -#include - -/* 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 ); -} -/*-----------------------------------------------------------*/ - -static portTASK_FUNCTION( vSuicidalTask, pvParameters ) -{ - volatile long l1, l2; - TaskHandle_t xTaskToKill; - const TickType_t xDelay = pdMS_TO_TICKS( ( TickType_t ) 200 ); - - /* Test deletion of a task's secure context, if any. */ - portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE ); - - 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; - - /* Delay at the start to ensure tasks created by other demos have been - * created before storing the current number of tasks. */ - vTaskDelay( xDelay ); - uxTasksRunningAtStart = ( UBaseType_t ) uxTaskGetNumberOfTasks(); - - 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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 + *
+ */ + + +#include + +/* 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 ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vSuicidalTask, pvParameters ) +{ + volatile long l1, l2; + TaskHandle_t xTaskToKill; + const TickType_t xDelay = pdMS_TO_TICKS( ( TickType_t ) 200 ); + + /* Test deletion of a task's secure context, if any. */ + portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE ); + + 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; + + /* Delay at the start to ensure tasks created by other demos have been + * created before storing the current number of tasks. */ + vTaskDelay( xDelay ); + uxTasksRunningAtStart = ( UBaseType_t ) uxTaskGetNumberOfTasks(); + + 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/dynamic.c b/FreeRTOS/Demo/Common/Minimal/dynamic.c index 64cc13e82..001685583 100644 --- a/FreeRTOS/Demo/Common/Minimal/dynamic.c +++ b/FreeRTOS/Demo/Common/Minimal/dynamic.c @@ -1,488 +1,488 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 - -/* 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. */ -#ifndef priSUSPENDED_RX_TASK_STACK_SIZE - #define priSUSPENDED_RX_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE ) -#endif -#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 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", priSUSPENDED_RX_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); - xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); - xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RX", priSUSPENDED_RX_TASK_STACK_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 ) -{ - volatile uint32_t * pulCounter; - - /* Take a pointer to the shared variable from the parameters passed into - * the task. */ - pulCounter = ( volatile 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 = ( volatile 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 ) - { - #if ( configNUMBER_OF_CORES > 1 ) - { - eTaskState eState = eTaskGetState( xContinuousIncrementHandle ); - configASSERT( ( eState == eReady ) || ( eState == eRunning ) ); - } - #else - { - configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady ); - } - #endif - } - #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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 + +/* 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. */ +#ifndef priSUSPENDED_RX_TASK_STACK_SIZE + #define priSUSPENDED_RX_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE ) +#endif +#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 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", priSUSPENDED_RX_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RX", priSUSPENDED_RX_TASK_STACK_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 ) +{ + volatile uint32_t * pulCounter; + + /* Take a pointer to the shared variable from the parameters passed into + * the task. */ + pulCounter = ( volatile 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 = ( volatile 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 ) + { + #if ( configNUMBER_OF_CORES > 1 ) + { + eTaskState eState = eTaskGetState( xContinuousIncrementHandle ); + configASSERT( ( eState == eReady ) || ( eState == eRunning ) ); + } + #else + { + configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady ); + } + #endif + } + #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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/flash.c b/FreeRTOS/Demo/Common/Minimal/flash.c index 8dffbe874..01aa0c2e9 100644 --- a/FreeRTOS/Demo/Common/Minimal/flash.c +++ b/FreeRTOS/Demo/Common/Minimal/flash.c @@ -1,117 +1,117 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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 - -/* 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. */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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 + +/* 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. */ diff --git a/FreeRTOS/Demo/Common/Minimal/flash_timer.c b/FreeRTOS/Demo/Common/Minimal/flash_timer.c index 29be0ae53..7dfb61d28 100644 --- a/FreeRTOS/Demo/Common/Minimal/flash_timer.c +++ b/FreeRTOS/Demo/Common/Minimal/flash_timer.c @@ -1,95 +1,95 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * 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 ); -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * 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 ); +} diff --git a/FreeRTOS/Demo/Common/Minimal/flop.c b/FreeRTOS/Demo/Common/Minimal/flop.c index beedb360f..5188c6815 100644 --- a/FreeRTOS/Demo/Common/Minimal/flop.c +++ b/FreeRTOS/Demo/Common/Minimal/flop.c @@ -1,346 +1,346 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 -#include - -/* 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 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 = ( volatile 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 = ( volatile 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 = ( volatile 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 = ( volatile 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 +#include + +/* 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 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 = ( volatile 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 = ( volatile 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 = ( volatile 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 = ( volatile 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/integer.c b/FreeRTOS/Demo/Common/Minimal/integer.c index aea434501..cc0bdefb4 100644 --- a/FreeRTOS/Demo/Common/Minimal/integer.c +++ b/FreeRTOS/Demo/Common/Minimal/integer.c @@ -1,161 +1,161 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 - -/* 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 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 + +/* 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 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/readme.txt b/FreeRTOS/Demo/Common/Minimal/readme.txt index 4125d2ca8..48668dcba 100644 --- a/FreeRTOS/Demo/Common/Minimal/readme.txt +++ b/FreeRTOS/Demo/Common/Minimal/readme.txt @@ -1,2 +1,2 @@ -This directory contains the implementation of the "common demo tasks". These +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. \ No newline at end of file diff --git a/FreeRTOS/Demo/Common/Minimal/recmutex.c b/FreeRTOS/Demo/Common/Minimal/recmutex.c index b1b3ebeee..d3de03a5c 100644 --- a/FreeRTOS/Demo/Common/Minimal/recmutex.c +++ b/FreeRTOS/Demo/Common/Minimal/recmutex.c @@ -1,411 +1,411 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 ) ) - -#ifndef recmuRECURSIVE_MUTEX_TEST_TASK_STACK_SIZE - #define recmuRECURSIVE_MUTEX_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE -#endif - -/* 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", recmuRECURSIVE_MUTEX_TEST_TASK_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle ); - xTaskCreate( prvRecursiveMutexBlockingTask, "Rec2", recmuRECURSIVE_MUTEX_TEST_TASK_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle ); - xTaskCreate( prvRecursiveMutexPollingTask, "Rec3", recmuRECURSIVE_MUTEX_TEST_TASK_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 != ( UBaseType_t ) ( 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. It should only be obtained 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 ) ) + +#ifndef recmuRECURSIVE_MUTEX_TEST_TASK_STACK_SIZE + #define recmuRECURSIVE_MUTEX_TEST_TASK_STACK_SIZE configMINIMAL_STACK_SIZE +#endif + +/* 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", recmuRECURSIVE_MUTEX_TEST_TASK_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle ); + xTaskCreate( prvRecursiveMutexBlockingTask, "Rec2", recmuRECURSIVE_MUTEX_TEST_TASK_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle ); + xTaskCreate( prvRecursiveMutexPollingTask, "Rec3", recmuRECURSIVE_MUTEX_TEST_TASK_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 != ( UBaseType_t ) ( 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. It should only be obtained 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/semtest.c b/FreeRTOS/Demo/Common/Minimal/semtest.c index 98ef9061f..29d2850a8 100644 --- a/FreeRTOS/Demo/Common/Minimal/semtest.c +++ b/FreeRTOS/Demo/Common/Minimal/semtest.c @@ -1,271 +1,271 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 - -/* 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. */ - if( pxParameters->xBlockTime != ( TickType_t ) 0 ) - { - 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 + +/* 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. */ + if( pxParameters->xBlockTime != ( TickType_t ) 0 ) + { + 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; +} diff --git a/FreeRTOS/Demo/Common/Minimal/sp_flop.c b/FreeRTOS/Demo/Common/Minimal/sp_flop.c index 15018548f..997c377e7 100644 --- a/FreeRTOS/Demo/Common/Minimal/sp_flop.c +++ b/FreeRTOS/Demo/Common/Minimal/sp_flop.c @@ -1,324 +1,324 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * 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 -#include - -/* 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; -} +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * 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 +#include + +/* 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; +} diff --git a/FreeRTOS/Demo/Common/ReadMe.txt b/FreeRTOS/Demo/Common/ReadMe.txt index 72b46db96..769b122bd 100644 --- a/FreeRTOS/Demo/Common/ReadMe.txt +++ b/FreeRTOS/Demo/Common/ReadMe.txt @@ -1,14 +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 +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. \ No newline at end of file diff --git a/FreeRTOS/Demo/Common/include/AbortDelay.h b/FreeRTOS/Demo/Common/include/AbortDelay.h index 08350ecab..7e6fa7671 100644 --- a/FreeRTOS/Demo/Common/include/AbortDelay.h +++ b/FreeRTOS/Demo/Common/include/AbortDelay.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef ABORT_DELAY_H -#define ABORT_DELAY_H - -void vCreateAbortDelayTasks( void ); -BaseType_t xAreAbortDelayTestTasksStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef ABORT_DELAY_H +#define ABORT_DELAY_H + +void vCreateAbortDelayTasks( void ); +BaseType_t xAreAbortDelayTestTasksStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/BlockQ.h b/FreeRTOS/Demo/Common/include/BlockQ.h index af9882fa3..aea427357 100644 --- a/FreeRTOS/Demo/Common/include/BlockQ.h +++ b/FreeRTOS/Demo/Common/include/BlockQ.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef BLOCK_Q_H -#define BLOCK_Q_H - -void vStartBlockingQueueTasks( UBaseType_t uxPriority ); -BaseType_t xAreBlockingQueuesStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef BLOCK_Q_H +#define BLOCK_Q_H + +void vStartBlockingQueueTasks( UBaseType_t uxPriority ); +BaseType_t xAreBlockingQueuesStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/EventGroupsDemo.h b/FreeRTOS/Demo/Common/include/EventGroupsDemo.h index 297b7694e..5f06d25b0 100644 --- a/FreeRTOS/Demo/Common/include/EventGroupsDemo.h +++ b/FreeRTOS/Demo/Common/include/EventGroupsDemo.h @@ -1,42 +1,42 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - - - -/* - * 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 */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + + +/* + * 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 */ diff --git a/FreeRTOS/Demo/Common/include/GenQTest.h b/FreeRTOS/Demo/Common/include/GenQTest.h index d591adff4..e5923a5f0 100644 --- a/FreeRTOS/Demo/Common/include/GenQTest.h +++ b/FreeRTOS/Demo/Common/include/GenQTest.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 */ diff --git a/FreeRTOS/Demo/Common/include/IntQueue.h b/FreeRTOS/Demo/Common/include/IntQueue.h index 92e69fd66..249962a57 100644 --- a/FreeRTOS/Demo/Common/include/IntQueue.h +++ b/FreeRTOS/Demo/Common/include/IntQueue.h @@ -1,35 +1,35 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 */ diff --git a/FreeRTOS/Demo/Common/include/IntSemTest.h b/FreeRTOS/Demo/Common/include/IntSemTest.h index b8509f294..024290643 100644 --- a/FreeRTOS/Demo/Common/include/IntSemTest.h +++ b/FreeRTOS/Demo/Common/include/IntSemTest.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 */ diff --git a/FreeRTOS/Demo/Common/include/MessageBufferAMP.h b/FreeRTOS/Demo/Common/include/MessageBufferAMP.h index 3aaae4dbc..932ad93c3 100644 --- a/FreeRTOS/Demo/Common/include/MessageBufferAMP.h +++ b/FreeRTOS/Demo/Common/include/MessageBufferAMP.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef MESSAGE_BUFFER_AMP_H -#define MESSAGE_BUFFER_AMP_H - -void vStartMessageBufferAMPTasks( configSTACK_DEPTH_TYPE xStackSize ); -BaseType_t xAreMessageBufferAMPTasksStillRunning( void ); -void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer ); - -#endif /* MESSAGE_BUFFER_AMP_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef MESSAGE_BUFFER_AMP_H +#define MESSAGE_BUFFER_AMP_H + +void vStartMessageBufferAMPTasks( configSTACK_DEPTH_TYPE xStackSize ); +BaseType_t xAreMessageBufferAMPTasksStillRunning( void ); +void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer ); + +#endif /* MESSAGE_BUFFER_AMP_H */ diff --git a/FreeRTOS/Demo/Common/include/MessageBufferDemo.h b/FreeRTOS/Demo/Common/include/MessageBufferDemo.h index 230e5fb8e..cf4c8255a 100644 --- a/FreeRTOS/Demo/Common/include/MessageBufferDemo.h +++ b/FreeRTOS/Demo/Common/include/MessageBufferDemo.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef MESSAGE_BUFFER_TEST_H -#define MESSAGE_BUFFER_TEST_H - -void vStartMessageBufferTasks( configSTACK_DEPTH_TYPE xStackSize ); -BaseType_t xAreMessageBufferTasksStillRunning( void ); - -#endif /* MESSAGE_BUFFER_TEST_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef MESSAGE_BUFFER_TEST_H +#define MESSAGE_BUFFER_TEST_H + +void vStartMessageBufferTasks( configSTACK_DEPTH_TYPE xStackSize ); +BaseType_t xAreMessageBufferTasksStillRunning( void ); + +#endif /* MESSAGE_BUFFER_TEST_H */ diff --git a/FreeRTOS/Demo/Common/include/PollQ.h b/FreeRTOS/Demo/Common/include/PollQ.h index dbc5b32ce..8585dbf4d 100644 --- a/FreeRTOS/Demo/Common/include/PollQ.h +++ b/FreeRTOS/Demo/Common/include/PollQ.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef POLLED_Q_H -#define POLLED_Q_H - -void vStartPolledQueueTasks( UBaseType_t uxPriority ); -BaseType_t xArePollingQueuesStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef POLLED_Q_H +#define POLLED_Q_H + +void vStartPolledQueueTasks( UBaseType_t uxPriority ); +BaseType_t xArePollingQueuesStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/QPeek.h b/FreeRTOS/Demo/Common/include/QPeek.h index 73b33d221..f5d8e8106 100644 --- a/FreeRTOS/Demo/Common/include/QPeek.h +++ b/FreeRTOS/Demo/Common/include/QPeek.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef Q_PEEK_TEST_H -#define Q_PEEK_TEST_H - -void vStartQueuePeekTasks( void ); -BaseType_t xAreQueuePeekTasksStillRunning( void ); - -#endif /* Q_PEEK_TEST_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef Q_PEEK_TEST_H +#define Q_PEEK_TEST_H + +void vStartQueuePeekTasks( void ); +BaseType_t xAreQueuePeekTasksStillRunning( void ); + +#endif /* Q_PEEK_TEST_H */ diff --git a/FreeRTOS/Demo/Common/include/QueueOverwrite.h b/FreeRTOS/Demo/Common/include/QueueOverwrite.h index 0618bbf97..a66c66027 100644 --- a/FreeRTOS/Demo/Common/include/QueueOverwrite.h +++ b/FreeRTOS/Demo/Common/include/QueueOverwrite.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef QUEUE_OVERWRITE_H -#define QUEUE_OVERWRITE_H - -void vStartQueueOverwriteTask( UBaseType_t uxPriority ); -BaseType_t xIsQueueOverwriteTaskStillRunning( void ); -void vQueueOverwritePeriodicISRDemo( void ); - -#endif /* QUEUE_OVERWRITE_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef QUEUE_OVERWRITE_H +#define QUEUE_OVERWRITE_H + +void vStartQueueOverwriteTask( UBaseType_t uxPriority ); +BaseType_t xIsQueueOverwriteTaskStillRunning( void ); +void vQueueOverwritePeriodicISRDemo( void ); + +#endif /* QUEUE_OVERWRITE_H */ diff --git a/FreeRTOS/Demo/Common/include/QueueSet.h b/FreeRTOS/Demo/Common/include/QueueSet.h index d2efabd9a..4e66d060d 100644 --- a/FreeRTOS/Demo/Common/include/QueueSet.h +++ b/FreeRTOS/Demo/Common/include/QueueSet.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 */ diff --git a/FreeRTOS/Demo/Common/include/QueueSetPolling.h b/FreeRTOS/Demo/Common/include/QueueSetPolling.h index dca872ebf..c83cc47ca 100644 --- a/FreeRTOS/Demo/Common/include/QueueSetPolling.h +++ b/FreeRTOS/Demo/Common/include/QueueSetPolling.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 */ diff --git a/FreeRTOS/Demo/Common/include/StaticAllocation.h b/FreeRTOS/Demo/Common/include/StaticAllocation.h index 6640cbe66..e729b41cb 100644 --- a/FreeRTOS/Demo/Common/include/StaticAllocation.h +++ b/FreeRTOS/Demo/Common/include/StaticAllocation.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef STATIC_ALLOCATION_H -#define STATIC_ALLOCATION_H - -void vStartStaticallyAllocatedTasks( void ); -BaseType_t xAreStaticAllocationTasksStillRunning( void ); - -#endif /* STATIC_ALLOCATION_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef STATIC_ALLOCATION_H +#define STATIC_ALLOCATION_H + +void vStartStaticallyAllocatedTasks( void ); +BaseType_t xAreStaticAllocationTasksStillRunning( void ); + +#endif /* STATIC_ALLOCATION_H */ diff --git a/FreeRTOS/Demo/Common/include/StreamBufferDemo.h b/FreeRTOS/Demo/Common/include/StreamBufferDemo.h index 935731439..ace38ac2c 100644 --- a/FreeRTOS/Demo/Common/include/StreamBufferDemo.h +++ b/FreeRTOS/Demo/Common/include/StreamBufferDemo.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef STREAM_BUFFER_TEST_H -#define STREAM_BUFFER_TEST_H - -void vStartStreamBufferTasks( void ); -BaseType_t xAreStreamBufferTasksStillRunning( void ); -void vPeriodicStreamBufferProcessing( void ); - -#endif /* STREAM_BUFFER_TEST_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef STREAM_BUFFER_TEST_H +#define STREAM_BUFFER_TEST_H + +void vStartStreamBufferTasks( void ); +BaseType_t xAreStreamBufferTasksStillRunning( void ); +void vPeriodicStreamBufferProcessing( void ); + +#endif /* STREAM_BUFFER_TEST_H */ diff --git a/FreeRTOS/Demo/Common/include/StreamBufferInterrupt.h b/FreeRTOS/Demo/Common/include/StreamBufferInterrupt.h index 39296ef17..885afa6d2 100644 --- a/FreeRTOS/Demo/Common/include/StreamBufferInterrupt.h +++ b/FreeRTOS/Demo/Common/include/StreamBufferInterrupt.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef STREAM_BUFFER_INTERRUPT_H -#define STREAM_BUFFER_INTERRUPT_H - -void vStartStreamBufferInterruptDemo( void ); -void vBasicStreamBufferSendFromISR( void ); -BaseType_t xIsInterruptStreamBufferDemoStillRunning( void ); - -#endif /* STREAM_BUFFER_INTERRUPT_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef STREAM_BUFFER_INTERRUPT_H +#define STREAM_BUFFER_INTERRUPT_H + +void vStartStreamBufferInterruptDemo( void ); +void vBasicStreamBufferSendFromISR( void ); +BaseType_t xIsInterruptStreamBufferDemoStillRunning( void ); + +#endif /* STREAM_BUFFER_INTERRUPT_H */ diff --git a/FreeRTOS/Demo/Common/include/TaskNotify.h b/FreeRTOS/Demo/Common/include/TaskNotify.h index f10a8a7a6..4e53148f4 100644 --- a/FreeRTOS/Demo/Common/include/TaskNotify.h +++ b/FreeRTOS/Demo/Common/include/TaskNotify.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef TASK_NOTIFY_H -#define TASK_NOTIFY_H - -void vStartTaskNotifyTask( void ); -BaseType_t xAreTaskNotificationTasksStillRunning( void ); -void xNotifyTaskFromISR( void ); - -#endif /* TASK_NOTIFY_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef TASK_NOTIFY_H +#define TASK_NOTIFY_H + +void vStartTaskNotifyTask( void ); +BaseType_t xAreTaskNotificationTasksStillRunning( void ); +void xNotifyTaskFromISR( void ); + +#endif /* TASK_NOTIFY_H */ diff --git a/FreeRTOS/Demo/Common/include/TaskNotifyArray.h b/FreeRTOS/Demo/Common/include/TaskNotifyArray.h index 596a7a6f3..d933cffbb 100644 --- a/FreeRTOS/Demo/Common/include/TaskNotifyArray.h +++ b/FreeRTOS/Demo/Common/include/TaskNotifyArray.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Demo/Common/include/TimerDemo.h b/FreeRTOS/Demo/Common/include/TimerDemo.h index 1f2e11143..ba48faca3 100644 --- a/FreeRTOS/Demo/Common/include/TimerDemo.h +++ b/FreeRTOS/Demo/Common/include/TimerDemo.h @@ -1,43 +1,43 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef TIMER_DEMO_H -#define TIMER_DEMO_H - -void vStartTimerDemoTask( TickType_t xBaseFrequencyIn ); -BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency ); -void vTimerPeriodicISRTests( void ); - -/* - * Test the behavior of backlogged timers. The backlog tests should not be - * included while other demos are running concurrently with the timer demo. The - * backlog tests utilize xTaskCatchUpTicks(), which is logically equivalent to - * starving all tasks for some number of ticks. Under these conditions, other - * demos may errantly detect test failures. - */ -void vTimerDemoIncludeBacklogTests( BaseType_t includeBacklogTests ); - -#endif /* TIMER_DEMO_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef TIMER_DEMO_H +#define TIMER_DEMO_H + +void vStartTimerDemoTask( TickType_t xBaseFrequencyIn ); +BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency ); +void vTimerPeriodicISRTests( void ); + +/* + * Test the behavior of backlogged timers. The backlog tests should not be + * included while other demos are running concurrently with the timer demo. The + * backlog tests utilize xTaskCatchUpTicks(), which is logically equivalent to + * starving all tasks for some number of ticks. Under these conditions, other + * demos may errantly detect test failures. + */ +void vTimerDemoIncludeBacklogTests( BaseType_t includeBacklogTests ); + +#endif /* TIMER_DEMO_H */ diff --git a/FreeRTOS/Demo/Common/include/blocktim.h b/FreeRTOS/Demo/Common/include/blocktim.h index c646184cd..9bd17dbbb 100644 --- a/FreeRTOS/Demo/Common/include/blocktim.h +++ b/FreeRTOS/Demo/Common/include/blocktim.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef BLOCK_TIME_TEST_H -#define BLOCK_TIME_TEST_H - -void vCreateBlockTimeTasks( void ); -BaseType_t xAreBlockTimeTestTasksStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef BLOCK_TIME_TEST_H +#define BLOCK_TIME_TEST_H + +void vCreateBlockTimeTasks( void ); +BaseType_t xAreBlockTimeTestTasksStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/comtest.h b/FreeRTOS/Demo/Common/include/comtest.h index f9bdf8571..4b3acdad8 100644 --- a/FreeRTOS/Demo/Common/include/comtest.h +++ b/FreeRTOS/Demo/Common/include/comtest.h @@ -1,39 +1,39 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 /* ifndef COMTEST_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 /* ifndef COMTEST_H */ diff --git a/FreeRTOS/Demo/Common/include/comtest2.h b/FreeRTOS/Demo/Common/include/comtest2.h index 288a45908..c4d0da11c 100644 --- a/FreeRTOS/Demo/Common/include/comtest2.h +++ b/FreeRTOS/Demo/Common/include/comtest2.h @@ -1,35 +1,35 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef COMTEST_H -#define COMTEST_H - -void vAltStartComTestTasks( UBaseType_t uxPriority, - uint32_t ulBaudRate, - UBaseType_t uxLED ); -BaseType_t xAreComTestTasksStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef COMTEST_H +#define COMTEST_H + +void vAltStartComTestTasks( UBaseType_t uxPriority, + uint32_t ulBaudRate, + UBaseType_t uxLED ); +BaseType_t xAreComTestTasksStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/comtest_strings.h b/FreeRTOS/Demo/Common/include/comtest_strings.h index 23a1d67d6..7d381578b 100644 --- a/FreeRTOS/Demo/Common/include/comtest_strings.h +++ b/FreeRTOS/Demo/Common/include/comtest_strings.h @@ -1,35 +1,35 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef COMTEST_STRINGS_H -#define COMTEST_STRINGS_H - -void vStartComTestStringsTasks( UBaseType_t uxPriority, - uint32_t ulBaudRate, - UBaseType_t uxLED ); -BaseType_t xAreComTestTasksStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef COMTEST_STRINGS_H +#define COMTEST_STRINGS_H + +void vStartComTestStringsTasks( UBaseType_t uxPriority, + uint32_t ulBaudRate, + UBaseType_t uxLED ); +BaseType_t xAreComTestTasksStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/countsem.h b/FreeRTOS/Demo/Common/include/countsem.h index 801fc3078..6951ffd37 100644 --- a/FreeRTOS/Demo/Common/include/countsem.h +++ b/FreeRTOS/Demo/Common/include/countsem.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef COUNT_SEMAPHORE_TEST_H -#define COUNT_SEMAPHORE_TEST_H - -void vStartCountingSemaphoreTasks( void ); -BaseType_t xAreCountingSemaphoreTasksStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef COUNT_SEMAPHORE_TEST_H +#define COUNT_SEMAPHORE_TEST_H + +void vStartCountingSemaphoreTasks( void ); +BaseType_t xAreCountingSemaphoreTasksStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/crflash.h b/FreeRTOS/Demo/Common/include/crflash.h index 2b6844eb7..a6c806488 100644 --- a/FreeRTOS/Demo/Common/include/crflash.h +++ b/FreeRTOS/Demo/Common/include/crflash.h @@ -1,45 +1,45 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 diff --git a/FreeRTOS/Demo/Common/include/crhook.h b/FreeRTOS/Demo/Common/include/crhook.h index 3459cdeb8..aaed9715c 100644 --- a/FreeRTOS/Demo/Common/include/crhook.h +++ b/FreeRTOS/Demo/Common/include/crhook.h @@ -1,41 +1,41 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 diff --git a/FreeRTOS/Demo/Common/include/death.h b/FreeRTOS/Demo/Common/include/death.h index 5ac4a1f3c..c4fe1608a 100644 --- a/FreeRTOS/Demo/Common/include/death.h +++ b/FreeRTOS/Demo/Common/include/death.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef SUICIDE_TASK_H -#define SUICIDE_TASK_H - -void vCreateSuicidalTasks( UBaseType_t uxPriority ); -BaseType_t xIsCreateTaskStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef SUICIDE_TASK_H +#define SUICIDE_TASK_H + +void vCreateSuicidalTasks( UBaseType_t uxPriority ); +BaseType_t xIsCreateTaskStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/dynamic.h b/FreeRTOS/Demo/Common/include/dynamic.h index 998bee817..f3a3c1605 100644 --- a/FreeRTOS/Demo/Common/include/dynamic.h +++ b/FreeRTOS/Demo/Common/include/dynamic.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef DYNAMIC_MANIPULATION_H -#define DYNAMIC_MANIPULATION_H - -void vStartDynamicPriorityTasks( void ); -BaseType_t xAreDynamicPriorityTasksStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef DYNAMIC_MANIPULATION_H +#define DYNAMIC_MANIPULATION_H + +void vStartDynamicPriorityTasks( void ); +BaseType_t xAreDynamicPriorityTasksStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/fileIO.h b/FreeRTOS/Demo/Common/include/fileIO.h index c7a93ff05..0039a870c 100644 --- a/FreeRTOS/Demo/Common/include/fileIO.h +++ b/FreeRTOS/Demo/Common/include/fileIO.h @@ -1,35 +1,35 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 diff --git a/FreeRTOS/Demo/Common/include/flash.h b/FreeRTOS/Demo/Common/include/flash.h index 386a3f72a..d30183739 100644 --- a/FreeRTOS/Demo/Common/include/flash.h +++ b/FreeRTOS/Demo/Common/include/flash.h @@ -1,32 +1,32 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef FLASH_LED_H -#define FLASH_LED_H - -void vStartLEDFlashTasks( UBaseType_t uxPriority ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef FLASH_LED_H +#define FLASH_LED_H + +void vStartLEDFlashTasks( UBaseType_t uxPriority ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/flash_timer.h b/FreeRTOS/Demo/Common/include/flash_timer.h index a5e42a8c3..b82e88d27 100644 --- a/FreeRTOS/Demo/Common/include/flash_timer.h +++ b/FreeRTOS/Demo/Common/include/flash_timer.h @@ -1,40 +1,40 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 */ diff --git a/FreeRTOS/Demo/Common/include/flop.h b/FreeRTOS/Demo/Common/include/flop.h index 534b5f5c8..3fb2d8ac1 100644 --- a/FreeRTOS/Demo/Common/include/flop.h +++ b/FreeRTOS/Demo/Common/include/flop.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef FLOP_TASKS_H -#define FLOP_TASKS_H - -void vStartMathTasks( UBaseType_t uxPriority ); -BaseType_t xAreMathsTaskStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef FLOP_TASKS_H +#define FLOP_TASKS_H + +void vStartMathTasks( UBaseType_t uxPriority ); +BaseType_t xAreMathsTaskStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/integer.h b/FreeRTOS/Demo/Common/include/integer.h index c9deffbbc..ff7dd17ff 100644 --- a/FreeRTOS/Demo/Common/include/integer.h +++ b/FreeRTOS/Demo/Common/include/integer.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef INTEGER_TASKS_H -#define INTEGER_TASKS_H - -void vStartIntegerMathTasks( UBaseType_t uxPriority ); -BaseType_t xAreIntegerMathsTaskStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef INTEGER_TASKS_H +#define INTEGER_TASKS_H + +void vStartIntegerMathTasks( UBaseType_t uxPriority ); +BaseType_t xAreIntegerMathsTaskStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/mevents.h b/FreeRTOS/Demo/Common/include/mevents.h index e1e890db4..7a4db7cb8 100644 --- a/FreeRTOS/Demo/Common/include/mevents.h +++ b/FreeRTOS/Demo/Common/include/mevents.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef EVENTS_TEST_H -#define EVENTS_TEST_H - -void vStartMultiEventTasks( void ); -BaseType_t xAreMultiEventTasksStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef EVENTS_TEST_H +#define EVENTS_TEST_H + +void vStartMultiEventTasks( void ); +BaseType_t xAreMultiEventTasksStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/partest.h b/FreeRTOS/Demo/Common/include/partest.h index 4811ae4e4..920f05835 100644 --- a/FreeRTOS/Demo/Common/include/partest.h +++ b/FreeRTOS/Demo/Common/include/partest.h @@ -1,37 +1,37 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 diff --git a/FreeRTOS/Demo/Common/include/print.h b/FreeRTOS/Demo/Common/include/print.h index ce8890aff..57d6182c6 100644 --- a/FreeRTOS/Demo/Common/include/print.h +++ b/FreeRTOS/Demo/Common/include/print.h @@ -1,34 +1,34 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef PRINT_H -#define PRINT_H - -void vPrintInitialise( void ); -void vPrintDisplayMessage( const char * const * pcMessageToSend ); -const char * pcPrintGetNextMessage( TickType_t xPrintRate ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PRINT_H +#define PRINT_H + +void vPrintInitialise( void ); +void vPrintDisplayMessage( const char * const * pcMessageToSend ); +const char * pcPrintGetNextMessage( TickType_t xPrintRate ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/recmutex.h b/FreeRTOS/Demo/Common/include/recmutex.h index 4ecbe75c4..61c202400 100644 --- a/FreeRTOS/Demo/Common/include/recmutex.h +++ b/FreeRTOS/Demo/Common/include/recmutex.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef RECURSIVE_MUTEX_TEST_H -#define RECURSIVE_MUTEX_TEST_H - -void vStartRecursiveMutexTasks( void ); -BaseType_t xAreRecursiveMutexTasksStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef RECURSIVE_MUTEX_TEST_H +#define RECURSIVE_MUTEX_TEST_H + +void vStartRecursiveMutexTasks( void ); +BaseType_t xAreRecursiveMutexTasksStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/semtest.h b/FreeRTOS/Demo/Common/include/semtest.h index 11cbfdaf1..74f447ce9 100644 --- a/FreeRTOS/Demo/Common/include/semtest.h +++ b/FreeRTOS/Demo/Common/include/semtest.h @@ -1,33 +1,33 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef SEMAPHORE_TEST_H -#define SEMAPHORE_TEST_H - -void vStartSemaphoreTasks( UBaseType_t uxPriority ); -BaseType_t xAreSemaphoreTasksStillRunning( void ); - -#endif +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef SEMAPHORE_TEST_H +#define SEMAPHORE_TEST_H + +void vStartSemaphoreTasks( UBaseType_t uxPriority ); +BaseType_t xAreSemaphoreTasksStillRunning( void ); + +#endif diff --git a/FreeRTOS/Demo/Common/include/serial.h b/FreeRTOS/Demo/Common/include/serial.h index 384f4429e..add579096 100644 --- a/FreeRTOS/Demo/Common/include/serial.h +++ b/FreeRTOS/Demo/Common/include/serial.h @@ -1,108 +1,108 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#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 /* ifndef SERIAL_COMMS_H */ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#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 /* ifndef SERIAL_COMMS_H */ diff --git a/FreeRTOS/License/license.txt b/FreeRTOS/License/license.txt index 4b899b24a..ab8628cbf 100644 --- a/FreeRTOS/License/license.txt +++ b/FreeRTOS/License/license.txt @@ -1,37 +1,37 @@ -The FreeRTOS kernel is released under the MIT open source license, the text of -which is provided below. - -This license covers the FreeRTOS kernel source files, which are located in the -/FreeRTOS/Source directory of the official FreeRTOS kernel 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. - - -License text: -------------- - -Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - +The FreeRTOS kernel is released under the MIT open source license, the text of +which is provided below. + +This license covers the FreeRTOS kernel source files, which are located in the +/FreeRTOS/Source directory of the official FreeRTOS kernel 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. + + +License text: +------------- + +Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/FreeRTOS/Test/CBMC/README.md b/FreeRTOS/Test/CBMC/README.md index 00baa4423..8c0576f48 100644 --- a/FreeRTOS/Test/CBMC/README.md +++ b/FreeRTOS/Test/CBMC/README.md @@ -84,6 +84,6 @@ This directory contains the following subdirectories: - `proofs` contains the proofs run against each pull request - `patches` contains a set of patches that get applied to the codebase prior to - running the proofs. The patches are used to remove static and volatile qulaifiers + running the proofs. The patches are used to remove static and volatile qualifiers from the source. - `include` and `windows` contain header files used by the proofs. diff --git a/FreeRTOS/Test/CBMC/include/aws_freertos_ip_verification_access_ip_define.h b/FreeRTOS/Test/CBMC/include/aws_freertos_ip_verification_access_ip_define.h index f238af08d..884562157 100644 --- a/FreeRTOS/Test/CBMC/include/aws_freertos_ip_verification_access_ip_define.h +++ b/FreeRTOS/Test/CBMC/include/aws_freertos_ip_verification_access_ip_define.h @@ -1,3 +1,29 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + eFrameProcessingResult_t publicProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer ) { diff --git a/FreeRTOS/Test/CBMC/include/aws_freertos_tcp_verification_access_tcp_define.h b/FreeRTOS/Test/CBMC/include/aws_freertos_tcp_verification_access_tcp_define.h index 5d95619cb..e0f9c7805 100644 --- a/FreeRTOS/Test/CBMC/include/aws_freertos_tcp_verification_access_tcp_define.h +++ b/FreeRTOS/Test/CBMC/include/aws_freertos_tcp_verification_access_tcp_define.h @@ -1,3 +1,29 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + int32_t publicTCPPrepareSend( FreeRTOS_Socket_t * pxSocket, NetworkBufferDescriptor_t ** ppxNetworkBuffer, UBaseType_t uxOptionsLength ) diff --git a/FreeRTOS/Test/CBMC/include/cbmc.h b/FreeRTOS/Test/CBMC/include/cbmc.h index 9c43cc502..1d898296a 100644 --- a/FreeRTOS/Test/CBMC/include/cbmc.h +++ b/FreeRTOS/Test/CBMC/include/cbmc.h @@ -1,3 +1,29 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + /* Standard includes. */ #include #include diff --git a/FreeRTOS/Test/CBMC/include/portmacro.h b/FreeRTOS/Test/CBMC/include/portmacro.h index 7d51260f4..329e1c392 100644 --- a/FreeRTOS/Test/CBMC/include/portmacro.h +++ b/FreeRTOS/Test/CBMC/include/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CBMC/include/queue_init.h b/FreeRTOS/Test/CBMC/include/queue_init.h index 0093c2117..04ae9518f 100644 --- a/FreeRTOS/Test/CBMC/include/queue_init.h +++ b/FreeRTOS/Test/CBMC/include/queue_init.h @@ -1,3 +1,29 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + #include "FreeRTOS.h" #include "queue.h" #include "queue_datastructure.h" diff --git a/FreeRTOS/Test/CBMC/include/tasksStubs.h b/FreeRTOS/Test/CBMC/include/tasksStubs.h index e50a5cad1..07ad57fdb 100644 --- a/FreeRTOS/Test/CBMC/include/tasksStubs.h +++ b/FreeRTOS/Test/CBMC/include/tasksStubs.h @@ -1,3 +1,29 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + #ifndef INC_TASK_STUBS_H #define INC_TASK_STUBS_H diff --git a/FreeRTOS/Test/CBMC/patches/FreeRTOSConfig.h b/FreeRTOS/Test/CBMC/patches/FreeRTOSConfig.h index d74971765..94abb3015 100644 --- a/FreeRTOS/Test/CBMC/patches/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CBMC/patches/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CBMC/patches/FreeRTOSIPConfig.h b/FreeRTOS/Test/CBMC/patches/FreeRTOSIPConfig.h index 0a1f2a8ac..9ad479b69 100644 --- a/FreeRTOS/Test/CBMC/patches/FreeRTOSIPConfig.h +++ b/FreeRTOS/Test/CBMC/patches/FreeRTOSIPConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -19,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ diff --git a/FreeRTOS/Test/CBMC/patches/compute_patch.py b/FreeRTOS/Test/CBMC/patches/compute_patch.py index 3e854177c..fb7c292f9 100755 --- a/FreeRTOS/Test/CBMC/patches/compute_patch.py +++ b/FreeRTOS/Test/CBMC/patches/compute_patch.py @@ -2,7 +2,7 @@ # # Generation of patches for CBMC proofs. # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/patches/patches_constants.py b/FreeRTOS/Test/CBMC/patches/patches_constants.py index 71f0b0537..2fd3ebab0 100755 --- a/FreeRTOS/Test/CBMC/patches/patches_constants.py +++ b/FreeRTOS/Test/CBMC/patches/patches_constants.py @@ -2,7 +2,7 @@ # # Constants for the generation of patches for CBMC proofs. # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/patches/unpatch.py b/FreeRTOS/Test/CBMC/patches/unpatch.py index 2162971fd..417388c5a 100755 --- a/FreeRTOS/Test/CBMC/patches/unpatch.py +++ b/FreeRTOS/Test/CBMC/patches/unpatch.py @@ -2,7 +2,7 @@ # # unpatching changes for the CBMC proofs. # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.c b/FreeRTOS/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.c index a9064ee40..03546af1c 100644 --- a/FreeRTOS/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.c +++ b/FreeRTOS/Test/CBMC/proofs/CBMCStubLibrary/tasksStubs.c @@ -1,3 +1,29 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + #include "FreeRTOS.h" #include "task.h" #include "tasksStubs.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/Makefile.json index eec7cba78..3f9aa8813 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/QueueCreateCountingSemaphore_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/QueueCreateCountingSemaphore_harness.c index 76394de48..44ef7f526 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/QueueCreateCountingSemaphore_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphore/QueueCreateCountingSemaphore_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/Makefile.json index 10fa56596..7fe2c4f20 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/QueueCreateCountingSemaphoreStatic_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/QueueCreateCountingSemaphoreStatic_harness.c index 38e05a315..872d07879 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/QueueCreateCountingSemaphoreStatic_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/QueueCreateCountingSemaphoreStatic_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/README.md index c6103de51..93e70465f 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/README.md +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateCountingSemaphoreStatic/README.md @@ -1,6 +1,6 @@ Assuming uxMaxCount > 0, uxInitialCount <= uxMaxCount and the reference to the storage area is not null, -this harness proves the memory saftey of QueueCreateCountingSemphoreStatic. +this harness proves the memory safety of QueueCreateCountingSemaphoreStatic. This proof is a work-in-progress. Proof assumptions are described in the harness. The proof also assumes the following functions are diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/Makefile.json index 51f3be625..d5f627eed 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/QueueCreateMutex_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/QueueCreateMutex_harness.c index 9034b31e1..ef4f27857 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/QueueCreateMutex_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutex/QueueCreateMutex_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/Makefile.json index 3af3c5652..59bfe7889 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/QueueCreateMutexStatic_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/QueueCreateMutexStatic_harness.c index 0c0558742..c52d6ba83 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/QueueCreateMutexStatic_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueCreateMutexStatic/QueueCreateMutexStatic_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/Configurations.json index f404c8f53..d39962763 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/QueueGenericCreate_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/QueueGenericCreate_harness.c index 1b7cb0169..d3565dfa9 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/QueueGenericCreate_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreate/QueueGenericCreate_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/Configurations.json index 0e02630bd..20021bcee 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/QueueGenericCreateStatic_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/QueueGenericCreateStatic_harness.c index 20346d86c..b52205455 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/QueueGenericCreateStatic_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericCreateStatic/QueueGenericCreateStatic_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/Makefile.json index d523842a2..19c142a3d 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/QueueGenericReset_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/QueueGenericReset_harness.c index 3e1f0f34d..61d6b97ad 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/QueueGenericReset_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericReset/QueueGenericReset_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/Configurations.json index e4435b1c1..b289fcc9a 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/QueueGenericSend_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/QueueGenericSend_harness.c index 4659b09ab..5c9493106 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/QueueGenericSend_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend/QueueGenericSend_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" @@ -120,7 +118,7 @@ void harness() if( xQueue->uxItemSize == 0 ) { /* uxQueue->xQueueType is a pointer to the head of the queue storage area. - * If an item has a sice, this pointer must not be modified after init. + * If an item has a size, this pointer must not be modified after init. * Otherwise some of the write statements will fail. */ xQueue->uxQueueType = nondet_int8_t(); pvItemToQueue = 0; diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/Configurations.json index ab240fc9a..e5fbbc18b 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/QueueGenericSendFromISR_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/QueueGenericSendFromISR_harness.c index 99dba9c1a..a91007a26 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/QueueGenericSendFromISR_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSendFromISR/QueueGenericSendFromISR_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/Makefile.json index 73f8bdedd..5ebdf2ab1 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/QueueGetMutexHolder_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/QueueGetMutexHolder_harness.c index 6ffb4cb37..896aa00a7 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/QueueGetMutexHolder_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolder/QueueGetMutexHolder_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/Makefile.json index 6005db359..46a601a90 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/QueueGetMutexHolderFromISR_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/QueueGetMutexHolderFromISR_harness.c index ca72a46e9..19ebd93ed 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/QueueGetMutexHolderFromISR_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGetMutexHolderFromISR/QueueGetMutexHolderFromISR_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/Configurations.json index 74e6418d4..416fe7010 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/QueueGiveFromISR_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/QueueGiveFromISR_harness.c index c7293a41a..70c503988 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/QueueGiveFromISR_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveFromISR/QueueGiveFromISR_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/Makefile.json index bccd5db02..f361a93e9 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/QueueGiveMutexRecursive_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/QueueGiveMutexRecursive_harness.c index 8b88fca96..7033adbc4 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/QueueGiveMutexRecursive_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueGiveMutexRecursive/QueueGiveMutexRecursive_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/Makefile.json index 8e7bac96f..5ad0f70b6 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/QueueMessagesWaiting_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/QueueMessagesWaiting_harness.c index c5891c1d4..cc4311f02 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/QueueMessagesWaiting_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/QueueMessagesWaiting_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/README.md index 811b5abb5..a36f6cce7 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/README.md +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueMessagesWaiting/README.md @@ -1,6 +1,6 @@ Assuming the parameter passed to QueueMessagesWaiting is a pointer to a Queue_t struct, this harness proves the memory safety of QueueMessagesWaiting. -The concurrency related functions vPortEnterCrititcal and vPortExitCritical +The concurrency related functions vPortEnterCritical and vPortExitCritical are abstracted away. This proof is a work-in-progress. Proof assumptions are described in diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/Makefile.json index c85000cb4..2d6254fdf 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/QueuePeek_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/QueuePeek_harness.c index b10a68c07..293be5160 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/QueuePeek_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueuePeek/QueuePeek_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/Makefile.json index d5e70dd6a..451bcda3c 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/QueueReceive_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/QueueReceive_harness.c index e08f755f9..6f1b73e5b 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/QueueReceive_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceive/QueueReceive_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/Makefile.json index ce5cd520a..c159d7ded 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/QueueReceiveFromISR_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/QueueReceiveFromISR_harness.c index 0f06b5092..baef388ea 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/QueueReceiveFromISR_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueReceiveFromISR/QueueReceiveFromISR_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/Makefile.json index 8d164e006..a3429d6da 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/QueueSemaphoreTake_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/QueueSemaphoreTake_harness.c index 2ccc4f9d0..195b54b3f 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/QueueSemaphoreTake_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSemaphoreTake/QueueSemaphoreTake_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/Makefile.json index b8c3d6e49..e7d87b10f 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/QueueSpacesAvailable_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/QueueSpacesAvailable_harness.c index 79cdafa1b..a61bd5d2c 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/QueueSpacesAvailable_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueSpacesAvailable/QueueSpacesAvailable_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/Makefile.json index 6749aa463..9a7638663 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/QueueTakeMutexRecursive_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/QueueTakeMutexRecursive_harness.c index 6cecbb8c6..dab275681 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/QueueTakeMutexRecursive_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/QueueTakeMutexRecursive/QueueTakeMutexRecursive_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/Configurations.json index a5ea43579..7c9c9a641 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/README.md index ee6bc03e0..ccd635579 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/README.md +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/README.md @@ -1,4 +1,4 @@ -This harness proves the memory safety of the prvNotifyQueuSetContainer method. +This harness proves the memory safety of the prvNotifyQueueSetContainer method. It assumes that the queue is initalized to a valid datastructure. The concurrency functions are abstracted away. diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/prvCopyDataToQueue_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/prvCopyDataToQueue_harness.c index 12ba181fe..6716309b9 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/prvCopyDataToQueue_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvCopyDataToQueue/prvCopyDataToQueue_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/Configurations.json index c3170fae0..b3d1c1386 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/README.md b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/README.md index 6dddc4172..067a2dc54 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/README.md +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/README.md @@ -1,8 +1,8 @@ -This harness proves the memory safety of the prvNotifyQueuSetContainer method. +This harness proves the memory safety of the prvNotifyQueueSetContainer method. It assumes that the queue is initalized to a valid datastructure and added to a QueueSet. The concurrency functions and task pool functions are abstracted away. prvCopyDataToQueue is replaced with a stub checking the preconditions -for prvCopyDataToQueue to be sucessful. +for prvCopyDataToQueue to be successful. This proof is a work-in-progress. Proof assumptions are described in the harness. The proof also assumes the following functions are diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/prvNotifyQueueSetContainer_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/prvNotifyQueueSetContainer_harness.c index 99f0e9f1c..b81b02884 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/prvNotifyQueueSetContainer_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvNotifyQueueSetContainer/prvNotifyQueueSetContainer_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/Configurations.json index 3f8549bf7..2ff017551 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/prvUnlockQueue_harness.c b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/prvUnlockQueue_harness.c index e3b2e2c75..76b9d7893 100644 --- a/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/prvUnlockQueue_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Queue/prvUnlockQueue/prvUnlockQueue_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "FreeRTOS.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/Makefile.json index 8b2904e30..651b021b4 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/TaskCheckForTimeOut_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/TaskCheckForTimeOut_harness.c index 30a3f1f23..351824a18 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/TaskCheckForTimeOut_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/TaskCheckForTimeOut_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/tasks_test_access_functions.h index e85250ce4..541e7d28a 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCheckForTimeOut/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "cbmc.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/Makefile.json index 71aac7719..4cf7f1221 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/TaskCreate_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/TaskCreate_harness.c index 6bd33a0e8..9e3e611bb 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/TaskCreate_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/TaskCreate_harness.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/tasks_test_access_functions.h index 2c5383c69..04acb6690 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskCreate/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "cbmc.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/Configurations.json index 5061e8e8a..484ec8f78 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/TaskDelay_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/TaskDelay_harness.c index 9bae6016e..33f4e4d47 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/TaskDelay_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/TaskDelay_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/tasks_test_access_functions.h index 4ad3479da..9b87333c2 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelay/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "cbmc.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/Makefile.json index bce77b851..6337398b3 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/TaskDelete_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/TaskDelete_harness.c index 22fcc447b..a6e74f07e 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/TaskDelete_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/TaskDelete_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/tasks_test_access_functions.h index f8cbc5f04..3918a1711 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskDelete/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "cbmc.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/Makefile.json index d461b1dd3..3c898e34f 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/TaskGetCurrentTaskHandle_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/TaskGetCurrentTaskHandle_harness.c index efdae8036..3f0af2054 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/TaskGetCurrentTaskHandle_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/TaskGetCurrentTaskHandle_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/tasks_test_access_functions.h index 96c2c0b44..731315266 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetCurrentTaskHandle/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "cbmc.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/Makefile.json index 633e659cd..21eb7a111 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/TaskGetSchedulerState_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/TaskGetSchedulerState_harness.c index 4a35b8a59..9929d550d 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/TaskGetSchedulerState_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/TaskGetSchedulerState_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/tasks_test_access_functions.h index c0d01e2c2..06933dbf5 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetSchedulerState/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /* diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/Makefile.json index 909ada3de..28382bcc1 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/TaskGetTaskNumber_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/TaskGetTaskNumber_harness.c index 484a01013..682cb3330 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/TaskGetTaskNumber_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/TaskGetTaskNumber_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/tasks_test_access_functions.h index b7a6ee5d1..9340a28a9 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTaskNumber/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "cbmc.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/Makefile.json index e9da10fef..3185fb460 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/TaskGetTickCount_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/TaskGetTickCount_harness.c index 1a5e44bcf..cc3e9feb7 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/TaskGetTickCount_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskGetTickCount/TaskGetTickCount_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/Configurations.json index 92df31095..0557d8857 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/TaskIncrementTick_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/TaskIncrementTick_harness.c index f66faf5ca..a61f3acff 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/TaskIncrementTick_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/TaskIncrementTick_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/tasks_test_access_functions.h index b1cf88e56..13d2373f0 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskIncrementTick/tasks_test_access_functions.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/Makefile.json index 9502f830f..8f174ebc2 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/TaskPrioritySet_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/TaskPrioritySet_harness.c index 4f3cc99d7..abb6bd55d 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/TaskPrioritySet_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/TaskPrioritySet_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/tasks_test_access_functions.h index 528992335..8745f71a2 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskPrioritySet/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "cbmc.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/Configurations.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/Configurations.json index e2ea2dcc5..07f1cd5db 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/Configurations.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/Configurations.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/TaskResumeAll_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/TaskResumeAll_harness.c index 25d2d8a86..fe5ec26b4 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/TaskResumeAll_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/TaskResumeAll_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/tasks_test_access_functions.h index 8124d71b0..81cbbc9b9 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskResumeAll/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "cbmc.h" diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/Makefile.json index 86e5e4b02..05222dbdf 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/TaskSetTimeOutState_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/TaskSetTimeOutState_harness.c index 469c3a4e5..5775c1124 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/TaskSetTimeOutState_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSetTimeOutState/TaskSetTimeOutState_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/Makefile.json index e2b8610ef..612b9069c 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/TaskStartScheduler_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/TaskStartScheduler_harness.c index 11e668210..655920e31 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/TaskStartScheduler_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/TaskStartScheduler_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/tasks_test_access_functions.h index 941b2a245..63635ba77 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskStartScheduler/tasks_test_access_functions.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/Makefile.json index e9403c769..e05646a5e 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/TaskSuspendAll_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/TaskSuspendAll_harness.c index 846f3af72..ccad6fad4 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/TaskSuspendAll_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSuspendAll/TaskSuspendAll_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/Makefile.json b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/Makefile.json index a17a721ca..314057456 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/Makefile.json +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/Makefile.json @@ -1,6 +1,6 @@ # # FreeRTOS memory safety proofs with CBMC. -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/TaskSwitchContext_harness.c b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/TaskSwitchContext_harness.c index ff5b181d4..9a5007459 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/TaskSwitchContext_harness.c +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/TaskSwitchContext_harness.c @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include diff --git a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/tasks_test_access_functions.h b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/tasks_test_access_functions.h index 9770fb4d4..98798093a 100644 --- a/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/tasks_test_access_functions.h +++ b/FreeRTOS/Test/CBMC/proofs/Task/TaskSwitchContext/tasks_test_access_functions.h @@ -1,29 +1,27 @@ /* - * FreeRTOS memory safety proofs with CBMC. - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * https://aws.amazon.com/freertos * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ #include "cbmc.h" diff --git a/FreeRTOS/Test/CBMC/proofs/make_cbmc_batch_files.py b/FreeRTOS/Test/CBMC/proofs/make_cbmc_batch_files.py index 622e000c3..fa44afaba 100755 --- a/FreeRTOS/Test/CBMC/proofs/make_cbmc_batch_files.py +++ b/FreeRTOS/Test/CBMC/proofs/make_cbmc_batch_files.py @@ -2,7 +2,7 @@ # # Generation of the cbmc-batch.yaml files for the CBMC proofs. # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/proofs/make_common_makefile.py b/FreeRTOS/Test/CBMC/proofs/make_common_makefile.py index 843420efd..f39088537 100755 --- a/FreeRTOS/Test/CBMC/proofs/make_common_makefile.py +++ b/FreeRTOS/Test/CBMC/proofs/make_common_makefile.py @@ -2,7 +2,7 @@ # # Generation of common Makefile for CBMC proofs. # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/proofs/make_configuration_directories.py b/FreeRTOS/Test/CBMC/proofs/make_configuration_directories.py index 8ac0ed316..40a59e255 100755 --- a/FreeRTOS/Test/CBMC/proofs/make_configuration_directories.py +++ b/FreeRTOS/Test/CBMC/proofs/make_configuration_directories.py @@ -2,7 +2,7 @@ # # Creating the CBMC proofs from Configurations.json. # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/proofs/make_proof_makefiles.py b/FreeRTOS/Test/CBMC/proofs/make_proof_makefiles.py index 846942ee4..749852b19 100755 --- a/FreeRTOS/Test/CBMC/proofs/make_proof_makefiles.py +++ b/FreeRTOS/Test/CBMC/proofs/make_proof_makefiles.py @@ -2,7 +2,7 @@ # # Generation of Makefiles for CBMC proofs. # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/proofs/make_remove_makefiles.py b/FreeRTOS/Test/CBMC/proofs/make_remove_makefiles.py index 12d0c72f1..d772ffec4 100755 --- a/FreeRTOS/Test/CBMC/proofs/make_remove_makefiles.py +++ b/FreeRTOS/Test/CBMC/proofs/make_remove_makefiles.py @@ -2,7 +2,7 @@ # # Removing the generated Makefiles and cbmc-batch.yaml files. # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/proofs/make_type_header_files.py b/FreeRTOS/Test/CBMC/proofs/make_type_header_files.py index a8ac66384..56d920d09 100755 --- a/FreeRTOS/Test/CBMC/proofs/make_type_header_files.py +++ b/FreeRTOS/Test/CBMC/proofs/make_type_header_files.py @@ -2,7 +2,7 @@ # # Compute type header files for c modules # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/proofs/prepare.py b/FreeRTOS/Test/CBMC/proofs/prepare.py index 99b494c3c..ec4030a98 100755 --- a/FreeRTOS/Test/CBMC/proofs/prepare.py +++ b/FreeRTOS/Test/CBMC/proofs/prepare.py @@ -2,7 +2,7 @@ # # Python script for preparing the code base for the CBMC proofs. # -# Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CBMC/proofs/utility/memory_assignments.c b/FreeRTOS/Test/CBMC/proofs/utility/memory_assignments.c index ed2ec5bbb..86e14a0e4 100644 --- a/FreeRTOS/Test/CBMC/proofs/utility/memory_assignments.c +++ b/FreeRTOS/Test/CBMC/proofs/utility/memory_assignments.c @@ -1,3 +1,29 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + #define ensure_memory_is_valid( px, length ) ( px != NULL ) && __CPROVER_w_ok( ( px ), length ) /* Implementation of safe malloc which returns NULL if the requested size is 0. diff --git a/FreeRTOS/Test/CMock/config/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/config/FreeRTOSConfig.h index 1c5f4c2ff..ba83eb84e 100644 --- a/FreeRTOS/Test/CMock/config/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/config/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/config/fake_assert.h b/FreeRTOS/Test/CMock/config/fake_assert.h index 17eef442b..ecd778fc4 100644 --- a/FreeRTOS/Test/CMock/config/fake_assert.h +++ b/FreeRTOS/Test/CMock/config/fake_assert.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/config/fake_port.h b/FreeRTOS/Test/CMock/config/fake_port.h index 2c427136b..23fe5653b 100644 --- a/FreeRTOS/Test/CMock/config/fake_port.h +++ b/FreeRTOS/Test/CMock/config/fake_port.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/config/portmacro.h b/FreeRTOS/Test/CMock/config/portmacro.h index a348f4b57..bf028ab48 100644 --- a/FreeRTOS/Test/CMock/config/portmacro.h +++ b/FreeRTOS/Test/CMock/config/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/event_groups/Makefile b/FreeRTOS/Test/CMock/event_groups/Makefile index 825428e4c..11ff0ffe3 100644 --- a/FreeRTOS/Test/CMock/event_groups/Makefile +++ b/FreeRTOS/Test/CMock/event_groups/Makefile @@ -31,12 +31,12 @@ MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h MOCK_FILES_FP += $(PROJECT_DIR)/list_macros.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 CPPFLAGS += -include list_macros.h CFLAGS += -include list_macros.h -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += -Wno-incompatible-pointer-types # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/event_groups/event_groups_utest.c b/FreeRTOS/Test/CMock/event_groups/event_groups_utest.c index fdadd4699..008d25b7d 100644 --- a/FreeRTOS/Test/CMock/event_groups/event_groups_utest.c +++ b/FreeRTOS/Test/CMock/event_groups/event_groups_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/event_groups/list_macros.h b/FreeRTOS/Test/CMock/event_groups/list_macros.h index 7e524e565..675a8e5fd 100644 --- a/FreeRTOS/Test/CMock/event_groups/list_macros.h +++ b/FreeRTOS/Test/CMock/event_groups/list_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/list/Makefile b/FreeRTOS/Test/CMock/list/Makefile index 7e865624e..7752c8d71 100644 --- a/FreeRTOS/Test/CMock/list/Makefile +++ b/FreeRTOS/Test/CMock/list/Makefile @@ -25,10 +25,10 @@ SUITE_SUPPORT_SRC := # List the headers used by PROJECT_SRC that you would like to mock MOCK_FILES_FP := -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += -Wno-unused-function # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/list/list_utest.c b/FreeRTOS/Test/CMock/list/list_utest.c index fb42a6b2f..76ce14b1a 100644 --- a/FreeRTOS/Test/CMock/list/list_utest.c +++ b/FreeRTOS/Test/CMock/list/list_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -887,7 +887,7 @@ void test_macro_listGET_OWNER_OF_HEAD_ENTRY( void ) /*! * @brief test macro listIS_CONTAINED_WITHIN normal case * @details This test ensures that the macro is returning whether the list item - * is contained witin the list + * is contained within the list */ void test_macro_listIS_CONTAINED_WITHIN( void ) { diff --git a/FreeRTOS/Test/CMock/message_buffer/message_buffer/Makefile b/FreeRTOS/Test/CMock/message_buffer/message_buffer/Makefile index 44f03aa94..2bf80cde9 100644 --- a/FreeRTOS/Test/CMock/message_buffer/message_buffer/Makefile +++ b/FreeRTOS/Test/CMock/message_buffer/message_buffer/Makefile @@ -27,10 +27,10 @@ MOCK_FILES_FP += $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/message_buffer/message_buffer/message_buffer_utest.c b/FreeRTOS/Test/CMock/message_buffer/message_buffer/message_buffer_utest.c index 1b7166dc8..9af967d10 100644 --- a/FreeRTOS/Test/CMock/message_buffer/message_buffer/message_buffer_utest.c +++ b/FreeRTOS/Test/CMock/message_buffer/message_buffer/message_buffer_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/message_buffer/size_mismatch/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/message_buffer/size_mismatch/FreeRTOSConfig.h index dce6d86ff..b643b6726 100644 --- a/FreeRTOS/Test/CMock/message_buffer/size_mismatch/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/message_buffer/size_mismatch/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/message_buffer/size_mismatch/Makefile b/FreeRTOS/Test/CMock/message_buffer/size_mismatch/Makefile index 289f8f975..b3e271fdb 100644 --- a/FreeRTOS/Test/CMock/message_buffer/size_mismatch/Makefile +++ b/FreeRTOS/Test/CMock/message_buffer/size_mismatch/Makefile @@ -27,10 +27,10 @@ MOCK_FILES_FP += $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -I . -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/message_buffer/size_mismatch/message_buffer_utest.c b/FreeRTOS/Test/CMock/message_buffer/size_mismatch/message_buffer_utest.c index 06b5b5936..77c8e1a61 100644 --- a/FreeRTOS/Test/CMock/message_buffer/size_mismatch/message_buffer_utest.c +++ b/FreeRTOS/Test/CMock/message_buffer/size_mismatch/message_buffer_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/dynamic/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/queue/dynamic/FreeRTOSConfig.h index 2a46fe083..e65996515 100644 --- a/FreeRTOS/Test/CMock/queue/dynamic/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/queue/dynamic/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/dynamic/Makefile b/FreeRTOS/Test/CMock/queue/dynamic/Makefile index 2199e5374..ce497588a 100644 --- a/FreeRTOS/Test/CMock/queue/dynamic/Makefile +++ b/FreeRTOS/Test/CMock/queue/dynamic/Makefile @@ -30,10 +30,10 @@ MOCK_FILES_FP += $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/queue/generic/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/queue/generic/FreeRTOSConfig.h index defe87b41..140156a2e 100644 --- a/FreeRTOS/Test/CMock/queue/generic/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/queue/generic/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/generic/Makefile b/FreeRTOS/Test/CMock/queue/generic/Makefile index 91d3b8b61..604ca9e5e 100644 --- a/FreeRTOS/Test/CMock/queue/generic/Makefile +++ b/FreeRTOS/Test/CMock/queue/generic/Makefile @@ -39,10 +39,10 @@ MOCK_FILES_FP += $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-exceptions # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_create_dynamic_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_create_dynamic_utest.c index c6af5d9b9..5b0d3d5cc 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_create_dynamic_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_create_dynamic_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -163,7 +163,7 @@ void test_macro_xQueueCreate_oneItem_zeroLength( void ) /* Verify that new queue is empty */ TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) ); - /* Valdiate that the queue has 1 space remaining */ + /* Validate that the queue has 1 space remaining */ TEST_ASSERT_EQUAL( 1, uxQueueSpacesAvailable( xQueue ) ); vQueueDelete( xQueue ); @@ -314,7 +314,7 @@ void test_macro_xQueueCreate_multiplication_overflow( void ) * ( xQueueSizeInBytes + sizeof(StaticQueue_t) ) > MAX(size_t) * @coverage xQueueGenericCreate */ -void test_macro_xQueueCreate_addiiton_overflow( void ) +void test_macro_xQueueCreate_addition_overflow( void ) { /* Based on the formula: * ( 2^x - 1 ) == ( 2^( x/2 ) + 1 ) * ( 2^( x/2 ) - 1 ) */ diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_create_static_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_create_static_utest.c index 3011194af..478e79eb7 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_create_static_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_create_static_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -147,7 +147,7 @@ void test_macro_xQueueCreateStatic_nullQueueStorage_oneItem_zeroLength( void ) /* Verify that new queue is empty */ TEST_ASSERT_EQUAL( 0, uxQueueMessagesWaiting( xQueue ) ); - /* Valdiate that the queue has 1 space remaining */ + /* Validate that the queue has 1 space remaining */ TEST_ASSERT_EQUAL( 1, uxQueueSpacesAvailable( xQueue ) ); /* Send a test value */ diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_delete_dynamic_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_delete_dynamic_utest.c index 5838f670c..8cbed72ff 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_delete_dynamic_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_delete_dynamic_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_delete_static_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_delete_static_utest.c index 0c8fca534..07dbad2b9 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_delete_static_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_delete_static_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -92,7 +92,7 @@ void test_vQueueDelete_empty( void ) TEST_ASSERT_EQUAL( 0, getLastMallocSize() ); vQueueDelete( xQueue ); - /* Veirfy that free was not called */ + /* Verify that free was not called */ TEST_ASSERT_EQUAL_PTR( NULL, getLastFreedAddress() ); free( queueBuffer ); free( queueData ); @@ -118,7 +118,7 @@ void test_vQueueDelete_half_full( void ) vQueueDelete( xQueue ); - /* Veirfy that free was not called */ + /* Verify that free was not called */ TEST_ASSERT_EQUAL_PTR( NULL, getLastFreedAddress() ); free( queueBuffer ); free( queueData ); @@ -144,7 +144,7 @@ void test_vQueueDelete_full( void ) vQueueDelete( xQueue ); - /* Veirfy that free was not called */ + /* Verify that free was not called */ TEST_ASSERT_EQUAL_PTR( NULL, getLastFreedAddress() ); free( queueBuffer ); free( queueData ); diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_get_static_buffers_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_get_static_buffers_utest.c index 52c40b8e0..b9ca2477d 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_get_static_buffers_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_get_static_buffers_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_receive_blocking_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_receive_blocking_utest.c index b566553cf..bd4c9719f 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_receive_blocking_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_receive_blocking_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_receive_nonblocking_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_receive_nonblocking_utest.c index 2c8147142..39982c6c2 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_receive_nonblocking_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_receive_nonblocking_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_reset_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_reset_utest.c index 43a622151..30a3f0e5c 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_reset_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_reset_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_send_blocking_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_send_blocking_utest.c index 6ae4ab7e3..422a16ac8 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_send_blocking_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_send_blocking_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_send_nonblocking_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_send_nonblocking_utest.c index 368202288..e52002ed4 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_send_nonblocking_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_send_nonblocking_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -136,7 +136,7 @@ void test_macro_xQueueSend_fail_full( void ) /** * @brief Test xQueueSend with uxQueueLength=1, uxItemSize=0 * @details xQueueSend should return pdTRUE because the queue is empty. - * This queue is eqivalent to a binary semaphore. + * This queue is equivalent to a binary semaphore. * @coverage xQueueGenericSend */ void test_macro_xQueueSend_oneQueueLength_zeroItemSize( void ) @@ -157,7 +157,7 @@ void test_macro_xQueueSend_oneQueueLength_zeroItemSize( void ) /** * @brief Test xQueueSend with uxQueueLength=1, uxItemSize=0 and null item. * @details xQueueSend should return pdTRUE because the queue is empty. - * This queue is eqivalent to a binary semaphore. + * This queue is equivalent to a binary semaphore. * @coverage xQueueGenericSend */ void test_macro_xQueueSend_oneQueueLength_zeroItemSize_null( void ) @@ -403,7 +403,7 @@ void test_macro_xQueueSendFromISR_fail( void ) /** * @brief Test xQueueSendFromISR with uxQueueLength=1, uxItemSize=0 * @details xQueueSendFromISR should return pdTRUE because the queue is empty. - * This queue is eqivalent to a binary semaphore. + * This queue is equivalent to a binary semaphore. * @coverage xQueueGenericSendFromISR */ void test_macro_xQueueSendFromISR_oneQueueLength_zeroItemSize( void ) @@ -426,7 +426,7 @@ void test_macro_xQueueSendFromISR_oneQueueLength_zeroItemSize( void ) /** * @brief Test xQueueSendFromISR with uxQueueLength=1, uxItemSize=0 and null item. * @details xQueueSendFromISR should return pdTRUE because the queue is empty. - * This queue is eqivalent to a binary semaphore. + * This queue is equivalent to a binary semaphore. * @coverage xQueueGenericSendFromISR */ void test_macro_xQueueSendFromISR_oneQueueLength_zeroItemSize_null( void ) diff --git a/FreeRTOS/Test/CMock/queue/generic/queue_status_utest.c b/FreeRTOS/Test/CMock/queue/generic/queue_status_utest.c index db99333e7..524cec071 100644 --- a/FreeRTOS/Test/CMock/queue/generic/queue_status_utest.c +++ b/FreeRTOS/Test/CMock/queue/generic/queue_status_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/queue_utest_common.c b/FreeRTOS/Test/CMock/queue/queue_utest_common.c index 7f66905a4..34d760ca6 100644 --- a/FreeRTOS/Test/CMock/queue/queue_utest_common.c +++ b/FreeRTOS/Test/CMock/queue/queue_utest_common.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/queue_utest_common.h b/FreeRTOS/Test/CMock/queue/queue_utest_common.h index 106006a40..bed06e0cc 100644 --- a/FreeRTOS/Test/CMock/queue/queue_utest_common.h +++ b/FreeRTOS/Test/CMock/queue/queue_utest_common.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -144,7 +144,7 @@ void tearDown( void ); void suiteSetUp(); /** - * @brief Setup function called afer this test suite (file) has completed. + * @brief Setup function called after this test suite (file) has completed. */ int suiteTearDown( int numFailures ); @@ -262,7 +262,7 @@ void queue_common_receive_sequential_from_queue( QueueHandle_t xQueue, uint32_t expectedFirstValue ); /** - * @brief Adds a given number of itesm to the given queue with sequential values in each item. + * @brief Adds a given number of items to the given queue with sequential values in each item. */ void queue_common_add_sequential_to_queue( QueueHandle_t xQueue, uint32_t numberOfItems ); diff --git a/FreeRTOS/Test/CMock/queue/semaphore/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/queue/semaphore/FreeRTOSConfig.h index defe87b41..140156a2e 100644 --- a/FreeRTOS/Test/CMock/queue/semaphore/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/queue/semaphore/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/semaphore/Makefile b/FreeRTOS/Test/CMock/queue/semaphore/Makefile index cf635ba24..653b9324a 100644 --- a/FreeRTOS/Test/CMock/queue/semaphore/Makefile +++ b/FreeRTOS/Test/CMock/queue/semaphore/Makefile @@ -35,10 +35,10 @@ MOCK_FILES_FP += $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/queue/semaphore/binary_semaphore_utest.c b/FreeRTOS/Test/CMock/queue/semaphore/binary_semaphore_utest.c index 1b18bdec8..26975c6e7 100644 --- a/FreeRTOS/Test/CMock/queue/semaphore/binary_semaphore_utest.c +++ b/FreeRTOS/Test/CMock/queue/semaphore/binary_semaphore_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -210,7 +210,7 @@ void test_macro_xSemaphoreGive_multiple_fail( void ) * @brief Test xSemaphoreTake multiple times on a Binary Semaphore * @details Create a binary semaphore using xSemaphoreCreateBinary, * verify that an immediate call to xSemaphoreGive succeeds, a subsequent - * call to xSemaphoreTake succeds, but a second call to xSemaphoreTake fails. + * call to xSemaphoreTake succeeds, but a second call to xSemaphoreTake fails. * @coverage xQueueSemaphoreTake */ void test_macro_xSemaphoreTake_multiple_fail( void ) diff --git a/FreeRTOS/Test/CMock/queue/semaphore/counting_semaphore_utest.c b/FreeRTOS/Test/CMock/queue/semaphore/counting_semaphore_utest.c index b35c15a30..bdba72d7c 100644 --- a/FreeRTOS/Test/CMock/queue/semaphore/counting_semaphore_utest.c +++ b/FreeRTOS/Test/CMock/queue/semaphore/counting_semaphore_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -163,7 +163,7 @@ void test_macro_xSemaphoreGive_CountingSemaphore_100_50( void ) /* Check the count */ TEST_ASSERT_EQUAL( 100, uxSemaphoreGetCount( xSemaphore ) ); - /* Veirfy that a subsequent call to xSemaphoreGive fails */ + /* Verify that a subsequent call to xSemaphoreGive fails */ TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreGive( xSemaphore ) ); /* Verify that an xSemaphoreTake operation succeeds */ @@ -199,7 +199,7 @@ void test_macro_xSemaphoreTake_CountingSemaphore_100_50( void ) /* Check the count */ TEST_ASSERT_EQUAL( 0, uxSemaphoreGetCount( xSemaphore ) ); - /* Veirfy that a subsequent call to xSemaphoreGive fails */ + /* Verify that a subsequent call to xSemaphoreGive fails */ TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTake( xSemaphore, 0 ) ); /* Verify that an xSemaphoreGive operation succeeds */ diff --git a/FreeRTOS/Test/CMock/queue/semaphore/mutex_utest.c b/FreeRTOS/Test/CMock/queue/semaphore/mutex_utest.c index 5a5c809af..d8d05b7db 100644 --- a/FreeRTOS/Test/CMock/queue/semaphore/mutex_utest.c +++ b/FreeRTOS/Test/CMock/queue/semaphore/mutex_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -255,7 +255,7 @@ void test_macro_xSemaphoreGive_multiple_Mutex_fail( void ) * @brief Test xSemaphoreTake multiple times on a Mutex. * @details Create a Mutex using xSemaphoreCreateMutex, * verify that an immediate call to xSemaphoreTake succeeds, a subsequent - * call to xSemaphoreGive succeds, but a second call to xSemaphoreGive fails. + * call to xSemaphoreGive succeeds, but a second call to xSemaphoreGive fails. * @coverage xQueueSemaphoreTake */ void test_macro_xSemaphoreTake_multiple_Mutex_fail( void ) diff --git a/FreeRTOS/Test/CMock/queue/semaphore/recursive_mutex_utest.c b/FreeRTOS/Test/CMock/queue/semaphore/recursive_mutex_utest.c index 294b9e6e4..da2fef5f9 100644 --- a/FreeRTOS/Test/CMock/queue/semaphore/recursive_mutex_utest.c +++ b/FreeRTOS/Test/CMock/queue/semaphore/recursive_mutex_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/semaphore/semaphore_common_utest.c b/FreeRTOS/Test/CMock/queue/semaphore/semaphore_common_utest.c index 4f5282ce9..3c7b8127e 100644 --- a/FreeRTOS/Test/CMock/queue/semaphore/semaphore_common_utest.c +++ b/FreeRTOS/Test/CMock/queue/semaphore/semaphore_common_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/semaphore/semaphore_create_utest.c b/FreeRTOS/Test/CMock/queue/semaphore/semaphore_create_utest.c index 3537349fe..3311ae15a 100644 --- a/FreeRTOS/Test/CMock/queue/semaphore/semaphore_create_utest.c +++ b/FreeRTOS/Test/CMock/queue/semaphore/semaphore_create_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/semaphore/semaphore_get_static_buffer_utest.c b/FreeRTOS/Test/CMock/queue/semaphore/semaphore_get_static_buffer_utest.c index 04b1509a2..d94628873 100644 --- a/FreeRTOS/Test/CMock/queue/semaphore/semaphore_get_static_buffer_utest.c +++ b/FreeRTOS/Test/CMock/queue/semaphore/semaphore_get_static_buffer_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/sets/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/queue/sets/FreeRTOSConfig.h index 9d4aad487..9612dae4d 100644 --- a/FreeRTOS/Test/CMock/queue/sets/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/queue/sets/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/sets/Makefile b/FreeRTOS/Test/CMock/queue/sets/Makefile index 59661c751..497a1ec30 100644 --- a/FreeRTOS/Test/CMock/queue/sets/Makefile +++ b/FreeRTOS/Test/CMock/queue/sets/Makefile @@ -36,10 +36,10 @@ MOCK_FILES_FP += $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/queue/sets/queue_in_set_utest.c b/FreeRTOS/Test/CMock/queue/sets/queue_in_set_utest.c index 3bce77d4a..cb8241643 100644 --- a/FreeRTOS/Test/CMock/queue/sets/queue_in_set_utest.c +++ b/FreeRTOS/Test/CMock/queue/sets/queue_in_set_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -463,7 +463,7 @@ void test_macro_xQueueSendFromISR_in_set_locked_and_low_priority_pending( void ) /** * @brief Test xQueueSendFromISR with a lower priority task waiting on a queue in a Queue Set - * @details Test xQueueSendFromISR on a Queeu in a Queue Set with a lower priority task waiting and + * @details Test xQueueSendFromISR on a Queue in a Queue Set with a lower priority task waiting and * verify that xHigherPriorityTaskWoken is not modified. * @coverage xQueueGenericSendFromISR */ diff --git a/FreeRTOS/Test/CMock/queue/sets/queue_set_utest.c b/FreeRTOS/Test/CMock/queue/sets/queue_set_utest.c index 98281a3ea..4432faaaa 100644 --- a/FreeRTOS/Test/CMock/queue/sets/queue_set_utest.c +++ b/FreeRTOS/Test/CMock/queue/sets/queue_set_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/sets/queue_unlock_cascaded_set_utest.c b/FreeRTOS/Test/CMock/queue/sets/queue_unlock_cascaded_set_utest.c index 99d59af36..ae5881dfa 100644 --- a/FreeRTOS/Test/CMock/queue/sets/queue_unlock_cascaded_set_utest.c +++ b/FreeRTOS/Test/CMock/queue/sets/queue_unlock_cascaded_set_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/sets/semaphore_in_set_utest.c b/FreeRTOS/Test/CMock/queue/sets/semaphore_in_set_utest.c index d9171d1cc..2bad2fe06 100644 --- a/FreeRTOS/Test/CMock/queue/sets/semaphore_in_set_utest.c +++ b/FreeRTOS/Test/CMock/queue/sets/semaphore_in_set_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -140,7 +140,7 @@ void test_macro_xSemaphoreGiveFromISR_in_set_high_priority_pending( void ) /** * @brief Test xSemaphoreGiveFromISR with a lower priority task waiting on a queue in a Queue Set - * @details Test xSemaphoreGiveFromISR on a Queeu in a Queue Set with a lower priority task waiting and + * @details Test xSemaphoreGiveFromISR on a Queue in a Queue Set with a lower priority task waiting and * verify that xHigherPriorityTaskWoken is not modified. * @coverage xQueueGiveFromISR */ diff --git a/FreeRTOS/Test/CMock/queue/static/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/queue/static/FreeRTOSConfig.h index 03f5db091..47905f636 100644 --- a/FreeRTOS/Test/CMock/queue/static/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/queue/static/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/static/Makefile b/FreeRTOS/Test/CMock/queue/static/Makefile index df490d0c2..fd92e29ea 100644 --- a/FreeRTOS/Test/CMock/queue/static/Makefile +++ b/FreeRTOS/Test/CMock/queue/static/Makefile @@ -31,10 +31,10 @@ MOCK_FILES_FP += $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/queue/td_port.c b/FreeRTOS/Test/CMock/queue/td_port.c index 5c83fab40..2d8cb5d16 100644 --- a/FreeRTOS/Test/CMock/queue/td_port.c +++ b/FreeRTOS/Test/CMock/queue/td_port.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/td_task.c b/FreeRTOS/Test/CMock/queue/td_task.c index 046d993a0..eff0cdc60 100644 --- a/FreeRTOS/Test/CMock/queue/td_task.c +++ b/FreeRTOS/Test/CMock/queue/td_task.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/tracing/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/queue/tracing/FreeRTOSConfig.h index 38dee7681..c3e7e386b 100644 --- a/FreeRTOS/Test/CMock/queue/tracing/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/queue/tracing/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/tracing/Makefile b/FreeRTOS/Test/CMock/queue/tracing/Makefile index 58932691d..e1b366b14 100644 --- a/FreeRTOS/Test/CMock/queue/tracing/Makefile +++ b/FreeRTOS/Test/CMock/queue/tracing/Makefile @@ -32,10 +32,10 @@ MOCK_FILES_FP += $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/queue/tracing/queue_registry_utest.c b/FreeRTOS/Test/CMock/queue/tracing/queue_registry_utest.c index 42c9ac18c..7f02b73a4 100644 --- a/FreeRTOS/Test/CMock/queue/tracing/queue_registry_utest.c +++ b/FreeRTOS/Test/CMock/queue/tracing/queue_registry_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/queue/tracing/queue_trace_utest.c b/FreeRTOS/Test/CMock/queue/tracing/queue_trace_utest.c index 8c8f2aaba..dabe814bc 100644 --- a/FreeRTOS/Test/CMock/queue/tracing/queue_trace_utest.c +++ b/FreeRTOS/Test/CMock/queue/tracing/queue_trace_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/stream_buffer/api/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/stream_buffer/api/FreeRTOSConfig.h index 29d43a905..271dffd17 100644 --- a/FreeRTOS/Test/CMock/stream_buffer/api/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/stream_buffer/api/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/stream_buffer/api/Makefile b/FreeRTOS/Test/CMock/stream_buffer/api/Makefile index 72991130d..b7ac1114e 100644 --- a/FreeRTOS/Test/CMock/stream_buffer/api/Makefile +++ b/FreeRTOS/Test/CMock/stream_buffer/api/Makefile @@ -27,10 +27,10 @@ MOCK_FILES_FP := $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/stream_buffer/api/stream_buffer_api_utest.c b/FreeRTOS/Test/CMock/stream_buffer/api/stream_buffer_api_utest.c index c077cb188..92b834647 100644 --- a/FreeRTOS/Test/CMock/stream_buffer/api/stream_buffer_api_utest.c +++ b/FreeRTOS/Test/CMock/stream_buffer/api/stream_buffer_api_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -1187,7 +1187,7 @@ void test_xStreamBufferReset_while_blocked( void ) /** * @brief Validates that a receiver task is able to receive data after lowering the stream buffer trigger level. */ -void test_xStreamBufferSetTrigerLevel_success( void ) +void test_xStreamBufferSetTriggerLevel_success( void ) { uint8_t data[ TEST_STREAM_BUFFER_SIZE ] = { 0xAA }; BaseType_t status; @@ -1222,7 +1222,7 @@ void test_xStreamBufferSetTrigerLevel_success( void ) /** * @brief Validate setting trigger level with invalid parameters fails. */ -void test_xStreamBufferSetTrigerLevel_larger_than_buffer_size( void ) +void test_xStreamBufferSetTriggerLevel_larger_than_buffer_size( void ) { BaseType_t status; @@ -1240,7 +1240,7 @@ void test_xStreamBufferSetTrigerLevel_larger_than_buffer_size( void ) /** * @brief Set the trigger level to 0 should pass but internally set trigger level to 1. */ -void test_xStreamBufferSetTrigerLevel_zero( void ) +void test_xStreamBufferSetTriggerLevel_zero( void ) { BaseType_t status; diff --git a/FreeRTOS/Test/CMock/stream_buffer/callback/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/stream_buffer/callback/FreeRTOSConfig.h index bf35e5c57..f6f5ad5d0 100644 --- a/FreeRTOS/Test/CMock/stream_buffer/callback/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/stream_buffer/callback/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/stream_buffer/callback/Makefile b/FreeRTOS/Test/CMock/stream_buffer/callback/Makefile index 622ee4a97..412098d90 100644 --- a/FreeRTOS/Test/CMock/stream_buffer/callback/Makefile +++ b/FreeRTOS/Test/CMock/stream_buffer/callback/Makefile @@ -27,10 +27,10 @@ MOCK_FILES_FP := $(KERNEL_DIR)/include/task.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h -# List any addiitonal flags needed by the preprocessor +# List any additional flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 -# List any addiitonal flags needed by the compiler +# List any additional flags needed by the compiler CFLAGS += # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/stream_buffer/callback/stream_buffer_callback_utest.c b/FreeRTOS/Test/CMock/stream_buffer/callback/stream_buffer_callback_utest.c index 2d88ebec4..58b283134 100644 --- a/FreeRTOS/Test/CMock/stream_buffer/callback/stream_buffer_callback_utest.c +++ b/FreeRTOS/Test/CMock/stream_buffer/callback/stream_buffer_callback_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -366,7 +366,7 @@ void test_xStreamBufferCreate_NoCallback( void ) } /** - * @brief Tests succesful creation of dynamic stream buffer with callbacks. + * @brief Tests successful creation of dynamic stream buffer with callbacks. */ void test_xStreamBufferCreate_WithCallback( void ) { diff --git a/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h b/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h index 1791c18ef..8b4a0e3e8 100644 --- a/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h +++ b/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h b/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h index c099c2b24..3dfcc5103 100644 --- a/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h +++ b/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/tasks/global_vars.h b/FreeRTOS/Test/CMock/tasks/global_vars.h index cfc649011..aec6e12c1 100644 --- a/FreeRTOS/Test/CMock/tasks/global_vars.h +++ b/FreeRTOS/Test/CMock/tasks/global_vars.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -23,8 +23,8 @@ * https://github.com/FreeRTOS * */ -#ifndef GBLOBAL_VARS_H -#define GBLOBAL_VARS_H +#ifndef GLOBAL_VARS_H +#define GLOBAL_VARS_H #include "task.h" @@ -283,22 +283,22 @@ typedef void (* port_yield_operation)( void ); TEST_ASSERT_FALSE( vApplicationStackOverflowHook_called ); \ } while( 0 ) -#define ASSERT_GET_IDLE_TASK_MEMORY_CALLED() \ - do { \ - TEST_ASSERT_TRUE( getIddleTaskMemory_called ); \ - getIddleTaskMemory_called = false; \ +#define ASSERT_GET_IDLE_TASK_MEMORY_CALLED() \ + do { \ + TEST_ASSERT_TRUE( getIdleTaskMemory_called ); \ + getIdleTaskMemory_called = false; \ } while( 0 ) -#define ASSERT_GET_IDLE_TASK_MEMORY_NOT_CALLED() \ - do { \ - TEST_ASSERT_FALSE( getIddleTaskMemory_called ); \ +#define ASSERT_GET_IDLE_TASK_MEMORY_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( getIdleTaskMemory_called ); \ } while( 0 ) #define RESET_ALL_HOOKS() \ do { \ vApplicationTickHook_called = false; \ vTaskDeletePre_called = false; \ - getIddleTaskMemory_called = false; \ + getIdleTaskMemory_called = false; \ port_yield_called = false; \ port_enable_interrupts_called = false; \ port_disable_interrupts_called = false; \ @@ -322,4 +322,4 @@ typedef void (* port_yield_operation)( void ); #undef HOOK_DIAG #define HOOK_DIAG() -#endif /* ifndef GBLOBAL_VARS_H */ +#endif /* ifndef GLOBAL_VARS_H */ diff --git a/FreeRTOS/Test/CMock/tasks/list_macros.h b/FreeRTOS/Test/CMock/tasks/list_macros.h index 07d129ad6..d5c3f1162 100644 --- a/FreeRTOS/Test/CMock/tasks/list_macros.h +++ b/FreeRTOS/Test/CMock/tasks/list_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/tasks/tasks_1_utest.c b/FreeRTOS/Test/CMock/tasks/tasks_1_utest.c index dfec02887..1c9c2a7d1 100644 --- a/FreeRTOS/Test/CMock/tasks/tasks_1_utest.c +++ b/FreeRTOS/Test/CMock/tasks/tasks_1_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -125,7 +125,7 @@ static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static TCB_t * ptcb; static StackType_t stack[ ( ( size_t ) 300 ) * sizeof( StackType_t ) ]; static TCB_t tcb[ TCB_ARRAY ]; -static bool getIddleTaskMemoryValid = false; +static bool getIdleTaskMemoryValid = false; static uint32_t critical_section_counter = 0; static bool is_first_task = true; static uint32_t created_tasks = 0; @@ -133,7 +133,7 @@ static uint32_t create_task_priority = 3; static port_yield_operation py_operation; static bool vTaskDeletePre_called = false; -static bool getIddleTaskMemory_called = false; +static bool getIdleTaskMemory_called = false; static bool vApplicationTickHook_called = false; static bool port_yield_called = false; static bool port_enable_interrupts_called = false; @@ -187,7 +187,7 @@ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, { HOOK_DIAG(); - if( getIddleTaskMemoryValid == true ) + if( getIdleTaskMemoryValid == true ) { /* Pass out a pointer to the StaticTask_t structure in which the Idle task's * state will be stored. */ @@ -208,7 +208,7 @@ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, *pulIdleTaskStackSize = 0; } - getIddleTaskMemory_called = true; + getIdleTaskMemory_called = true; } void vConfigureTimerForRunTimeStats( void ) @@ -423,7 +423,7 @@ static void start_scheduler() xTimerCreateTimerTask_ExpectAndReturn( pdPASS ); xPortStartScheduler_ExpectAndReturn( pdTRUE ); - getIddleTaskMemoryValid = true; + getIdleTaskMemoryValid = true; vTaskStartScheduler(); ASSERT_GET_IDLE_TASK_MEMORY_CALLED(); TEST_ASSERT_TRUE( xSchedulerRunning ); @@ -824,7 +824,7 @@ void test_xTaskCreate_fail_tcb_malloc( void ) } /* -------------------------- INCLUDE_vTaskDelete --------------------------- */ -void test_vTaskDelete_sucess_current_task( void ) +void test_vTaskDelete_success_current_task( void ) { ptcb = ( TCB_t * ) create_task(); @@ -842,7 +842,7 @@ void test_vTaskDelete_sucess_current_task( void ) TEST_ASSERT_EQUAL( 1, uxDeletedTasksWaitingCleanUp ); } -void test_vTaskDelete_sucess_current_task_ready_empty( void ) +void test_vTaskDelete_success_current_task_ready_empty( void ) { /* Setup */ ptcb = ( TCB_t * ) create_task(); @@ -861,7 +861,7 @@ void test_vTaskDelete_sucess_current_task_ready_empty( void ) TEST_ASSERT_EQUAL( 1, uxDeletedTasksWaitingCleanUp ); } -void test_vTaskDelete_sucess_current_task_ready_empty_null_task( void ) +void test_vTaskDelete_success_current_task_ready_empty_null_task( void ) { ptcb = ( TCB_t * ) create_task(); @@ -880,7 +880,7 @@ void test_vTaskDelete_sucess_current_task_ready_empty_null_task( void ) TEST_ASSERT_EQUAL( 1, uxDeletedTasksWaitingCleanUp ); } -void test_vTaskDelete_sucess_current_task_yield( void ) +void test_vTaskDelete_success_current_task_yield( void ) { xSchedulerRunning = pdTRUE; ptcb = ( TCB_t * ) create_task(); @@ -900,7 +900,7 @@ void test_vTaskDelete_sucess_current_task_yield( void ) TEST_ASSERT_EQUAL( 1, uxDeletedTasksWaitingCleanUp ); } -void test_vTaskDelete_sucess_not_current_task( void ) +void test_vTaskDelete_success_not_current_task( void ) { ptcb = ( TCB_t * ) create_task(); TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); @@ -921,7 +921,7 @@ void test_vTaskDelete_sucess_not_current_task( void ) TEST_ASSERT_EQUAL( 0, uxDeletedTasksWaitingCleanUp ); } -void test_vTaskDelete_sucess_not_current_task_no_yield( void ) +void test_vTaskDelete_success_not_current_task_no_yield( void ) { xSchedulerRunning = pdTRUE; ptcb = ( TCB_t * ) create_task(); @@ -975,7 +975,7 @@ void test_vTaskStartScheduler_success( void ) xTimerCreateTimerTask_ExpectAndReturn( pdPASS ); xPortStartScheduler_ExpectAndReturn( pdTRUE ); - getIddleTaskMemoryValid = true; + getIdleTaskMemoryValid = true; vTaskStartScheduler(); ASSERT_GET_IDLE_TASK_MEMORY_CALLED(); @@ -986,7 +986,7 @@ void test_vTaskStartScheduler_success( void ) void test_vTaskStartScheduler_idle_fail( void ) { - getIddleTaskMemoryValid = false; + getIdleTaskMemoryValid = false; vTaskStartScheduler(); ASSERT_GET_IDLE_TASK_MEMORY_CALLED(); @@ -1396,7 +1396,7 @@ void test_vTaskPrioritySet_success_same_prio( void ) } -/* ensures if the set priority is less thatn the current priority and it is the +/* ensures if the set priority is less than the current priority and it is the * current tcb the task is yielded */ void test_vTaskPrioritySet_success_lt_curr_prio_curr_task( void ) @@ -1426,7 +1426,7 @@ void test_vTaskPrioritySet_success_lt_curr_prio_curr_task( void ) ASSERT_PORT_YIELD_WITHIN_API_CALLED(); } -/* ensures if the set priority is less thatn the current priority and it is not +/* ensures if the set priority is less than the current priority and it is not * the current tcb the task is not yielded */ void test_vTaskPrioritySet_success_lt_curr_prio_not_curr_task( void ) @@ -2189,7 +2189,7 @@ void test_vTaskSuspend_success( void ) ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); } -void test_vTaskSuspend_success_shced_running( void ) +void test_vTaskSuspend_success_sched_running( void ) { TaskHandle_t task_handle; @@ -2214,7 +2214,7 @@ void test_vTaskSuspend_success_shced_running( void ) ASSERT_PORT_YIELD_WITHIN_API_CALLED(); } -void test_vTaskSuspend_success_shced_running_not_curr( void ) +void test_vTaskSuspend_success_sched_running_not_curr( void ) { TaskHandle_t task_handle, task_handle2; @@ -2764,7 +2764,7 @@ void test_xtaskGetHandle_fail_no_task_found( void ) } -void test_xtaskGetHandle_fail_no_taks_running( void ) +void test_xtaskGetHandle_fail_no_tasks_running( void ) { TaskHandle_t task_handle2; @@ -2786,7 +2786,7 @@ void test_xtaskGetHandle_fail_no_taks_running( void ) } /* testing always available functions */ -void test_xTaskGetTickCount_sucess( void ) +void test_xTaskGetTickCount_success( void ) { TickType_t ret_get_tick_count; @@ -3796,8 +3796,8 @@ void test_vTaskMissedYield( void ) TEST_ASSERT_TRUE( xYieldPending ); } -/* TODO: find a way to fix the iddle task UnitTest as it is an infitine loop */ -void ignore_test_prvIddleTask_yield( void ) +/* TODO: find a way to fix the idle task UnitTest as it is an infinite loop */ +void ignore_test_prvIdleTask_yield( void ) { int i = 8; void * args = &i; @@ -3918,7 +3918,7 @@ void test_vTaskStepTick() /* testing configNUM_THREAD_LOCAL_STORAGE_POINTERS */ -/* this test ensures that the value set is also retreived */ +/* this test ensures that the value set is also retrieved */ void test_vTask_Set_Get_ThreadLocalStoragePointer_success( void ) { TaskHandle_t task_handle; @@ -4463,7 +4463,7 @@ static void notif_received() ptcb->ucNotifyState[ 0 ] = 2; /* taskNOTIFICATION_RECEIVED */ } -void test_ulTaskGenericNotifyTake_sucess( void ) +void test_ulTaskGenericNotifyTake_success( void ) { TaskHandle_t task_handle; UBaseType_t uxIndexToWait = 0; @@ -4483,7 +4483,7 @@ void test_ulTaskGenericNotifyTake_sucess( void ) ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); } -void test_ulTaskGenericNotifyTake_sucess2( void ) +void test_ulTaskGenericNotifyTake_success2( void ) { TaskHandle_t task_handle; UBaseType_t uxIndexToWait = 0; @@ -4503,7 +4503,7 @@ void test_ulTaskGenericNotifyTake_sucess2( void ) ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); } -void test_ulTaskGenericNotifyTake_sucess_clear_count( void ) +void test_ulTaskGenericNotifyTake_success_clear_count( void ) { TaskHandle_t task_handle; UBaseType_t uxIndexToWait = 0; @@ -4523,7 +4523,7 @@ void test_ulTaskGenericNotifyTake_sucess_clear_count( void ) ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); } -void test_ulTaskGenericNotifyTake_sucess_yield( void ) +void test_ulTaskGenericNotifyTake_success_yield( void ) { TaskHandle_t task_handle; UBaseType_t uxIndexToWait = 0; @@ -5114,7 +5114,7 @@ void test_xTaskGenericNotify_success_default_ISR_task_woken_null( void ) } -void test_xTaskGenericNotifyWait_success_notif_recieved( void ) +void test_xTaskGenericNotifyWait_success_notif_received( void ) { UBaseType_t uxIndexToWait = 0; uint32_t ulBitsToClearOnEntry = 0; @@ -5140,7 +5140,7 @@ void test_xTaskGenericNotifyWait_success_notif_recieved( void ) ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); } -void test_xTaskGenericNotifyWait_success_notif_not_recieved( void ) +void test_xTaskGenericNotifyWait_success_notif_not_received( void ) { UBaseType_t uxIndexToWait = 0; uint32_t ulBitsToClearOnEntry = 0; @@ -5173,7 +5173,7 @@ void test_xTaskGenericNotifyWait_success_notif_not_recieved( void ) ASSERT_PORT_YIELD_WITHIN_API_CALLED(); } -void test_xTaskGenericNotifyWait_success_notif_not_recieved_no_wait( void ) +void test_xTaskGenericNotifyWait_success_notif_not_received_no_wait( void ) { UBaseType_t uxIndexToWait = 0; uint32_t ulBitsToClearOnEntry = 0; @@ -5202,7 +5202,7 @@ void test_xTaskGenericNotifyWait_success_notif_not_recieved_no_wait( void ) ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); } -void test_xTaskGenericNotifyWait_success_notif_not_recieved_pull_null( void ) +void test_xTaskGenericNotifyWait_success_notif_not_received_pull_null( void ) { UBaseType_t uxIndexToWait = 0; uint32_t ulBitsToClearOnEntry = 0; @@ -5229,7 +5229,7 @@ void test_xTaskGenericNotifyWait_success_notif_not_recieved_pull_null( void ) ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); } -void test_xTaskGenericNotifyWait_success_notif_recieved_while_waiting( void ) +void test_xTaskGenericNotifyWait_success_notif_received_while_waiting( void ) { UBaseType_t uxIndexToWait = 0; uint32_t ulBitsToClearOnEntry = 0; diff --git a/FreeRTOS/Test/CMock/tasks/tasks_2_utest.c b/FreeRTOS/Test/CMock/tasks/tasks_2_utest.c index c82b0f816..5ee618abd 100644 --- a/FreeRTOS/Test/CMock/tasks/tasks_2_utest.c +++ b/FreeRTOS/Test/CMock/tasks/tasks_2_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -93,14 +93,14 @@ static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static TCB_t * ptcb; static StackType_t stack[ ( ( size_t ) 300 ) * sizeof( StackType_t ) ]; static TCB_t tcb[ 10 ]; /* simulate up to 10 tasks: add more if needed */ -static bool getIddleTaskMemoryValid = false; +static bool getIdleTaskMemoryValid = false; static uint32_t critical_section_counter = 0; static bool is_first_task = true; static uint32_t created_tasks = 0; static uint32_t create_task_priority = 3; static port_yield_operation py_operation; static bool vTaskDeletePre_called = false; -static bool getIddleTaskMemory_called = false; +static bool getIdleTaskMemory_called = false; static bool vApplicationTickHook_called = false; static bool port_yield_called = false; static bool port_enable_interrupts_called = false; @@ -155,7 +155,7 @@ static void start_scheduler() xTimerCreateTimerTask_ExpectAndReturn( pdPASS ); xPortStartScheduler_ExpectAndReturn( pdTRUE ); - getIddleTaskMemoryValid = true; + getIdleTaskMemoryValid = true; vTaskStartScheduler(); ASSERT_GET_IDLE_TASK_MEMORY_CALLED(); TEST_ASSERT_TRUE( xSchedulerRunning ); @@ -253,7 +253,7 @@ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, { HOOK_DIAG(); - if( getIddleTaskMemoryValid == true ) + if( getIdleTaskMemoryValid == true ) { /* Pass out a pointer to the StaticTask_t structure in which the Idle task's * state will be stored. */ @@ -274,7 +274,7 @@ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, *pulIdleTaskStackSize = 0; } - getIddleTaskMemory_called = true; + getIdleTaskMemory_called = true; } void vConfigureTimerForRunTimeStats( void ) @@ -661,7 +661,7 @@ void test_vTaskPrioritySet_success_gt_curr_prio( void ) void vTaskEnterCritical( void ); void vTaskExitCritical( void ); -void test_vTaskExitCritical_succes( void ) +void test_vTaskExitCritical_success( void ) { TaskHandle_t task_handle; @@ -725,7 +725,7 @@ void test_vTaskExitCritical_scheduler_off( void ) ASSERT_PORT_ENABLE_INTERRUPT_NOT_CALLED(); } -void test_vTaskEnterCritical_succes( void ) +void test_vTaskEnterCritical_success( void ) { TaskHandle_t task_handle; @@ -740,7 +740,7 @@ void test_vTaskEnterCritical_succes( void ) ASSERT_IF_IN_ISR_CALLED(); } -void test_vTaskEnterCritical_succes_twice( void ) +void test_vTaskEnterCritical_success_twice( void ) { TaskHandle_t task_handle; diff --git a/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h b/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h index d1d124d8b..7bc5a1f9e 100644 --- a/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h +++ b/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_dynamic.h b/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_dynamic.h index 1eb07d81d..57f183391 100644 --- a/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_dynamic.h +++ b/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_dynamic.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/timers/global_vars.h b/FreeRTOS/Test/CMock/timers/global_vars.h index 44489c79a..6261d404a 100644 --- a/FreeRTOS/Test/CMock/timers/global_vars.h +++ b/FreeRTOS/Test/CMock/timers/global_vars.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/timers/list_macros.h b/FreeRTOS/Test/CMock/timers/list_macros.h index 521bc4b56..1dbf5a1e5 100644 --- a/FreeRTOS/Test/CMock/timers/list_macros.h +++ b/FreeRTOS/Test/CMock/timers/list_macros.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/timers/timers_1_utest.c b/FreeRTOS/Test/CMock/timers/timers_1_utest.c index e78ce6768..d7273027d 100644 --- a/FreeRTOS/Test/CMock/timers/timers_1_utest.c +++ b/FreeRTOS/Test/CMock/timers/timers_1_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -67,8 +67,8 @@ static bool xCallback_Test_1_end_called = pdFALSE; static bool xCallback_Test_2_end_called = pdFALSE; /* ================================= DEFINES ============================== */ -#define DEFAULT_TIMER_PEIOD 1000 -#define DEFAULT_TIMER_NAME "ut_timer" +#define DEFAULT_TIMER_PERIOD 1000 +#define DEFAULT_TIMER_NAME "ut_timer" /* ============================= FUNCTION MACROS ========================== */ #define ASSERT_APPLICATION_DAEMON_STARTUP_HOOK_CALLED() \ @@ -265,7 +265,7 @@ static TimerHandle_t create_timer() vListInitialiseItem_ExpectAnyArgs(); xTimer = xTimerCreateStatic( DEFAULT_TIMER_NAME, - DEFAULT_TIMER_PEIOD, + DEFAULT_TIMER_PERIOD, pdTRUE, ( void * ) &pvTimerID, xCallback_Test, @@ -563,7 +563,7 @@ void test_xTimerGenericCommand_success_null_timer_not_started( void ) } /*! - * @brief sucess testcase, getter for the timer handle daemon + * @brief success testcase, getter for the timer handle daemon * expects a non NULL value */ void test_xTimerGetTimerDaemonTaskHandle_success( void ) @@ -580,7 +580,7 @@ void test_xTimerGetTimerDaemonTaskHandle_success( void ) } /*! - * @brief sucess testcase, getter for the timer period in ticks + * @brief success testcase, getter for the timer period in ticks * expects a similar value to the one created */ void test_xTimerGetPeriod_success( void ) @@ -594,11 +594,11 @@ void test_xTimerGetPeriod_success( void ) /* API Call */ ret_get_period = xTimerGetPeriod( xTimer ); /* Validations */ - TEST_ASSERT_EQUAL( DEFAULT_TIMER_PEIOD, ret_get_period ); + TEST_ASSERT_EQUAL( DEFAULT_TIMER_PERIOD, ret_get_period ); } /*! - * @brief sucess testcase, set and test timer reload mode + * @brief success testcase, set and test timer reload mode */ void test_vTimer_Set_Get_ReloadMode_success( void ) { @@ -624,7 +624,7 @@ void test_vTimer_Set_Get_ReloadMode_success( void ) } /*! - * @brief sucess testcase, get timer expiry time + * @brief success testcase, get timer expiry time */ void test_xTimerGetExpiryTime( void ) { @@ -642,7 +642,7 @@ void test_xTimerGetExpiryTime( void ) } /*! - * @brief sucess testcase, get and test the default timer name + * @brief success testcase, get and test the default timer name */ void test_pcTimerGetName( void ) { @@ -659,7 +659,7 @@ void test_pcTimerGetName( void ) } /*! - * @brief sucess testcase, get timer status and test if it is active + * @brief success testcase, get timer status and test if it is active */ void test_xTimerIsTimerActive_true( void ) { @@ -678,7 +678,7 @@ void test_xTimerIsTimerActive_true( void ) } /*! - * @brief sucess testcase, get timer status and test if it is active + * @brief success testcase, get timer status and test if it is active * expects the timer not to be active by default */ void test_xTimerIsTimerActive_false( void ) @@ -696,7 +696,7 @@ void test_xTimerIsTimerActive_false( void ) } /*! - * @brief sucess testcase, set timer ID then tests if it was set properly + * @brief success testcase, set timer ID then tests if it was set properly */ void test_vTimerSetTimerID( void ) { @@ -717,7 +717,7 @@ void test_vTimerSetTimerID( void ) } /*! - * @brief sucess testcase, sets a pended function call + * @brief success testcase, sets a pended function call */ void test_xTimerPendFunctionCall_success( void ) { @@ -738,7 +738,7 @@ void test_xTimerPendFunctionCall_success( void ) } /*! - * @brief sucess testcase, sets a pended function call from ISR + * @brief success testcase, sets a pended function call from ISR */ void test_xTimerPendFunctionCallFromISR_success( void ) { @@ -760,7 +760,7 @@ void test_xTimerPendFunctionCallFromISR_success( void ) } /*! - * @brief sucess testcase, expired timer is calling the callback + * @brief success testcase, expired timer is calling the callback */ void test_timer_function_expired_callback( void ) { @@ -800,8 +800,8 @@ void test_timer_function_expired_callback( void ) } /*! - * @brief sucess testcase, port yields when no context switch happens because of - * reusming the scheduler + * @brief success testcase, port yields when no context switch happens because of + * resuming the scheduler */ void test_timer_function_success3( void ) { @@ -832,7 +832,7 @@ void test_timer_function_success3( void ) } /*! - * @brief sucess testcase, timer callback called + * @brief success testcase, timer callback called */ void test_timer_function_success4( void ) { diff --git a/FreeRTOS/Test/CMock/timers/timers_dynamic_utest.c b/FreeRTOS/Test/CMock/timers/timers_dynamic_utest.c index c27f67fe5..599f8d108 100644 --- a/FreeRTOS/Test/CMock/timers/timers_dynamic_utest.c +++ b/FreeRTOS/Test/CMock/timers/timers_dynamic_utest.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/CMock/tools/callgraph.py b/FreeRTOS/Test/CMock/tools/callgraph.py index 7f67ed8ff..27cc4fdbc 100755 --- a/FreeRTOS/Test/CMock/tools/callgraph.py +++ b/FreeRTOS/Test/CMock/tools/callgraph.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 ############################################################################### # FreeRTOS -# Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/CMock/tools/filtercov.py b/FreeRTOS/Test/CMock/tools/filtercov.py index f8733b910..e051d98b8 100755 --- a/FreeRTOS/Test/CMock/tools/filtercov.py +++ b/FreeRTOS/Test/CMock/tools/filtercov.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 ############################################################################### # FreeRTOS -# Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/FreeRTOS/Test/Target/boards/pico/FreeRTOSConfig.h b/FreeRTOS/Test/Target/boards/pico/FreeRTOSConfig.h index a947b7fde..863bf5715 100644 --- a/FreeRTOS/Test/Target/boards/pico/FreeRTOSConfig.h +++ b/FreeRTOS/Test/Target/boards/pico/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/Target/boards/pico/main.c b/FreeRTOS/Test/Target/boards/pico/main.c index b17dcacce..52b72af6e 100644 --- a/FreeRTOS/Test/Target/boards/pico/main.c +++ b/FreeRTOS/Test/Target/boards/pico/main.c @@ -1,123 +1,123 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * @file main.c - * @brief The implementation of main function to start test runner task. - * - * Procedure: - * - Initialize environment. - * - Run the test case. - */ - -/* Kernel includes. */ -#include "FreeRTOS.h" /* Must come first. */ -#include "task.h" /* RTOS task related API prototypes. */ - -/* Unity includes. */ -#include "unity.h" - -/* Pico includes. */ -#include "pico/multicore.h" -#include "pico/stdlib.h" - -/*-----------------------------------------------------------*/ - -/** - * Initialize required peripherals. - */ -static void prvInitializeHardware( void ); - -/** - * @brief Run test. - */ -extern void vRunTest( void ); -/*-----------------------------------------------------------*/ - -static void prvInitializeHardware( void ) -{ - /* Needed for printf. */ - stdio_init_all(); - - while( !stdio_usb_connected() ) - { - sleep_ms( 250 ); - } -} -/*-----------------------------------------------------------*/ - -void vApplicationStackOverflowHook( TaskHandle_t xTask, - char * pcTaskName ) -{ - ( void ) pcTaskName; - ( void ) xTask; - - printf( "ERROR: Stack Overflow\n\0" ); - - /* Run time stack overflow checking is performed if - * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook - * function is called if a stack overflow is detected. pxCurrentTCB can be - * inspected in the debugger if the task name passed into this function is - * corrupt. */ - for( ; ; ) - { - /* Always running, put asm here to avoid optimization by compiler. */ - __asm volatile ( "nop" ); - } -} -/*-----------------------------------------------------------*/ - -void vApplicationTickHook( void ) -{ -} -/*-----------------------------------------------------------*/ - -void vApplicationMallocFailedHook( void ) -{ - printf( "ERROR: Malloc Failed\n\0" ); - - for( ; ; ) - { - /* Always running, put asm here to avoid optimization by compiler. */ - __asm volatile ( "nop" ); - } -} -/*-----------------------------------------------------------*/ - -int main( void ) -{ - prvInitializeHardware(); - - vRunTest(); - - vTaskStartScheduler(); - - /* Should never reach here. */ - panic_unsupported(); - - return 0; -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * @file main.c + * @brief The implementation of main function to start test runner task. + * + * Procedure: + * - Initialize environment. + * - Run the test case. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" /* Must come first. */ +#include "task.h" /* RTOS task related API prototypes. */ + +/* Unity includes. */ +#include "unity.h" + +/* Pico includes. */ +#include "pico/multicore.h" +#include "pico/stdlib.h" + +/*-----------------------------------------------------------*/ + +/** + * Initialize required peripherals. + */ +static void prvInitializeHardware( void ); + +/** + * @brief Run test. + */ +extern void vRunTest( void ); +/*-----------------------------------------------------------*/ + +static void prvInitializeHardware( void ) +{ + /* Needed for printf. */ + stdio_init_all(); + + while( !stdio_usb_connected() ) + { + sleep_ms( 250 ); + } +} +/*-----------------------------------------------------------*/ + +void vApplicationStackOverflowHook( TaskHandle_t xTask, + char * pcTaskName ) +{ + ( void ) pcTaskName; + ( void ) xTask; + + printf( "ERROR: Stack Overflow\n\0" ); + + /* Run time stack overflow checking is performed if + * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook + * function is called if a stack overflow is detected. pxCurrentTCB can be + * inspected in the debugger if the task name passed into this function is + * corrupt. */ + for( ; ; ) + { + /* Always running, put asm here to avoid optimization by compiler. */ + __asm volatile ( "nop" ); + } +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ +} +/*-----------------------------------------------------------*/ + +void vApplicationMallocFailedHook( void ) +{ + printf( "ERROR: Malloc Failed\n\0" ); + + for( ; ; ) + { + /* Always running, put asm here to avoid optimization by compiler. */ + __asm volatile ( "nop" ); + } +} +/*-----------------------------------------------------------*/ + +int main( void ) +{ + prvInitializeHardware(); + + vRunTest(); + + vTaskStartScheduler(); + + /* Should never reach here. */ + panic_unsupported(); + + return 0; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Test/Target/boards/pico/tests/smp/multiple_tasks_running/multiple_tasks_running_test_runner.c b/FreeRTOS/Test/Target/boards/pico/tests/smp/multiple_tasks_running/multiple_tasks_running_test_runner.c index fd2e299d2..5f645ac33 100644 --- a/FreeRTOS/Test/Target/boards/pico/tests/smp/multiple_tasks_running/multiple_tasks_running_test_runner.c +++ b/FreeRTOS/Test/Target/boards/pico/tests/smp/multiple_tasks_running/multiple_tasks_running_test_runner.c @@ -1,76 +1,76 @@ -/* - * FreeRTOS V202212.00 - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/** - * @file multiple_tasks_running_test_runner.c - * @brief The implementation of test runner task which runs the test. - */ - -/* Kernel includes. */ -#include "FreeRTOS.h" /* Must come first. */ -#include "task.h" /* RTOS task related API prototypes. */ - -/* Unity includes. */ -#include "unity.h" - -/* Pico includes. */ -#include "pico/multicore.h" -#include "pico/stdlib.h" - -/*-----------------------------------------------------------*/ - -/** - * @brief The task that runs the test. - */ -static void prvTestRunnerTask( void * pvParameters ); - -/** - * @brief The test case to run. - */ -extern void vRunMultipleTasksRunningTest( void ); -/*-----------------------------------------------------------*/ - -static void prvTestRunnerTask( void * pvParameters ) -{ - ( void ) pvParameters; - - /* Run test case. */ - vRunMultipleTasksRunningTest(); - - vTaskDelete( NULL ); -} -/*-----------------------------------------------------------*/ - -void vRunTest( void ) -{ - xTaskCreate( prvTestRunnerTask, - "testRunner", - configMINIMAL_STACK_SIZE, - NULL, - configMAX_PRIORITIES - 1, - NULL ); -} -/*-----------------------------------------------------------*/ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * @file multiple_tasks_running_test_runner.c + * @brief The implementation of test runner task which runs the test. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" /* Must come first. */ +#include "task.h" /* RTOS task related API prototypes. */ + +/* Unity includes. */ +#include "unity.h" + +/* Pico includes. */ +#include "pico/multicore.h" +#include "pico/stdlib.h" + +/*-----------------------------------------------------------*/ + +/** + * @brief The task that runs the test. + */ +static void prvTestRunnerTask( void * pvParameters ); + +/** + * @brief The test case to run. + */ +extern void vRunMultipleTasksRunningTest( void ); +/*-----------------------------------------------------------*/ + +static void prvTestRunnerTask( void * pvParameters ) +{ + ( void ) pvParameters; + + /* Run test case. */ + vRunMultipleTasksRunningTest(); + + vTaskDelete( NULL ); +} +/*-----------------------------------------------------------*/ + +void vRunTest( void ) +{ + xTaskCreate( prvTestRunnerTask, + "testRunner", + configMINIMAL_STACK_SIZE, + NULL, + configMAX_PRIORITIES - 1, + NULL ); +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Test/Target/tests/smp/multiple_tasks_running/multiple_tasks_running.c b/FreeRTOS/Test/Target/tests/smp/multiple_tasks_running/multiple_tasks_running.c index 035e2699d..c1a4de96f 100644 --- a/FreeRTOS/Test/Target/tests/smp/multiple_tasks_running/multiple_tasks_running.c +++ b/FreeRTOS/Test/Target/tests/smp/multiple_tasks_running/multiple_tasks_running.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/Target/tests/smp/multiple_tasks_running/test_config.h b/FreeRTOS/Test/Target/tests/smp/multiple_tasks_running/test_config.h index a3d1d7245..1998c3175 100644 --- a/FreeRTOS/Test/Target/tests/smp/multiple_tasks_running/test_config.h +++ b/FreeRTOS/Test/Target/tests/smp/multiple_tasks_running/test_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/Target/tests/smp/template/test_config.h b/FreeRTOS/Test/Target/tests/smp/template/test_config.h index 86dfb51eb..0a029c1d5 100644 --- a/FreeRTOS/Test/Target/tests/smp/template/test_config.h +++ b/FreeRTOS/Test/Target/tests/smp/template/test_config.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/Target/tests/smp/template/test_name.c b/FreeRTOS/Test/Target/tests/smp/template/test_name.c index 6ce7b7d4c..7a18c3df8 100644 --- a/FreeRTOS/Test/Target/tests/smp/template/test_name.c +++ b/FreeRTOS/Test/Target/tests/smp/template/test_name.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/include/proof/common.gh b/FreeRTOS/Test/VeriFast/include/proof/common.gh index 63117f7eb..019dd723b 100644 --- a/FreeRTOS/Test/VeriFast/include/proof/common.gh +++ b/FreeRTOS/Test/VeriFast/include/proof/common.gh @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/include/proof/list.h b/FreeRTOS/Test/VeriFast/include/proof/list.h index 2206c1cfd..c0c2917b1 100644 --- a/FreeRTOS/Test/VeriFast/include/proof/list.h +++ b/FreeRTOS/Test/VeriFast/include/proof/list.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/include/proof/queue.h b/FreeRTOS/Test/VeriFast/include/proof/queue.h index ce6ff1172..6b93fd66b 100644 --- a/FreeRTOS/Test/VeriFast/include/proof/queue.h +++ b/FreeRTOS/Test/VeriFast/include/proof/queue.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/include/proof/queuecontracts.h b/FreeRTOS/Test/VeriFast/include/proof/queuecontracts.h index 22d417209..d5fbfabbb 100644 --- a/FreeRTOS/Test/VeriFast/include/proof/queuecontracts.h +++ b/FreeRTOS/Test/VeriFast/include/proof/queuecontracts.h @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/list/listLIST_IS_EMPTY.c b/FreeRTOS/Test/VeriFast/list/listLIST_IS_EMPTY.c index 0dc288cb8..ce8e81745 100644 --- a/FreeRTOS/Test/VeriFast/list/listLIST_IS_EMPTY.c +++ b/FreeRTOS/Test/VeriFast/list/listLIST_IS_EMPTY.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/list/uxListRemove.c b/FreeRTOS/Test/VeriFast/list/uxListRemove.c index 3f992e465..e88b8b238 100644 --- a/FreeRTOS/Test/VeriFast/list/uxListRemove.c +++ b/FreeRTOS/Test/VeriFast/list/uxListRemove.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/list/vListInitialise.c b/FreeRTOS/Test/VeriFast/list/vListInitialise.c index 43dddb83b..e4a58380e 100644 --- a/FreeRTOS/Test/VeriFast/list/vListInitialise.c +++ b/FreeRTOS/Test/VeriFast/list/vListInitialise.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/list/vListInitialiseItem.c b/FreeRTOS/Test/VeriFast/list/vListInitialiseItem.c index ee10ec416..a9444ff76 100644 --- a/FreeRTOS/Test/VeriFast/list/vListInitialiseItem.c +++ b/FreeRTOS/Test/VeriFast/list/vListInitialiseItem.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/list/vListInsert.c b/FreeRTOS/Test/VeriFast/list/vListInsert.c index 9b1729a14..17ea638e0 100644 --- a/FreeRTOS/Test/VeriFast/list/vListInsert.c +++ b/FreeRTOS/Test/VeriFast/list/vListInsert.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/list/vListInsertEnd.c b/FreeRTOS/Test/VeriFast/list/vListInsertEnd.c index fc5a51c9e..3f5a748b9 100644 --- a/FreeRTOS/Test/VeriFast/list/vListInsertEnd.c +++ b/FreeRTOS/Test/VeriFast/list/vListInsertEnd.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/create.c b/FreeRTOS/Test/VeriFast/queue/create.c index c8522231d..f7341cebe 100644 --- a/FreeRTOS/Test/VeriFast/queue/create.c +++ b/FreeRTOS/Test/VeriFast/queue/create.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/prvCopyDataFromQueue.c b/FreeRTOS/Test/VeriFast/queue/prvCopyDataFromQueue.c index 23c7c5166..73455c570 100644 --- a/FreeRTOS/Test/VeriFast/queue/prvCopyDataFromQueue.c +++ b/FreeRTOS/Test/VeriFast/queue/prvCopyDataFromQueue.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/prvCopyDataToQueue.c b/FreeRTOS/Test/VeriFast/queue/prvCopyDataToQueue.c index 93f509907..e694a7ba7 100644 --- a/FreeRTOS/Test/VeriFast/queue/prvCopyDataToQueue.c +++ b/FreeRTOS/Test/VeriFast/queue/prvCopyDataToQueue.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/prvIsQueueEmpty.c b/FreeRTOS/Test/VeriFast/queue/prvIsQueueEmpty.c index 080e68c49..b470db596 100644 --- a/FreeRTOS/Test/VeriFast/queue/prvIsQueueEmpty.c +++ b/FreeRTOS/Test/VeriFast/queue/prvIsQueueEmpty.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/prvIsQueueFull.c b/FreeRTOS/Test/VeriFast/queue/prvIsQueueFull.c index 1a01e456a..e77167e75 100644 --- a/FreeRTOS/Test/VeriFast/queue/prvIsQueueFull.c +++ b/FreeRTOS/Test/VeriFast/queue/prvIsQueueFull.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/prvLockQueue.c b/FreeRTOS/Test/VeriFast/queue/prvLockQueue.c index a95db7afe..43b99b0ae 100644 --- a/FreeRTOS/Test/VeriFast/queue/prvLockQueue.c +++ b/FreeRTOS/Test/VeriFast/queue/prvLockQueue.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/prvUnlockQueue.c b/FreeRTOS/Test/VeriFast/queue/prvUnlockQueue.c index 0d5fc0e83..90de73ee3 100644 --- a/FreeRTOS/Test/VeriFast/queue/prvUnlockQueue.c +++ b/FreeRTOS/Test/VeriFast/queue/prvUnlockQueue.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/uxQueueMessagesWaiting.c b/FreeRTOS/Test/VeriFast/queue/uxQueueMessagesWaiting.c index 4ab6606cd..19d602f0a 100644 --- a/FreeRTOS/Test/VeriFast/queue/uxQueueMessagesWaiting.c +++ b/FreeRTOS/Test/VeriFast/queue/uxQueueMessagesWaiting.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/uxQueueSpacesAvailable.c b/FreeRTOS/Test/VeriFast/queue/uxQueueSpacesAvailable.c index 39d45741b..3fc5f5e6b 100644 --- a/FreeRTOS/Test/VeriFast/queue/uxQueueSpacesAvailable.c +++ b/FreeRTOS/Test/VeriFast/queue/uxQueueSpacesAvailable.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/vQueueDelete.c b/FreeRTOS/Test/VeriFast/queue/vQueueDelete.c index 299f47cd5..a716505e2 100644 --- a/FreeRTOS/Test/VeriFast/queue/vQueueDelete.c +++ b/FreeRTOS/Test/VeriFast/queue/vQueueDelete.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/xQueueGenericSend.c b/FreeRTOS/Test/VeriFast/queue/xQueueGenericSend.c index 78cee3e87..45da60ee1 100644 --- a/FreeRTOS/Test/VeriFast/queue/xQueueGenericSend.c +++ b/FreeRTOS/Test/VeriFast/queue/xQueueGenericSend.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/xQueueGenericSendFromISR.c b/FreeRTOS/Test/VeriFast/queue/xQueueGenericSendFromISR.c index 4865c86da..fd704ae12 100644 --- a/FreeRTOS/Test/VeriFast/queue/xQueueGenericSendFromISR.c +++ b/FreeRTOS/Test/VeriFast/queue/xQueueGenericSendFromISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/xQueueIsQueueEmptyFromISR.c b/FreeRTOS/Test/VeriFast/queue/xQueueIsQueueEmptyFromISR.c index 50d06f0fe..02ddf183c 100644 --- a/FreeRTOS/Test/VeriFast/queue/xQueueIsQueueEmptyFromISR.c +++ b/FreeRTOS/Test/VeriFast/queue/xQueueIsQueueEmptyFromISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/xQueueIsQueueFullFromISR.c b/FreeRTOS/Test/VeriFast/queue/xQueueIsQueueFullFromISR.c index 0921feba7..8218216f2 100644 --- a/FreeRTOS/Test/VeriFast/queue/xQueueIsQueueFullFromISR.c +++ b/FreeRTOS/Test/VeriFast/queue/xQueueIsQueueFullFromISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/xQueuePeek.c b/FreeRTOS/Test/VeriFast/queue/xQueuePeek.c index d3cbb6b6d..15d8fef89 100644 --- a/FreeRTOS/Test/VeriFast/queue/xQueuePeek.c +++ b/FreeRTOS/Test/VeriFast/queue/xQueuePeek.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/xQueuePeekFromISR.c b/FreeRTOS/Test/VeriFast/queue/xQueuePeekFromISR.c index 00818cc53..17bcc457c 100644 --- a/FreeRTOS/Test/VeriFast/queue/xQueuePeekFromISR.c +++ b/FreeRTOS/Test/VeriFast/queue/xQueuePeekFromISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/xQueueReceive.c b/FreeRTOS/Test/VeriFast/queue/xQueueReceive.c index eb2c52e8d..f23a7af06 100644 --- a/FreeRTOS/Test/VeriFast/queue/xQueueReceive.c +++ b/FreeRTOS/Test/VeriFast/queue/xQueueReceive.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/Test/VeriFast/queue/xQueueReceiveFromISR.c b/FreeRTOS/Test/VeriFast/queue/xQueueReceiveFromISR.c index 46f553d16..89bf686e2 100644 --- a/FreeRTOS/Test/VeriFast/queue/xQueueReceiveFromISR.c +++ b/FreeRTOS/Test/VeriFast/queue/xQueueReceiveFromISR.c @@ -1,6 +1,6 @@ /* * FreeRTOS V202212.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/FreeRTOS/links_to_doc_pages_for_the_demo_projects.url b/FreeRTOS/links_to_doc_pages_for_the_demo_projects.url index 1ae5cac2c..cfd5526f7 100644 --- a/FreeRTOS/links_to_doc_pages_for_the_demo_projects.url +++ b/FreeRTOS/links_to_doc_pages_for_the_demo_projects.url @@ -1,5 +1,5 @@ -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 -[InternetShortcut] -URL=http://www.freertos.org/a00090.html -IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/a00090.html +IDList= diff --git a/History.txt b/History.txt index 2171f0615..2decb00d2 100644 --- a/History.txt +++ b/History.txt @@ -1,2894 +1,2894 @@ -Documentation and download available at https://www.FreeRTOS.org/ - -Changes between FreeRTOS 202112.00 and FreeRTOS 202212.00 released December 2022 - - + Released LTS 2.0 versions of FreeRTOS Kernel, FreeRTOS+TCP, coreMQTT, corePKCS11, - coreHTTP, coreJSON, AWS IoT Over-the-air-Updates (OTA), AWS IoT Device Shadow, AWS IoT Jobs, - AWS IoT Device Defender, Backoff Algorithm, AWS IoT Fleet Provisioning, coreSNTP, - SigV4, and FreeRTOS Cellular Interface libraries - - FreeRTOS Kernel V10.5.1 - - FreeRTOS+TCP V3.1.0 - - coreMQTT v2.1.1 - - corePKCS11 v3.5.0 - - coreJSON v3.2.0 - - AWS IoT Over-the-air (OTA) Update v3.4.0 - - AWS IoT Device Shadow v1.3.0 - - AWS IoT Jobs v1.3.0 - - AWS IoT Device Defender v1.3.0 - - Backoff Algorithm v1.3.0 - - AWS IoT Fleet Provisioning v1.1.0 - - coreSNTP v1.2.0 - - SigV4 v1.2.0 - - FreeRTOS Cellular Interface v1.3.0 - + Updated coreMQTT Agent library to v1.2.0 to be compatible with coreMQTT v2.X.X. - + Demo Updates - - Added Visual Studio static library projects for FreeRTOS Kernel, FreeRTOS+TCP, - Logging, MbedTLS, coreHTTP, and corePKCS11 in FreeRTOS-Plus/VisualStudio_StaticProjects. - - All demos dependent on coreMQTT have been updated to be compatible with coreMQTT v2.X.X. - - All Windows Simulator projects have been updated to use new static Visual Studio projects. - + Updated MbedTLS version to 3.2.1. - -Changes between FreeRTOS 202111.00 and FreeRTOS 202112.00 released December 2021 - - + Added Fleet Provisioning library and demo showcasing the use of Fleet Provisioning library. - + Added Sigv4 library and updated HTTP S3 download demo to showcase its use. - + Added CBMC proofs for all public and private functions in the OTA Update library - + Updated mbed TLS version used by corePKCS11 to v2.28.0 - -Changes between FreeRTOS 202107.00 and FreeRTOS 202111.00 released November 2021 - - + Add Cellular library and demo showcasing use of Cellular library. - + Add demo project for [PolarFire SoC FPGA Icicle Kit](https://www.microsemi.com/existing-parts/parts/152514). - -Changes between FreeRTOS 202104.00 and FreeRTOS 202107.00 released July 2021 - - + Release coreSNTP v1.0.0, a client library for SNTP communication. - + Add demo showcasing use of coreSNTP library to setup SNTP client for - synchronizing demo system time with time servers. - + Demo Updates - - Update Device Shadow demo to use Named Shadow feature. - - -Changes between FreeRTOS 202012.00 and FreeRTOS 202104.00 released April 2021 - - + Released LTS versions of AWS IoT Device Defender, AWS IoT Jobs and - AWS IoT Over-the-air-Updates (OTA) libraries - - AWS IoT Device Defender v1.1.0 - - AWS IoT Jobs v1.1.0 - - AWS IoT Over-the-air (OTA) Update v3.0.0 - + Added new coreMQTT Agent library. - + Demo Updates - - Add basic publish-subscribe demo for coreMQTT Agent library. - - For examples of using coreMQTT Agent library to communicate with - multiple AWS IoT services from different tasks using a shared - MQTT connection, refer to https://github.com/FreeRTOS/coreMQTT-Agent-Demos - - OTA demo over MQTT - - OTA demo over HTTP - - Added custom metrics to AWS Device Defender demo. - -Changes between FreeRTOS 202011.00 and FreeRTOS 202012.00 released December 2020 - - + Includes libraries that are part of the FreeRTOS 202012.00 LTS release. - - Learn more at https:/freertos.org/lts-libraries.html - + Networking support for QEMU MPS2 - + Demo Updates - - AWS IoT Jobs Library - - AWS Device Defender - - HTTP Mutual Auth - - HTTP Plaintext - - UDP for FreeRTOS+TCP - - S3 Upload & Download - - -Changes between FreeRTOS V10.4.1 and FreeRTOS 202011.00 released November 10 2020 - - + Added new coreJSON Library. See https://www.freertos.org/json/ - + Added new coreMQTT Library. See https://www.freertos.org/mqtt/ - + Added new corePKCS11 Library. See https://www.freertos.org/pkcs11/ - + Added new AWS IoT Device Shadow Library. See - https://www.freertos.org/iot-device-shadow/ - + Updated to FreeRTOS Kernel v10.4.2. See - https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/master/History.txt - + Updated to FreeRTOS+TCP v2.3.1. See - https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/master/History.txt - + Update WolfSSL to 4.5.0 and add the WolfSSL FIPS ready demo. - + Convert most dependent libraries to Git submodules. - + Various general maintenance and improvements. - - -Changes between FreeRTOS V10.4.0 and FreeRTOS V10.4.1 released September 17 2020 - See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html - - + Fixed an incorrectly named parameter that prevented the - ulTaskNotifyTakeIndexed macro compiling, and the name space clash in the - test code that prevented this error causing test failures. - - -Changes between FreeRTOS V10.3.1 and FreeRTOS V10.4.0 released September 10 2020 - - See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html - - Major enhancements: - - + Task notifications: Prior to FreeRTOS V10.4.0 each created task had a - single direct to task notification. From FreeRTOS V10.4.0 each task has - an array of notifications. The direct to task notification API has been - extended with API functions postfixed with "Indexed" to enable the API to - operate on a task notification at any array index. See - https://www.freertos.org/RTOS-task-notifications.html for more information. - + Kernel ports that support memory protection units (MPUs): The ARMv7-M and - ARMv8-M MPU ports now support a privilege access only heap. The ARMv7-M - MPU ports now support devices that have 16 MPU regions, have the ability - to override default memory attributes for privileged code and data - regions, and have the ability to place the FreeRTOS kernel code outside of - the Flash memory. The ARMv8-M MPU ports now support tickless idle mode. - See https://www.freertos.org/FreeRTOS-MPU-memory-protection-unit.html - for more information. - - Additional noteworthy updates: - - + Code formatting is now automated to facilitate the increase in - collaborative development in Git. The auto-formated code is not identical - to the original formatting conventions. Most notably spaces are now used - in place of tabs. - + The prototypes for callback functions (those that start with "Application", - such as vApplicationStackOverflowHook()) are now in the FreeRTOS header - files, removing the need for application writers to add prototypes into - the C files in which they define the functions. - + New Renesas RXv3 port layer. - + Updates to the Synopsys ARC code, including support for EM and HS cores, - and updated BSP. - + Added new POSIX port layer that allows FreeRTOS to run on Linux hosts in - the same way the Windows port layer enables FreeRTOS to run on Windows - hosts. - + Many other minor optimisations and enhancements. For full details - see https://github.com/FreeRTOS/FreeRTOS-Kernel/commits/master - - -Changes between FreeRTOS V10.3.0 and FreeRTOS V10.3.1 released February 18 2020 - - See https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html - - + ./FreeRTOS-Labs directory was removed from this file. The libraries it - contained are now available as a separate download. - -Changes between FreeRTOS V10.2.1 and FreeRTOS V10.3.0 released February 7 2020 - - See https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html - - New and updated kernel ports: - - + Added RISC-V port for the IAR compiler. - + Update the Windows simulator port to use a synchronous object to prevent - a user reported error whereby a task continues to run for a short time - after being moved to the Blocked state. Note we were not able to - replicate the reported issue and it likely depends on your CPU model. - + Correct alignment of stack top in RISC-V port when - configISR_STACK_SIZE_WORDS is defined to a non zero value, which causes - the interrupt stack to be statically allocated. - + The RISC-V machine timer compare register can now be for any HART, whereas - previously it was always assumed FreeRTOS was running on HART 0. - + Update the sequence used to update the 64-bit machine timer - compare register on 32-bit cores to match that suggested in RISC-V - documentation. - + Added tickless low power modes into the ARM, IAR and GCC Cortex-M0 compiler - ports. - + Updated the behaviour of the ARMv7-M MPU (Memory Protection Unit) ports to - match that of the ARMv8-M ports whereby privilege escalations can only - originate from within the kernel's own memory segment. Added - configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY configuration constant. - + Update existing MPU ports to correctly disable the MPU before it is - updated. - + Added contributed port and demo application for a T-Head (formally C-SKY) - microcontroller. - - New API functions: - - + Added the vPortGetHeapStats() API function which returns information on - the heap_4 and heap_5 state. - + Added xTaskCatchUpTicks(), which corrects the tick count value after the - application code has held interrupts disabled for an extended period. - + Added xTaskNotifyValueClear() API function. - + Added uxTimerGetReloadMode() API function. - - Other miscellaneous changes: - + Change type of uxPendedTicks from UBaseType_t to TickType_t to ensure it - has the same type as variables with which it is compared to, and therefore - also renamed the variable xPendingTicks. - + Update Keil projects that use the MPU so memory regions come from linker - script (scatter file) variables instead of being hard coded. - + Added LPC51U68 Cortex-M0+ demos for GCC (MCUXpresso), Keil and IAR - compilers. - + Added CORTEX_MPU_STM32L4_Discovery_Keil_STM32Cube demo. - + Added LPC54018 MPU demo. - + Rename xTaskGetIdleRunTimeCounter() to ulTaskGetIdleRunTimeCounter(). - - -Changes between FreeRTOS V10.2.1 and FreeRTOS V10.2.0 released May 13 2019: - - + Added ARM Cortex-M23 port layer to complement the pre-existing ARM - Cortex-M33 port layer. - + The RISC-V port now automatically switches between 32-bit and 64-bit - cores. - + Introduced the portMEMORY_BARRIER macro to prevent instruction re-ordering - when GCC link time optimisation is used. - + Introduced the portDONT_DISCARD macro to the ARMv8-M ports to try and - prevent the secure side builds from removing symbols required by the - non secure side build. - + Introduced the portARCH_NAME to provide additional data to select semi- - automated build environments. - + Cortex-M33 and Cortex-M23 ports now correctly disable the MPU before - updating the MPU registers. - - + Added Nuvoton NuMaker-PFM-M2351 ARM Cortex-M23 demo. - + Added LPC55S69 ARM Cortex-M33 demo. - + Added an STM32 dual core AMP stress test demo. - - -Changes between FreeRTOS V10.1.1 and FreeRTOS V10.2.0 released February 25 2019: - - + Added GCC RISC-V MCU port with three separate demo applications. - + Included pre-existing ARM Cortex-M33 (ARMv8-M) GCC/ARMclang and IAR ports - with Keil simulator demo. - + Update the method used to detect if a timer is active. Previously the - timer was deemed to be inactive if it was not referenced from a list. - However, when a timer is updated it is temporarily removed from, then - re-added to a list, so now the timer's active status is stored separately. - + Add vTimerSetReloadMode(), xTaskGetIdleRunTimeCounter(), and - xTaskGetApplicationTaskTagFromISR() API functions. - + Updated third party Xtensa port so it is MIT licensed. - + Added configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H to the Renesas - compiler RX600v2 port to enable switching between platform.h and - iodefine.h includes within that port's port.c file. - + Removed the 'FromISR' functions from the MPU ports as ISRs run privileged - anyway. - + Added uxTaskGetStackHighWaterMark2() function to enable the return type to - be changed without breaking backward compatibility. - uxTaskGetStackHighWaterMark() returns a UBaseType_t as always, - uxTaskGetStackHighWaterMark2() returns configSTACK_DEPTH_TYPE to allow the - user to determine the return type. - + Fixed issues in memory protected ports related to different combinations - of static memory only and dynamic memory only builds. As a result the - definition of tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE became more - complex and was moved to FreeRTOS.h with a table explaining its definition. - + Added a 'get task tag from ISR' function. - + Change the method used to determine if a timer is active or not from just - seeing if it is referenced from the active timer list to storing its - active state explicitly. The change prevents the timer reporting that it - is inactive while it is being moved from one list to another. - + The pcName parameter passed into the task create functions can be NULL, - previously a name had to be provided. - + When using tickless idle, prvResetNextTaskUnblockTime() is now only called - in xTaskRemoveFromEventList() if the scheduler is not suspended. - + Introduced portHAS_STACK_OVERFLOW_CHECKING, which should be set to 1 for - FreeRTOS ports that run on architectures that have stack limit registers. - - -Changes between FreeRTOS V10.1.0 and FreeRTOS V10.1.1 released 7 September 2018 - - + Reverted a few structure name changes that broke several kernel aware - debugger plug-ins. - + Updated to the latest trace recorder code. - + Fixed some formatting in the FreeRTOS+TCP TCP/IP stack code. - + Reverted moving some variables from file to function scope as doing so - broke debug scenarios that require the static qualifier to be removed. - -Changes between FreeRTOS V10.0.1 and FreeRTOS V10.1.0 released 22 August 2018 - - FreeRTOS Kernel Changes: - - + Update lint checked MISRA compliance to use the latest MISRA standard, was - previously using the original MISRA standard. - + Updated all object handles (TaskHandle_t, QueueHandle_t, etc.) to be - unique types instead of void pointers, improving type safety. (this was - attempted some years back but had to be backed out due to bugs in some - debuggers). Note this required the pvContainer member of a ListItem_t - struct to be renamed - set configENABLE_BACKWARD_COMPATIBILITY to 1 if - this causes an issue. - + Added configUSE_POSIX_ERRNO to enable per task POSIX style errno - functionality in a more user friendly way - previously the generic thread - local storage feature was used for this purpose. - + Added Xtensa port and demo application for the XCC compiler. - + Changed the implementation of vPortEndScheduler() for the Win32 port to - simply call exit( 0 ). - + Bug fix in vPortEnableInterrupt() for the GCC Microblaze port to protect - the read modify write access to an internal Microblaze register. - + Fix minor niggles when the MPU is used with regards to prototype - differences, static struct size differences, etc. - + The usStackHighWaterMark member of the TaskStatus_t structure now has type - configSTACK_DEPTH_TYPE in place of uint16_t - that change should have been - made when the configSTACK_DEPTH_TYPE type (which gets around the previous - 16-bit limit on stack size specifications) was introduced. - + Added the xMessageBufferNextLengthBytes() API function and likewise stream - buffer equivalent. - + Introduce configMESSAGE_BUFFER_LENGTH_TYPE to allow the number of bytes - used to hold the length of a message in the message buffer to be reduced. - configMESSAGE_BUFFER_LENGTH_TYPE default to size_t, but if, for example, - messages can never be more than 255 bytes it could be set to uint8_t, - saving 3 bytes each time a message is written into the message buffer - (assuming sizeof( size_t ) is 4). - + Updated the StaticTimer_t structure to ensure it matches the size of the - Timer_t structure when the size of TaskFunction_t does not equal the size - of void *. - + Update various Xilinx demos to use 2018.1 version of the SDK tools. - + Various updates to demo tasks to maintain test coverage. - + FreeRTOS+UDP was removed in FreeRTOS V10.1.0 as it was replaced by - FreeRTOS+TCP, which was brought into the main download in FreeRTOS - V10.0.0. FreeRTOS+TCP can be configured as a UDP only stack, and - FreeRTOS+UDP does not contain the patches applied to FreeRTOS+TCP. - - FreeRTOS+TCP Changes: - - + Multiple security improvements and fixes in packet parsing routines, DNS - caching, and TCP sequence number and ID generation. - + Disable NBNS and LLMNR by default. - + Add TCP hang protection by default. - - We thank Ori Karliner of Zimperium zLabs Team for reporting these issues. - - -Changes between FreeRTOS V10.0.0 and FreeRTOS V10.0.1, released December 20 2017 - - + Fix position of "#if defined( __cplusplus )" in stream_buffer.h. - + Correct declarations of MPU_xQueuePeek() and MPU_xQueueSemaphoreTake() in - mpu_prototypes.h. - + Correct formatting in vTaskList() helper function when it prints the state - of the currently executing task. - + Introduce #error if stream_buffer.c is built without - configUSE_TASK_NOTIFICATIONS set to 1. - + Update FreeRTOS+TCP to V2.0.0 - - Improve the formatting of text that displays the available netword - interfaces when FreeRTOS+TCP is used on Windows with WinPCap. - - Introduce ipconfigSOCKET_HAS_USER_WAKE_CALLBACK option to enable a user - definable callback to execute when data arrives on a socket. - -Changes between FreeRTOS V9.0.1 and FreeRTOS V10.0.0: - - The FreeRTOS kernel is now MIT licensed: https://www.FreeRTOS.org/license - - New Features and components: - - + Stream Buffers - see https://www.FreeRTOS.org/RTOS-stream-buffer-example.html - + Message Buffers - see https://www.FreeRTOS.org//RTOS-message-buffer-example.html - + Move FreeRTOS+TCP into the main repository, along with the basic Win32 - TCP demo FreeRTOS_Plus_TCP_Minimal_Windows_Simulator. - - New ports or demos: - - + Added demo for TI SimpleLink CC3220 MCU. - + Added MPU and non MPU projects for Microchip CEC and MEC 17xx and 51xx - MCUs. - + Added CORTEX_MPU_Static_Simulator_Keil_GCC demo to test static allocation - in the MPU port. - - Fixes or enhancements: - - + Cortex-M ports push additional register prior to calling - vTaskSwitchContext to ensure 8-byte alignment is maintained. Only - important if a user defined tick hook function performs an operation that - requires 8-byte alignment. - + Optimisations to the implementation of the standard tickless idle mode on - Cortex-M devices. - + Improvements to the Win32 port including using higher priority threads. - + Ensure interrupt stack alignment on PIC32 ports. - + Updated GCC TriCore port to build with later compiler versions. - + Update mpu_wrappers.c to support static allocation. - + The uxNumberOfItems member of List_t is now volatile - solving an issue - when the IAR compiler was used with maximum optimization. - + Introduced configRECORD_STACK_HIGH_ADDRESS. When set to 1 the stack start - address is saved into each task's TCB (assuming stack grows down). - + Introduced configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H to allow user defined - functionality, and user defined initialisation, to be added to FreeRTOS's - tasks.c source file. When configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H is - set to 1 a user provided header file called freertos_task_c_additions.h - will be included at the bottom of tasks.c. Functions defined in that - header file can call freertos_tasks_c_additions_init(), which in turn - calls a macro called FREERTOS_TASKS_C_ADDITIONS_INIT(), if it is defined. - FREERTOS_TASKS_C_ADDITIONS_INIT() can be defined in FreeRTOSConfig.h. - + Introduced configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) which can be - defined by a user in FreeRTOSConfig.h. The macro is called before - assessing whether to enter tickless idle mode or not. If the macro sets - x to zero then tickless idle mode will not be entered. This allows users - to abort tickless idle mode entry before the tickless idle function is - even called - previously it was only possible to abort from within the - tickless idle function itself. - + Added configPRINTF(), which can be defined by users to allow all libraries - to use the same print formatter. - + Introduced configMAX() and configMIN() macros which default to standard - max( x, y ) and min( x, y ) macro behaviour, but can be overridden if the - application writer defines the same macros in FreeRTOSConfig.h. - + Corrected the definition of StaticTask_t in the case where - INCLUDE_xTaskAbortDelay is set to 1. - + Introduced configTIMER_SERVICE_TASK_NAME and configIDLE_TASK_NAME, both of - which can be defined to strings in FreeRTOSConfig.h to change the default - names of the timer service and idle tasks respectively. - + Only fill the stack of a newly created task with a known value if stack - checking, or high water mark checking/viewing, is in use - removing the - dependency on memset() in other cases. - + Introduced xTaskCreateRestrictedStatic() so static allocation can be used - with the MPU. - + Ensure suspended tasks cannot be unsuspended by a received task - notification. - + Fix race condition in vTaskSetTimeOutState(). - + Updated trace recorder files to the latest version. - -Changes since FreeRTOS V9.0.0: - - + Priority dis-inheritance behaviour has been enhanced in the case where a - task that attempted to take a mutex that was held by a lower priority task - timed out before it was able to obtain the mutex (causing the task that - holds the mutex to have its priority raised, then lowered again, in - accordance with the priority inheritance protocol). - + Split the overloaded xQueueGenericReceive() function into three separate - dedicated functions. - + Allow the default human readable text names given to the Idle and Timer - tasks to be overridden by defining the configIDLE_TASK_NAME and - configTIMER_SERVICE_TASK_NAME definitions respectively in FreeRTOSConfig.h. - + Introduced configINITIAL_TICK_COUNT to allow the tick count to take a - value of than than 0 when the system boots. This can be useful for - testing purposes - although setting configUSE_16_BIT_TICKS to 1 can also - be used to test frequent tick overflows. - + Ensure the Cortex-M SysTick count is cleared to zero before starting the - first task. - + Add configASSERT() into ARM Cortex-M ports to check the number of priority - bit settings. - + Clear the 'control' register before starting ARM Cortex-M4F ports in case - the FPU is used before the scheduler is started. This just saves a few - bytes on the main stack as it prevents space being left for a later save - of FPU registers. - + Added xSemaphoreGetMutexHolderFromISR(). - + Corrected use of portNVIC_PENDSVSET to portNVIC_PENDSVSET_BIT in MPU ports. - + Introduced configSTACK_DEPTH_TYPE to allow users to change the type used - to specify the stack size when using xTaskCreate(). For historic reasons, - when FreeRTOS was only used on small MCUs, the type was set to uint16_t, - but that can be too restrictive when FreeRTOS is used on larger - processors. configSTACK_DEPTH_TYPE defaults to uint16_t. - xTaskCreateStatic(), being a newer function, used a uint32_t. - + Increase the priority of the Windows threads used by the Win32 port. As - all the threads run on the same core, and the threads run with very high - priority, there is a risk that the host will become unresponsive, so also - prevent the Windows port executing on single core hosts. - -Changes between FreeRTOS V9.0.0 and FreeRTOS V9.0.0rc2 released May 25 2016: - - See https://www.FreeRTOS.org/FreeRTOS-V9.html - - RTOS kernel updates: - - + The prototype of the new xTaskCreateStatic() API function was modified to - remove a parameter and improve compatibility with other new - "CreateStatic()" API functions. The stack size parameter in - xTaskCreateStatic() is now uint32_t, which changes the prototype of the - callback functions. See the following URL: - https://www.FreeRTOS.org/xTaskCreateStatic.html - + GCC ARM Cortex-A port: Introduced the configUSE_TASK_FPU_SUPPORT - constant. When configUSE_TASK_FPU_SUPPORT is set to 2 every task is - automatically given a floating point (FPU) context. - + GCC ARM Cortex-A port: It is now possible to automatically save and - restore all floating point (FPU) registers on entry to each potentially - nested interrupt by defining vApplicationFPUSafeIRQHandler() instead of - vApplicationIRQHandler(). - + All ARM Cortex-M3/4F/7 ports: Clear the least significant bit of the task - entry address placed onto the stack of a task when the task is created for - strict compliance with the ARM Cortex-M3/4/7 architecture documentation - (no noticeable effect unless using the QMEU emulator). - + Added GCC and Keil ARM Cortex-M4F MPU ports - previously the MPU was only - supported on ARM Cortex-M3. - + ARM Cortex-M3/4F MPU ports: Update to fully support the FreeRTOS V9.0.0 - API (other than static object creation) and added the - FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC demo application to - demonstrate how to use the updated MPU port. - + All ARM Cortex-M3/4F/7 ports: Add additional barrier instructions to the - default low power tickless implementation. - + All ARM Cortex-M0 ports: Prevent an item being left on the stack of the - first task that executes. - + Win32 ports: Reduce the amount of stack used and change the way Windows - threads are deleted to increase the maximum execution time. - + Add an ARM Cortex-M4F port for the MikroC compiler. Ensure to read the - documentation page for this port before use. - + MPS430X IAR port: Update to be compatible with the latest EW430 tools - release. - + IAR32 GCC port: Correct vPortExitCritical() when - configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY. - + For consistency vTaskGetTaskInfo() now has the alias vTaskGetInfo(), - xTaskGetTaskHandle() now has the alias xTaskGetHandle() and - pcQueueGetQueueName() now has an alias pcQueueGetName(). - + Fix various errors in comments and compiler warnings. - - Demo application updates: - - + Update Atmel Studio projects to use Atmel Studio 7. - + Update Xilinx SDK projects to use the 2016.1 version of the SDK. - + Remove dependency on legacy IO libraries from the PIC32 demos. - + Move the Xilinx UltraScale Cortex-R5 demo into the main distribution. - + Update the MSP432 libraries to the latest version. - + Add Microchip CEC1302 (ARM Cortex-M4F) demos for GCC, Keil and MikroC - compilers. - + Move the Atmel SAMA5D2 demo into the main distribution. - -Changes between FreeRTOS V9.0.0rc1 and FreeRTOS V9.0.0rc2 (release candidate 2) -released March 30 2016: - - NOTE - See https://www.FreeRTOS.org/FreeRTOS-V9.html for details - - + The functions that create RTOS objects using static memory allocation have - been simplified and will not revert to using dynamic allocation if a - buffer is passed into a function as NULL. - + Introduced the configSUPPORT_DYNAMIC_ALLOCATION configuration constant to - allow a FreeRTOS application to be built without a heap even being being - defined. The Win32 example located in the - /FreeRTOS/demo/WIN32-MSVC-Static-Allocation-Only directory is provided as - a reference for projects that do not include a FreeRTOS heap. - + Minor run-time optimisations. - + Two new low power tickless implementations that target Silicon Labs EFM32 - microcontrollers. - + Addition of the xTimerGetPeriod() and xTimerGetExpireTime() API functions. - -Changes between FreeRTOS V8.2.3 and FreeRTOS V9.0.0rc1 (release candidate 1) -released February 19 2016: - - RTOS Kernel Updates: - - + Major new feature - tasks, semaphores, queues, timers and event groups can - now be created using statically allocated memory, so without any calls to - pvPortMalloc(). - + Major new features - Added the xTaskAbortDelay() API function which allows - one task to force another task to immediately leave the Blocked state, - even if the event the blocked task is waiting for has not occurred, or the - blocked task's timeout has not expired. - + Updates necessary to allow FreeRTOS to run on 64-bit architectures. - + Added vApplicationDaemonTaskStartupHook() which executes when the RTOS - daemon task (which used to be called the timer service task) starts - running. This is useful if the application includes initialisation code - that would benefit from executing after the scheduler has been started. - + Added the xTaskGetTaskHandle() API function, which obtains a task handle - from the task's name. xTaskGetTaskHandle() uses multiple string compare - operations, so it is recommended that it is called only once per task. - The handle returned by xTaskGetTaskHandle() can then be stored locally for - later re-use. - + Added the pcQueueGetQueueName() API function, which obtains the name of - a queue from the queue's handle. - + Tickless idling (for low power applications) can now also be used when - configUSE_PREEMPTION is 0. - + If one task deletes another task, then the stack and TCB of the deleted - task is now freed immediately. If a task deletes itself, then the stack - and TCB of the deleted task are freed by the Idle task as before. - + If a task notification is used to unblock a task from an ISR, but the - xHigherPriorityTaskWoken parameter is not used, then pend a context switch - that will then occur during the next tick interrupt. - + Heap_1.c and Heap_2.c now use the configAPPLICATION_ALLOCATED_HEAP - settings, which previously was only used by heap_4.c. - configAPPLICATION_ALLOCATED_HEAP allows the application writer to declare - the array that will be used as the FreeRTOS heap, and in-so-doing, place - the heap at a specific memory location. - + TaskStatus_t structures are used to obtain details of a task. - TaskStatus_t now includes the bae address of the task's stack. - + Added the vTaskGetTaskInfo() API function, which returns a TaskStatus_t - structure that contains information about a single task. Previously this - information could only be obtained for all the tasks at once, as an array - of TaskStatus_t structures. - + Added the uxSemaphoreGetCount() API function. - + Replicate previous Cortex-M4F and Cortex-M7 optimisations in some - Cortex-M3 port layers. - - Demo Application Updates: - - Further demo applications will be added prior to the final FreeRTOS V9 - release. - - + Updated SAM4L Atmel Studio project to use Atmel Studio 7. - + Added ARM Cortex-A53 64-bit port. - + Added a port and demo for the ARM Cortex-A53 64-bit cores on the Xilinx - Ultrascale MPSoC. - + Added Cortex-M7 SAME70 GCC demo. - + Added EFM32 Giant and Wonder Gecko demos. - - -Changes between V8.2.2 and V8.2.3 released October 16, 2015 - - RTOS kernel updates: - - + Fix bug identified in a modification made in V8.2.2 to the software timer - code that allows tickless low power applications to sleep indefinitely - when software timers are used. - + Simplify and improve efficiency of stack overflow checking. - + Add xTaskNotifyStateClear() API function. - + New IAR and GCC Cortex-R ports for microprocessors that do not use an ARM - generic interrupt controller (GIC). - + New PIC32MEC14xx port. - + Add support for PIC32MZ EF parts (with floating point) into the PIC32MZ - port. - + Zynq7000 port layer now declares the functions that setup and clear the - tick interrupt as weak symbols so they can be overridden by the - application, and uses a global XScuGic object so the same object can be - used by the application code. - + Introduced configUSE_TASK_FPU_SUPPORT, although the PIC32MZ EF port is - currently the only port that uses it. - + Updates to RL78 and 78K0 IAR port layers to improve support for - combinations of memory models. - + Minor updates to heap_5.c to remove compiler warnings generated by some - compilers. - + License simplifications. See /FreeRTOS/License/license.txt in the - official distribution. - - FreeRTOS+ updates: - - + Update directory names to use WolfSSL instead of CyaSSL, inline with - WolfSSL's re-branding. - + Update to latest WolfSSL code. - + Update to latest FreeRTOS+Trace recorder code. - + Add in the FreeRTOS+Trace recorder library required for streaming trace. - - Demo application changes: - - + Add demo applications for Renesas RZ/T (Cortex-R), PIC32MZ EF (PIC32 with - floating point hardware), PIC32MEC14xx, RX71M, RX113 and RX231. - + General tidy up of spelling and compiler warnings. - - -Changes between V8.2.1 and V8.2.2 released August 12, 2015 - - RTOS kernel updates: - - + Added Intel IA32/x86 32-bit port. - + General maintenance. - + PRIVILEGED_FUNCTION and PRIVILEGED_DATA macros, which are used in memory - protected systems, have been added to the newer event group and software - timer functions. - + Add the errno definitions used by FreeRTOS+ components into projdefs.h. - + Remove the restriction that prevented tick-less idle implementations - waiting indefinitely when software timers were used in the same - application. - + Introduce xTaskNotifyAndQueryFromISR() as the interrupt safe version of - xTaskNotifyAndQuery(). - + Add additional NOPs to the MSP430X port layers to ensure strict compliance - with the hardware documentation. - + Microblaze port: Added option for port optimised task selection. - + Microblaze port: Previously tasks inherited the exception enable state - at the time the task was created. Now all tasks are created with - exceptions enabled if the Microblaze design supports exceptions. - + Windows port: Add additional safe guards to ensure the correct start up - sequence and thread switching timing. - + Windows port: Improve the implementation of the port optimised task - selection assembly code. - + Update heap_4 and heap_5 to allow use on 64-bit processors. - + Simplify the code that creates a queue. - + General improved tick-less idle behaviour. - + Ensure none of the variables in the common kernel files are initialised to - anything other than zero. - + Correct calculation of xHeapStructSize in heap_4 and heap_5. - - Demo application updates: - - + Added demo project for the new IA32/x86 port that targets the Galileo - hardware. - + Added MSP430FR5969 demos (previously provided as a separate download). - + Added FreeRTOS BSP repository for automatic creation of FreeRTOS - applications in the Xilinx SDK. - + Added Atmel Studio / GCC project for the SAMV71 (ARM Cortex-M7) - + Update Xilinx SDK projects to use version 2015.2 of the SDK. - + Remove Microblaze demos that were using obsolete tools. - + Add MSP43FR5969 IAR and CCS demos. - - FreeRTOS+ Updates: - - + Updated FreeRTOS+Trace recorder library, which requires an update to the - FreeRTOS+Trace application. - + Added Reliance Edge source code and demo application. Reliance edge is - a fail safe transactional file system ideal for applications that require - file storage, and especially when high reliability is essential. - + Introduce configAPPLICATION_PROVIDES_cOutputBuffer to allow FreeRTOS+CLI - users to place the output buffer at a fixed memory address. - + Improve the NetworkInterface.c file provided for the Windows port of - FreeRTOS+UDP. - -Changes between V8.2.0 and V8.2.1 released 24th March 2015. - - RTOS kernel updates: - - + Added user definable and flexible thread local storage facility. - + Added vTimerSetTimerID() API function to complement the pvTimerGetTimerID() - function to allow the timer's ID to be used as timer local storage. - + Fixed a potential issue related to the use of queue sets from an ISR. - + Some updates to the Xilinx Microblaze GCC port. - + Added ARM Cortex-M4F port for Texas Instruments Code Composer Studio. - + Added ARM Cortex-M7 r0p1 port layer for IAR, GCC and Keil which contains a - minor errata work around. All other ARM Cortex-M7 core revisions should - use the ARM Cortex-M4F port. - + Exclude the whole of croutine.c if configUSE_CO_ROUTINES is set to 0. - + Change some data types from uint32_t to size_t in preparation for 64-bit - Windows port. - + Update the PIC32 port to remove deprecation warnings output by the latest - XC32 compilers. - + Fix bug when xQueueOverwrite() and xQueueOverwrite() from ISR are used to - overwrite items in two queues that are part of the same set. - - Demo application updates: - - + Added demo application for TI's ARM Cortex-M4F based MSP432 - microcontroller using IAR, Keil and CCS compilers. - + Added demo application for STM32F ARM Cortex-M7 based microcontroller - using IAR and Keil. - + Added demo application for Atmel SAMV71 ARM Cortex-M7 based - microcontroller using IAR and Keil. - + Added Microblaze demo that uses the 2014.4 version of the Xilinx SDK and - runs on the KC705 evaluation board (Kintex FPGA). - -Changes between V8.1.2 and V8.2.0 released 16th January 2015 - - Changes between release candidate 1 and the official release are restricted - to maintenance only. - - Significant RTOS kernel updates: - - + MAJOR NEW FEATURE! Task notifications. Please see the following URL for - details: https://www.FreeRTOS.org/RTOS-task-notifications.html - + NEW HEADER FILE REQUIRED! Obsolete definitions have been separated into - a new header file called FreeRTOS/Source/include/deprecated_definitions.h. - This header file must be present to build. Note some of the obsolete - definitions are still used by very old demo application projects. - - Other RTOS kernel updates: - - + Made xSemaphoreGiveFromISR() a function rather than a macro that calls - xQueueGenericSendFromISR(). This allows for major performance - enhancements at the expense of some additional code size if both functions - are used in the same application. NOTE: In most uses cases such use of - a semaphore can now be replaced with a task notification which is smaller - and faster still. - + The TCB is now always allocated such that the task's stack grows away from - the TCB (improves debugging of stack overflows as the overflow will not - overwrite the task's name). - + GCC, IAR and Keil Cortex-M4F ports now use more inlining (performance - enhancements at the cost of a little additional code space). - + Queues are now allocated with a single call to pvPortMalloc() which - allocates both the queue structure and the queue storage area. - + Introduced a new critical section macro for reading the tick count that - defines away to nothing in cases where the width of the tick allows the - tick count to be read atomically (performance benefits - especially when - optimisation is on). - + Introduced configAPPLICATION_ALLOCATED_HEAP in heap_4.c to allow the - application writer to provide their own heap array - and in so doing - control the location of the heap. - + Introduced configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES which, when set, will - include known values in both list and list item structures. The values - are intended to assist debugging. If the values get overwritten then it - is likely application code has written over RAM used by the kernel. - + configASSERT()s in all Cortex-M ports used to test the lowest 5 bits of - the interrupt control register to detect taskENTER_CRITICAL() being called - from an interrupt. This has been changed to test all 8 bits. - + Introduced uxTaskPriorityGetFromISR(). - + Microblze V8 port now tests XPAR_MICROBLAZE_0_USE_FPU for inequality to 0 - rather than equality to 1, and 2 and 3 are also valid values. - + Cortex-A5 GIC-less port no longer passes the address of the interrupting - peripheral into the interrupt handler. - + Fix an issue in FreeRTOS-MPU where an attempt was made to free the stack - belonging to a task when the task was deleted, even when the stack was - allocated statically. - + Utility (helper) functions that format task statistic information into - human readable tables now pad task names with spaces to ensure columns - line up correctly even where task name lengths vary greatly. - + Update FreeRTOS+Trace recorder library to version 2.7.0. - - Demo application updates: - - + Added two new standard demo task sets: IntSemTest and TaskNotify. - + Added port and demo application for Atmel SAMA5D4 Cortex-A5 MPU. - + Added demo application for Altera Cyclone V Cortex-A9 MPU. - + Updated Zynq demo to use version 2014.4 of Xilinx's SDK and added in - demo tasks for new RTOS features. - + Updated Atmel SAM4E and SAM4S demos to include a lot of additional test - and demo tasks. - + Fixed a corner case issue in Atmel SAM4L low power tickless - implementation, and added button interrupt handling. - + Make the interrupt queue tests more tolerant to heave CPU loads. - + Updated MSVC FreeRTOS simulator demo to include the latest standard test - and demo tasks. - + Updated MingW/Eclipse FreeRTOS simulator demo to match the FreeRTOS MSVC - simulator demo. - + Updated all demos that use FreeRTOS+Trace to work with the latest trace - recorder code. - - -Changes between V8.1.1 and V8.1.2 released September 2nd 2014 - - Move the defaulting of configUSE_PORT_OPTIMISED_TASK_SELECTION into the - individual port layers where necessary so it does not affect ports that do - not support the definition. - -Changes between V8.1.0 and V8.1.1 released August 29th 2014 - - By popular requests - a minor patch to V8.1.0 to re-instate the ability to - give a mutex type semaphore (with priority inheritance) from an interrupt - handler. - -Changes between V8.0.1 and V8.1.0 released August 26th 2014 - - FreeRTOS scheduler, kernel, demo and test updates: - - + Improved the priority inheritance algorithms to assist integration with - off the shelf middleware that may hold multiple mutexes simultaneously. - + Introduce heap_5.c, which is similar to heap_4.c but allows the heap to - span multiple non-contiguous memory regions. - + Updated all Cortex-A9 ports to help trap a couple of common usage errors - - the first being when a task incorrectly attempts to exit its implementing - function and the second being when a non interrupt safe API function is - called from an interrupt. - + Update all Cortex-A9 ports to remove obsolete mode switches prior to - restoring a task context. - + configUSE_PORT_OPTIMISED_TASK_SELECTION now defaults to 1 instead of 0. - + Update all Cortex-M3/4F ports to trap a non interrupt safe API function - being called from an interrupt handler. - + Simplify the alignment checks in heap_4.c. - + Update the MSVC Windows simulator demo to use heap_5.c in place of - heap_4.c to ensure end users have an example to refer to. - + Updated standard demo test code to test the new priority inheritance - algorithms. - + Updated the standard demo tasks to make use of stdint and the FreeRTOS - specific typedefs that were introduced in FreeRTOS V8.0.0. - + Introduce the pdMS_TO_TICKS() macro as a more user friendly and intuitive - alternative to pdTICKS_PER_MS - both of which can be used to convert a - time specified in milliseconds to a time specified in RTOS ticks. - + Fix a bug in the Tasking compiler's Cortex-M port that resulted in an - incorrect value being written to the basepri register. This only effects - users of the Tasking compiler. - + Update the Zynq demo to use version 2014.2 of the SDK and add in an lwIP - example that demonstrates lwIP being used with both its raw and sockets - interfaces. - + Updated the CCS Cortex-R4 port to enable it to be built with the latest - CCS compiler. - - New ports and demo applications: - - + Two Renesas RX64M ports (RXv2 core) and demos introduced, one for the GCC - compiler and one for the Renesas compiler. Both demos use e2 studio. - + Generic IAR Cortex-A5 port (without any reliance on a GIC) introduced. - The new port is demonstrated on an Atmel SAMA5D3 XPlained board. - - FreeRTOS+ component updates: - - + Update CyaSSL to the latest version. - + Updated the FreeRTOS+ components supplied directly by Real Time Engineers - Ltd. to make use of stdint and the FreeRTOS specific typedefs that were - introduced in FreeRTOS V8.0.0. - + Rework and simplify the FreeRTOS+FAT SL RAM disk driver. - - Miscellaneous updates and maintenance: - - + Update the IAR and DS-5/ARM RZ demos to target the official RZ RSK - hardware in place of the previously targeted Renesas internal (not - publicly available) hardware. - + Various other maintenance tasks. - - -Changes between V8.0.0 and V8.0.1 released 2nd May 2014 - - + Minor fixes to the event group functionality that was released in V8.0.0. - The 'clear bits from ISR' functionality is now implemented using a - deferred interrupt callback instead of a function, and the 'wait bits' and - 'task sync' functions now correctly clear internal control bits before - returning a value in every possible path through the respective functions. - + Ensure the updating of internal control data is protected by a critical - section after a task is deleted or suspended. - + Minor fixes to FreeRTOS+FAT SL - namely seeking beyond the end of a file - when the offset was not a multiple of the sector size. - + Ensure Cortex-A9 system registers are only ever accessed as 32-bit values, - even when only the lest significant byte of the register is implemented. - - Other updates: - - + Updated the XMC4200 IAR project so it links with version 7.x of the IAR - tools. - + Add RL78L1C demo. - + Add pcTimerGetName() API function. - + Call _reclaim_reent() when a task is deleted if configUSE_NEWLIB_REENTRANT - is defined. - -Changes between V7.6.0 and V8.0.0 released 19th Feb 2014 - - https://www.FreeRTOS.org/upgrading-to-FreeRTOS-V8.html - - FreeRTOS V8.x.x is a drop-in compatible replacement for FreeRTOS V7.x.x, - although a change to the type used to reference character strings may result - in application code generating a few (easily clearable) compiler warnings - after the upgrade, and an updated typedef naming convention means use of the - old typedef names is now discouraged. - See https://www.FreeRTOS.org/upgrading-to-FreeRTOS-V8.html for full - information. - - New features and functionality: - - + Event groups - see https://www.FreeRTOS.org/FreeRTOS-Event-Groups.html - + Centralised deferred interrupt processing - see - https://www.FreeRTOS.org/xTimerPendFunctionCallFromISR.html - - Other updates: - - + Previously, when a task left the Blocked state, a context switch was - performed if the priority of the unblocked task was greater than or equal - to the priority of the Running task. Now a context switch is only - performed if the priority of the unblocked task is greater than the - priority of the Running task. - + New low power tickless demonstration project that targets the ST STM32L - microcontroller - see - https://www.FreeRTOS.org/STM32L-discovery-low-power-tickless-RTOS-demo.html - + Add xPortGetMinimumEverFreeHeapSize() to heap_4.c. - + Small change to the tickless low power implementation on the SAM4L to - ensure the alarm value (compare match value) cannot be set to zero when a - tickless period is exited due to an interrupt originating from a source - other than the RTOS tick. - + Update the GCC/Eclipse Win32 simulator demo to make better use of Eclipse - resource filters and match the functionality of the MSVC equivalent. - + xTaskIsTaskSuspended() is no longer a public function. Use - eTaskGetState() in its place. - + Improved trace macros, including tracing of heap usage. - + Remove one level of indirection when accepting interrupts on the PIC32MZ. - + Add Cortex-A9 GCC port layer. - + Add Xilinx Zynq demo application. - - -Changes between V7.5.3 and V7.6.0 released 18th November 2013 - - V7.6.0 changes some behaviour when the co-operative scheduler is used (when - configUSE_PREEMPTION is set to 0). It is important to note that the - behaviour of the pre-emptive scheduler is unchanged - the following - description only applies when configUSE_PREEMPTION is set to 0: - - WHEN configUSE_PREEMPTION IS SET TO 0 (which is in a small minority of - cases) a context switch will now only occur when a task places itself into - the Blocked state, or explicitly calls taskYIELD(). This differs from - previous versions, where a context switch would also occur when implicitly - moving a higher priority task out of the Blocked state. For example, - previously, WHEN PREEMPTION WAS TURNED OFF, if task A unblocks task B by - writing to a queue, then the scheduler would switch to the higher priority - task. Now, WHEN PREEMPTION IS TURNED OFF, if task A unblocks task B by - writing to a queue, task B will not start running until task A enters the - Blocked state or task A calls taskYIELD(). [If configUSE_PREEMPTION is not - set to 0, so the normal pre-emptive scheduler is being used, then task B - will start running immediately that it is moved out of the Blocked state]. - - Other changes: - - + Added a port layer and a demo project for the new PIC32MZ architecture. - + Update the PIC32MX port layer to re-introduce some ehb instructions that - were previously removed, add the ability to catch interrupt stack - overflows (previously only task stack overflows were trapped), and also - add the ability to catch an application task incorrectly attempting to - return from its implementing function. - + Make dramatic improvements to the performance of the Win32 simulator port - layer. - + Ensure tasks that are blocked indefinitely report their state as Blocked - instead of Suspended. - + Slight improvement to the Cortex-M4F port layers where previously one - register was inadvertently being saved twice. - + Introduce the xSemaphoreCreateBinary() API function to ensure consistency - in the semantics of how each semaphore type is created. It is no longer - recommended to use vSemaphoreCreateBinary() (the version prefixed with a - 'v'), although it will remain in the code for backward compatibility. - + Update the Cortex-M0 port layers to allow the scheduler to be started - without using the SVC handler. - + Added a build configuration to the PIC32MX MPLAB X demo project that - targets the PIC32 USB II starter kit. Previously all the build - configurations required the Explorer 16 hardware. - + Some of the standard demo tasks have been updated to ensure they execute - correctly with the updated co-operative scheduling behaviour. - + Added comprehensive demo for the Atmel SAM4E, including use of - FreeRTOS+UDP, FreeRTOS+FAT SL and FreeRTOS+CLI. - - FreeRTOS+ Changes: - - + Minor maintenance on FreeRTOS+UDP. - -Changes between V7.5.2 and V7.5.3 released October 14 2013 - - Kernel changes: - - + Prior to V7.5.x yields requested from the tick hook would occur in the - same tick interrupt - revert to that original behaviour. - + New API function uxQueueSpacesAvailable(). - + Introduced the prvTaskExitError() function to Cortex-M0, Cortex-M3/4 - and Cortex-M4F ports. prvTaskExitError() is used to trap tasks that - attempt to return from their implementing functions (tasks should call - vTaskDelete( NULL ); if they want to exit). - + The Cortex-M0 version of portSET_INTERRUPT_MASK_FROM_ISR and - portCLEAR_INTERRUPT_MASK_FROM_ISR are now fully nestable. - + Improved behaviour and robustness of the default Cortex-M tickless idle - behaviour. - + Add workaround for silicon errata PMU_CM001 in Infineon XMC4000 devices to - all Cortex-M4F ports. - + Add Cortex-M0 port for Keil. - + Updated Cortus port. - + Ensure _impure_ptr is initialised before the scheduler is started. - Previously it was not set until the first context switch. - - FreeRTOS+ changes: - - + Update FreeRTOS+UDP to V1.0.1 - including direct integration of the - FreeRTOS+Nabto task, improvements to the DHCP behaviour, and a correction - to the test that prevents the network event hook being called on the first - network down event. The FreeRTOS+UDP change history is maintained - separately. - + Correct the __NVIC_PRIO_BITS setting in the LPC18xx.h header files - provided in the NXP CMSIS library, then update the interrupts used by the - LPC18xx demos accordingly. - + Replace double quotes (") with single quotes (') in FreeRTOS+CLI help - strings to ensure the strings can be used with the JSON descriptions used - in the FreeRTOS+Nabto demos. - - Demo and miscellaneous changes: - - + Added demo for the Atmel SAMD20 Cortex-M0+. The demo includes - FreeRTOS+CLI - + Added a demo for the Infineon Cortex-M0 that can be built with the IAR - Keil and GCC tools. - + Updated the Infineon XMC4000 demos for IAR, Keil, GCC and Tasking tools, - with additional build configurations to directly support the XMC4200 and - XMC4400 devices, in addition to the previously supported XMC4500. - + Updated the demo application. - + Added additional trace macros traceMALLOC and traceFREE to track heap - usage. - -Changes between V7.5.0 and V7.5.2 released July 24 2013 - - V7.5.2 makes the new Cortex-M vPortCheckInterruptPriority() function - compatible with the STM32 standard peripheral driver library, and adds - an extra critical section to the default low power tickless mode - implementation. Only users of the STM32 peripheral library or the default - tickless implementation need update from version 7.5.0. - -Changes between V7.4.2 and V7.5.0 released July 19 2013 - - V7.5.0 is a major upgrade that includes multiple scheduling and efficiency - improvements, and some new API functions. - - Compatibility information for FreeRTOS users: - FreeRTOS V7.5.0 is backward compatible with FreeRTOS V7.4.0 with one - exception; the vTaskList() and vTaskGetRunTimeStats() functions are now - considered legacy, having been replaced by the single uxTaskGetSystemState() - function. configUSE_STATS_FORMATTING_FUNCTIONS must be set to 1 in - FreeRTOSConfig.h for vTaskList() and vTaskGetRunTimeStats() to be - available. - - Compatibility information for FreeRTOS port writers: - vTaskIncrementTick() is now called xTaskIncrementTick() (because it now - returns a value). - - Headline changes: - - + Multiple scheduling and efficiency improvements. - + Core kernel files now pass PC-Lint V8 static checking without outputting - any warnings (information on the test conditions will follow). - - New API functions: - - + uxTaskGetSystemState() https://www.FreeRTOS.org/uxTaskGetSystemState.html - + xQueueOverwrite() https://www.FreeRTOS.org/xQueueOverwrite.html - + xQueueOverwriteFromISR() - + xQueuePeekFromISR() - - The following ports and demos, which were previously available separately, - are now incorporated into the main FreeRTOS zip file download: - - + ARM Cortex-A9 IAR - + ARM Cortex-A9 ARM compiler - + Renesas RZ - + Microsemi SmartFusion2 - - New FreeRTOSConfig.h settings - http://shop.freertos.org/FreeRTOS_API_and_Configuration_Reference_s/1822.htm - - + configUSE_TIME_SLICING - + configUSE_NEWLIB_REENTRANT - + configUSE_STATS_FORMATTING_FUNCTIONS - + configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS - - Other changes: - - + (MPU port only) The configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS - options provides a mechanism that allows application writers to execute - certain functions in privileged mode even when a task is running in user - mode. - + Ports that support interrupt nesting now include a configASSERT() that - will trigger if an interrupt safe FreeRTOS function is called from an - interrupt that has a priority designated as above the maximum system/API - call interrupt priority. - + The included FreeRTOS+Trace recorder code has been updated to the latest - version, and the demo applications that use the trace recorder code have - been updated accordingly. - + The FreeRTOS Windows Simulator (MSVC version only) has been updated to - include a new basic 'blinky' build option in addition to the original - comprehensive build option. - + Improve RAM usage efficiency of heap_4.c and heap_2.c. - + Prevent heap_4.c from attempting to free memory blocks that were not - allocated by heap_4.c, or have already been freed. - + As FreeRTOS now comes with FreeRTOS+FAT SL (donated by HCC) the Chan FATfs - files have been removed from FreeRTOS/Demo/Common. - + Fix build error when R4 port is build in co-operative mode. - + Multiple port and demo application maintenance activities. - -Changes between V7.4.1 and V7.4.2 released May 1 2013 - - NOTE: There are no changes in the FreeRTOS kernel between V7.4.1 and V7.4.2 - - + Added FreeRTOS+FAT SL source code and demo project. The demo project - runs in the FreeRTOS Windows simulator for easy and hardware independent - experimentation and evaluation. See https://www.FreeRTOS.org/fat_sl - -Changes between V7.4.0 and V7.4.1 released April 18 2013 - - + To ensure strict conformance with the spec and ensure compatibility with - future chips data and instruction barrier instructions have been added to - the yield macros of Cortex-M and Cortex-R port layers. For efficiency - the Cortex-M port layer "yield" and "yield" from ISR are now implemented - separately as the barrier instructions are not required in the ISR case. - + Added FreeRTOS+UDP into main download. - + Reorganised the FreeRTOS+ directory so it now matches the FreeRTOS - directory with Source and Demo subdirectories. - + Implemented the Berkeley sockets select() function in FreeRTOS+UDP. - + Changed (unsigned) casting in calls to standard library functions with - (size_t) casting. - + Added the Atmel SAM4L and Renesas RX100 demos that demonstrates the - tickless (tick suppression) low power FreeRTOS features. - + Add a new RL78 IAR demo that targets numerous new RL78 chips and - evaluation boards. - + Adjusted stack alignment on RX200 ports to ensure an assert was not - falsely triggered when configASSERT() is defined. - + Updated the Cortex_M4F_Infineon_XMC4500_IAR demo to build with the latest - version of EWARM. - + Corrected header comments in the het.c and het.h files (RM48/TMS570 demo). - - -Changes between V7.3.0 and V7.4.0 released February 20 2013 - - + New feature: Queue sets. See: - https://www.FreeRTOS.org/Pend-on-multiple-rtos-objects.html - + Overhauled the default tickless idle mode implementation provided with the - ARM Cortex-M3 port layers. - + Enhanced tickless support in the core kernel code with the introduction of - the configEXPECTED_IDLE_TIME_BEFORE_SLEEP macro and the - eTaskConfirmSleepModeStatus() function. - + Added the QueueSet.c common demo/test file. Several demo applications - have been updated to use the new demo/test tasks. - + Removed reliance on the PLIB libraries from the MPLAB PIC32 port layer and - demo applications. - + Added the FreeRTOS+Trace recorder code to the MSVC Win32 demo. - + Renamed eTaskStateGet() to eTaskGetState() for consistency, and added a - pre-processor macro for backward compatibility with the previous name. - + Updated functions implemented in the core queue.c source file to allow - queue.h to be included from the .c file directly (this prevents compiler - warnings that were generated by some compilers). - + Updated the CCS Cortex-R4 port layer to replace the CLZ assembler function - with the CLZ compiler intrinsic that is provided by the latest versions of - the CCS ARM compiler. - + Updated all heap_x.c implementations to replace the structure that was - used to ensure the start of the heap was aligned with a more portable - direct C code implementation. - + Added support for PIC24 devices that include EDS. - + Minor optimisations to the PIC32 port layer. - + Minor changes to tasks.c that allow the state viewer plug-ins to display - additional information. - + Bug fix: Update prvProcessReceivedCommands() in timers.c to remove an - issue that could occur if the priority of the timer daemon task was set - below the priority of tasks that used timer services. - + Update the FreeRTOS+Trace recorder code to the latest version. - -Changes between V7.2.0 and V7.3.0 released October 31 2012 - - + Added ability to override the default scheduler task selection mechanism - with implementations that make use of architecture specific instructions. - + Added ability to suppress tick interrupts during idle time, and in so - doing, provide the ability to make use of architecture specific low power - functionality. - + Added the portSUPPRESS_TICKS_AND_SLEEP() macro and vTaskStepTick() helper - function. - + Added the configSYSTICK_CLOCK_HZ configuration constant. - + Reworked the Cortex-M3 and Cortex-M4F port layers for GCC, Keil and IAR to - directly support basic power saving functionality. - + Added hooks to allow basic power saving to be augmented in the application - by making use of chip specific functionality. - + Minor change to allow mutex type semaphores to be used from interrupts - (which would not be a normal usage model for a mutex). - + Change the behaviour of the interrupt safe interrupt mask save and restore - macros in the Cortex-M ports. The save macro now returns the previous - mask value. The restore macro now uses the previous mask value. These - changes are not necessary for the kernel's own implementation, and are - made purely because the macros were being used by application writers. - + Added eTaskStateGet() API function. - + Added port specific optimisations to the PIC32 port layer, and updated the - PIC32 demo applications to make use of this new feature. - + Added port specific optimisations to the Win32 simulator port. - + Added new ports and demo applications for the TI Hercules RM48 and TMS570 - safety microcontrollers. - + Added SAM3 demos targeting the ATSAM3S-EK2 and ATSAM3X-EK evaluation - boards. - + Updated the PIC32 MPLAB X project to manually set the compiler include - paths instead of using the IDE entry box following reports that the - include paths were somehow being deleted. - + Improved character handling in FreeRTOS+CLI. - -Changes between V7.1.1 and V7.2.0 released 14 August 2012 - - FreeRTOS V7.2.0 is backward compatible with FreeRTOS V7.1.2. - - + Added a FreeRTOS+ sub-directory. The directory contains some FreeRTOS+ - source code, and example projects that use the FreeRTOS Win32 simulator. - + Added a new example heap allocation implementation (heap_4.c) that - includes memory block coalescence. - + Added a demo that targets the Atmel SAM4S Cortex-M4 based microcontroller. - The demo is preconfigured to build using the free Atmel Studio 6 IDE and - GCC compiler. - + Added xSemaphoreTakeFromISR() implementation. - + The last parameter in ISR safe FreeRTOS queue and semaphore functions - (xHigherPriorityTaskWoken) is now optional and can be set to NULL if it - is not required. - + Update the IAR and MSP430X ports to clear all lower power mode bits before - exiting the tick interrupt [bug fix]. - + Allow xQueueReset() to be used, even when the queues event lists are not - empty. - + Added a vQueueDelete() handler for the FreeRTOS MPU port (this was - previously missing). - + Updated the vPortSVCHandler() functions in the FreeRTOS MPU port layer to - ensure it compiles with the latest ARM GCC compilers from Linaro. - + Updated the prvReadGP() function in the NIOS II port to ensure the compiler - can choose any register for the functions parameter (required at high - compiler optimisation levels). - + Add #error macros into the Keil and IAR Cortex-M ports to ensure they - cannot be built if the user has set configMAX_SYSCALL_INTERRUPT_PRIORITY - to 0. - + Added comments in the FreeRTOSConfig.h files associated with Cortex-M3 and - Cortex-M4 demos stating that the configMAX_SYSCALL_INTERRUPT_PRIORITY - parameter must not be set to 0. - + Introduce new INCLUDE_xQueueGetMutexHolder configuration constant - (defaulted to 0). - + Added two new list handling macros - for internal use only in upcoming new - products. - + Removed all mention of the legacy vTaskStartTrace and ulTaskEndTrace - macros. FreeRTOS+Trace supersedes the legacy trace. - + Added a configASSERT() into the vPortFree() function in heap_1.c as it is - invalid for the function to be called. - + Made the xRxLock and xTxLock members of the queue structure volatile. - This is probably not necessary, and is included as a precautionary - measure. - + Modify the assert() that checks to see if the priority passed into an - xTaskCreate() function is within valid bounds to permit the assert to be - used in the FreeRTOS MPU port. - + The software timer service (daemon) task is now created in a way that - to ensure compatibility with FreeRTOS MPU. - -Changes between V7.1.0 and V7.1.1 released May 1 2012 - - New ports: - - The following ports are brand new: - + Cortex-M3 Tasking - - The following ports have been available as separate downloads for a number - of months, but are now included in the main FreeRTOS download. - + Cortex-M0 IAR - + Cortex-M0 GCC - + Cortex-M4F GCC (with full floating point support) - - - New demos: - - The following demos are brand new: - + Renesas RX63N RDK (Renesas compiler) - - The following demos have been available as separate downloads for a number - of months, but are now included in the main FreeRTOS download. - + NXP LPC1114 GCC/LPCXpresso - + ST STM32F0518 IAR - + Infineon XMC4500 GCC/Atollic - + Infineon XMC4500 IAR - + Infineon XMC4500 Keil - + Infineon XMC4500 Tasking - - - Kernel miscellaneous / maintenance: - - + Introduced the portSETUP_TCB() macro to remove the requirement for the - Windows simulator to use the traceTASK_CREATE() macro, leaving the trace - macro available for use by FreeRTOS+Trace (https://www.FreeRTOS.org/trace). - + Added a new trace macro, traceMOVE_TASK_TO_READY_STATE(), to allow future - FreeRTOS+Trace versions to provide even more information to users. - + Updated the FreeRTOS MPU port to be correct for changes that were - introduced in FreeRTOS V7.1.0. - + Introduced the xQueueReset() API function. - + Introduced the xSemaphoreGetMutexHolder() API function. - + Tidy up various port implementations to add the static key word where - appropriate, and remove obsolete code. - + Slight change to the initial stack frame given to the RX600 ports to allow - them to be used in the Eclipse based E2Studio IDE without confusing GDB. - + Correct the alignment given to the initial stack of Cortex-M4F tasks. - + Added a NOP following each DINT instruction on MSP430 devices for strict - conformance with the instructions on using DINT. - + Changed the implementation of thread deletes in the Win32 port to prevent - the port making use of the traceTASK_DELETE() trace macros - leaving this - macro free for use by FreeRTOS+Trace. - + Made some benign changes to the RX600 Renesas compiler port layer to - ensure the code can be built to a library without essential code being - removed by the linker. - + Reverted the change in the name of the uxTaskNumber variable made in - V7.1.0 as it broke the IAR plug-in. - - - Demo miscellaneous / maintenance: - - + The command interpreter has now been formally released as FreeRTOS+CLI, - and been moved out of the main FreeRTOS download, to instead be available - from the FreeRTOS+ Ecosystem site https://www.FreeRTOS.org/plus. - + flash_timer.c/h has been added to the list of standard demo tasks. This - performs the same functionality as the flash.c tasks, but using software - timers in place of tasks. - + Upgraded the PIC32 demo as follows: Changes to how the library functions - are called necessitated by the new compiler version, addition of MPLAB X - project with PIC32MX360, PIC32MX460 and PIC32MX795 configurations, - addition of simply blinky demo, updated FreeRTOSConfig.h to include more - parameters, addition of hook function stubs. - + The MSP430X IAR and CCS demos have been updated to ensure the power - settings are correct for the configured CPU frequency. - + Rowley CrossWorks projects have been updated to correct the "multiple - definition of ..." warnings introduced when the toolchain was updated. - + Updated various FreeRTOSConfig.h header files associated with projects - that build with Eclipse to include a #error statement informing the user - that the CreateProjectDirectoryStructure.bat batch file needs to be - executed before the projects can be opened. - + Renamed directories that included "CCS4" in their name to remove the '4' - and instead just be "CCS". This is because the demo was updated and - tested to also work with later Code Composer Studio versions. - + Updated the TCP/IP periodic timer frequency in numerous uIP demos to be - 50ms instead of 500ms. - -Changes between V7.0.2 and V7.1.0 released December 13 2011 - - New ports: - - + Cortex-M4F IAR port. - + Cortex-M4F Keil/RVDS port. - + TriCore GCC port. - - New demos: - - + NXP LPC4350 using the Keil MDK, and demonstrated on a Hitex development - board. - + ST STM32F407 using the IAR Embedded Workbench for ARM, and demonstrated on - the IAR STM32F407ZG-SK starter kit. - + Infineon TriCore TC1782, using the GCC compiler, demonstrated on the - TriBoard TC1782 evaluation board. - + Renesas RX630, using the Renesas compiler and HEW, demonstrated on an - RX630 RSK (Renesas Starter Kit). - - Miscellaneous / maintenance: - - + Removed all calls to printf() from the K60/IAR Kinetis demo so the project - can execute stand alone - without being connected to the debugger. - + Completed the command interpreter framework. Command handlers now receive - the entire command string, giving them direct access to parameters. - Utility functions are provided to check the number of parameters, and - return parameter sub-strings. - + The previously documented fix for the bug in xTaskResumeFromISR() that - effected (only) ports supporting interrupt nesting has now been - incorporated into the main release. - + The portALIGNMENT_ASSERT_pxCurrentTCB() definition has been added to allow - specific ports to skip the second stack alignment check when a task is - created. This is because the second check is not appropriate for some - ports - including the new TriCore port where the checked pointer does not - actually point to a stack. - + The portCLEAN_UP_TCB() macro has been added to allow port specific clean - up when a task is deleted - again this is required by the TriCore port. - + Various other minor changes to ensure warning free builds on a growing - number of microcontroller and toolchain platforms. This includes a - (benign) correction to the prototype of the - vApplicationStackOverflowHook() definition found in lots of recent demos. - - Trace system: - - + The legacy trace mechanism has been completely removed - it has been - obsolete for the years since the trace macros were introduced. The - configuration constant configUSE_TRACE_FACILITY is now used to optionally - include additional queue and task information. The additional information - is intended to make the trace mechanism more generic, and allow the trace - output to provide more information. When configUSE_TRACE_FACILITY is set - to 1: - - the queue structure includes an additional member to hold the queue - type, which can be base, mutex, counting semaphore, binary semaphore - or recursive mutex. - - the queue structure includes an additional member to hold a queue - number. A trace tool can set and query the queue number for its own - purposes. The kernel does not use the queue number itself. - - the TCB structure includes an additional member to hold a task number - number. A trace tool can set and query the task number for its own - purposes. The kernel does not use the task number itself. - + Queues and all types of semaphores are now automatically allocated their - type as they are created. - + Added two new trace macros - traceTASK_PRIORITY_INHERIT() and - traskTASK_PRIORITY_DISINHERIT(). - + Updated the traceQUEUE_CREATE_FAILED() macro to take a parameter that - indicates the type of queue, mutex, or semaphore that failed to be - created. - + The position from which traceCREATE_MUTEX() is called has been moved from - after the call to xQueueGenericSend() [within the same function] to before - the call. This ensures the trace events occur in the correct order. - + The value passed into tracePRIORITY_SET() has been corrected for the case - where vTaskPrioritySet() is called with a null parameter. - -Changes between V7.0.1 and V7.0.2 released September 20 2011 - - New ports: - - + The official FreeRTOS Renesas RX200 port and demo application have been - incorporated into the main FreeRTOS zip file download. - + The official FreeRTOS Renesas RL78 port and demo application have been - incorporated into the main FreeRTOS zip file download. - + The official FreeRTOS Freescale Kinetis K60 tower demo application has - been incorporated into the main FreeRTOS zip file download. This includes - an embedded web server example. - + A new Microblaze V8 port layer has been created to replace the older, now - deprecated, port layer. The V8 port supports V8.x of the Microblaze IP, - including exceptions, caches, and the floating point unit. A new - Microblaze demo has also been added to demonstrate the new Microblaze V8 - port layer. The demo application was created using V13.1 of the Xilinx - EDK, and includes a basic embedded web server that uses lwIP V1.4.0. - + The official FreeRTOS Fujitsu FM3 MB9A310 demo application has been - incorporated into the main FreeRTOS zip file download. Projects are - provided for both the IAR and Keil toolchains. - - - API additions: - - + xTaskGetIdleTaskHandle() has been added. - + xTaskGetTimerDaemonTaskHandle() has been added. - + pcTaskGetTaskName() has been added. - + vSemaphoreDelete() macro has been added to make it obvious how to delete - a semaphore. In previous versions vQueueDelete() had to be used. - + vTaskCleanUpResources() has been removed. It has been obsolete for a - while. - + portPOINTER_SIZE_TYPE has been introduced to prevent compiler warnings - being generated when the size of a pointer does not match the size of - the stack type. This will (has already) be used in new ports, but will - not be retrofitted to existing ports until the existing port itself is - updated. - - Other updates and news: - - + The core files have all been modified to tighten the coding standard even - further. These are style, not functional changes. - + All ARM7 port layers have been slightly modified to prevent erroneous - assert() failures when tasks are created and configASSERT() is defined. - + All ARM IAR projects have been updated to build with the latest V6.2.x - versions of the IAR Embedded Workbench for ARM tools (EWARM). This was - necessary due to a change in the way EWARM uses the CMSIS libraries. - + The PIC32 port layer has been updated in preparation for V2 of the C32 - compiler. - + The old Virtex-4 Microblaze demo has been marked as deprecated. Please - use the brand new Spartan-6 port and demo in its place. - + The bones of a new generic command interpreter is located in - FreeRTOS/Demo/Common/Utils/CommandInterpreter.c. This is still a work in - progress, and not documented. It is however already in use. It will be - documented in full when the projects that are already using it are - completed. - + A couple of new standard demos have been included. First, a version of - flop.c called sp_flop.c. This is similar to flop.c, but uses single - precision floats in place of double precision doubles. This allows the - for testing ports to processors that have only single precision floating - point units, and revert to using emulated calculations whenever a double - is used. Second, comtest_strings.c has been included to allow the test - of UART drivers when an entire string is transmitted at once. The - previous comtest.c only used single character transmission and reception. - + lwIP V1.4.0 is now included in the FreeRTOS/Demo/Common directory, and - used by a couple of new demos. - -Changes between V7.0.0 and V7.0.1 released May 13 2011 - - + Added a Fujitsu FM3 demo application for both the IAR and Keil tool - chains. - + Added a SmartFusion demo application for all of the IAR, Keil and - SoftConsole (GCC/Eclipse) tool chains. - + Updated the RX600 port and demo applications to take into account the - different semantics required when using the latest (V1.0.2.0) version of - the Renesas compiler. - + Modified the RX600 Ethernet driver slightly to make it more robust under - heavy load, and updated the uIP handling task to make use of the FreeRTOS - software timers. - + Slightly changed the PIC32 port layer to move an ehb instruction in line - with the recommendations of the MIPS core manual, and ensure 8 byte stack - alignment is truly always obtained. - + Changed the behaviour when tasks are suspended before the scheduler has - been started. Before, there needed to be at least one task that was not - in the suspended state. This is no longer the case. - -Changes between V6.1.1 and V7.0.0 released April 8 2011 - - FreeRTOS V7.0.0 is backward compatible with FreeRTOS V6.x.x - - Main changes: - - + Introduced a new software timer implementation. - + Introduced a new common demo application file to exercise the new timer - implementation. - + Updated the Win32/MSVC simulator project to include the new software timer - demo tasks and software timer tick hook test. Much simpler software timer - demonstrations are included in the demo projects for both of the new ports - (MSP430X with CCS4 and STM32 with TrueStudio). - + Various enhancements to the kernel implementation in tasks.c. These are - transparent to users and do not effect the pre-existing API. - + Added calls to configASSERT() within the kernel code. configASSERT() is - functionally equivalent to the standard C assert() macro, but does not - rely on the compiler providing assert.h. - - Other changes: - - + Updated the MSP430X IAR port and demo project to include support for the - medium memory model. - + Added a demo project for the MSP430X that targets the MSP430X Discovery - board and uses the Code Composer Studio 4 tools. This demo includes use - of the new software timer implementation. - + Added an STM32F100RB demo project that targets the STM32 Discovery Board - and uses the TrueStudio Eclipse based IDE from Atollic. - + Removed some compiler warnings from the PSoC demo application. - + Updated the PIC32 port layer to ensure the - configMAX_SYSCALL_INTERRUPT_PRIORITY constant works as expected no matter - what its value is (within the valid range set by the microcontroller - kernel). - + Updated the PIC24, dsPIC and PIC32 projects so they work with the latest - MPLAB compiler versions from Microchip. - + Various cosmetic changes to prepare for a standards compliance statement - that will be published after the software release. - - -Changes between V6.1.0 and V6.1.1 released January 14 2011 - - + Added two new Windows simulator ports. One uses the free Microsoft Visual - Studio 2010 express edition, and the other the free MingW/Eclipse - environment. Demo projects are provided for both. - + Added three demo projects for the PSoC 5 (CYAC5588). These are for the - GCC, Keil, and RVDS build tools, and all use the PSoC Creator IDE. - + Added a demo for the low power STM32L152 microcontroller using the IAR - Embedded Workbench. - + Added a new port for the MSP430X core using the IAR Embedded Workbench. - + Updated all the RX62N demo projects that target the Renesas Demonstration - Kit (RDK) to take into account the revered LED wiring on later hardware - revisions, and the new J-Link debug interface DLL. - + Updated all the RX62N demo projects so the IO page served by the example - embedded web server works with all web browsers. - + Updated the Red Suite projects to work with the up coming Red Suite - release, and to use a more recent version of the CMSIS libraries. - + Added the traceTAKE_MUTEX_RECURSIVE_FAILED() trace macro. - + Removed the (pointless) parameter from the traceTASK_CREATE_FAILED() - trace macro. - + Introduced the portALT_GET_RUN_TIME_COUNTER_VALUE() macro to compliment - the already existing portGET_RUN_TIME_COUNTER_VALUE(). This allows for - more flexibility in how the time base for the run time statistics feature - can be implemented. - + Added a "cpsie i" instruction before the "svc 0" instruction used to start - the scheduler in each of the Cortex M3 ports. This is to ensure that - interrupts are globally enabled prior to the "svc 0" instruction being - executed in cases where interrupts are left disabled by the C start up - code. - + Slight optimisation in the run time stats calculation. - -Changes between V6.0.5 and V6.1.0 released October 6 2010 - - + Added xTaskGetTickCountFromISR() function. - + Modified vTaskSuspend() to allow tasks that have just been created to be - immediately suspended even when the kernel has not been started. This - allows them to effectively start in the Suspended state - a feature that - has been asked for on numerous occasions to assist with initialisation - procedures. - + Added ports for the Renesas RX62N using IAR, GCC and Renesas tool suites. - + Added a STM32F103 demo application that uses the Rowley tools. - + Under specific conditions xFreeBytesRemaining within heap_2.c could end up - with an incorrect value. This has been fixed. - + xTaskCreateGeneric() has a parameter that can be used to pass the handle - of the task just created out to the calling task. The assignment to this - parameter has been moved to ensure it is assigned prior to the newly - created having any possibility of executing. This takes into account the - case where the assignment is made to a global variable that is accessed by - the newly created task. - + Fixed some build time compiler warnings in various FreeTCPIP (based on - uIP) files. - + Fixed some build time compiler warnings in Demo/Common/Minimal/IntQueue.c. - -Changes between V6.0.4 and V6.0.5 released May 17 2010 - - + Added port and demo application for the Cortus APS3 processor. - -Changes between V6.0.3 and V6.0.4 released March 14 2010 - - + All the contributed files that were located in the Demo/Unsupported_Demos - directory have been removed. These files are instead now available in the - new Community Contributions section of the FreeRTOS website. See - https://www.FreeRTOS.org/RTOS-contributed-ports.html - + The project file located in the Demo/CORTEX_STM32F107_GCC_Rowley directory - has been upgraded to use V2.x of the Rowley Crossworks STM32 support - package. - + An initial Energy Micro EFM32 demo has been included. This will be - updated over the coming months to make better use of the low power modes - the EFM32 provides. - -Changes between V6.0.2 and V6.0.3 released February 26 2010 - - + SuperH SH7216 (SH2A-FPU) port and demo application added. - + Slight modification made to the default implementation of - pvPortMallocAligned() and vPortFreeAligned() macros so by default they - just call pvPortMalloc() and vPortFree(). The macros are only needed to - be defined when a memory protection unit (MPU) is being used - and then - only depending on other configuration settings. - -Changes between V6.0.1 and V6.0.2 released January 9th 2010 - - + Changed all GCC ARM 7 ports to use 0 as the SWI instruction parameter. - Previously the parameter was blank and therefore only an implicit 0 but - newer GCC releases do not permit this. - + Updated IAR SAM7S and SAM7X ports to work with IAR V5.40. - + Changed the stack alignment requirement for PIC32 from 4 bytes to 8 bytes. - + Updated prvListTaskWithinSingleList() is it works on processors where the - stack grows up from low memory. - + Corrected some comments. - + Updated the startup file for the RVDS LPC21xx demo. - -Changes between V6.0.0 and V6.0.1 released November 15th 2009 - - + Altered pxPortInitialiseStack() for all Cortex-M3 ports to ensure the - stack pointer is where the compiler expects it to be when a task first - starts executing. - - The following minor changes only effect the Cortex-M3 MPU port: - - + portRESET_PRIVILEGE() assembly macro updated to include a clobber list. - + Added prototypes for all the privileged function wrappers to ensure no - compile time warnings are generated no matter what the warning level - setting. - + Corrected the name of portSVC_prvRaisePrivilege to - portSVC_RAISE_PRIVILEGE. - + Added conditional compilation into xTaskGenericCreate() to prevent some - compilers issuing warnings when portPRIVILEGE_BIT is defined as zero. - - -Changes between V5.4.2 and V6.0.0 released October 16th 2009 - - FreeRTOS V6 is backward compatible with FreeRTOS V5.x. - - Main changes: - - + FreeRTOS V6 is the first version to include memory protection unit (MPU) - support. Two ports now exist for the Cortex M3, the standard FreeRTOS - which does not include MPU support, and FreeRTOS-MPU which does. - + xTaskCreateRestricted() and vTaskAllocateMPURegions() API functions added - in support of FreeRTOS-MPU. - + Wording for the GPL exception has been (hopefully) clarified. Also the - license.txt file included in the download has been fixed (the previous - version contained some corruption). - - Other changes: - - + New API function xPortGetFreeHeapSize() added to heap_1.c and heap_2.c. - + ARM7 GCC demo interrupt service routines wrappers have been modified to - call the C portion using an __asm statement. This prevents the function - call being inlined at higher optimisation levels. - + ARM7 ports now automatically set the THUMB bit if necessary when - setting up the initial stack of a task - removing the need for - THUMB_INTERWORK to be defined. This also allows THUMB mode and ARM mode - tasks to be mixed more easily. - + All ARM7/9 ports now have portBYTE_ALIGNMENT set to 8 by default. - + Various demo application project files have been updated to be up to date - with the latest IDE versions. - + The linker scripts used with command line GCC demos have been updated to - include an eh_frame section to allow their use with the latest Yagarto - release. Likewise the demo makefiles have been updated to include - command line options to reduce or eliminate the eh_frame section all - together. - + The definition of portBYTE_ALIGNMENT_MASK has been moved out of the - various memory allocation files and into the common portable.h header - file. - + Removed unnecessary use of portLONG, portSHORT and portCHAR. - + Added LM3Sxxxx demo for Rowley CrossWorks. - + Posix simulator has been upgraded - see the corresponding WEB page on the - FreeRTOS.org site. - - -Changes between V5.4.1 and V5.4.2 released August 9th 2009 - - + Added a new port and demo app for the Altera Nios2 soft core. - + Added LPC1768 demo for IAR. - + Added a USB CDC demo to all LPC1768 demos (Code Red, CrossWorks and IAR). - + Changed clock frequency of LPC1768 demos to 99MHz. - -Changes between V5.4.0 and V5.4.1 released July 25th 2009 - - + New hook function added. vApplicationMallocFailedHook() is (optionally) - called if pvPortMalloc() returns NULL. - + Additional casting added to xTaskCheckForTimeOut(). This prevents - problems that can arise should configUSE_16_BIT_TICKS be set to 1 on a - 32 bit architecture (which would probably be a mistake, anyway). - + Corrected the parameter passed to NVIC_SetPriority() to set the MAC - interrupt priority in both LPC1768 demos. - + Decreased the default setting of configMINIMAL_STACK_SIZE in the PIC32 - demo application to ensure the heap space was not completely consumed - before the scheduler was started. - -Changes between V5.3.1 and V5.4.0 released July 13th 2009 - - + Added Virtex5 / PPC440 port and demos. - + Replaced the LPC1766 Red Suite demo with an LPC1768 Red Suite demo. The - original demo was configured to use engineering samples of the CPU. The - new demo has an improved Ethernet driver. - + Added LPC1768 Rowley demo with zero copy Ethernet driver. - + Reworked byte alignment code to ensure 8 byte alignment works correctly. - + Set configUSE_16_BIT_TICKS to 0 in the PPC405 demo projects. - + Changed the initial stack setup for the PPC405 to ensure the small data - area pointers are setup correctly. - -Changes between V5.3.0 and V5.3.1 released June 21st 2009 - - + Added ColdFire V1 MCF51CN128 port and WEB server demo. - + Added STM32 Connectivity Line STM32107 Cortex M3 WEB server demo. - + Changed the Cortex M3 port.c asm statements to __asm so it can be - compiled using Rowley CrossWorks V2 in its default configuration. - + Updated the Posix/Linux simulator contributed port. - -Changes between V5.2.0 and V5.3.0 released June 1st 2009 - - Main changes: - - + Added new (optional) feature that gathers statistics on the amount of CPU - time used by each task. - + Added a new demo application for the Atmel AT91SAM3U Cortex-M3 based - microcontroller. - + Added a new demo application for the NXP LPC1766 Cortex-M3 based - microcontroller. - + Added a contributed port/demo that allows FreeRTOS to be 'simulated' in a - Linux environment. - - Minor changes: - + Updated the Stellaris uIP WEB server demos to include the new run time - statistics gathering feature - and include a served WEB page that - presents the information in a tabular format. - + Added in the lwIP port layer for the Coldfire MCF52259. - + Updated the CrossWorks LPC2368 WEB server to include an image in the - served content. - + Changed some of the timing in the initialisation of the LPC2368 MAC to - permit its use on all part revisions. - + Minor modifications to the core uIP code to remove some compiler warnings. - + Added xTaskGetApplicationTaskTag() function and updated the OpenWatcom - demo to make use of the new function. - + Added contributed demos for AVR32 AP7000, STM32 Primer 2 and STM32 using - Rowley Crossworks. - + Heap_1.c and Heap_2.c used to define structures for the purpose of data - alignment. These have been converted to unions to save a few bytes of - RAM that would otherwise be wasted. - + Remove the call to strncpy() used to copy the task name into the TCB when - the maximum task name is configured to be 1 byte long. - -Changes between V5.1.2 and V5.2.0 released March 14th 2009 - - + Optimised the queue send and receive functions (also used by semaphores). - + Replaced the standard critical sections used to protect BIOS calls in the - PC port to instead use scheduler locks. This is because the BIOS calls - always return with interrupts enabled. - + Corrected unclosed comments in boot.s. - -Changes between V5.1.1 and V5.1.2 released February 9th 2009 - - + Added NEC V850ES port and demo. - + Added NEC 78K0R port and demo. - + Added MCF52259 port and demo. - + Added the AT91SAM9XE port and demo. - + Updated the MCF52233 FEC driver to work around a silicon bug that - prevents the part auto negotiating some network parameters. - + Minor modifications to the MCF52233 makefile to permit it to be used - on Linux hosts. - + Updated the STM32 primer files to allow them to be built with the latest - version of the RIDE tools. - + Updated the threads.js Java script used for kernel aware debugging in - the Rowley CrossWorks IDE. - - -Changes between V5.1.0 and V5.1.1 released November 20, 2008 - - + Added Coldfire MCF52233 WEB server demo using GCC and Eclipse. - + Added IAR MSP430 port and demo. - + Corrected several compiler time issues that had crept in as tool versions - change. - + Included FreeRTOS-uIP - a faster uIP. This is not yet complete. - -Changes between V5.0.4 and V5.1.0 released October 24, 2008 - - + Added a new port and demo application for the ColdFire V2 core using the - CodeWarrior development tools. - + Replaced the ARM7 demo that used the old (and now no longer supported) - Keil compiler with a new port that uses the new Keil/RVDS combo. - + Stack overflow checking now works for stacks that grow up from low - memory (PIC24 and dsPIC). - + BUG FIX - set the PIC32 definition of portSTACK_GROWTH to the correct - value of -1. - + MSP430 port layers have been updated to permit tasks to place the - microcontroller into power down modes 1 to 3. The demo applications have - likewise been updated to demonstrate the new feature. - + Replaced the two separate MSP430/Rowley port layers with a single and more - flexible version. - + Added more contributed ports, including ports for NEC and SAM9 - microcontrollers. - + Changed the linker script used in the LPC2368 Eclipse demo. - -Changes between V5.0.3 and V5.0.4 released September 22, 2008 - - + Completely re-written port for ColdFire GCC. - + Bug fix: All Cortex M3 ports have a minor change to the code that sets - the pending interrupt. - + Some header files require that FreeRTOS.h be included prior to their - inclusion. #error message have been added to all such header file - informing users to the cause of the compilation error should the headers - not be included in the correct order. - -Changes between V5.0.2 and V5.0.3 released July 31, 2008 - - Changes relating to the Cortex M3: - - + Added configMAX_SYSCALL_INTERRUPT_PRIORITY usage to all the Cortex M3 - ports and demos. See the port documentation pages on the FreeRTOS.org - WEB site for full usage information. - + Improved efficiency of Cortex M3 port even further. - + Ensure the Cortex M3 port works no matter where the vector table is - located. - + Added the IntQTimer demo/test tasks to a demo project for each CM3 port - (Keil, GCC and IAR) to test the new configMAX_SYSCALL_INTERRUPT_PRIORITY - functionality. - + Added the mainINCLUDE_WEB_SERVER definition to the LM3SXXXX IAR and Keil - projects to allow the WEB server to be conditionally excluded from the - build and therefore allow use of the KickStart (code size limited) - compiler version. - - Other changes: - - + Moved the PIC24 and dsPIC versions of vPortYield() from the C file to - an assembly file to allow use with all MPLAB compiler versions. This also - allows the omit-frame-pointer optimisation to be turned off. - -Changes between V5.0.0 and V5.0.2 released May 30, 2008 - - + Updated the PIC32 port to allow queue API calls to be used from - interrupts above the kernel interrupt priority, and to allow full - interrupt nesting. Task stack usages has also been reduced. - + Added a new PowerPC port that demonstrates how the trace macros can be - used to allow the use of a floating point co-processor. The - traceTASK_SWITCHED_OUT() and traceTASK_SWITCHED_INT() macros are used to - save and restore the floating point context respectively for those tasks - that actually use floating point operations. - + BUG FIX: The first PPC405 port contained a bug in that it did not leave - adequate space above the stack for the backchain to be saved when a task - started to execute for the first time. - + Updated queue.c to add in the means to allow interrupt nesting and for - queue API functions to be called from interrupts that have a priority - above the kernel priority. This is only supported on PIC32 ports thus - far. - + Fixed the compiler warnings that were generated when the latest version - of WinAVR was used. - + Remove all inline usage of 'inline' from the core kernel code. - + Added the queue registry feature. The queue registry is provided as a - means for kernel aware debuggers to locate queue definitions. It has no - purpose unless you are using a kernel aware debugger. The queue registry - will only be used when configQUEUE_REGISTRY_SIZE is greater than zero. - + Added the ST Cortex-M3 drivers into the Demo/Common/Drivers directory to - prevent them from having to be included in multiple demos. - + Added a Keil STM32 demo application. - + Changed the blocktim.c test files as it is no longer legitimate for all - ports to call queue API functions from within a critical section. - + Added the IntQueue.c test file to test the calling of queue API functions - from different interrupt priority levels, and test interrupt nesting. - -Changes between V5.0.0 and V5.0.1 - - + V5.0.1 was a customer specific release. - -Changes between V4.8.0 and V5.0.0 released April 15, 2008 - - *** VERY IMPORTANT INFORMATION ON UPGRADING TO FREERTOS.ORG V5.0.0 *** - - The parameters to the functions xQueueSendFromISR(), xQueueSendToFrontFromISR(), - xQueueSendToBackFromISR() and xSemaphoreGiveFromISR() have changed. You must - update all calls to these functions to use the new calling convention! Your - compiler might not issue any type mismatch warnings! - - - Other changes: - - + Support added for the new Luminary Micro LM3S3768 and LM3S3748 Cortex-M3 - microcontrollers. - + New task hook feature added. - + PowerPC demo updated to use version 10.1 of the Xilinx EDK. - + Efficiency gains within the PIC32 port layer. - -Changes between V4.7.2 and V4.8.0 released March 26 2008 - - + Added a Virtex4 PowerPC 405 port and demo application. - + Added optional stack overflow checking and new - uxTaskGetStackHighWaterMark() function. - + Added new xQueueIsQueueEmptyFromISR(), xQueueIsQueueFullFromISR() and - uxQueueMessagesWaitingFromISR() API functions. - + Efficiency improvements to the Cortex-M3 port layer. NOTE: This - requires that an SVC handler be installed in the application. - + Efficiency improvements to the queue send and receive functions. - + Added new trace macros. These are application definable to provide - a flexible trace facility. - + Implemented the configKERNEL_INTERRUPT_PRIORITY within the Keil Cortex - M3 port layer (bringing it up to the same standard as the IAR and GCC - versions). - + Ports that used the arm-stellaris-eabi-gcc tools have been converted to - use the arm-non-eabi-gcc tools. - -Changes between V4.7.1 and V4.7.2 released February 21, 2008 - - + Added Fujitsu MB91460 port and demo. - + Added Fujitsu MB96340 port and demo. - + Tidied up the capitalisation of include files to facilitate builds on - Linux hosts. - + Removed some redundant casting that was generating warnings - but was - included to remove warnings on other compilers. - -Changes between V4.7.0 and V4.7.1 released February 3, 2008 - - + Updated all IAR ARM projects to use V5.11 of the IAR Embedded Workbench - for ARM. - + Introduced recursive semaphore feature. - + Updated LPC2368 demos to take into account silicon bugs in old chip - revisions. - + Updated STR9 uIP port to manually set the net mask and gateway addresses. - + Updating demos to allow more to run with the co-operative scheduler. - + Fixed co-operative scheduler behaviour upon the occurrence of a tick - interrupt while the scheduler was suspended. - + Updated documentation contained within semphr.h. - + ARM7 GCC ports no longer use the IRQ attribute. - -Changes between V4.6.1 and V4.7.0 released December 6, 2007 - - + Introduced the counting semaphore macros and demo source files. The - Open Watcom PC project has been updated to include the new demo. See - the online documentation for more information. - + Introduced the 'alternative' queue handling API and demo source files. - The Open Watcom PC project has been updated to include the new demo - source files. See the online documentation for more information. - + Added AT91SAM7X Eclipse demo project. - + Added the STM32 primer demo project for the GCC compiler and Ride IDE. - + Removed the .lock files that were mistakenly included in the V4.6.1 - eclipse workspaces. - -Changes between V4.6.0 and V4.6.1 released November 5 2007 - - + Added support for the MIPS M4K based PIC32. - + Added 'extern "C"' to all the header files to facilitate use with C++. - -Changes between V4.5.0 and V4.6.0 released October 28 2007 - - + Changed the method used to force a context switch within an ISR for the - ARM7/9 GCC ports only. The portENTER_SWITCHING_ISR() and - portEXIT_SWITCHING_ISR() macros are no longer supported. This is to - ensure correct behaviour no matter which GCC version is used, with or - without the -fomit-frame-pointer option, and at all optimisation levels. - + Corrected the prototype for xQueueGenericSend() within queue.h. - -Changes between V4.4.0 and V4.5.0 released September 17 2007 - - + Added the xQueueSendToFront(), xQueueSendToBack() and xQueuePeek() - functionality. These should now be used in preference to the old - xQueueSend() function - which is maintained for backward compatibility. - + Added Mutex functionality. The behaviour of mutexes is subtly different - to the already existing binary semaphores as mutexes automatically - include a priority inheritance mechanism. - + Added the GenQTest.c and QPeek.c to test and demonstrate the behaviour - of the new functionality. - + Updated the LM3Sxxxx and PC ports to include the new GenQTest.c and - QPeek.c files. - + Updated the GCC port for the Cortex M3 to include the - configKERNEL_INTERRUPT_PRIORITY functionality. This was previously only - included in the IAR port. - + Optimised the GCC and IAR port layer code - specifically the context - switch code. - + Consolidated the LM3Sxxxx EK demos for all development tools into a - single project that automatically detects which version of the EK the - application is executing on. - + Added Eclipse support for LM3Sxxxx evaluation kits. - + Added Eclipse support for the Keil LPC2368 evaluation kit. - + Added the Demo/Drivers directory to hold code that is common to multiple - demo application projects. - + Included some minor bug fixes in the uIP 1.0 code. - + Added an lwIP demo for the STR9 - thanks ST for assistance. - + Updated the AVR32 port to ensure correct behaviour with full compiler - optimisation. - + Included binaries for OpenOCD FTDI and parallel port interfaces. - -Changes between V4.4.0 and V4.3.1 released July 31, 2007 - - + Added AVR32 UC3B demo application. - + Updated AVR32 UC3A port and demo applications. - + Added IAR lwIP demo for AVR32 UC3A. - + Updated listGET_OWNER_OF_NEXT_ENTRY() to assist compiler optimisation - (thanks Niu Yong for making the suggestion). - + Added xTaskGetSchedulerState() API function. - + BUG FIX: Corrected behaviour when tasks that are blocked indefinitely - have their block time adjusted (within xQueueSend() and xQueueReceive()), - and are the subject of a call the vTaskResume() when they are not - actually in the Suspended state (thanks Dan Searles for reporting the - issues). - - -Changes between V4.3.0 and V4.3.1 released June 11, 2007 - - + Added STMicroelectronics STM32 Cortex-M3 demo application. - + Updated ustdlib.c for the GCC LM3S6965 demo. - -Changes between V4.2.1 and V4.3.0 released June 5, 2007 - - + Introduced configKERNEL_INTERRUPT_PRIORITY to the IAR Cortex-M3, PIC24 - and dsPIC ports. See the LM3S6965 and PIC24 demo application - documentation pages for more information. - + Updated the PIC24 and dsPIC demos to build with V3.0 of the PIC30 GCC - tools, and changed the demo applications. - + Added demos for the new Ethernet and CAN enabled Luminary Micro Stellaris - microcontrollers. - + Corrected bug in uIP the demos that prevented frames of approximately 1480 - bytes and over from being transmitted. - + Included the LPC2368/uIP/Rowley demo into the main FreeRTOS.org - download. - + Update to WizC PIC18 port to permit its use with version 14 of the - compiler. Thanks Marcel! - -Changes between V4.2.1 and V4.2.0 released April 2, 2007 - - + Added AVR32 AT32UC3A ports for GCC and IAR. - + Added -fomit-frame-pointer option to lwIP SAM7X demo makefile. - + Moved location of call to LCD_Init() in STR9 demo to ensure it is only - called after the scheduler has been started. - -Changes between V4.1.3 and V4.2.0 released February 8, 2007 - - + Changes to both task.c and queue.c as a result of testing performed on - the SafeRTOS code base. - + Added Cortex-M3 LM3S811 demos for GCC and IAR tools. - -Changes between V4.1.2 and V4.1.3 released November 19, 2006 - - + Added STR750 ARM7 port using the Raisonance RIDE/GCC tools. - + Added -fomit-frame-pointer option to Rowley ARM7 demos as work around - to GCC bug at some optimisation levels. - + Altered the way the heap is defined in the LM3S811 Keil demo to prevent - the RAM usage from counting toward the code size limit calculation. - + CO-ROUTINE BUG FIX: Removed the call to prvIsQueueEmpty from within - xQueueCRReceive as it exited with interrupts enabled. Thanks Paul Katz. - + Tasks that block on events with a timeout of portMAX_DELAY are now - blocked indefinitely if configINCLUDE_vTaskSuspend is defined. - Previously portMAX_DELAY was just the longest block time possible. This - is still the case if configINCLUDE_vTaskSuspend is not defined. - + Minor changes to some demo application files. - -Changes between V4.1.1 and V4.1.2 released October 21, 2006 - - + Added 16bit PIC ports and demos. - + Added STR750 port and demo. - - -Changes between V4.1.0 and V4.1.1 released September 24, 2006 - - + Added the Luminary Micro Stellaris LM3S811 demo application. - -Changes between V4.0.5 and V4.1.0 released August 28, 2006 - - + Prior to V4.1.0, under certain documented circumstances, it was possible - for xQueueSend() and xQueueReceive() to return without having completed - and without their block time expiring. The block time effectively - stated a maximum block time, and the return value of the function needed - to be checked to determine the reason for returning. This is no longer - the case as the functions will only return once the block time has - expired or they are able to complete their operation. It is therefore no - longer necessary to wrap calls within loops. - + Changed the critical section handling in the IAR AVR port to correct the - behaviour when used with later compiler versions. - + Added the LPC2138 CrossWorks demo into the zip file. Previously this was - only available as a separate download. - + Modified the AVR demo applications to demonstrate the use of co-routines. - -Changes between V4.0.4 and V4.0.5 released August 13, 2006 - - + Introduced API function xTaskResumeFromISR(). Same functionality as - xTaskResume(), but can be called from within an interrupt service routine. - + Optimised vListInsert() in the case when the wake time is the maximum - tick count value. - + Bug fix: The 'value' of the event list item is updated when the priority - of a task is changed. Previously only the priority of the TCB itself was - changed. - + vTaskPrioritySet() and vTaskResume() no longer use the event list item. - This has not been necessary since V4.0.1 when the xMissedYield handling - was added. - + Lowered the PCLK setting on the ARM9 STR9 demo from 96MHz to 48MHz. - + When ending the scheduler - do not try to attempt a context switch when - deleting the current task. - + SAM7X EMAC drivers: Corrected the Rx frame length mask when obtaining - the length from the rx descriptor. - - -Changes between V4.0.3 and V4.0.4 released June 22, 2006 - - + Added a port and demo application for the STR9 ARM9 based processors from - ST. - + Slight optimisation to the vTaskPrioritySet() function. - + Included the latest uIP version (1.0) in the demo/common/ethernet - directory. - -Changes between V4.0.2 and V4.0.3 released June 7, 2006 - - + Added a port and demo application for the Cortex-M3 target using the IAR - development tools. - + The ARM Cortex-m3 Rowley projects have been updated to use V1.6 of the - CrossStudio tools. - + The heap size defined for the lwIP Rowley demo has been reduced so that - the project will link correctly when using the command line GCC tools - also. The makefile has also been modified to allow debugging. - + The lwIP Rowley demo not includes a 'kernel aware' debug window. - + The uIP Rowley project has been updated to build with V1.6 of CrossWorks. - + The second set of tasks in the blockQ demo were created the wrong way - around (inconsistent to the description in the file). This has been - corrected. - -Changes between V4.0.1 and V4.0.2 released May 28, 2006 - - + Port and demo application added for the Tern Ethernet Engine controller. - + Port and demo application added for MC9S12 using GCC, thanks to - Jefferson "imajeff" Smith. - + The function vTaskList() now suspends the scheduler rather than disabling - interrupts during the creation of the task list. - + Allow a task to delete itself by passing in its own handle. Previously - this could only be done by passing in NULL. - + Corrected the value passed to the WDG_PeriodValueConfig() library - function in the STR71x demo. - + The tick hook function is now called only within a tick isr. Previously - it was also called when the tick function was called during the scheduler - unlocking process. - + The EMAC driver in the SAM7X lwIP demo has been made more robust as per - the thread: http://sourceforge.net/forum/message.php?msg_id=3714405 - + In the PC ports: Add function prvSetTickFrequencyDefault() to set the - DOS tick back to its proper value when the scheduler exits. Thanks - Raynald! - + In the Borland x86 ports there was a mistake in the portFIRST_CONTEXT - macro where the BP register was not popped from the stack correctly. The - BP value would never get used so this did not cause a problem, but it has - been corrected all the same. - - -Changes between V4.0.0 and V4.0.1 released April 7 2006 - - + Improved the ARM CORTEX M3 ports so they now only have to service - pendSV interrupts. - + Added a Luminary Micro port and demo for use with Rowley CrossWorks. - + Added the xMissedYield handling to tasks.c. - -Changes between V3.2.4 and V4.0.0 - - Major changes: - - + Added new RTOS port for Luminary Micros ARM CORTEX M3 microcontrollers. - + Added new co-routine functionality. - - Other kernel changes: - - + An optional tick hook call is now included in the tick function. - + Introduced the xMiniListItem structure and removed the list pxHead - member in order to reduce RAM usage. - + Added the following definitions to the FreeRTOSConfig.h file included - with every port: - configUSE_TICK_HOOK - configUSE_CO_ROUTINES - configMAX_CO_ROUTINE_PRIORITIES - + The volatile qualification has been changed on the list members to allow - the task.c code to be tidied up a bit. - + The scheduler can now be started even if no tasks have been created! - This is to allow co-routines to run when there are no tasks. - + A task being woken by an event will now preempt the currently running task - even if its priority is only equal to the currently running task. - - Port and demo application changes: - - + Updated the WinAVR demo to compile with the latest version of WinAVR - with no warnings generated. - + Changed the WinAVR makefile to make chars signed - needed for the - co-routine code if BaseType_t is set to char. - + Added new demo application file crflash.c. This demonstrates co-routine - functionality including passing data between co-routines. - + Added new demo application file crhook.c. This demonstrates co-routine - and tick hook functionality including passing data between and ISR and - a co-routine. - + Some NOP's were missing following stmdb{}^ instructions in various ARM7 - ports. These have been added. - + Updated the Open Watcom PC demo project to include the crflash and crhook - demo co-routines as an example of their use. - + Updated the H8S demo to compile with the latest version of GCC. - + Updated the SAM7X EMAC drivers to take into account the hardware errata - regarding lost packets. - + Changed the default MAC address used by some WEB server demos as the - original addresses used was not liked by some routers. - + Modified the SAM7X/IAR startup code slightly to prevent it hanging on - some systems when the code is executed using a j-link debugger. The - j-link macro file configures the PLL before the code executes so - attempting to configure it again in the startup code was causing a - problem for some user. Now a check is performed first to see if the - PLL is already set up. - + GCC port now contain all assembler code in a single asm block rather than - individual blocks as before. - + GCC LPC2000 code now explicitly uses R0 rather than letting the assembler - choose the register to use as a temporary register during the context - switch. - + Added portNOP() macro. - + The compare match load value on LPC2000 ports now has 1 added to correct - the value used. - + The minimal stack depth has been increased slightly on the WIZC PIC18 - port. - -Changes between V3.2.3 and V3.2.4 - - + Modified the GCC ARM7 port layer to allow use with GCC V4.0.0 and above. - Many thanks to Glen Biagioni for the provided update. - + Added a new Microblaze port and demo application. - + Modified the SAM7X EMAC demo to default to use the MII interface rather - than the RMII interface. - + Modified the startup sequence of the SAM7X demo slightly to allow the - EMAC longer to auto negotiate. - -Changes between V3.2.2 and V3.2.3 - - + Added MII interface support to the SAM7X EMAC peripheral driver. - Previously versions worked with the RMII interface only. - + Added command line GCC support to the SAM7X lwIP demo. Previously the - project could only be built using the CrossWorks IDE. Modifications to - this end include the addition of a standard makefile and linker script to - the download, and some adjustments to the stacks allocated to each task. - + Changed the page returned by the lwIP WEB server demo to display the - task status table rather than the TCP/IP statistics. - + Corrected the capitalisation of some header file includes and makefile - dependencies to facilitate use on Linux host computers. - + The various LPC2000 ports had a mistake in the timer setup where the - prescale value was written to T0_PC instead of T0_PR. This would have - no effect unless a prescale value was actually required. This has been - corrected. - -Changes between V3.2.1 and V3.2.2 - Released 23 September, 2005 - - + Added an IAR port for the Philips LPC2129 - + The Atmel ARM7 IAR demo project files are now saved in the IAR Embedded - Workbench V4.30a format. - + Updated the J-Link macro file included with the SAM7X uIP demo project - to allow the demo board to be reset over the J-Link. - -Changes between V3.2.0 and V3.2.1 - Released 1 September, 2005 - - + Added lwIP demo for AT91SAM7X using Rowley tools. - + Added uIP demo for AT91SAM7X using IAR tools. - + Added function xTaskGetCurrentTaskHandle(). - + Renamed events.h to mevents.h to prevent it conflicting with the events.h - generated automatically by the HCS12 processor expert utility. events.h - is only used by the PC demo application. - + Both PIC18 ports now initialise the TBLPTRU to 0 as this is the value - expected by the compiler, and the compilers do not write to this - register. - + The HCS12 banked model demo now creates the 'suicide' tasks immediately - prior to starting the scheduler. These tasks should be the last tasks to - get started in order for the test to function correctly. - -Changes between V3.1.1 and V3.2.0 - Released 29 June, 2005 - - V3.2.0 introduces two new MSP430 ports and corrects a minor kernel - issues. Thanks to Ares.qi for his input. - - + Added two MSP430 ports that use the Rowley CrossWorks development tools. - One port just mirrors the existing GCC port. The other port was provided - by Milos Prokic. Thanks! - + V3.2.0 corrects the behavior when vTaskPrioritySet() or vTaskResume() - are called while the scheduler is locked (by a call to - vTaskSuspendAll()). When this is done the subject task now starts to - execute immediately when the scheduler is unlocked if it has the highest - priority that is ready to run. Previously there was a possibility that - the task would not run until the next RTOS tick or call to portYIELD(). - + Another similar small correction ensures that in the case where more than - one task is blocked on a semaphore or queue, the task with the highest - priority is guaranteed to be unblocked first. - + Added a couple of more test tasks to the PC demo which cover the points - above. - -Changes between V3.1.0 and V3.1.1 - Released 21st June, 2005 - - This release updates the HCS12 port. The common kernel code - remains unchanged. - - + Updated the HCS12 port to support banking and introduced a demo - application for the MC9S12DP256. The new demo application is - located in the Demo/HCS12_CodeWarrior_banked directory. - + The name of the directory containing the MC9S12F32 demo application - has been changed to Demo/HCS12_CodeWarrior_small (as in 'small' - memory model). - + MC9S12F32 demo updated slightly to use the PLL. The CPU speed for the - demo application is now 24MHz. Previously it was 8MHz. - + The demo application file Demo/Common/Minimal/death.c has a slight - alteration to prevent it using floating point variables. - - -Changes between V3.0.0 and V3.1.0 - Released 11th June, 2005 - - + Added new ports for ST Microsystems STR71x, and Freescale HCS12 - microcontrollers. Currently the HCS12 port is limited to the small - memory model. Large memory models will be supported in the next - release. - + PIC18 wizC port updated. Thanks to Marcel van Lieshout for his - continuing contribution. - + The accuracy of the AVR port timer setup has been improved. Thanks to - Thomas Krutmann for this contribution. - + Added a new conditional compilation macro configIDLE_SHOULD_YIELD. - See the WEB documentation for details. - + Updated the CrossWorks uIP demo to build with V1.4 of CrossWorks. - + Slight modification to the SAM7 release build configuration to correct - an include path definition. - + Updated the MPLAB PIC18 documentation to provide extra details on linker - file configuration. - -Changes between V3.0.0 and V2.6.1 - Released 23rd April, 2005 - - V3.0.0 includes many enhancements, so this history list is broken into - subsections as follows: - - API changes - New ports - Directory name changes - Kernel and miscellaneous changes changes - - - API changes - - + Each port now defines BaseType_t as the data type that is most - efficient for that architecture. The type BaseType_t is used - extensively in API calls necessitating the following changes to the - FreeRTOS API function prototypes. - - See the "New for V3.0.0" section of the FreeRTOS online - documentation for full details of API changes. - - - New ports - - + The AT91FR40008 ARM7 port contributed by John Feller is now included - in the download (thanks John!). - + The PIC18 port for the wizC/fedC compiler contributed by Marcel van - Lieshout is now included in the download (thanks Marcel!). - + The IAR port for the AVR microcontroller has been upgraded to V3.0.0 - and is now a supported port. - - - Directory name changes - - For consistency, and to allow integration of the new ports, the - following directory names have been changed. - - + The source/portable/GCC/ARM7 directory has been renamed - source/portable/GCC/ARM7_LPC2000 so it is compatible with the naming - of other GCC ARM7 ports. - + The Demo/PIC directory has been renamed Demo/PIC18_MPLAB to - accommodate the wizC/fedC PIC port. - + The demo applications for the two AVR ports no longer share the same - directory. The WinAVR demo is in the Demo/AVR_ATMega323_WinAVR - directory and the IAR port in the Demo/AVR_ATMega323_IAR directory. - - - - Kernel and miscellaneous changes changes - - See the "New for V3.0.0" section of the FreeRTOS online - documentation for more information. - - + Previously 'portmacro.h' contained some user editable definitions - relating to the user application, and some fixed definitions relating - specifically to the port being used. The application specific - definitions have been removed from 'portmacro.h' and placed inside a - new header file called 'FreeRTOSConfig.h'. 'portmacro.h' should now - never be modified by the user. A 'FreeRTOSConfig.h' is now included - in each of FreeRTOS/Demo subdirectories - as it's settings relate to - the demo application rather than being specific to the port. - + Introduced configUSE_IDLE_HOOK in idle task. - + The idle task will yield when another idle priority task is ready to - run. Previously the idle task would run to the end of its time slice - regardless. - + The idle task is now created when the scheduler is started. This - requires less stack than the previous scheme where it was created upon - creation of the first application task. - + The function usPortCheckFreeStackSpace() has been renamed - usTaskCheckFreeStackSpace() and moved from the portable layer to - tasks.c. - + Corrected spelling of portMINMAL_STACK_SIZE to portMINIMAL_STACK_SIZE. - + The portheap.c file included with the AVR port has been deleted. The - AVR demo now uses the standard heap1 sample memory allocator. - + The GCC AVR port is now build using the standard make utility. The - batch files used previously have been deleted. This means a recent - version of WinAVR is required in order to create a binary suitable for - source level debugging. - + vTaskStartScheduler() no longer takes the configUSE_PREEMPTION - constant as a parameter. Instead the constant is used directly within - tasks.c and no parameter is required. - + The header file 'FreeRTOS.h' has been created and is used to include - 'projdefs.h', 'FreeRTOSConfig.h' and 'portable.h' in the necessary - order. FreeRTOS.h can now be included in place of these other - headers. - + The header file 'errors.h' has been deleted. The definitions it - contained are now located within 'projdefs.h'. - + pvPortMalloc() now takes a size_t parameter as per the ANSI malloc(). - Previously an unsigned short was used. - + When resuming the scheduler a yield is performed if either a tick has - been missed, or a task is moved from the pending ready list into a - ready list. Previously a yield was not performed on this second - condition. - + In heap1.c an overflow check has been added to ensure the next free - byte variable does not wrap around. - + Introduced the portTASK_FUNCTION() and portTASK_FUNCTION_PROTO() - macros. - + The MPLAB PIC port now saved the TABLAT register in interrupt service - routines. - -Changes between V2.6.0 and V2.6.1 - Released Feb 22, 2005 - - This version adds support for the H8 processor. - - Other changes: - - + tskMAX_TASK_NAME_LEN removed from the task.h header and added to each - individual portmacro.h file as portMAX_TASK_NAME_LEN. This allows RAM - limited ports to allocate fewer characters to the task name. - + AVR port - Replaced the inb() and outb() functions with direct memory - access. This allows the port to be built with the 20050414 build of - WinAVR. - + GCC LPC2106 port - removed the 'static' from the definition of - vNonPreemptiveTick() to allow the demo to link when using the cooperative - scheduler. - + GCC LPC2106 port - Corrected the optimisation options in the batch files - ROM_THUMB.bat, RAM_THUMB.bat, ROM_ARM.bat and RAM_ARM.bat. The lower case - -o is replaced by an uppercase -O. - + Tasks.c - The strcpy call has been removed when copying across the task - name into the TCB. - + Updated the trace visualisation to always be 4 byte aligned so it can be - used on ARM architectures. - + There are now two tracecon executables (that convert the trace file binary - into an ASCII file). One for big endian targets and one for little endian - targets. - + Added ucTasksDeleted variable to prevent vTaskSuspendAll() being called - too often in the idle task. - + SAM7 USB driver - Replaced the duplicated RX_DATA_BK0 in the interrupt - mask with the RX_DATA_BK1. - - -Changes between V2.5.5 and V2.6.0 - Released January 16, 2005 - - + Added the API function vTaskDelayUntil(). The demo app file - Demo/Common/Minimal/flash.c has been updated to demonstrate its use. - + Added INCLUDE_vTaskDelay conditional compilation. - + Changed the name of the Demo/ARM7_AtmelSAM7S64_IAR directory to - Demo/ARM7_AT91SAM7S64_IAR for consistency. - + Modified the AT91SAM7S USB driver to allow descriptors that have - a length that is an exact multiple of the FIFO to be transmitted. - -Changes between V2.5.4 and V2.5.5 - Released January 3, 2005 - - This version adds support for the Atmel SAM7 ARM7 microcontrollers - along with the IAR development tools. - - Other changes: - - + Renamed the Demo/ARM7 directory to Demo/ARM7_LPC2106_GCC. - + Renamed the Demo/ARM7_Keil directory to Demo/ARM7_LPC2129_Keil. - + Modified the Philips ARM7 serial interrupt service routines to only - process one interrupt per call. This seems to enable the ISR to - operate more quickly. - + Removed the 'far' keyword from the Open Watcom portable layer source - files. This allows their use with V1.3 of Open Watcom. - + Minor modifications to the SDCC build files to allow their use under - Linux. Thanks to Frieder Ferlemann for this contribution. - + Small change to sTaskCreate() to allow a context switch even when - pxCreatedTask is NULL. Thanks to Kamil for this contribution. - + inline keyword removed from vTaskSwitchContext() and VTaskIncrementTick() - definitions. - -Changes between V2.5.3 and V2.5.4 - Released Dec 1, 2004 - - This is an important maintenance release. - - The function cTaskResumeAll() has been modified so it can be used safely - prior to the kernel being initialised. This was an issue as - cTaskResumeAll() is called from pvPortMalloc(). Thanks to Daniel Braun - for highlighting this issue. - -Changes between V2.5.2 and V2.5.3 - Released Nov 2, 2004 - - The critical section handling functions have been changed for the GCC ARM7 - port. Some optimisation levels use the stack differently to others. This - means the interrupt flags cannot always be stored on the stack and are - instead now stored in a variable, which is then saved as part of the - tasks context. This allows the GCC ARM7 port to be used at all - optimisation levels - including -Os. - - Other minor changes: - - + MSP430 definition of usCriticalNesting now uses the volatile qualifier. - This is probably not required but added just in case. - -Changes between V2.5.1 and V2.5.2 - Released Oct 26, 2004 - - + Added the Keil ARM7 port. - + Slight modification to comtest.c to make the delay periods more random. - This creates a better test condition. - -Changes between V2.5.0 and V2.5.1 - Released Oct 9, 2004 - - + Added the MSP430 port. - + Extra comments added to the GCC ARM7 port.c and portISR.c files. - + The memory pool allocated within heap_1.c has been placed within a - structure to ensure correct memory alignment on 32bit systems. - + Within the GCC ARM7 serial drivers an extra check is made to ensure - the post to the queue was successful if then attempting immediately - retrieve the posted character. - + Changed the name of the constant portTICKS_PER_MS to portTICK_PERIOD_MS - as the old name was misleading. - - -Changes between V2.4.2 and V2.5.0 - Released Aug 12, 2004 - - The RTOS source code download now includes three separate memory allocation - schemes - so you can choose the most appropriate for your application. - These are found in the Source/Portable/MemMang directory. The demo - application projects have also been updated to demonstrate the new schemes. - See the "Memory Management" page of the API documentation for more details. - - + Added heap_1.c, heap_2.c and heap_3.c in the Source/Portable/MemMang - directory. - + Replaced the portheap.c files for each demo application with one of the - new memory allocation files. - + Updated the portmacro.h file for each demo application to include the - constants required for the new memory allocators: portTOTAL_HEAP_SIZE and - portBYTE_ALIGNMENT. - + Added a new test to the ARM7 demo application that tests the operation - of the heap_2 memory allocator. - - -Changes between V2.4.1 and V2.4.2 - Released July 14, 2004 - - + The ARM7 port now supports THUMB mode. - + Modification to the ARM7 demo application serial port driver. - -Changes between V2.4.0 and V2.4.1 - Released July 2, 2004 - - + Rationalised the ARM7 port version of portEXIT_CRITICAL() - - improvements provided by Bill Knight. - + Made demo serial driver more complete and robust. - - -Changes between V2.4.0 and V2.3.1 - Released June 30, 2004 - - + Added the first ARM7 port - thanks to Bill Knight for the assistance - provided. - + Added extra files to the Demo/Common/Minimal directory. These are - equivalent to their Demo/Common/Full counterparts but with the - calls to the functions defined in print.c removed. - + Added TABLAT to the list of registers saved as part of a PIC18 context. - -Changes between V2.3.0 and V2.3.1 - Released June 25, 2004 - - + Changed the way the vector table is defined to be more portable. - + Corrected the definitions of SPH and SPL in portmacro.s90. - The previous definitions prevented V2.3.0 operating if the iom323.h - header file was included in portmacro.s90. - -Changes between V2.2.0 and V2.3.0 - Released June 19, 2004 - - + Added an AVR port that uses the IAR compiler. - + Explicit use of 'signed' qualifier on plain char types. - + Modified the Open Watcom project files to use 'signed' as the - default char type. - + Changed odd calculation of initial pxTopOfStack value when - portSTACK_GROWTH < 0. - + Added inline qualifier to context switch functions within task.c. - Ports that do not support the (non ANSI) inline keyword have the - inline #define'd away in their respective portmacro.h files. - -Changes between V2.1.1 and V2.2.0 - Released May 18, 2004 - - + Added Cygnal 8051 port. - + PCLATU and PCLATH are now saved as part of the PIC18 context. This - allows function pointers to be used within tasks. Thanks to Javier - Espeche for the enhancement. - + Minor changes to demo application files to reduce stack usage. - + Minor changes to prevent compiler warnings when compiling the new port. - -Changes between V2.1.0 and V2.1.1 - Released March 12, 2004 - - + Bug fix - pxCurrentTCB is now initialised before the call to - prvInitialiseTaskLists(). Previously pxCurrentTCB could be accessed - while null during the initialisation sequence. Thanks to Giuseppe - Franco for the correction. - -Changes between V2.0.0 and V2.1.0 - Released Feb 29, 2004 - - V2.1.0 has significant reworks that greatly reduce the amount of time - the kernel has interrupts disabled. The first section of modifications - listed here must be taken into account by users. The second section - are related to the kernel implementation and as such are transparent. - - Section1 : - - + The typedef TickType_t has been introduced. All delay times should - now use a variable of type TickType_t in place of the unsigned long's - used previously. API function prototypes have been updated - appropriately. - + The configuration macro USE_16_BIT_TICKS has been introduced. If set - to 1 TickType_t is defined as an unsigned short. If set to 0 - TickType_t is defined as an unsigned long. See the configuration - section of the API documentation for more details. - + The configuration macro INCLUDE_vTaskSuspendAll is now obsolete. - + vTaskResumeAll() has been renamed cTaskResumeAll() as it now returns a - value (see the API documentation). - + ulTaskGetTickCount() has been renamed xTaskGetTickCount() as the type - it returns now depends on the USE_16_BIT_TICKS definition. - + cQueueReceive() must now >never< be used from within an ISR. Use the new - cQueueReceiveFromISR() function instead. - - Section 2: - - + A mechanism has been introduced that allows a queue to be accessed by - a task and ISR simultaneously. - + A "pending ready" queue has been introduced that enables interrupts to - be processed when the scheduler is suspended. - + The list implementation has been improved to provide faster item - removal. - + The scheduler now makes use of the scheduler suspend mechanism in places - where previously interrupts were disabled. - -Changes between V1.2.6 and V2.0.0 - Released Jan 31, 2004 - - + Introduced new API functions: - vTaskPriorityGet () - vTaskPrioritySet () - vTaskSuspend () - vTaskResume () - vTaskSuspendAll () - vTaskResumeAll () - + Added conditional compilation options that allow the components of the - kernel that are unused by an application to be excluded from the build. - See the Configuration section on the WEB site for more information (on - the API pages). The macros have been added to each portmacro.h file ( - sometimes called prtmacro.h). - + Rearranged tasks.c. - + Added demo application file dynamic.c. - + Updated the PC demo application to make use of dynamic.c. - + Updated the documentation contained in the kernel header files. - + Creating a task now causes a context switch if the task being created - has a higher priority than the calling task - assuming the kernel is - running. - + vTaskDelete() now only causes a context switch if the calling task is - the task being deleted. - -Changes between V1.2.5 and V1.2.6 - Released December 31, 2003 - - Barring the change to the interrupt vector (PIC port) these are minor - enhancements. - - + The interrupt vector used for the PIC master ISR has been changed from - 0x18 to 0x08 - where it should have always been. The incorrect address - still works but probably executes a number of NOP's before getting to the - ISR. - + Changed the baud rate used by the AVR demo application to 38400. This - has an error percentage of less than one percent with an 8MHz clock. - + Raised the priority of the Rx task in demo\full\comtest.c. This only - affects the Flashlite and PC ports. This was done to prevent the Rx - buffer becoming full. - + Reverted the Flashlite COM port driver back so it does not use the DMA. - The DMA appears to miss characters under stress. The Borland Flashlite - port was also calculating a register value incorrectly resulting in the - wrong DMA source address being used. The same code worked fine when - compiling with Open Watcom. Other minor enhancements were made to the - interrupt handling. - + Modified the PIC serial Rx ISR to check for and clear overrun errors. - Overrun errors seem to prevent any further characters being received. - + The PIC demo projects now have some optimisation switched on. - - -Changes between V1.2.4 and V1.2.5 - - Small fix made to the PIC specific port.c file described below. - - + Introduced portGLOBAL_INTERRUPT_FLAG definition to test the global - interrupt flag setting. Using the two bits defined within - portINITAL_INTERRUPT_STATE was causing the w register to get clobbered - before the test was performed. - -Changes between V1.2.3 and V1.2.4 - - V1.2.4 contains a release version of the PIC18 port. - An optional exception has been included with the GPL. See the licensing - section of www.FreeRTOS.org for details. - - + The function xPortInitMinimal() has been renamed to - xSerialPortInitMinimal() and the function xPortInit() has been renamed - to xSerialPortInit(). - + The function sSerialPutChar() has been renamed cSerialPutChar() and - the function return type chaned to portCHAR. - + The integer and flop tasks now include calls to tskYIELD(), allowing - them to be used with the cooperative scheduler. - + All the demo applications now use the integer and comtest tasks when the - cooperative scheduler is being used. Previously they were only used with - the preemptive scheduler. - + Minor changes made to operation of minimal versions of comtest.c and - integer.c. - + The ATMega port definition of portCPU_CLOSK_HZ definition changed to - 8MHz base 10, previously it base 16. - - - -Changes between V1.2.2a and V1.2.3 - - The only change of any significance is to the license, which has changed - from the Open Software License to the GNU GPL. - - The zip file also contains a pre-release version of the PIC18 port. This - has not yet completed testing and as such does not constitute part of the - V1.2.3 release. It is still however covered by the GNU GPL. - - There are minor source code changes to accommodate the PIC C compiler. - These mainly involve more explicit casting. - - + sTaskCreate() has been modified slightly to make use of the - portSTACK_GROWTH macro. This is required for the PIC port where the - stack grows in the opposite direction to the other existing ports. - + prvCheckTasksWaitingTermination() has been modified slightly to bring - the decrementing of usCurrentNumberOfTasks within the critical section, - where it should have been since the creation of an eight bit port. - -Changes between V1.2.2 and V1.2.2a - - The makefile and buildcoff.bat files included with the AVR demo application - have been modified for use with the September 2003 build of WinAVR. No - source files have changed. - -Changes between V1.2.1 and V1.2.2 - - There are only minor changes here to allow the PC and Flashlite 186 ports - to use the Borland V4.52 compiler, as supplied with the Flashlite 186 - development kit. - - + Introduced a BCC directory under source\portable. This contains all the - files specific to the Borland compiler port. - + Corrected the macro naming of portMS_PER_TICK to portTICKS_PER_MS. - + Modified comtest.c to increase the rate at which the string is - transmitted and received on the serial port. The Flashlite 186 demo - app baud rate has also been increased. - + The values of the constants used in both integer.c files have been - increased to force the Borland compiler to use 32 bit values. The - Borland optimiser placed the previous values in 16 bit registers, and in - So doing invalidated the test. - -Changes between V1.2.0 and V1.2.1 - - This version includes some minor changes to the list implementation aimed - at improving the context switch time - with is now approximately 10% faster. - Changes include the removal of some null pointer assignment checks. These - were redundant where the scheduler uses the list functions, but means any - user application choosing to use the same list functions must now check - that no NULL pointers are passed as a parameter. - - The Flashlite 186 serial port driver has also been modified to use a DMA - channel for transmissions. The serial driver is fully functional but still - under development. Flashlite users may prefer to use V1.2.0 for now. - - Details: - - + Changed the baud rate for the ATMega323 serial test from 19200 to 57600. - + Use vSerialPutString() instead of single character puts in - Demo\Full\Comtest.c. This allows the use of the flashlite DMA serial - driver. Also the check variable only stops incrementing after two - consecutive failures. - + semtest.c creates four tasks, two of which operate at the idle priority. - 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 signalling an error because they have not been - scheduled enough time for each of them to count the shared variable to - the higher original value. - + The flashlite 186 serial driver now uses a DMA channel for transmissions. - + Removed the volatile modifier from the list function parameters. This was - only ever included to prevent compiler warnings. Now warnings are - removed by casting parameters where the calls are made. - + prvListGetOwnerOfNextEntry() and prvListGetOwnerOfHeadEntry() have been - removed from list.c and added as macros in list.h. - + usNumberOfItems has been added to the list structure. This removes the - need for a pointer comparison when checking if a list is empty, and so - is slightly faster. - + Removed the NULL check in vListRemove(). This makes the call faster but - necessitates any application code utilising the list implementation to - ensure NULL pointers are not passed. - + Renamed portTICKS_PER_MS definition to portMS_PER_TICK (milli seconds - per tick). This is what it always should have been. - -Changes between V1.01 and V1.2.0 - - The majority of these changes were made to accommodate the 8bit AVR port. - The scheduler workings have not changed, but some of the data types used - have been made more friendly to an eight bit environment. - - Details: - - + Changed the version numbering format. - + Added AVR port. - + Split the directory demo\common into demo\common\minimal and - demo\common\full. The files in the full directory are for systems with - a display (currently PC and Flashlite 186 demo's). The files in the - minimal directory are for systems with limited RAM and no display - (currently MegaAVR). - + Minor changes to demo application function prototypes to make more use - of 8bit data types. - + Within the scheduler itself the following functions have slightly - modified declarations to make use of 8bit data types where possible: - xQueueCreate(), - sQueueReceive(), - sQUeueReceive(), - usQueueMessageWaiting(), - sQueueSendFromISR(), - sSemaphoreTake(), - sSemaphoreGive(), - sSemaphoreGiveFromISR(), - sTaskCreate(), - sTaskMoveFromEventList(). - - Where the return type has changed the function name has also changed in - accordance with the naming convention. For example - usQueueMessageWaiting() has become ucQueueMessageWaiting(). - + The definition tskMAX_PRIORITIES has been moved from task.h to - portmacro.h and renamed portMAX_PRIORITIES. This allows different - ports to allocate a different maximum number of priorities. - + By default the trace facility is off, previously USE_TRACE_FACILITY - was defined. - + comtest.c now uses a psuedo random delay between sends. This allows for - better testing as the interrupts do not arrive at regular intervals. - + Minor change to the Flashlite serial port driver. The driver is written - to demonstrate the scheduler and is not written to be efficient. - - - -Changes between V1.00 and V1.01 - - These changes improve the ports. The scheduler itself has not changed. - - Improved context switch mechanism used when performing a context - switch from an ISR (both the tick ISR and the serial comms ISR's within - the demo application). The new mechanism is faster and uses less stack. - - The assembler file portasm.asm has been replaced by a header file - portasm.h. This includes a few assembler macro definitions. - - All saving and restoring of registers onto/off of the stack is now handled - by the compiler. This means the initial stack setup for a task has to - mimic the stack used by the compiler, which is different for debug and - release builds. - - Slightly changed the operation of the demo application, details below. - - Details: - - + portSWITCH_CONTEXT() replaced by vPortFirstContext(). - + pxPortInitialiseStack() modified to replicate the stack used by the - compiler. - + portasm.asm file removed. - + portasm.h introduced. This contains macro definitions for - portSWITCH_CONTEXT() and portFIRST_CONTEXT(). - + Context switch from ISR now uses the compiler generated interrupt - mechanism. This is done simply by calling portSWITCH_CONTEXT and leaving - the save/restore to compiler generated code. - + Calls to taskYIELD() during ISR's have been replaced by calling the - simpler and faster portSWITCH_CONTEXT(). - + The Flashlite 186 port now uses 186 instruction set (used to use 80x86 - instructions only). - + The blocking queue tasks within the demo application did not operate - quite as described. This has been corrected. - + The priority of the comtest Rx task within the demo application 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. - + Prevent the call to kbhit() in main.c for debug builds as the debugger - seems to have problems stepping over the call. This if for the PC port - only. - - - +Documentation and download available at https://www.FreeRTOS.org/ + +Changes between FreeRTOS 202112.00 and FreeRTOS 202212.00 released December 2022 + + + Released LTS 2.0 versions of FreeRTOS Kernel, FreeRTOS+TCP, coreMQTT, corePKCS11, + coreHTTP, coreJSON, AWS IoT Over-the-air-Updates (OTA), AWS IoT Device Shadow, AWS IoT Jobs, + AWS IoT Device Defender, Backoff Algorithm, AWS IoT Fleet Provisioning, coreSNTP, + SigV4, and FreeRTOS Cellular Interface libraries + - FreeRTOS Kernel V10.5.1 + - FreeRTOS+TCP V3.1.0 + - coreMQTT v2.1.1 + - corePKCS11 v3.5.0 + - coreJSON v3.2.0 + - AWS IoT Over-the-air (OTA) Update v3.4.0 + - AWS IoT Device Shadow v1.3.0 + - AWS IoT Jobs v1.3.0 + - AWS IoT Device Defender v1.3.0 + - Backoff Algorithm v1.3.0 + - AWS IoT Fleet Provisioning v1.1.0 + - coreSNTP v1.2.0 + - SigV4 v1.2.0 + - FreeRTOS Cellular Interface v1.3.0 + + Updated coreMQTT Agent library to v1.2.0 to be compatible with coreMQTT v2.X.X. + + Demo Updates + - Added Visual Studio static library projects for FreeRTOS Kernel, FreeRTOS+TCP, + Logging, MbedTLS, coreHTTP, and corePKCS11 in FreeRTOS-Plus/VisualStudio_StaticProjects. + - All demos dependent on coreMQTT have been updated to be compatible with coreMQTT v2.X.X. + - All Windows Simulator projects have been updated to use new static Visual Studio projects. + + Updated MbedTLS version to 3.2.1. + +Changes between FreeRTOS 202111.00 and FreeRTOS 202112.00 released December 2021 + + + Added Fleet Provisioning library and demo showcasing the use of Fleet Provisioning library. + + Added Sigv4 library and updated HTTP S3 download demo to showcase its use. + + Added CBMC proofs for all public and private functions in the OTA Update library + + Updated mbed TLS version used by corePKCS11 to v2.28.0 + +Changes between FreeRTOS 202107.00 and FreeRTOS 202111.00 released November 2021 + + + Add Cellular library and demo showcasing use of Cellular library. + + Add demo project for [PolarFire SoC FPGA Icicle Kit](https://www.microsemi.com/existing-parts/parts/152514). + +Changes between FreeRTOS 202104.00 and FreeRTOS 202107.00 released July 2021 + + + Release coreSNTP v1.0.0, a client library for SNTP communication. + + Add demo showcasing use of coreSNTP library to setup SNTP client for + synchronizing demo system time with time servers. + + Demo Updates + - Update Device Shadow demo to use Named Shadow feature. + + +Changes between FreeRTOS 202012.00 and FreeRTOS 202104.00 released April 2021 + + + Released LTS versions of AWS IoT Device Defender, AWS IoT Jobs and + AWS IoT Over-the-air-Updates (OTA) libraries + - AWS IoT Device Defender v1.1.0 + - AWS IoT Jobs v1.1.0 + - AWS IoT Over-the-air (OTA) Update v3.0.0 + + Added new coreMQTT Agent library. + + Demo Updates + - Add basic publish-subscribe demo for coreMQTT Agent library. + - For examples of using coreMQTT Agent library to communicate with + multiple AWS IoT services from different tasks using a shared + MQTT connection, refer to https://github.com/FreeRTOS/coreMQTT-Agent-Demos + - OTA demo over MQTT + - OTA demo over HTTP + - Added custom metrics to AWS Device Defender demo. + +Changes between FreeRTOS 202011.00 and FreeRTOS 202012.00 released December 2020 + + + Includes libraries that are part of the FreeRTOS 202012.00 LTS release. + - Learn more at https:/freertos.org/lts-libraries.html + + Networking support for QEMU MPS2 + + Demo Updates + - AWS IoT Jobs Library + - AWS Device Defender + - HTTP Mutual Auth + - HTTP Plaintext + - UDP for FreeRTOS+TCP + - S3 Upload & Download + + +Changes between FreeRTOS V10.4.1 and FreeRTOS 202011.00 released November 10 2020 + + + Added new coreJSON Library. See https://www.freertos.org/json/ + + Added new coreMQTT Library. See https://www.freertos.org/mqtt/ + + Added new corePKCS11 Library. See https://www.freertos.org/pkcs11/ + + Added new AWS IoT Device Shadow Library. See + https://www.freertos.org/iot-device-shadow/ + + Updated to FreeRTOS Kernel v10.4.2. See + https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/master/History.txt + + Updated to FreeRTOS+TCP v2.3.1. See + https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/master/History.txt + + Update WolfSSL to 4.5.0 and add the WolfSSL FIPS ready demo. + + Convert most dependent libraries to Git submodules. + + Various general maintenance and improvements. + + +Changes between FreeRTOS V10.4.0 and FreeRTOS V10.4.1 released September 17 2020 + See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html + + + Fixed an incorrectly named parameter that prevented the + ulTaskNotifyTakeIndexed macro compiling, and the name space clash in the + test code that prevented this error causing test failures. + + +Changes between FreeRTOS V10.3.1 and FreeRTOS V10.4.0 released September 10 2020 + + See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html + + Major enhancements: + + + Task notifications: Prior to FreeRTOS V10.4.0 each created task had a + single direct to task notification. From FreeRTOS V10.4.0 each task has + an array of notifications. The direct to task notification API has been + extended with API functions postfixed with "Indexed" to enable the API to + operate on a task notification at any array index. See + https://www.freertos.org/RTOS-task-notifications.html for more information. + + Kernel ports that support memory protection units (MPUs): The ARMv7-M and + ARMv8-M MPU ports now support a privilege access only heap. The ARMv7-M + MPU ports now support devices that have 16 MPU regions, have the ability + to override default memory attributes for privileged code and data + regions, and have the ability to place the FreeRTOS kernel code outside of + the Flash memory. The ARMv8-M MPU ports now support tickless idle mode. + See https://www.freertos.org/FreeRTOS-MPU-memory-protection-unit.html + for more information. + + Additional noteworthy updates: + + + Code formatting is now automated to facilitate the increase in + collaborative development in Git. The auto-formated code is not identical + to the original formatting conventions. Most notably spaces are now used + in place of tabs. + + The prototypes for callback functions (those that start with "Application", + such as vApplicationStackOverflowHook()) are now in the FreeRTOS header + files, removing the need for application writers to add prototypes into + the C files in which they define the functions. + + New Renesas RXv3 port layer. + + Updates to the Synopsys ARC code, including support for EM and HS cores, + and updated BSP. + + Added new POSIX port layer that allows FreeRTOS to run on Linux hosts in + the same way the Windows port layer enables FreeRTOS to run on Windows + hosts. + + Many other minor optimisations and enhancements. For full details + see https://github.com/FreeRTOS/FreeRTOS-Kernel/commits/master + + +Changes between FreeRTOS V10.3.0 and FreeRTOS V10.3.1 released February 18 2020 + + See https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html + + + ./FreeRTOS-Labs directory was removed from this file. The libraries it + contained are now available as a separate download. + +Changes between FreeRTOS V10.2.1 and FreeRTOS V10.3.0 released February 7 2020 + + See https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html + + New and updated kernel ports: + + + Added RISC-V port for the IAR compiler. + + Update the Windows simulator port to use a synchronous object to prevent + a user reported error whereby a task continues to run for a short time + after being moved to the Blocked state. Note we were not able to + replicate the reported issue and it likely depends on your CPU model. + + Correct alignment of stack top in RISC-V port when + configISR_STACK_SIZE_WORDS is defined to a non zero value, which causes + the interrupt stack to be statically allocated. + + The RISC-V machine timer compare register can now be for any HART, whereas + previously it was always assumed FreeRTOS was running on HART 0. + + Update the sequence used to update the 64-bit machine timer + compare register on 32-bit cores to match that suggested in RISC-V + documentation. + + Added tickless low power modes into the ARM, IAR and GCC Cortex-M0 compiler + ports. + + Updated the behaviour of the ARMv7-M MPU (Memory Protection Unit) ports to + match that of the ARMv8-M ports whereby privilege escalations can only + originate from within the kernel's own memory segment. Added + configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY configuration constant. + + Update existing MPU ports to correctly disable the MPU before it is + updated. + + Added contributed port and demo application for a T-Head (formally C-SKY) + microcontroller. + + New API functions: + + + Added the vPortGetHeapStats() API function which returns information on + the heap_4 and heap_5 state. + + Added xTaskCatchUpTicks(), which corrects the tick count value after the + application code has held interrupts disabled for an extended period. + + Added xTaskNotifyValueClear() API function. + + Added uxTimerGetReloadMode() API function. + + Other miscellaneous changes: + + Change type of uxPendedTicks from UBaseType_t to TickType_t to ensure it + has the same type as variables with which it is compared to, and therefore + also renamed the variable xPendingTicks. + + Update Keil projects that use the MPU so memory regions come from linker + script (scatter file) variables instead of being hard coded. + + Added LPC51U68 Cortex-M0+ demos for GCC (MCUXpresso), Keil and IAR + compilers. + + Added CORTEX_MPU_STM32L4_Discovery_Keil_STM32Cube demo. + + Added LPC54018 MPU demo. + + Rename xTaskGetIdleRunTimeCounter() to ulTaskGetIdleRunTimeCounter(). + + +Changes between FreeRTOS V10.2.1 and FreeRTOS V10.2.0 released May 13 2019: + + + Added ARM Cortex-M23 port layer to complement the pre-existing ARM + Cortex-M33 port layer. + + The RISC-V port now automatically switches between 32-bit and 64-bit + cores. + + Introduced the portMEMORY_BARRIER macro to prevent instruction re-ordering + when GCC link time optimisation is used. + + Introduced the portDONT_DISCARD macro to the ARMv8-M ports to try and + prevent the secure side builds from removing symbols required by the + non secure side build. + + Introduced the portARCH_NAME to provide additional data to select semi- + automated build environments. + + Cortex-M33 and Cortex-M23 ports now correctly disable the MPU before + updating the MPU registers. + + + Added Nuvoton NuMaker-PFM-M2351 ARM Cortex-M23 demo. + + Added LPC55S69 ARM Cortex-M33 demo. + + Added an STM32 dual core AMP stress test demo. + + +Changes between FreeRTOS V10.1.1 and FreeRTOS V10.2.0 released February 25 2019: + + + Added GCC RISC-V MCU port with three separate demo applications. + + Included pre-existing ARM Cortex-M33 (ARMv8-M) GCC/ARMclang and IAR ports + with Keil simulator demo. + + Update the method used to detect if a timer is active. Previously the + timer was deemed to be inactive if it was not referenced from a list. + However, when a timer is updated it is temporarily removed from, then + re-added to a list, so now the timer's active status is stored separately. + + Add vTimerSetReloadMode(), xTaskGetIdleRunTimeCounter(), and + xTaskGetApplicationTaskTagFromISR() API functions. + + Updated third party Xtensa port so it is MIT licensed. + + Added configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H to the Renesas + compiler RX600v2 port to enable switching between platform.h and + iodefine.h includes within that port's port.c file. + + Removed the 'FromISR' functions from the MPU ports as ISRs run privileged + anyway. + + Added uxTaskGetStackHighWaterMark2() function to enable the return type to + be changed without breaking backward compatibility. + uxTaskGetStackHighWaterMark() returns a UBaseType_t as always, + uxTaskGetStackHighWaterMark2() returns configSTACK_DEPTH_TYPE to allow the + user to determine the return type. + + Fixed issues in memory protected ports related to different combinations + of static memory only and dynamic memory only builds. As a result the + definition of tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE became more + complex and was moved to FreeRTOS.h with a table explaining its definition. + + Added a 'get task tag from ISR' function. + + Change the method used to determine if a timer is active or not from just + seeing if it is referenced from the active timer list to storing its + active state explicitly. The change prevents the timer reporting that it + is inactive while it is being moved from one list to another. + + The pcName parameter passed into the task create functions can be NULL, + previously a name had to be provided. + + When using tickless idle, prvResetNextTaskUnblockTime() is now only called + in xTaskRemoveFromEventList() if the scheduler is not suspended. + + Introduced portHAS_STACK_OVERFLOW_CHECKING, which should be set to 1 for + FreeRTOS ports that run on architectures that have stack limit registers. + + +Changes between FreeRTOS V10.1.0 and FreeRTOS V10.1.1 released 7 September 2018 + + + Reverted a few structure name changes that broke several kernel aware + debugger plug-ins. + + Updated to the latest trace recorder code. + + Fixed some formatting in the FreeRTOS+TCP TCP/IP stack code. + + Reverted moving some variables from file to function scope as doing so + broke debug scenarios that require the static qualifier to be removed. + +Changes between FreeRTOS V10.0.1 and FreeRTOS V10.1.0 released 22 August 2018 + + FreeRTOS Kernel Changes: + + + Update lint checked MISRA compliance to use the latest MISRA standard, was + previously using the original MISRA standard. + + Updated all object handles (TaskHandle_t, QueueHandle_t, etc.) to be + unique types instead of void pointers, improving type safety. (this was + attempted some years back but had to be backed out due to bugs in some + debuggers). Note this required the pvContainer member of a ListItem_t + struct to be renamed - set configENABLE_BACKWARD_COMPATIBILITY to 1 if + this causes an issue. + + Added configUSE_POSIX_ERRNO to enable per task POSIX style errno + functionality in a more user friendly way - previously the generic thread + local storage feature was used for this purpose. + + Added Xtensa port and demo application for the XCC compiler. + + Changed the implementation of vPortEndScheduler() for the Win32 port to + simply call exit( 0 ). + + Bug fix in vPortEnableInterrupt() for the GCC Microblaze port to protect + the read modify write access to an internal Microblaze register. + + Fix minor niggles when the MPU is used with regards to prototype + differences, static struct size differences, etc. + + The usStackHighWaterMark member of the TaskStatus_t structure now has type + configSTACK_DEPTH_TYPE in place of uint16_t - that change should have been + made when the configSTACK_DEPTH_TYPE type (which gets around the previous + 16-bit limit on stack size specifications) was introduced. + + Added the xMessageBufferNextLengthBytes() API function and likewise stream + buffer equivalent. + + Introduce configMESSAGE_BUFFER_LENGTH_TYPE to allow the number of bytes + used to hold the length of a message in the message buffer to be reduced. + configMESSAGE_BUFFER_LENGTH_TYPE default to size_t, but if, for example, + messages can never be more than 255 bytes it could be set to uint8_t, + saving 3 bytes each time a message is written into the message buffer + (assuming sizeof( size_t ) is 4). + + Updated the StaticTimer_t structure to ensure it matches the size of the + Timer_t structure when the size of TaskFunction_t does not equal the size + of void *. + + Update various Xilinx demos to use 2018.1 version of the SDK tools. + + Various updates to demo tasks to maintain test coverage. + + FreeRTOS+UDP was removed in FreeRTOS V10.1.0 as it was replaced by + FreeRTOS+TCP, which was brought into the main download in FreeRTOS + V10.0.0. FreeRTOS+TCP can be configured as a UDP only stack, and + FreeRTOS+UDP does not contain the patches applied to FreeRTOS+TCP. + + FreeRTOS+TCP Changes: + + + Multiple security improvements and fixes in packet parsing routines, DNS + caching, and TCP sequence number and ID generation. + + Disable NBNS and LLMNR by default. + + Add TCP hang protection by default. + + We thank Ori Karliner of Zimperium zLabs Team for reporting these issues. + + +Changes between FreeRTOS V10.0.0 and FreeRTOS V10.0.1, released December 20 2017 + + + Fix position of "#if defined( __cplusplus )" in stream_buffer.h. + + Correct declarations of MPU_xQueuePeek() and MPU_xQueueSemaphoreTake() in + mpu_prototypes.h. + + Correct formatting in vTaskList() helper function when it prints the state + of the currently executing task. + + Introduce #error if stream_buffer.c is built without + configUSE_TASK_NOTIFICATIONS set to 1. + + Update FreeRTOS+TCP to V2.0.0 + - Improve the formatting of text that displays the available netword + interfaces when FreeRTOS+TCP is used on Windows with WinPCap. + - Introduce ipconfigSOCKET_HAS_USER_WAKE_CALLBACK option to enable a user + definable callback to execute when data arrives on a socket. + +Changes between FreeRTOS V9.0.1 and FreeRTOS V10.0.0: + + The FreeRTOS kernel is now MIT licensed: https://www.FreeRTOS.org/license + + New Features and components: + + + Stream Buffers - see https://www.FreeRTOS.org/RTOS-stream-buffer-example.html + + Message Buffers - see https://www.FreeRTOS.org//RTOS-message-buffer-example.html + + Move FreeRTOS+TCP into the main repository, along with the basic Win32 + TCP demo FreeRTOS_Plus_TCP_Minimal_Windows_Simulator. + + New ports or demos: + + + Added demo for TI SimpleLink CC3220 MCU. + + Added MPU and non MPU projects for Microchip CEC and MEC 17xx and 51xx + MCUs. + + Added CORTEX_MPU_Static_Simulator_Keil_GCC demo to test static allocation + in the MPU port. + + Fixes or enhancements: + + + Cortex-M ports push additional register prior to calling + vTaskSwitchContext to ensure 8-byte alignment is maintained. Only + important if a user defined tick hook function performs an operation that + requires 8-byte alignment. + + Optimisations to the implementation of the standard tickless idle mode on + Cortex-M devices. + + Improvements to the Win32 port including using higher priority threads. + + Ensure interrupt stack alignment on PIC32 ports. + + Updated GCC TriCore port to build with later compiler versions. + + Update mpu_wrappers.c to support static allocation. + + The uxNumberOfItems member of List_t is now volatile - solving an issue + when the IAR compiler was used with maximum optimization. + + Introduced configRECORD_STACK_HIGH_ADDRESS. When set to 1 the stack start + address is saved into each task's TCB (assuming stack grows down). + + Introduced configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H to allow user defined + functionality, and user defined initialisation, to be added to FreeRTOS's + tasks.c source file. When configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H is + set to 1 a user provided header file called freertos_task_c_additions.h + will be included at the bottom of tasks.c. Functions defined in that + header file can call freertos_tasks_c_additions_init(), which in turn + calls a macro called FREERTOS_TASKS_C_ADDITIONS_INIT(), if it is defined. + FREERTOS_TASKS_C_ADDITIONS_INIT() can be defined in FreeRTOSConfig.h. + + Introduced configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) which can be + defined by a user in FreeRTOSConfig.h. The macro is called before + assessing whether to enter tickless idle mode or not. If the macro sets + x to zero then tickless idle mode will not be entered. This allows users + to abort tickless idle mode entry before the tickless idle function is + even called - previously it was only possible to abort from within the + tickless idle function itself. + + Added configPRINTF(), which can be defined by users to allow all libraries + to use the same print formatter. + + Introduced configMAX() and configMIN() macros which default to standard + max( x, y ) and min( x, y ) macro behaviour, but can be overridden if the + application writer defines the same macros in FreeRTOSConfig.h. + + Corrected the definition of StaticTask_t in the case where + INCLUDE_xTaskAbortDelay is set to 1. + + Introduced configTIMER_SERVICE_TASK_NAME and configIDLE_TASK_NAME, both of + which can be defined to strings in FreeRTOSConfig.h to change the default + names of the timer service and idle tasks respectively. + + Only fill the stack of a newly created task with a known value if stack + checking, or high water mark checking/viewing, is in use - removing the + dependency on memset() in other cases. + + Introduced xTaskCreateRestrictedStatic() so static allocation can be used + with the MPU. + + Ensure suspended tasks cannot be unsuspended by a received task + notification. + + Fix race condition in vTaskSetTimeOutState(). + + Updated trace recorder files to the latest version. + +Changes since FreeRTOS V9.0.0: + + + Priority dis-inheritance behaviour has been enhanced in the case where a + task that attempted to take a mutex that was held by a lower priority task + timed out before it was able to obtain the mutex (causing the task that + holds the mutex to have its priority raised, then lowered again, in + accordance with the priority inheritance protocol). + + Split the overloaded xQueueGenericReceive() function into three separate + dedicated functions. + + Allow the default human readable text names given to the Idle and Timer + tasks to be overridden by defining the configIDLE_TASK_NAME and + configTIMER_SERVICE_TASK_NAME definitions respectively in FreeRTOSConfig.h. + + Introduced configINITIAL_TICK_COUNT to allow the tick count to take a + value of than than 0 when the system boots. This can be useful for + testing purposes - although setting configUSE_16_BIT_TICKS to 1 can also + be used to test frequent tick overflows. + + Ensure the Cortex-M SysTick count is cleared to zero before starting the + first task. + + Add configASSERT() into ARM Cortex-M ports to check the number of priority + bit settings. + + Clear the 'control' register before starting ARM Cortex-M4F ports in case + the FPU is used before the scheduler is started. This just saves a few + bytes on the main stack as it prevents space being left for a later save + of FPU registers. + + Added xSemaphoreGetMutexHolderFromISR(). + + Corrected use of portNVIC_PENDSVSET to portNVIC_PENDSVSET_BIT in MPU ports. + + Introduced configSTACK_DEPTH_TYPE to allow users to change the type used + to specify the stack size when using xTaskCreate(). For historic reasons, + when FreeRTOS was only used on small MCUs, the type was set to uint16_t, + but that can be too restrictive when FreeRTOS is used on larger + processors. configSTACK_DEPTH_TYPE defaults to uint16_t. + xTaskCreateStatic(), being a newer function, used a uint32_t. + + Increase the priority of the Windows threads used by the Win32 port. As + all the threads run on the same core, and the threads run with very high + priority, there is a risk that the host will become unresponsive, so also + prevent the Windows port executing on single core hosts. + +Changes between FreeRTOS V9.0.0 and FreeRTOS V9.0.0rc2 released May 25 2016: + + See https://www.FreeRTOS.org/FreeRTOS-V9.html + + RTOS kernel updates: + + + The prototype of the new xTaskCreateStatic() API function was modified to + remove a parameter and improve compatibility with other new + "CreateStatic()" API functions. The stack size parameter in + xTaskCreateStatic() is now uint32_t, which changes the prototype of the + callback functions. See the following URL: + https://www.FreeRTOS.org/xTaskCreateStatic.html + + GCC ARM Cortex-A port: Introduced the configUSE_TASK_FPU_SUPPORT + constant. When configUSE_TASK_FPU_SUPPORT is set to 2 every task is + automatically given a floating point (FPU) context. + + GCC ARM Cortex-A port: It is now possible to automatically save and + restore all floating point (FPU) registers on entry to each potentially + nested interrupt by defining vApplicationFPUSafeIRQHandler() instead of + vApplicationIRQHandler(). + + All ARM Cortex-M3/4F/7 ports: Clear the least significant bit of the task + entry address placed onto the stack of a task when the task is created for + strict compliance with the ARM Cortex-M3/4/7 architecture documentation + (no noticeable effect unless using the QMEU emulator). + + Added GCC and Keil ARM Cortex-M4F MPU ports - previously the MPU was only + supported on ARM Cortex-M3. + + ARM Cortex-M3/4F MPU ports: Update to fully support the FreeRTOS V9.0.0 + API (other than static object creation) and added the + FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC demo application to + demonstrate how to use the updated MPU port. + + All ARM Cortex-M3/4F/7 ports: Add additional barrier instructions to the + default low power tickless implementation. + + All ARM Cortex-M0 ports: Prevent an item being left on the stack of the + first task that executes. + + Win32 ports: Reduce the amount of stack used and change the way Windows + threads are deleted to increase the maximum execution time. + + Add an ARM Cortex-M4F port for the MikroC compiler. Ensure to read the + documentation page for this port before use. + + MPS430X IAR port: Update to be compatible with the latest EW430 tools + release. + + IAR32 GCC port: Correct vPortExitCritical() when + configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY. + + For consistency vTaskGetTaskInfo() now has the alias vTaskGetInfo(), + xTaskGetTaskHandle() now has the alias xTaskGetHandle() and + pcQueueGetQueueName() now has an alias pcQueueGetName(). + + Fix various errors in comments and compiler warnings. + + Demo application updates: + + + Update Atmel Studio projects to use Atmel Studio 7. + + Update Xilinx SDK projects to use the 2016.1 version of the SDK. + + Remove dependency on legacy IO libraries from the PIC32 demos. + + Move the Xilinx UltraScale Cortex-R5 demo into the main distribution. + + Update the MSP432 libraries to the latest version. + + Add Microchip CEC1302 (ARM Cortex-M4F) demos for GCC, Keil and MikroC + compilers. + + Move the Atmel SAMA5D2 demo into the main distribution. + +Changes between FreeRTOS V9.0.0rc1 and FreeRTOS V9.0.0rc2 (release candidate 2) +released March 30 2016: + + NOTE - See https://www.FreeRTOS.org/FreeRTOS-V9.html for details + + + The functions that create RTOS objects using static memory allocation have + been simplified and will not revert to using dynamic allocation if a + buffer is passed into a function as NULL. + + Introduced the configSUPPORT_DYNAMIC_ALLOCATION configuration constant to + allow a FreeRTOS application to be built without a heap even being being + defined. The Win32 example located in the + /FreeRTOS/demo/WIN32-MSVC-Static-Allocation-Only directory is provided as + a reference for projects that do not include a FreeRTOS heap. + + Minor run-time optimisations. + + Two new low power tickless implementations that target Silicon Labs EFM32 + microcontrollers. + + Addition of the xTimerGetPeriod() and xTimerGetExpireTime() API functions. + +Changes between FreeRTOS V8.2.3 and FreeRTOS V9.0.0rc1 (release candidate 1) +released February 19 2016: + + RTOS Kernel Updates: + + + Major new feature - tasks, semaphores, queues, timers and event groups can + now be created using statically allocated memory, so without any calls to + pvPortMalloc(). + + Major new features - Added the xTaskAbortDelay() API function which allows + one task to force another task to immediately leave the Blocked state, + even if the event the blocked task is waiting for has not occurred, or the + blocked task's timeout has not expired. + + Updates necessary to allow FreeRTOS to run on 64-bit architectures. + + Added vApplicationDaemonTaskStartupHook() which executes when the RTOS + daemon task (which used to be called the timer service task) starts + running. This is useful if the application includes initialisation code + that would benefit from executing after the scheduler has been started. + + Added the xTaskGetTaskHandle() API function, which obtains a task handle + from the task's name. xTaskGetTaskHandle() uses multiple string compare + operations, so it is recommended that it is called only once per task. + The handle returned by xTaskGetTaskHandle() can then be stored locally for + later re-use. + + Added the pcQueueGetQueueName() API function, which obtains the name of + a queue from the queue's handle. + + Tickless idling (for low power applications) can now also be used when + configUSE_PREEMPTION is 0. + + If one task deletes another task, then the stack and TCB of the deleted + task is now freed immediately. If a task deletes itself, then the stack + and TCB of the deleted task are freed by the Idle task as before. + + If a task notification is used to unblock a task from an ISR, but the + xHigherPriorityTaskWoken parameter is not used, then pend a context switch + that will then occur during the next tick interrupt. + + Heap_1.c and Heap_2.c now use the configAPPLICATION_ALLOCATED_HEAP + settings, which previously was only used by heap_4.c. + configAPPLICATION_ALLOCATED_HEAP allows the application writer to declare + the array that will be used as the FreeRTOS heap, and in-so-doing, place + the heap at a specific memory location. + + TaskStatus_t structures are used to obtain details of a task. + TaskStatus_t now includes the bae address of the task's stack. + + Added the vTaskGetTaskInfo() API function, which returns a TaskStatus_t + structure that contains information about a single task. Previously this + information could only be obtained for all the tasks at once, as an array + of TaskStatus_t structures. + + Added the uxSemaphoreGetCount() API function. + + Replicate previous Cortex-M4F and Cortex-M7 optimisations in some + Cortex-M3 port layers. + + Demo Application Updates: + + Further demo applications will be added prior to the final FreeRTOS V9 + release. + + + Updated SAM4L Atmel Studio project to use Atmel Studio 7. + + Added ARM Cortex-A53 64-bit port. + + Added a port and demo for the ARM Cortex-A53 64-bit cores on the Xilinx + Ultrascale MPSoC. + + Added Cortex-M7 SAME70 GCC demo. + + Added EFM32 Giant and Wonder Gecko demos. + + +Changes between V8.2.2 and V8.2.3 released October 16, 2015 + + RTOS kernel updates: + + + Fix bug identified in a modification made in V8.2.2 to the software timer + code that allows tickless low power applications to sleep indefinitely + when software timers are used. + + Simplify and improve efficiency of stack overflow checking. + + Add xTaskNotifyStateClear() API function. + + New IAR and GCC Cortex-R ports for microprocessors that do not use an ARM + generic interrupt controller (GIC). + + New PIC32MEC14xx port. + + Add support for PIC32MZ EF parts (with floating point) into the PIC32MZ + port. + + Zynq7000 port layer now declares the functions that setup and clear the + tick interrupt as weak symbols so they can be overridden by the + application, and uses a global XScuGic object so the same object can be + used by the application code. + + Introduced configUSE_TASK_FPU_SUPPORT, although the PIC32MZ EF port is + currently the only port that uses it. + + Updates to RL78 and 78K0 IAR port layers to improve support for + combinations of memory models. + + Minor updates to heap_5.c to remove compiler warnings generated by some + compilers. + + License simplifications. See /FreeRTOS/License/license.txt in the + official distribution. + + FreeRTOS+ updates: + + + Update directory names to use WolfSSL instead of CyaSSL, inline with + WolfSSL's re-branding. + + Update to latest WolfSSL code. + + Update to latest FreeRTOS+Trace recorder code. + + Add in the FreeRTOS+Trace recorder library required for streaming trace. + + Demo application changes: + + + Add demo applications for Renesas RZ/T (Cortex-R), PIC32MZ EF (PIC32 with + floating point hardware), PIC32MEC14xx, RX71M, RX113 and RX231. + + General tidy up of spelling and compiler warnings. + + +Changes between V8.2.1 and V8.2.2 released August 12, 2015 + + RTOS kernel updates: + + + Added Intel IA32/x86 32-bit port. + + General maintenance. + + PRIVILEGED_FUNCTION and PRIVILEGED_DATA macros, which are used in memory + protected systems, have been added to the newer event group and software + timer functions. + + Add the errno definitions used by FreeRTOS+ components into projdefs.h. + + Remove the restriction that prevented tick-less idle implementations + waiting indefinitely when software timers were used in the same + application. + + Introduce xTaskNotifyAndQueryFromISR() as the interrupt safe version of + xTaskNotifyAndQuery(). + + Add additional NOPs to the MSP430X port layers to ensure strict compliance + with the hardware documentation. + + Microblaze port: Added option for port optimised task selection. + + Microblaze port: Previously tasks inherited the exception enable state + at the time the task was created. Now all tasks are created with + exceptions enabled if the Microblaze design supports exceptions. + + Windows port: Add additional safe guards to ensure the correct start up + sequence and thread switching timing. + + Windows port: Improve the implementation of the port optimised task + selection assembly code. + + Update heap_4 and heap_5 to allow use on 64-bit processors. + + Simplify the code that creates a queue. + + General improved tick-less idle behaviour. + + Ensure none of the variables in the common kernel files are initialised to + anything other than zero. + + Correct calculation of xHeapStructSize in heap_4 and heap_5. + + Demo application updates: + + + Added demo project for the new IA32/x86 port that targets the Galileo + hardware. + + Added MSP430FR5969 demos (previously provided as a separate download). + + Added FreeRTOS BSP repository for automatic creation of FreeRTOS + applications in the Xilinx SDK. + + Added Atmel Studio / GCC project for the SAMV71 (ARM Cortex-M7) + + Update Xilinx SDK projects to use version 2015.2 of the SDK. + + Remove Microblaze demos that were using obsolete tools. + + Add MSP43FR5969 IAR and CCS demos. + + FreeRTOS+ Updates: + + + Updated FreeRTOS+Trace recorder library, which requires an update to the + FreeRTOS+Trace application. + + Added Reliance Edge source code and demo application. Reliance edge is + a fail safe transactional file system ideal for applications that require + file storage, and especially when high reliability is essential. + + Introduce configAPPLICATION_PROVIDES_cOutputBuffer to allow FreeRTOS+CLI + users to place the output buffer at a fixed memory address. + + Improve the NetworkInterface.c file provided for the Windows port of + FreeRTOS+UDP. + +Changes between V8.2.0 and V8.2.1 released 24th March 2015. + + RTOS kernel updates: + + + Added user definable and flexible thread local storage facility. + + Added vTimerSetTimerID() API function to complement the pvTimerGetTimerID() + function to allow the timer's ID to be used as timer local storage. + + Fixed a potential issue related to the use of queue sets from an ISR. + + Some updates to the Xilinx Microblaze GCC port. + + Added ARM Cortex-M4F port for Texas Instruments Code Composer Studio. + + Added ARM Cortex-M7 r0p1 port layer for IAR, GCC and Keil which contains a + minor errata work around. All other ARM Cortex-M7 core revisions should + use the ARM Cortex-M4F port. + + Exclude the whole of croutine.c if configUSE_CO_ROUTINES is set to 0. + + Change some data types from uint32_t to size_t in preparation for 64-bit + Windows port. + + Update the PIC32 port to remove deprecation warnings output by the latest + XC32 compilers. + + Fix bug when xQueueOverwrite() and xQueueOverwrite() from ISR are used to + overwrite items in two queues that are part of the same set. + + Demo application updates: + + + Added demo application for TI's ARM Cortex-M4F based MSP432 + microcontroller using IAR, Keil and CCS compilers. + + Added demo application for STM32F ARM Cortex-M7 based microcontroller + using IAR and Keil. + + Added demo application for Atmel SAMV71 ARM Cortex-M7 based + microcontroller using IAR and Keil. + + Added Microblaze demo that uses the 2014.4 version of the Xilinx SDK and + runs on the KC705 evaluation board (Kintex FPGA). + +Changes between V8.1.2 and V8.2.0 released 16th January 2015 + + Changes between release candidate 1 and the official release are restricted + to maintenance only. + + Significant RTOS kernel updates: + + + MAJOR NEW FEATURE! Task notifications. Please see the following URL for + details: https://www.FreeRTOS.org/RTOS-task-notifications.html + + NEW HEADER FILE REQUIRED! Obsolete definitions have been separated into + a new header file called FreeRTOS/Source/include/deprecated_definitions.h. + This header file must be present to build. Note some of the obsolete + definitions are still used by very old demo application projects. + + Other RTOS kernel updates: + + + Made xSemaphoreGiveFromISR() a function rather than a macro that calls + xQueueGenericSendFromISR(). This allows for major performance + enhancements at the expense of some additional code size if both functions + are used in the same application. NOTE: In most uses cases such use of + a semaphore can now be replaced with a task notification which is smaller + and faster still. + + The TCB is now always allocated such that the task's stack grows away from + the TCB (improves debugging of stack overflows as the overflow will not + overwrite the task's name). + + GCC, IAR and Keil Cortex-M4F ports now use more inlining (performance + enhancements at the cost of a little additional code space). + + Queues are now allocated with a single call to pvPortMalloc() which + allocates both the queue structure and the queue storage area. + + Introduced a new critical section macro for reading the tick count that + defines away to nothing in cases where the width of the tick allows the + tick count to be read atomically (performance benefits - especially when + optimisation is on). + + Introduced configAPPLICATION_ALLOCATED_HEAP in heap_4.c to allow the + application writer to provide their own heap array - and in so doing + control the location of the heap. + + Introduced configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES which, when set, will + include known values in both list and list item structures. The values + are intended to assist debugging. If the values get overwritten then it + is likely application code has written over RAM used by the kernel. + + configASSERT()s in all Cortex-M ports used to test the lowest 5 bits of + the interrupt control register to detect taskENTER_CRITICAL() being called + from an interrupt. This has been changed to test all 8 bits. + + Introduced uxTaskPriorityGetFromISR(). + + Microblze V8 port now tests XPAR_MICROBLAZE_0_USE_FPU for inequality to 0 + rather than equality to 1, and 2 and 3 are also valid values. + + Cortex-A5 GIC-less port no longer passes the address of the interrupting + peripheral into the interrupt handler. + + Fix an issue in FreeRTOS-MPU where an attempt was made to free the stack + belonging to a task when the task was deleted, even when the stack was + allocated statically. + + Utility (helper) functions that format task statistic information into + human readable tables now pad task names with spaces to ensure columns + line up correctly even where task name lengths vary greatly. + + Update FreeRTOS+Trace recorder library to version 2.7.0. + + Demo application updates: + + + Added two new standard demo task sets: IntSemTest and TaskNotify. + + Added port and demo application for Atmel SAMA5D4 Cortex-A5 MPU. + + Added demo application for Altera Cyclone V Cortex-A9 MPU. + + Updated Zynq demo to use version 2014.4 of Xilinx's SDK and added in + demo tasks for new RTOS features. + + Updated Atmel SAM4E and SAM4S demos to include a lot of additional test + and demo tasks. + + Fixed a corner case issue in Atmel SAM4L low power tickless + implementation, and added button interrupt handling. + + Make the interrupt queue tests more tolerant to heave CPU loads. + + Updated MSVC FreeRTOS simulator demo to include the latest standard test + and demo tasks. + + Updated MingW/Eclipse FreeRTOS simulator demo to match the FreeRTOS MSVC + simulator demo. + + Updated all demos that use FreeRTOS+Trace to work with the latest trace + recorder code. + + +Changes between V8.1.1 and V8.1.2 released September 2nd 2014 + + Move the defaulting of configUSE_PORT_OPTIMISED_TASK_SELECTION into the + individual port layers where necessary so it does not affect ports that do + not support the definition. + +Changes between V8.1.0 and V8.1.1 released August 29th 2014 + + By popular requests - a minor patch to V8.1.0 to re-instate the ability to + give a mutex type semaphore (with priority inheritance) from an interrupt + handler. + +Changes between V8.0.1 and V8.1.0 released August 26th 2014 + + FreeRTOS scheduler, kernel, demo and test updates: + + + Improved the priority inheritance algorithms to assist integration with + off the shelf middleware that may hold multiple mutexes simultaneously. + + Introduce heap_5.c, which is similar to heap_4.c but allows the heap to + span multiple non-contiguous memory regions. + + Updated all Cortex-A9 ports to help trap a couple of common usage errors - + the first being when a task incorrectly attempts to exit its implementing + function and the second being when a non interrupt safe API function is + called from an interrupt. + + Update all Cortex-A9 ports to remove obsolete mode switches prior to + restoring a task context. + + configUSE_PORT_OPTIMISED_TASK_SELECTION now defaults to 1 instead of 0. + + Update all Cortex-M3/4F ports to trap a non interrupt safe API function + being called from an interrupt handler. + + Simplify the alignment checks in heap_4.c. + + Update the MSVC Windows simulator demo to use heap_5.c in place of + heap_4.c to ensure end users have an example to refer to. + + Updated standard demo test code to test the new priority inheritance + algorithms. + + Updated the standard demo tasks to make use of stdint and the FreeRTOS + specific typedefs that were introduced in FreeRTOS V8.0.0. + + Introduce the pdMS_TO_TICKS() macro as a more user friendly and intuitive + alternative to pdTICKS_PER_MS - both of which can be used to convert a + time specified in milliseconds to a time specified in RTOS ticks. + + Fix a bug in the Tasking compiler's Cortex-M port that resulted in an + incorrect value being written to the basepri register. This only effects + users of the Tasking compiler. + + Update the Zynq demo to use version 2014.2 of the SDK and add in an lwIP + example that demonstrates lwIP being used with both its raw and sockets + interfaces. + + Updated the CCS Cortex-R4 port to enable it to be built with the latest + CCS compiler. + + New ports and demo applications: + + + Two Renesas RX64M ports (RXv2 core) and demos introduced, one for the GCC + compiler and one for the Renesas compiler. Both demos use e2 studio. + + Generic IAR Cortex-A5 port (without any reliance on a GIC) introduced. + The new port is demonstrated on an Atmel SAMA5D3 XPlained board. + + FreeRTOS+ component updates: + + + Update CyaSSL to the latest version. + + Updated the FreeRTOS+ components supplied directly by Real Time Engineers + Ltd. to make use of stdint and the FreeRTOS specific typedefs that were + introduced in FreeRTOS V8.0.0. + + Rework and simplify the FreeRTOS+FAT SL RAM disk driver. + + Miscellaneous updates and maintenance: + + + Update the IAR and DS-5/ARM RZ demos to target the official RZ RSK + hardware in place of the previously targeted Renesas internal (not + publicly available) hardware. + + Various other maintenance tasks. + + +Changes between V8.0.0 and V8.0.1 released 2nd May 2014 + + + Minor fixes to the event group functionality that was released in V8.0.0. + The 'clear bits from ISR' functionality is now implemented using a + deferred interrupt callback instead of a function, and the 'wait bits' and + 'task sync' functions now correctly clear internal control bits before + returning a value in every possible path through the respective functions. + + Ensure the updating of internal control data is protected by a critical + section after a task is deleted or suspended. + + Minor fixes to FreeRTOS+FAT SL - namely seeking beyond the end of a file + when the offset was not a multiple of the sector size. + + Ensure Cortex-A9 system registers are only ever accessed as 32-bit values, + even when only the lest significant byte of the register is implemented. + + Other updates: + + + Updated the XMC4200 IAR project so it links with version 7.x of the IAR + tools. + + Add RL78L1C demo. + + Add pcTimerGetName() API function. + + Call _reclaim_reent() when a task is deleted if configUSE_NEWLIB_REENTRANT + is defined. + +Changes between V7.6.0 and V8.0.0 released 19th Feb 2014 + + https://www.FreeRTOS.org/upgrading-to-FreeRTOS-V8.html + + FreeRTOS V8.x.x is a drop-in compatible replacement for FreeRTOS V7.x.x, + although a change to the type used to reference character strings may result + in application code generating a few (easily clearable) compiler warnings + after the upgrade, and an updated typedef naming convention means use of the + old typedef names is now discouraged. + See https://www.FreeRTOS.org/upgrading-to-FreeRTOS-V8.html for full + information. + + New features and functionality: + + + Event groups - see https://www.FreeRTOS.org/FreeRTOS-Event-Groups.html + + Centralised deferred interrupt processing - see + https://www.FreeRTOS.org/xTimerPendFunctionCallFromISR.html + + Other updates: + + + Previously, when a task left the Blocked state, a context switch was + performed if the priority of the unblocked task was greater than or equal + to the priority of the Running task. Now a context switch is only + performed if the priority of the unblocked task is greater than the + priority of the Running task. + + New low power tickless demonstration project that targets the ST STM32L + microcontroller - see + https://www.FreeRTOS.org/STM32L-discovery-low-power-tickless-RTOS-demo.html + + Add xPortGetMinimumEverFreeHeapSize() to heap_4.c. + + Small change to the tickless low power implementation on the SAM4L to + ensure the alarm value (compare match value) cannot be set to zero when a + tickless period is exited due to an interrupt originating from a source + other than the RTOS tick. + + Update the GCC/Eclipse Win32 simulator demo to make better use of Eclipse + resource filters and match the functionality of the MSVC equivalent. + + xTaskIsTaskSuspended() is no longer a public function. Use + eTaskGetState() in its place. + + Improved trace macros, including tracing of heap usage. + + Remove one level of indirection when accepting interrupts on the PIC32MZ. + + Add Cortex-A9 GCC port layer. + + Add Xilinx Zynq demo application. + + +Changes between V7.5.3 and V7.6.0 released 18th November 2013 + + V7.6.0 changes some behaviour when the co-operative scheduler is used (when + configUSE_PREEMPTION is set to 0). It is important to note that the + behaviour of the pre-emptive scheduler is unchanged - the following + description only applies when configUSE_PREEMPTION is set to 0: + + WHEN configUSE_PREEMPTION IS SET TO 0 (which is in a small minority of + cases) a context switch will now only occur when a task places itself into + the Blocked state, or explicitly calls taskYIELD(). This differs from + previous versions, where a context switch would also occur when implicitly + moving a higher priority task out of the Blocked state. For example, + previously, WHEN PREEMPTION WAS TURNED OFF, if task A unblocks task B by + writing to a queue, then the scheduler would switch to the higher priority + task. Now, WHEN PREEMPTION IS TURNED OFF, if task A unblocks task B by + writing to a queue, task B will not start running until task A enters the + Blocked state or task A calls taskYIELD(). [If configUSE_PREEMPTION is not + set to 0, so the normal pre-emptive scheduler is being used, then task B + will start running immediately that it is moved out of the Blocked state]. + + Other changes: + + + Added a port layer and a demo project for the new PIC32MZ architecture. + + Update the PIC32MX port layer to re-introduce some ehb instructions that + were previously removed, add the ability to catch interrupt stack + overflows (previously only task stack overflows were trapped), and also + add the ability to catch an application task incorrectly attempting to + return from its implementing function. + + Make dramatic improvements to the performance of the Win32 simulator port + layer. + + Ensure tasks that are blocked indefinitely report their state as Blocked + instead of Suspended. + + Slight improvement to the Cortex-M4F port layers where previously one + register was inadvertently being saved twice. + + Introduce the xSemaphoreCreateBinary() API function to ensure consistency + in the semantics of how each semaphore type is created. It is no longer + recommended to use vSemaphoreCreateBinary() (the version prefixed with a + 'v'), although it will remain in the code for backward compatibility. + + Update the Cortex-M0 port layers to allow the scheduler to be started + without using the SVC handler. + + Added a build configuration to the PIC32MX MPLAB X demo project that + targets the PIC32 USB II starter kit. Previously all the build + configurations required the Explorer 16 hardware. + + Some of the standard demo tasks have been updated to ensure they execute + correctly with the updated co-operative scheduling behaviour. + + Added comprehensive demo for the Atmel SAM4E, including use of + FreeRTOS+UDP, FreeRTOS+FAT SL and FreeRTOS+CLI. + + FreeRTOS+ Changes: + + + Minor maintenance on FreeRTOS+UDP. + +Changes between V7.5.2 and V7.5.3 released October 14 2013 + + Kernel changes: + + + Prior to V7.5.x yields requested from the tick hook would occur in the + same tick interrupt - revert to that original behaviour. + + New API function uxQueueSpacesAvailable(). + + Introduced the prvTaskExitError() function to Cortex-M0, Cortex-M3/4 + and Cortex-M4F ports. prvTaskExitError() is used to trap tasks that + attempt to return from their implementing functions (tasks should call + vTaskDelete( NULL ); if they want to exit). + + The Cortex-M0 version of portSET_INTERRUPT_MASK_FROM_ISR and + portCLEAR_INTERRUPT_MASK_FROM_ISR are now fully nestable. + + Improved behaviour and robustness of the default Cortex-M tickless idle + behaviour. + + Add workaround for silicon errata PMU_CM001 in Infineon XMC4000 devices to + all Cortex-M4F ports. + + Add Cortex-M0 port for Keil. + + Updated Cortus port. + + Ensure _impure_ptr is initialised before the scheduler is started. + Previously it was not set until the first context switch. + + FreeRTOS+ changes: + + + Update FreeRTOS+UDP to V1.0.1 - including direct integration of the + FreeRTOS+Nabto task, improvements to the DHCP behaviour, and a correction + to the test that prevents the network event hook being called on the first + network down event. The FreeRTOS+UDP change history is maintained + separately. + + Correct the __NVIC_PRIO_BITS setting in the LPC18xx.h header files + provided in the NXP CMSIS library, then update the interrupts used by the + LPC18xx demos accordingly. + + Replace double quotes (") with single quotes (') in FreeRTOS+CLI help + strings to ensure the strings can be used with the JSON descriptions used + in the FreeRTOS+Nabto demos. + + Demo and miscellaneous changes: + + + Added demo for the Atmel SAMD20 Cortex-M0+. The demo includes + FreeRTOS+CLI + + Added a demo for the Infineon Cortex-M0 that can be built with the IAR + Keil and GCC tools. + + Updated the Infineon XMC4000 demos for IAR, Keil, GCC and Tasking tools, + with additional build configurations to directly support the XMC4200 and + XMC4400 devices, in addition to the previously supported XMC4500. + + Updated the demo application. + + Added additional trace macros traceMALLOC and traceFREE to track heap + usage. + +Changes between V7.5.0 and V7.5.2 released July 24 2013 + + V7.5.2 makes the new Cortex-M vPortCheckInterruptPriority() function + compatible with the STM32 standard peripheral driver library, and adds + an extra critical section to the default low power tickless mode + implementation. Only users of the STM32 peripheral library or the default + tickless implementation need update from version 7.5.0. + +Changes between V7.4.2 and V7.5.0 released July 19 2013 + + V7.5.0 is a major upgrade that includes multiple scheduling and efficiency + improvements, and some new API functions. + + Compatibility information for FreeRTOS users: + FreeRTOS V7.5.0 is backward compatible with FreeRTOS V7.4.0 with one + exception; the vTaskList() and vTaskGetRunTimeStats() functions are now + considered legacy, having been replaced by the single uxTaskGetSystemState() + function. configUSE_STATS_FORMATTING_FUNCTIONS must be set to 1 in + FreeRTOSConfig.h for vTaskList() and vTaskGetRunTimeStats() to be + available. + + Compatibility information for FreeRTOS port writers: + vTaskIncrementTick() is now called xTaskIncrementTick() (because it now + returns a value). + + Headline changes: + + + Multiple scheduling and efficiency improvements. + + Core kernel files now pass PC-Lint V8 static checking without outputting + any warnings (information on the test conditions will follow). + + New API functions: + + + uxTaskGetSystemState() https://www.FreeRTOS.org/uxTaskGetSystemState.html + + xQueueOverwrite() https://www.FreeRTOS.org/xQueueOverwrite.html + + xQueueOverwriteFromISR() + + xQueuePeekFromISR() + + The following ports and demos, which were previously available separately, + are now incorporated into the main FreeRTOS zip file download: + + + ARM Cortex-A9 IAR + + ARM Cortex-A9 ARM compiler + + Renesas RZ + + Microsemi SmartFusion2 + + New FreeRTOSConfig.h settings + http://shop.freertos.org/FreeRTOS_API_and_Configuration_Reference_s/1822.htm + + + configUSE_TIME_SLICING + + configUSE_NEWLIB_REENTRANT + + configUSE_STATS_FORMATTING_FUNCTIONS + + configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + + Other changes: + + + (MPU port only) The configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + options provides a mechanism that allows application writers to execute + certain functions in privileged mode even when a task is running in user + mode. + + Ports that support interrupt nesting now include a configASSERT() that + will trigger if an interrupt safe FreeRTOS function is called from an + interrupt that has a priority designated as above the maximum system/API + call interrupt priority. + + The included FreeRTOS+Trace recorder code has been updated to the latest + version, and the demo applications that use the trace recorder code have + been updated accordingly. + + The FreeRTOS Windows Simulator (MSVC version only) has been updated to + include a new basic 'blinky' build option in addition to the original + comprehensive build option. + + Improve RAM usage efficiency of heap_4.c and heap_2.c. + + Prevent heap_4.c from attempting to free memory blocks that were not + allocated by heap_4.c, or have already been freed. + + As FreeRTOS now comes with FreeRTOS+FAT SL (donated by HCC) the Chan FATfs + files have been removed from FreeRTOS/Demo/Common. + + Fix build error when R4 port is build in co-operative mode. + + Multiple port and demo application maintenance activities. + +Changes between V7.4.1 and V7.4.2 released May 1 2013 + + NOTE: There are no changes in the FreeRTOS kernel between V7.4.1 and V7.4.2 + + + Added FreeRTOS+FAT SL source code and demo project. The demo project + runs in the FreeRTOS Windows simulator for easy and hardware independent + experimentation and evaluation. See https://www.FreeRTOS.org/fat_sl + +Changes between V7.4.0 and V7.4.1 released April 18 2013 + + + To ensure strict conformance with the spec and ensure compatibility with + future chips data and instruction barrier instructions have been added to + the yield macros of Cortex-M and Cortex-R port layers. For efficiency + the Cortex-M port layer "yield" and "yield" from ISR are now implemented + separately as the barrier instructions are not required in the ISR case. + + Added FreeRTOS+UDP into main download. + + Reorganised the FreeRTOS+ directory so it now matches the FreeRTOS + directory with Source and Demo subdirectories. + + Implemented the Berkeley sockets select() function in FreeRTOS+UDP. + + Changed (unsigned) casting in calls to standard library functions with + (size_t) casting. + + Added the Atmel SAM4L and Renesas RX100 demos that demonstrates the + tickless (tick suppression) low power FreeRTOS features. + + Add a new RL78 IAR demo that targets numerous new RL78 chips and + evaluation boards. + + Adjusted stack alignment on RX200 ports to ensure an assert was not + falsely triggered when configASSERT() is defined. + + Updated the Cortex_M4F_Infineon_XMC4500_IAR demo to build with the latest + version of EWARM. + + Corrected header comments in the het.c and het.h files (RM48/TMS570 demo). + + +Changes between V7.3.0 and V7.4.0 released February 20 2013 + + + New feature: Queue sets. See: + https://www.FreeRTOS.org/Pend-on-multiple-rtos-objects.html + + Overhauled the default tickless idle mode implementation provided with the + ARM Cortex-M3 port layers. + + Enhanced tickless support in the core kernel code with the introduction of + the configEXPECTED_IDLE_TIME_BEFORE_SLEEP macro and the + eTaskConfirmSleepModeStatus() function. + + Added the QueueSet.c common demo/test file. Several demo applications + have been updated to use the new demo/test tasks. + + Removed reliance on the PLIB libraries from the MPLAB PIC32 port layer and + demo applications. + + Added the FreeRTOS+Trace recorder code to the MSVC Win32 demo. + + Renamed eTaskStateGet() to eTaskGetState() for consistency, and added a + pre-processor macro for backward compatibility with the previous name. + + Updated functions implemented in the core queue.c source file to allow + queue.h to be included from the .c file directly (this prevents compiler + warnings that were generated by some compilers). + + Updated the CCS Cortex-R4 port layer to replace the CLZ assembler function + with the CLZ compiler intrinsic that is provided by the latest versions of + the CCS ARM compiler. + + Updated all heap_x.c implementations to replace the structure that was + used to ensure the start of the heap was aligned with a more portable + direct C code implementation. + + Added support for PIC24 devices that include EDS. + + Minor optimisations to the PIC32 port layer. + + Minor changes to tasks.c that allow the state viewer plug-ins to display + additional information. + + Bug fix: Update prvProcessReceivedCommands() in timers.c to remove an + issue that could occur if the priority of the timer daemon task was set + below the priority of tasks that used timer services. + + Update the FreeRTOS+Trace recorder code to the latest version. + +Changes between V7.2.0 and V7.3.0 released October 31 2012 + + + Added ability to override the default scheduler task selection mechanism + with implementations that make use of architecture specific instructions. + + Added ability to suppress tick interrupts during idle time, and in so + doing, provide the ability to make use of architecture specific low power + functionality. + + Added the portSUPPRESS_TICKS_AND_SLEEP() macro and vTaskStepTick() helper + function. + + Added the configSYSTICK_CLOCK_HZ configuration constant. + + Reworked the Cortex-M3 and Cortex-M4F port layers for GCC, Keil and IAR to + directly support basic power saving functionality. + + Added hooks to allow basic power saving to be augmented in the application + by making use of chip specific functionality. + + Minor change to allow mutex type semaphores to be used from interrupts + (which would not be a normal usage model for a mutex). + + Change the behaviour of the interrupt safe interrupt mask save and restore + macros in the Cortex-M ports. The save macro now returns the previous + mask value. The restore macro now uses the previous mask value. These + changes are not necessary for the kernel's own implementation, and are + made purely because the macros were being used by application writers. + + Added eTaskStateGet() API function. + + Added port specific optimisations to the PIC32 port layer, and updated the + PIC32 demo applications to make use of this new feature. + + Added port specific optimisations to the Win32 simulator port. + + Added new ports and demo applications for the TI Hercules RM48 and TMS570 + safety microcontrollers. + + Added SAM3 demos targeting the ATSAM3S-EK2 and ATSAM3X-EK evaluation + boards. + + Updated the PIC32 MPLAB X project to manually set the compiler include + paths instead of using the IDE entry box following reports that the + include paths were somehow being deleted. + + Improved character handling in FreeRTOS+CLI. + +Changes between V7.1.1 and V7.2.0 released 14 August 2012 + + FreeRTOS V7.2.0 is backward compatible with FreeRTOS V7.1.2. + + + Added a FreeRTOS+ sub-directory. The directory contains some FreeRTOS+ + source code, and example projects that use the FreeRTOS Win32 simulator. + + Added a new example heap allocation implementation (heap_4.c) that + includes memory block coalescence. + + Added a demo that targets the Atmel SAM4S Cortex-M4 based microcontroller. + The demo is preconfigured to build using the free Atmel Studio 6 IDE and + GCC compiler. + + Added xSemaphoreTakeFromISR() implementation. + + The last parameter in ISR safe FreeRTOS queue and semaphore functions + (xHigherPriorityTaskWoken) is now optional and can be set to NULL if it + is not required. + + Update the IAR and MSP430X ports to clear all lower power mode bits before + exiting the tick interrupt [bug fix]. + + Allow xQueueReset() to be used, even when the queues event lists are not + empty. + + Added a vQueueDelete() handler for the FreeRTOS MPU port (this was + previously missing). + + Updated the vPortSVCHandler() functions in the FreeRTOS MPU port layer to + ensure it compiles with the latest ARM GCC compilers from Linaro. + + Updated the prvReadGP() function in the NIOS II port to ensure the compiler + can choose any register for the functions parameter (required at high + compiler optimisation levels). + + Add #error macros into the Keil and IAR Cortex-M ports to ensure they + cannot be built if the user has set configMAX_SYSCALL_INTERRUPT_PRIORITY + to 0. + + Added comments in the FreeRTOSConfig.h files associated with Cortex-M3 and + Cortex-M4 demos stating that the configMAX_SYSCALL_INTERRUPT_PRIORITY + parameter must not be set to 0. + + Introduce new INCLUDE_xQueueGetMutexHolder configuration constant + (defaulted to 0). + + Added two new list handling macros - for internal use only in upcoming new + products. + + Removed all mention of the legacy vTaskStartTrace and ulTaskEndTrace + macros. FreeRTOS+Trace supersedes the legacy trace. + + Added a configASSERT() into the vPortFree() function in heap_1.c as it is + invalid for the function to be called. + + Made the xRxLock and xTxLock members of the queue structure volatile. + This is probably not necessary, and is included as a precautionary + measure. + + Modify the assert() that checks to see if the priority passed into an + xTaskCreate() function is within valid bounds to permit the assert to be + used in the FreeRTOS MPU port. + + The software timer service (daemon) task is now created in a way that + to ensure compatibility with FreeRTOS MPU. + +Changes between V7.1.0 and V7.1.1 released May 1 2012 + + New ports: + + The following ports are brand new: + + Cortex-M3 Tasking + + The following ports have been available as separate downloads for a number + of months, but are now included in the main FreeRTOS download. + + Cortex-M0 IAR + + Cortex-M0 GCC + + Cortex-M4F GCC (with full floating point support) + + + New demos: + + The following demos are brand new: + + Renesas RX63N RDK (Renesas compiler) + + The following demos have been available as separate downloads for a number + of months, but are now included in the main FreeRTOS download. + + NXP LPC1114 GCC/LPCXpresso + + ST STM32F0518 IAR + + Infineon XMC4500 GCC/Atollic + + Infineon XMC4500 IAR + + Infineon XMC4500 Keil + + Infineon XMC4500 Tasking + + + Kernel miscellaneous / maintenance: + + + Introduced the portSETUP_TCB() macro to remove the requirement for the + Windows simulator to use the traceTASK_CREATE() macro, leaving the trace + macro available for use by FreeRTOS+Trace (https://www.FreeRTOS.org/trace). + + Added a new trace macro, traceMOVE_TASK_TO_READY_STATE(), to allow future + FreeRTOS+Trace versions to provide even more information to users. + + Updated the FreeRTOS MPU port to be correct for changes that were + introduced in FreeRTOS V7.1.0. + + Introduced the xQueueReset() API function. + + Introduced the xSemaphoreGetMutexHolder() API function. + + Tidy up various port implementations to add the static key word where + appropriate, and remove obsolete code. + + Slight change to the initial stack frame given to the RX600 ports to allow + them to be used in the Eclipse based E2Studio IDE without confusing GDB. + + Correct the alignment given to the initial stack of Cortex-M4F tasks. + + Added a NOP following each DINT instruction on MSP430 devices for strict + conformance with the instructions on using DINT. + + Changed the implementation of thread deletes in the Win32 port to prevent + the port making use of the traceTASK_DELETE() trace macros - leaving this + macro free for use by FreeRTOS+Trace. + + Made some benign changes to the RX600 Renesas compiler port layer to + ensure the code can be built to a library without essential code being + removed by the linker. + + Reverted the change in the name of the uxTaskNumber variable made in + V7.1.0 as it broke the IAR plug-in. + + + Demo miscellaneous / maintenance: + + + The command interpreter has now been formally released as FreeRTOS+CLI, + and been moved out of the main FreeRTOS download, to instead be available + from the FreeRTOS+ Ecosystem site https://www.FreeRTOS.org/plus. + + flash_timer.c/h has been added to the list of standard demo tasks. This + performs the same functionality as the flash.c tasks, but using software + timers in place of tasks. + + Upgraded the PIC32 demo as follows: Changes to how the library functions + are called necessitated by the new compiler version, addition of MPLAB X + project with PIC32MX360, PIC32MX460 and PIC32MX795 configurations, + addition of simply blinky demo, updated FreeRTOSConfig.h to include more + parameters, addition of hook function stubs. + + The MSP430X IAR and CCS demos have been updated to ensure the power + settings are correct for the configured CPU frequency. + + Rowley CrossWorks projects have been updated to correct the "multiple + definition of ..." warnings introduced when the toolchain was updated. + + Updated various FreeRTOSConfig.h header files associated with projects + that build with Eclipse to include a #error statement informing the user + that the CreateProjectDirectoryStructure.bat batch file needs to be + executed before the projects can be opened. + + Renamed directories that included "CCS4" in their name to remove the '4' + and instead just be "CCS". This is because the demo was updated and + tested to also work with later Code Composer Studio versions. + + Updated the TCP/IP periodic timer frequency in numerous uIP demos to be + 50ms instead of 500ms. + +Changes between V7.0.2 and V7.1.0 released December 13 2011 + + New ports: + + + Cortex-M4F IAR port. + + Cortex-M4F Keil/RVDS port. + + TriCore GCC port. + + New demos: + + + NXP LPC4350 using the Keil MDK, and demonstrated on a Hitex development + board. + + ST STM32F407 using the IAR Embedded Workbench for ARM, and demonstrated on + the IAR STM32F407ZG-SK starter kit. + + Infineon TriCore TC1782, using the GCC compiler, demonstrated on the + TriBoard TC1782 evaluation board. + + Renesas RX630, using the Renesas compiler and HEW, demonstrated on an + RX630 RSK (Renesas Starter Kit). + + Miscellaneous / maintenance: + + + Removed all calls to printf() from the K60/IAR Kinetis demo so the project + can execute stand alone - without being connected to the debugger. + + Completed the command interpreter framework. Command handlers now receive + the entire command string, giving them direct access to parameters. + Utility functions are provided to check the number of parameters, and + return parameter sub-strings. + + The previously documented fix for the bug in xTaskResumeFromISR() that + effected (only) ports supporting interrupt nesting has now been + incorporated into the main release. + + The portALIGNMENT_ASSERT_pxCurrentTCB() definition has been added to allow + specific ports to skip the second stack alignment check when a task is + created. This is because the second check is not appropriate for some + ports - including the new TriCore port where the checked pointer does not + actually point to a stack. + + The portCLEAN_UP_TCB() macro has been added to allow port specific clean + up when a task is deleted - again this is required by the TriCore port. + + Various other minor changes to ensure warning free builds on a growing + number of microcontroller and toolchain platforms. This includes a + (benign) correction to the prototype of the + vApplicationStackOverflowHook() definition found in lots of recent demos. + + Trace system: + + + The legacy trace mechanism has been completely removed - it has been + obsolete for the years since the trace macros were introduced. The + configuration constant configUSE_TRACE_FACILITY is now used to optionally + include additional queue and task information. The additional information + is intended to make the trace mechanism more generic, and allow the trace + output to provide more information. When configUSE_TRACE_FACILITY is set + to 1: + - the queue structure includes an additional member to hold the queue + type, which can be base, mutex, counting semaphore, binary semaphore + or recursive mutex. + - the queue structure includes an additional member to hold a queue + number. A trace tool can set and query the queue number for its own + purposes. The kernel does not use the queue number itself. + - the TCB structure includes an additional member to hold a task number + number. A trace tool can set and query the task number for its own + purposes. The kernel does not use the task number itself. + + Queues and all types of semaphores are now automatically allocated their + type as they are created. + + Added two new trace macros - traceTASK_PRIORITY_INHERIT() and + traskTASK_PRIORITY_DISINHERIT(). + + Updated the traceQUEUE_CREATE_FAILED() macro to take a parameter that + indicates the type of queue, mutex, or semaphore that failed to be + created. + + The position from which traceCREATE_MUTEX() is called has been moved from + after the call to xQueueGenericSend() [within the same function] to before + the call. This ensures the trace events occur in the correct order. + + The value passed into tracePRIORITY_SET() has been corrected for the case + where vTaskPrioritySet() is called with a null parameter. + +Changes between V7.0.1 and V7.0.2 released September 20 2011 + + New ports: + + + The official FreeRTOS Renesas RX200 port and demo application have been + incorporated into the main FreeRTOS zip file download. + + The official FreeRTOS Renesas RL78 port and demo application have been + incorporated into the main FreeRTOS zip file download. + + The official FreeRTOS Freescale Kinetis K60 tower demo application has + been incorporated into the main FreeRTOS zip file download. This includes + an embedded web server example. + + A new Microblaze V8 port layer has been created to replace the older, now + deprecated, port layer. The V8 port supports V8.x of the Microblaze IP, + including exceptions, caches, and the floating point unit. A new + Microblaze demo has also been added to demonstrate the new Microblaze V8 + port layer. The demo application was created using V13.1 of the Xilinx + EDK, and includes a basic embedded web server that uses lwIP V1.4.0. + + The official FreeRTOS Fujitsu FM3 MB9A310 demo application has been + incorporated into the main FreeRTOS zip file download. Projects are + provided for both the IAR and Keil toolchains. + + + API additions: + + + xTaskGetIdleTaskHandle() has been added. + + xTaskGetTimerDaemonTaskHandle() has been added. + + pcTaskGetTaskName() has been added. + + vSemaphoreDelete() macro has been added to make it obvious how to delete + a semaphore. In previous versions vQueueDelete() had to be used. + + vTaskCleanUpResources() has been removed. It has been obsolete for a + while. + + portPOINTER_SIZE_TYPE has been introduced to prevent compiler warnings + being generated when the size of a pointer does not match the size of + the stack type. This will (has already) be used in new ports, but will + not be retrofitted to existing ports until the existing port itself is + updated. + + Other updates and news: + + + The core files have all been modified to tighten the coding standard even + further. These are style, not functional changes. + + All ARM7 port layers have been slightly modified to prevent erroneous + assert() failures when tasks are created and configASSERT() is defined. + + All ARM IAR projects have been updated to build with the latest V6.2.x + versions of the IAR Embedded Workbench for ARM tools (EWARM). This was + necessary due to a change in the way EWARM uses the CMSIS libraries. + + The PIC32 port layer has been updated in preparation for V2 of the C32 + compiler. + + The old Virtex-4 Microblaze demo has been marked as deprecated. Please + use the brand new Spartan-6 port and demo in its place. + + The bones of a new generic command interpreter is located in + FreeRTOS/Demo/Common/Utils/CommandInterpreter.c. This is still a work in + progress, and not documented. It is however already in use. It will be + documented in full when the projects that are already using it are + completed. + + A couple of new standard demos have been included. First, a version of + flop.c called sp_flop.c. This is similar to flop.c, but uses single + precision floats in place of double precision doubles. This allows the + for testing ports to processors that have only single precision floating + point units, and revert to using emulated calculations whenever a double + is used. Second, comtest_strings.c has been included to allow the test + of UART drivers when an entire string is transmitted at once. The + previous comtest.c only used single character transmission and reception. + + lwIP V1.4.0 is now included in the FreeRTOS/Demo/Common directory, and + used by a couple of new demos. + +Changes between V7.0.0 and V7.0.1 released May 13 2011 + + + Added a Fujitsu FM3 demo application for both the IAR and Keil tool + chains. + + Added a SmartFusion demo application for all of the IAR, Keil and + SoftConsole (GCC/Eclipse) tool chains. + + Updated the RX600 port and demo applications to take into account the + different semantics required when using the latest (V1.0.2.0) version of + the Renesas compiler. + + Modified the RX600 Ethernet driver slightly to make it more robust under + heavy load, and updated the uIP handling task to make use of the FreeRTOS + software timers. + + Slightly changed the PIC32 port layer to move an ehb instruction in line + with the recommendations of the MIPS core manual, and ensure 8 byte stack + alignment is truly always obtained. + + Changed the behaviour when tasks are suspended before the scheduler has + been started. Before, there needed to be at least one task that was not + in the suspended state. This is no longer the case. + +Changes between V6.1.1 and V7.0.0 released April 8 2011 + + FreeRTOS V7.0.0 is backward compatible with FreeRTOS V6.x.x + + Main changes: + + + Introduced a new software timer implementation. + + Introduced a new common demo application file to exercise the new timer + implementation. + + Updated the Win32/MSVC simulator project to include the new software timer + demo tasks and software timer tick hook test. Much simpler software timer + demonstrations are included in the demo projects for both of the new ports + (MSP430X with CCS4 and STM32 with TrueStudio). + + Various enhancements to the kernel implementation in tasks.c. These are + transparent to users and do not effect the pre-existing API. + + Added calls to configASSERT() within the kernel code. configASSERT() is + functionally equivalent to the standard C assert() macro, but does not + rely on the compiler providing assert.h. + + Other changes: + + + Updated the MSP430X IAR port and demo project to include support for the + medium memory model. + + Added a demo project for the MSP430X that targets the MSP430X Discovery + board and uses the Code Composer Studio 4 tools. This demo includes use + of the new software timer implementation. + + Added an STM32F100RB demo project that targets the STM32 Discovery Board + and uses the TrueStudio Eclipse based IDE from Atollic. + + Removed some compiler warnings from the PSoC demo application. + + Updated the PIC32 port layer to ensure the + configMAX_SYSCALL_INTERRUPT_PRIORITY constant works as expected no matter + what its value is (within the valid range set by the microcontroller + kernel). + + Updated the PIC24, dsPIC and PIC32 projects so they work with the latest + MPLAB compiler versions from Microchip. + + Various cosmetic changes to prepare for a standards compliance statement + that will be published after the software release. + + +Changes between V6.1.0 and V6.1.1 released January 14 2011 + + + Added two new Windows simulator ports. One uses the free Microsoft Visual + Studio 2010 express edition, and the other the free MingW/Eclipse + environment. Demo projects are provided for both. + + Added three demo projects for the PSoC 5 (CYAC5588). These are for the + GCC, Keil, and RVDS build tools, and all use the PSoC Creator IDE. + + Added a demo for the low power STM32L152 microcontroller using the IAR + Embedded Workbench. + + Added a new port for the MSP430X core using the IAR Embedded Workbench. + + Updated all the RX62N demo projects that target the Renesas Demonstration + Kit (RDK) to take into account the revered LED wiring on later hardware + revisions, and the new J-Link debug interface DLL. + + Updated all the RX62N demo projects so the IO page served by the example + embedded web server works with all web browsers. + + Updated the Red Suite projects to work with the up coming Red Suite + release, and to use a more recent version of the CMSIS libraries. + + Added the traceTAKE_MUTEX_RECURSIVE_FAILED() trace macro. + + Removed the (pointless) parameter from the traceTASK_CREATE_FAILED() + trace macro. + + Introduced the portALT_GET_RUN_TIME_COUNTER_VALUE() macro to compliment + the already existing portGET_RUN_TIME_COUNTER_VALUE(). This allows for + more flexibility in how the time base for the run time statistics feature + can be implemented. + + Added a "cpsie i" instruction before the "svc 0" instruction used to start + the scheduler in each of the Cortex M3 ports. This is to ensure that + interrupts are globally enabled prior to the "svc 0" instruction being + executed in cases where interrupts are left disabled by the C start up + code. + + Slight optimisation in the run time stats calculation. + +Changes between V6.0.5 and V6.1.0 released October 6 2010 + + + Added xTaskGetTickCountFromISR() function. + + Modified vTaskSuspend() to allow tasks that have just been created to be + immediately suspended even when the kernel has not been started. This + allows them to effectively start in the Suspended state - a feature that + has been asked for on numerous occasions to assist with initialisation + procedures. + + Added ports for the Renesas RX62N using IAR, GCC and Renesas tool suites. + + Added a STM32F103 demo application that uses the Rowley tools. + + Under specific conditions xFreeBytesRemaining within heap_2.c could end up + with an incorrect value. This has been fixed. + + xTaskCreateGeneric() has a parameter that can be used to pass the handle + of the task just created out to the calling task. The assignment to this + parameter has been moved to ensure it is assigned prior to the newly + created having any possibility of executing. This takes into account the + case where the assignment is made to a global variable that is accessed by + the newly created task. + + Fixed some build time compiler warnings in various FreeTCPIP (based on + uIP) files. + + Fixed some build time compiler warnings in Demo/Common/Minimal/IntQueue.c. + +Changes between V6.0.4 and V6.0.5 released May 17 2010 + + + Added port and demo application for the Cortus APS3 processor. + +Changes between V6.0.3 and V6.0.4 released March 14 2010 + + + All the contributed files that were located in the Demo/Unsupported_Demos + directory have been removed. These files are instead now available in the + new Community Contributions section of the FreeRTOS website. See + https://www.FreeRTOS.org/RTOS-contributed-ports.html + + The project file located in the Demo/CORTEX_STM32F107_GCC_Rowley directory + has been upgraded to use V2.x of the Rowley Crossworks STM32 support + package. + + An initial Energy Micro EFM32 demo has been included. This will be + updated over the coming months to make better use of the low power modes + the EFM32 provides. + +Changes between V6.0.2 and V6.0.3 released February 26 2010 + + + SuperH SH7216 (SH2A-FPU) port and demo application added. + + Slight modification made to the default implementation of + pvPortMallocAligned() and vPortFreeAligned() macros so by default they + just call pvPortMalloc() and vPortFree(). The macros are only needed to + be defined when a memory protection unit (MPU) is being used - and then + only depending on other configuration settings. + +Changes between V6.0.1 and V6.0.2 released January 9th 2010 + + + Changed all GCC ARM 7 ports to use 0 as the SWI instruction parameter. + Previously the parameter was blank and therefore only an implicit 0 but + newer GCC releases do not permit this. + + Updated IAR SAM7S and SAM7X ports to work with IAR V5.40. + + Changed the stack alignment requirement for PIC32 from 4 bytes to 8 bytes. + + Updated prvListTaskWithinSingleList() is it works on processors where the + stack grows up from low memory. + + Corrected some comments. + + Updated the startup file for the RVDS LPC21xx demo. + +Changes between V6.0.0 and V6.0.1 released November 15th 2009 + + + Altered pxPortInitialiseStack() for all Cortex-M3 ports to ensure the + stack pointer is where the compiler expects it to be when a task first + starts executing. + + The following minor changes only effect the Cortex-M3 MPU port: + + + portRESET_PRIVILEGE() assembly macro updated to include a clobber list. + + Added prototypes for all the privileged function wrappers to ensure no + compile time warnings are generated no matter what the warning level + setting. + + Corrected the name of portSVC_prvRaisePrivilege to + portSVC_RAISE_PRIVILEGE. + + Added conditional compilation into xTaskGenericCreate() to prevent some + compilers issuing warnings when portPRIVILEGE_BIT is defined as zero. + + +Changes between V5.4.2 and V6.0.0 released October 16th 2009 + + FreeRTOS V6 is backward compatible with FreeRTOS V5.x. + + Main changes: + + + FreeRTOS V6 is the first version to include memory protection unit (MPU) + support. Two ports now exist for the Cortex M3, the standard FreeRTOS + which does not include MPU support, and FreeRTOS-MPU which does. + + xTaskCreateRestricted() and vTaskAllocateMPURegions() API functions added + in support of FreeRTOS-MPU. + + Wording for the GPL exception has been (hopefully) clarified. Also the + license.txt file included in the download has been fixed (the previous + version contained some corruption). + + Other changes: + + + New API function xPortGetFreeHeapSize() added to heap_1.c and heap_2.c. + + ARM7 GCC demo interrupt service routines wrappers have been modified to + call the C portion using an __asm statement. This prevents the function + call being inlined at higher optimisation levels. + + ARM7 ports now automatically set the THUMB bit if necessary when + setting up the initial stack of a task - removing the need for + THUMB_INTERWORK to be defined. This also allows THUMB mode and ARM mode + tasks to be mixed more easily. + + All ARM7/9 ports now have portBYTE_ALIGNMENT set to 8 by default. + + Various demo application project files have been updated to be up to date + with the latest IDE versions. + + The linker scripts used with command line GCC demos have been updated to + include an eh_frame section to allow their use with the latest Yagarto + release. Likewise the demo makefiles have been updated to include + command line options to reduce or eliminate the eh_frame section all + together. + + The definition of portBYTE_ALIGNMENT_MASK has been moved out of the + various memory allocation files and into the common portable.h header + file. + + Removed unnecessary use of portLONG, portSHORT and portCHAR. + + Added LM3Sxxxx demo for Rowley CrossWorks. + + Posix simulator has been upgraded - see the corresponding WEB page on the + FreeRTOS.org site. + + +Changes between V5.4.1 and V5.4.2 released August 9th 2009 + + + Added a new port and demo app for the Altera Nios2 soft core. + + Added LPC1768 demo for IAR. + + Added a USB CDC demo to all LPC1768 demos (Code Red, CrossWorks and IAR). + + Changed clock frequency of LPC1768 demos to 99MHz. + +Changes between V5.4.0 and V5.4.1 released July 25th 2009 + + + New hook function added. vApplicationMallocFailedHook() is (optionally) + called if pvPortMalloc() returns NULL. + + Additional casting added to xTaskCheckForTimeOut(). This prevents + problems that can arise should configUSE_16_BIT_TICKS be set to 1 on a + 32 bit architecture (which would probably be a mistake, anyway). + + Corrected the parameter passed to NVIC_SetPriority() to set the MAC + interrupt priority in both LPC1768 demos. + + Decreased the default setting of configMINIMAL_STACK_SIZE in the PIC32 + demo application to ensure the heap space was not completely consumed + before the scheduler was started. + +Changes between V5.3.1 and V5.4.0 released July 13th 2009 + + + Added Virtex5 / PPC440 port and demos. + + Replaced the LPC1766 Red Suite demo with an LPC1768 Red Suite demo. The + original demo was configured to use engineering samples of the CPU. The + new demo has an improved Ethernet driver. + + Added LPC1768 Rowley demo with zero copy Ethernet driver. + + Reworked byte alignment code to ensure 8 byte alignment works correctly. + + Set configUSE_16_BIT_TICKS to 0 in the PPC405 demo projects. + + Changed the initial stack setup for the PPC405 to ensure the small data + area pointers are setup correctly. + +Changes between V5.3.0 and V5.3.1 released June 21st 2009 + + + Added ColdFire V1 MCF51CN128 port and WEB server demo. + + Added STM32 Connectivity Line STM32107 Cortex M3 WEB server demo. + + Changed the Cortex M3 port.c asm statements to __asm so it can be + compiled using Rowley CrossWorks V2 in its default configuration. + + Updated the Posix/Linux simulator contributed port. + +Changes between V5.2.0 and V5.3.0 released June 1st 2009 + + Main changes: + + + Added new (optional) feature that gathers statistics on the amount of CPU + time used by each task. + + Added a new demo application for the Atmel AT91SAM3U Cortex-M3 based + microcontroller. + + Added a new demo application for the NXP LPC1766 Cortex-M3 based + microcontroller. + + Added a contributed port/demo that allows FreeRTOS to be 'simulated' in a + Linux environment. + + Minor changes: + + Updated the Stellaris uIP WEB server demos to include the new run time + statistics gathering feature - and include a served WEB page that + presents the information in a tabular format. + + Added in the lwIP port layer for the Coldfire MCF52259. + + Updated the CrossWorks LPC2368 WEB server to include an image in the + served content. + + Changed some of the timing in the initialisation of the LPC2368 MAC to + permit its use on all part revisions. + + Minor modifications to the core uIP code to remove some compiler warnings. + + Added xTaskGetApplicationTaskTag() function and updated the OpenWatcom + demo to make use of the new function. + + Added contributed demos for AVR32 AP7000, STM32 Primer 2 and STM32 using + Rowley Crossworks. + + Heap_1.c and Heap_2.c used to define structures for the purpose of data + alignment. These have been converted to unions to save a few bytes of + RAM that would otherwise be wasted. + + Remove the call to strncpy() used to copy the task name into the TCB when + the maximum task name is configured to be 1 byte long. + +Changes between V5.1.2 and V5.2.0 released March 14th 2009 + + + Optimised the queue send and receive functions (also used by semaphores). + + Replaced the standard critical sections used to protect BIOS calls in the + PC port to instead use scheduler locks. This is because the BIOS calls + always return with interrupts enabled. + + Corrected unclosed comments in boot.s. + +Changes between V5.1.1 and V5.1.2 released February 9th 2009 + + + Added NEC V850ES port and demo. + + Added NEC 78K0R port and demo. + + Added MCF52259 port and demo. + + Added the AT91SAM9XE port and demo. + + Updated the MCF52233 FEC driver to work around a silicon bug that + prevents the part auto negotiating some network parameters. + + Minor modifications to the MCF52233 makefile to permit it to be used + on Linux hosts. + + Updated the STM32 primer files to allow them to be built with the latest + version of the RIDE tools. + + Updated the threads.js Java script used for kernel aware debugging in + the Rowley CrossWorks IDE. + + +Changes between V5.1.0 and V5.1.1 released November 20, 2008 + + + Added Coldfire MCF52233 WEB server demo using GCC and Eclipse. + + Added IAR MSP430 port and demo. + + Corrected several compiler time issues that had crept in as tool versions + change. + + Included FreeRTOS-uIP - a faster uIP. This is not yet complete. + +Changes between V5.0.4 and V5.1.0 released October 24, 2008 + + + Added a new port and demo application for the ColdFire V2 core using the + CodeWarrior development tools. + + Replaced the ARM7 demo that used the old (and now no longer supported) + Keil compiler with a new port that uses the new Keil/RVDS combo. + + Stack overflow checking now works for stacks that grow up from low + memory (PIC24 and dsPIC). + + BUG FIX - set the PIC32 definition of portSTACK_GROWTH to the correct + value of -1. + + MSP430 port layers have been updated to permit tasks to place the + microcontroller into power down modes 1 to 3. The demo applications have + likewise been updated to demonstrate the new feature. + + Replaced the two separate MSP430/Rowley port layers with a single and more + flexible version. + + Added more contributed ports, including ports for NEC and SAM9 + microcontrollers. + + Changed the linker script used in the LPC2368 Eclipse demo. + +Changes between V5.0.3 and V5.0.4 released September 22, 2008 + + + Completely re-written port for ColdFire GCC. + + Bug fix: All Cortex M3 ports have a minor change to the code that sets + the pending interrupt. + + Some header files require that FreeRTOS.h be included prior to their + inclusion. #error message have been added to all such header file + informing users to the cause of the compilation error should the headers + not be included in the correct order. + +Changes between V5.0.2 and V5.0.3 released July 31, 2008 + + Changes relating to the Cortex M3: + + + Added configMAX_SYSCALL_INTERRUPT_PRIORITY usage to all the Cortex M3 + ports and demos. See the port documentation pages on the FreeRTOS.org + WEB site for full usage information. + + Improved efficiency of Cortex M3 port even further. + + Ensure the Cortex M3 port works no matter where the vector table is + located. + + Added the IntQTimer demo/test tasks to a demo project for each CM3 port + (Keil, GCC and IAR) to test the new configMAX_SYSCALL_INTERRUPT_PRIORITY + functionality. + + Added the mainINCLUDE_WEB_SERVER definition to the LM3SXXXX IAR and Keil + projects to allow the WEB server to be conditionally excluded from the + build and therefore allow use of the KickStart (code size limited) + compiler version. + + Other changes: + + + Moved the PIC24 and dsPIC versions of vPortYield() from the C file to + an assembly file to allow use with all MPLAB compiler versions. This also + allows the omit-frame-pointer optimisation to be turned off. + +Changes between V5.0.0 and V5.0.2 released May 30, 2008 + + + Updated the PIC32 port to allow queue API calls to be used from + interrupts above the kernel interrupt priority, and to allow full + interrupt nesting. Task stack usages has also been reduced. + + Added a new PowerPC port that demonstrates how the trace macros can be + used to allow the use of a floating point co-processor. The + traceTASK_SWITCHED_OUT() and traceTASK_SWITCHED_INT() macros are used to + save and restore the floating point context respectively for those tasks + that actually use floating point operations. + + BUG FIX: The first PPC405 port contained a bug in that it did not leave + adequate space above the stack for the backchain to be saved when a task + started to execute for the first time. + + Updated queue.c to add in the means to allow interrupt nesting and for + queue API functions to be called from interrupts that have a priority + above the kernel priority. This is only supported on PIC32 ports thus + far. + + Fixed the compiler warnings that were generated when the latest version + of WinAVR was used. + + Remove all inline usage of 'inline' from the core kernel code. + + Added the queue registry feature. The queue registry is provided as a + means for kernel aware debuggers to locate queue definitions. It has no + purpose unless you are using a kernel aware debugger. The queue registry + will only be used when configQUEUE_REGISTRY_SIZE is greater than zero. + + Added the ST Cortex-M3 drivers into the Demo/Common/Drivers directory to + prevent them from having to be included in multiple demos. + + Added a Keil STM32 demo application. + + Changed the blocktim.c test files as it is no longer legitimate for all + ports to call queue API functions from within a critical section. + + Added the IntQueue.c test file to test the calling of queue API functions + from different interrupt priority levels, and test interrupt nesting. + +Changes between V5.0.0 and V5.0.1 + + + V5.0.1 was a customer specific release. + +Changes between V4.8.0 and V5.0.0 released April 15, 2008 + + *** VERY IMPORTANT INFORMATION ON UPGRADING TO FREERTOS.ORG V5.0.0 *** + + The parameters to the functions xQueueSendFromISR(), xQueueSendToFrontFromISR(), + xQueueSendToBackFromISR() and xSemaphoreGiveFromISR() have changed. You must + update all calls to these functions to use the new calling convention! Your + compiler might not issue any type mismatch warnings! + + + Other changes: + + + Support added for the new Luminary Micro LM3S3768 and LM3S3748 Cortex-M3 + microcontrollers. + + New task hook feature added. + + PowerPC demo updated to use version 10.1 of the Xilinx EDK. + + Efficiency gains within the PIC32 port layer. + +Changes between V4.7.2 and V4.8.0 released March 26 2008 + + + Added a Virtex4 PowerPC 405 port and demo application. + + Added optional stack overflow checking and new + uxTaskGetStackHighWaterMark() function. + + Added new xQueueIsQueueEmptyFromISR(), xQueueIsQueueFullFromISR() and + uxQueueMessagesWaitingFromISR() API functions. + + Efficiency improvements to the Cortex-M3 port layer. NOTE: This + requires that an SVC handler be installed in the application. + + Efficiency improvements to the queue send and receive functions. + + Added new trace macros. These are application definable to provide + a flexible trace facility. + + Implemented the configKERNEL_INTERRUPT_PRIORITY within the Keil Cortex + M3 port layer (bringing it up to the same standard as the IAR and GCC + versions). + + Ports that used the arm-stellaris-eabi-gcc tools have been converted to + use the arm-non-eabi-gcc tools. + +Changes between V4.7.1 and V4.7.2 released February 21, 2008 + + + Added Fujitsu MB91460 port and demo. + + Added Fujitsu MB96340 port and demo. + + Tidied up the capitalisation of include files to facilitate builds on + Linux hosts. + + Removed some redundant casting that was generating warnings - but was + included to remove warnings on other compilers. + +Changes between V4.7.0 and V4.7.1 released February 3, 2008 + + + Updated all IAR ARM projects to use V5.11 of the IAR Embedded Workbench + for ARM. + + Introduced recursive semaphore feature. + + Updated LPC2368 demos to take into account silicon bugs in old chip + revisions. + + Updated STR9 uIP port to manually set the net mask and gateway addresses. + + Updating demos to allow more to run with the co-operative scheduler. + + Fixed co-operative scheduler behaviour upon the occurrence of a tick + interrupt while the scheduler was suspended. + + Updated documentation contained within semphr.h. + + ARM7 GCC ports no longer use the IRQ attribute. + +Changes between V4.6.1 and V4.7.0 released December 6, 2007 + + + Introduced the counting semaphore macros and demo source files. The + Open Watcom PC project has been updated to include the new demo. See + the online documentation for more information. + + Introduced the 'alternative' queue handling API and demo source files. + The Open Watcom PC project has been updated to include the new demo + source files. See the online documentation for more information. + + Added AT91SAM7X Eclipse demo project. + + Added the STM32 primer demo project for the GCC compiler and Ride IDE. + + Removed the .lock files that were mistakenly included in the V4.6.1 + eclipse workspaces. + +Changes between V4.6.0 and V4.6.1 released November 5 2007 + + + Added support for the MIPS M4K based PIC32. + + Added 'extern "C"' to all the header files to facilitate use with C++. + +Changes between V4.5.0 and V4.6.0 released October 28 2007 + + + Changed the method used to force a context switch within an ISR for the + ARM7/9 GCC ports only. The portENTER_SWITCHING_ISR() and + portEXIT_SWITCHING_ISR() macros are no longer supported. This is to + ensure correct behaviour no matter which GCC version is used, with or + without the -fomit-frame-pointer option, and at all optimisation levels. + + Corrected the prototype for xQueueGenericSend() within queue.h. + +Changes between V4.4.0 and V4.5.0 released September 17 2007 + + + Added the xQueueSendToFront(), xQueueSendToBack() and xQueuePeek() + functionality. These should now be used in preference to the old + xQueueSend() function - which is maintained for backward compatibility. + + Added Mutex functionality. The behaviour of mutexes is subtly different + to the already existing binary semaphores as mutexes automatically + include a priority inheritance mechanism. + + Added the GenQTest.c and QPeek.c to test and demonstrate the behaviour + of the new functionality. + + Updated the LM3Sxxxx and PC ports to include the new GenQTest.c and + QPeek.c files. + + Updated the GCC port for the Cortex M3 to include the + configKERNEL_INTERRUPT_PRIORITY functionality. This was previously only + included in the IAR port. + + Optimised the GCC and IAR port layer code - specifically the context + switch code. + + Consolidated the LM3Sxxxx EK demos for all development tools into a + single project that automatically detects which version of the EK the + application is executing on. + + Added Eclipse support for LM3Sxxxx evaluation kits. + + Added Eclipse support for the Keil LPC2368 evaluation kit. + + Added the Demo/Drivers directory to hold code that is common to multiple + demo application projects. + + Included some minor bug fixes in the uIP 1.0 code. + + Added an lwIP demo for the STR9 - thanks ST for assistance. + + Updated the AVR32 port to ensure correct behaviour with full compiler + optimisation. + + Included binaries for OpenOCD FTDI and parallel port interfaces. + +Changes between V4.4.0 and V4.3.1 released July 31, 2007 + + + Added AVR32 UC3B demo application. + + Updated AVR32 UC3A port and demo applications. + + Added IAR lwIP demo for AVR32 UC3A. + + Updated listGET_OWNER_OF_NEXT_ENTRY() to assist compiler optimisation + (thanks Niu Yong for making the suggestion). + + Added xTaskGetSchedulerState() API function. + + BUG FIX: Corrected behaviour when tasks that are blocked indefinitely + have their block time adjusted (within xQueueSend() and xQueueReceive()), + and are the subject of a call the vTaskResume() when they are not + actually in the Suspended state (thanks Dan Searles for reporting the + issues). + + +Changes between V4.3.0 and V4.3.1 released June 11, 2007 + + + Added STMicroelectronics STM32 Cortex-M3 demo application. + + Updated ustdlib.c for the GCC LM3S6965 demo. + +Changes between V4.2.1 and V4.3.0 released June 5, 2007 + + + Introduced configKERNEL_INTERRUPT_PRIORITY to the IAR Cortex-M3, PIC24 + and dsPIC ports. See the LM3S6965 and PIC24 demo application + documentation pages for more information. + + Updated the PIC24 and dsPIC demos to build with V3.0 of the PIC30 GCC + tools, and changed the demo applications. + + Added demos for the new Ethernet and CAN enabled Luminary Micro Stellaris + microcontrollers. + + Corrected bug in uIP the demos that prevented frames of approximately 1480 + bytes and over from being transmitted. + + Included the LPC2368/uIP/Rowley demo into the main FreeRTOS.org + download. + + Update to WizC PIC18 port to permit its use with version 14 of the + compiler. Thanks Marcel! + +Changes between V4.2.1 and V4.2.0 released April 2, 2007 + + + Added AVR32 AT32UC3A ports for GCC and IAR. + + Added -fomit-frame-pointer option to lwIP SAM7X demo makefile. + + Moved location of call to LCD_Init() in STR9 demo to ensure it is only + called after the scheduler has been started. + +Changes between V4.1.3 and V4.2.0 released February 8, 2007 + + + Changes to both task.c and queue.c as a result of testing performed on + the SafeRTOS code base. + + Added Cortex-M3 LM3S811 demos for GCC and IAR tools. + +Changes between V4.1.2 and V4.1.3 released November 19, 2006 + + + Added STR750 ARM7 port using the Raisonance RIDE/GCC tools. + + Added -fomit-frame-pointer option to Rowley ARM7 demos as work around + to GCC bug at some optimisation levels. + + Altered the way the heap is defined in the LM3S811 Keil demo to prevent + the RAM usage from counting toward the code size limit calculation. + + CO-ROUTINE BUG FIX: Removed the call to prvIsQueueEmpty from within + xQueueCRReceive as it exited with interrupts enabled. Thanks Paul Katz. + + Tasks that block on events with a timeout of portMAX_DELAY are now + blocked indefinitely if configINCLUDE_vTaskSuspend is defined. + Previously portMAX_DELAY was just the longest block time possible. This + is still the case if configINCLUDE_vTaskSuspend is not defined. + + Minor changes to some demo application files. + +Changes between V4.1.1 and V4.1.2 released October 21, 2006 + + + Added 16bit PIC ports and demos. + + Added STR750 port and demo. + + +Changes between V4.1.0 and V4.1.1 released September 24, 2006 + + + Added the Luminary Micro Stellaris LM3S811 demo application. + +Changes between V4.0.5 and V4.1.0 released August 28, 2006 + + + Prior to V4.1.0, under certain documented circumstances, it was possible + for xQueueSend() and xQueueReceive() to return without having completed + and without their block time expiring. The block time effectively + stated a maximum block time, and the return value of the function needed + to be checked to determine the reason for returning. This is no longer + the case as the functions will only return once the block time has + expired or they are able to complete their operation. It is therefore no + longer necessary to wrap calls within loops. + + Changed the critical section handling in the IAR AVR port to correct the + behaviour when used with later compiler versions. + + Added the LPC2138 CrossWorks demo into the zip file. Previously this was + only available as a separate download. + + Modified the AVR demo applications to demonstrate the use of co-routines. + +Changes between V4.0.4 and V4.0.5 released August 13, 2006 + + + Introduced API function xTaskResumeFromISR(). Same functionality as + xTaskResume(), but can be called from within an interrupt service routine. + + Optimised vListInsert() in the case when the wake time is the maximum + tick count value. + + Bug fix: The 'value' of the event list item is updated when the priority + of a task is changed. Previously only the priority of the TCB itself was + changed. + + vTaskPrioritySet() and vTaskResume() no longer use the event list item. + This has not been necessary since V4.0.1 when the xMissedYield handling + was added. + + Lowered the PCLK setting on the ARM9 STR9 demo from 96MHz to 48MHz. + + When ending the scheduler - do not try to attempt a context switch when + deleting the current task. + + SAM7X EMAC drivers: Corrected the Rx frame length mask when obtaining + the length from the rx descriptor. + + +Changes between V4.0.3 and V4.0.4 released June 22, 2006 + + + Added a port and demo application for the STR9 ARM9 based processors from + ST. + + Slight optimisation to the vTaskPrioritySet() function. + + Included the latest uIP version (1.0) in the demo/common/ethernet + directory. + +Changes between V4.0.2 and V4.0.3 released June 7, 2006 + + + Added a port and demo application for the Cortex-M3 target using the IAR + development tools. + + The ARM Cortex-m3 Rowley projects have been updated to use V1.6 of the + CrossStudio tools. + + The heap size defined for the lwIP Rowley demo has been reduced so that + the project will link correctly when using the command line GCC tools + also. The makefile has also been modified to allow debugging. + + The lwIP Rowley demo not includes a 'kernel aware' debug window. + + The uIP Rowley project has been updated to build with V1.6 of CrossWorks. + + The second set of tasks in the blockQ demo were created the wrong way + around (inconsistent to the description in the file). This has been + corrected. + +Changes between V4.0.1 and V4.0.2 released May 28, 2006 + + + Port and demo application added for the Tern Ethernet Engine controller. + + Port and demo application added for MC9S12 using GCC, thanks to + Jefferson "imajeff" Smith. + + The function vTaskList() now suspends the scheduler rather than disabling + interrupts during the creation of the task list. + + Allow a task to delete itself by passing in its own handle. Previously + this could only be done by passing in NULL. + + Corrected the value passed to the WDG_PeriodValueConfig() library + function in the STR71x demo. + + The tick hook function is now called only within a tick isr. Previously + it was also called when the tick function was called during the scheduler + unlocking process. + + The EMAC driver in the SAM7X lwIP demo has been made more robust as per + the thread: http://sourceforge.net/forum/message.php?msg_id=3714405 + + In the PC ports: Add function prvSetTickFrequencyDefault() to set the + DOS tick back to its proper value when the scheduler exits. Thanks + Raynald! + + In the Borland x86 ports there was a mistake in the portFIRST_CONTEXT + macro where the BP register was not popped from the stack correctly. The + BP value would never get used so this did not cause a problem, but it has + been corrected all the same. + + +Changes between V4.0.0 and V4.0.1 released April 7 2006 + + + Improved the ARM CORTEX M3 ports so they now only have to service + pendSV interrupts. + + Added a Luminary Micro port and demo for use with Rowley CrossWorks. + + Added the xMissedYield handling to tasks.c. + +Changes between V3.2.4 and V4.0.0 + + Major changes: + + + Added new RTOS port for Luminary Micros ARM CORTEX M3 microcontrollers. + + Added new co-routine functionality. + + Other kernel changes: + + + An optional tick hook call is now included in the tick function. + + Introduced the xMiniListItem structure and removed the list pxHead + member in order to reduce RAM usage. + + Added the following definitions to the FreeRTOSConfig.h file included + with every port: + configUSE_TICK_HOOK + configUSE_CO_ROUTINES + configMAX_CO_ROUTINE_PRIORITIES + + The volatile qualification has been changed on the list members to allow + the task.c code to be tidied up a bit. + + The scheduler can now be started even if no tasks have been created! + This is to allow co-routines to run when there are no tasks. + + A task being woken by an event will now preempt the currently running task + even if its priority is only equal to the currently running task. + + Port and demo application changes: + + + Updated the WinAVR demo to compile with the latest version of WinAVR + with no warnings generated. + + Changed the WinAVR makefile to make chars signed - needed for the + co-routine code if BaseType_t is set to char. + + Added new demo application file crflash.c. This demonstrates co-routine + functionality including passing data between co-routines. + + Added new demo application file crhook.c. This demonstrates co-routine + and tick hook functionality including passing data between and ISR and + a co-routine. + + Some NOP's were missing following stmdb{}^ instructions in various ARM7 + ports. These have been added. + + Updated the Open Watcom PC demo project to include the crflash and crhook + demo co-routines as an example of their use. + + Updated the H8S demo to compile with the latest version of GCC. + + Updated the SAM7X EMAC drivers to take into account the hardware errata + regarding lost packets. + + Changed the default MAC address used by some WEB server demos as the + original addresses used was not liked by some routers. + + Modified the SAM7X/IAR startup code slightly to prevent it hanging on + some systems when the code is executed using a j-link debugger. The + j-link macro file configures the PLL before the code executes so + attempting to configure it again in the startup code was causing a + problem for some user. Now a check is performed first to see if the + PLL is already set up. + + GCC port now contain all assembler code in a single asm block rather than + individual blocks as before. + + GCC LPC2000 code now explicitly uses R0 rather than letting the assembler + choose the register to use as a temporary register during the context + switch. + + Added portNOP() macro. + + The compare match load value on LPC2000 ports now has 1 added to correct + the value used. + + The minimal stack depth has been increased slightly on the WIZC PIC18 + port. + +Changes between V3.2.3 and V3.2.4 + + + Modified the GCC ARM7 port layer to allow use with GCC V4.0.0 and above. + Many thanks to Glen Biagioni for the provided update. + + Added a new Microblaze port and demo application. + + Modified the SAM7X EMAC demo to default to use the MII interface rather + than the RMII interface. + + Modified the startup sequence of the SAM7X demo slightly to allow the + EMAC longer to auto negotiate. + +Changes between V3.2.2 and V3.2.3 + + + Added MII interface support to the SAM7X EMAC peripheral driver. + Previously versions worked with the RMII interface only. + + Added command line GCC support to the SAM7X lwIP demo. Previously the + project could only be built using the CrossWorks IDE. Modifications to + this end include the addition of a standard makefile and linker script to + the download, and some adjustments to the stacks allocated to each task. + + Changed the page returned by the lwIP WEB server demo to display the + task status table rather than the TCP/IP statistics. + + Corrected the capitalisation of some header file includes and makefile + dependencies to facilitate use on Linux host computers. + + The various LPC2000 ports had a mistake in the timer setup where the + prescale value was written to T0_PC instead of T0_PR. This would have + no effect unless a prescale value was actually required. This has been + corrected. + +Changes between V3.2.1 and V3.2.2 - Released 23 September, 2005 + + + Added an IAR port for the Philips LPC2129 + + The Atmel ARM7 IAR demo project files are now saved in the IAR Embedded + Workbench V4.30a format. + + Updated the J-Link macro file included with the SAM7X uIP demo project + to allow the demo board to be reset over the J-Link. + +Changes between V3.2.0 and V3.2.1 - Released 1 September, 2005 + + + Added lwIP demo for AT91SAM7X using Rowley tools. + + Added uIP demo for AT91SAM7X using IAR tools. + + Added function xTaskGetCurrentTaskHandle(). + + Renamed events.h to mevents.h to prevent it conflicting with the events.h + generated automatically by the HCS12 processor expert utility. events.h + is only used by the PC demo application. + + Both PIC18 ports now initialise the TBLPTRU to 0 as this is the value + expected by the compiler, and the compilers do not write to this + register. + + The HCS12 banked model demo now creates the 'suicide' tasks immediately + prior to starting the scheduler. These tasks should be the last tasks to + get started in order for the test to function correctly. + +Changes between V3.1.1 and V3.2.0 - Released 29 June, 2005 + + V3.2.0 introduces two new MSP430 ports and corrects a minor kernel + issues. Thanks to Ares.qi for his input. + + + Added two MSP430 ports that use the Rowley CrossWorks development tools. + One port just mirrors the existing GCC port. The other port was provided + by Milos Prokic. Thanks! + + V3.2.0 corrects the behavior when vTaskPrioritySet() or vTaskResume() + are called while the scheduler is locked (by a call to + vTaskSuspendAll()). When this is done the subject task now starts to + execute immediately when the scheduler is unlocked if it has the highest + priority that is ready to run. Previously there was a possibility that + the task would not run until the next RTOS tick or call to portYIELD(). + + Another similar small correction ensures that in the case where more than + one task is blocked on a semaphore or queue, the task with the highest + priority is guaranteed to be unblocked first. + + Added a couple of more test tasks to the PC demo which cover the points + above. + +Changes between V3.1.0 and V3.1.1 - Released 21st June, 2005 + + This release updates the HCS12 port. The common kernel code + remains unchanged. + + + Updated the HCS12 port to support banking and introduced a demo + application for the MC9S12DP256. The new demo application is + located in the Demo/HCS12_CodeWarrior_banked directory. + + The name of the directory containing the MC9S12F32 demo application + has been changed to Demo/HCS12_CodeWarrior_small (as in 'small' + memory model). + + MC9S12F32 demo updated slightly to use the PLL. The CPU speed for the + demo application is now 24MHz. Previously it was 8MHz. + + The demo application file Demo/Common/Minimal/death.c has a slight + alteration to prevent it using floating point variables. + + +Changes between V3.0.0 and V3.1.0 - Released 11th June, 2005 + + + Added new ports for ST Microsystems STR71x, and Freescale HCS12 + microcontrollers. Currently the HCS12 port is limited to the small + memory model. Large memory models will be supported in the next + release. + + PIC18 wizC port updated. Thanks to Marcel van Lieshout for his + continuing contribution. + + The accuracy of the AVR port timer setup has been improved. Thanks to + Thomas Krutmann for this contribution. + + Added a new conditional compilation macro configIDLE_SHOULD_YIELD. + See the WEB documentation for details. + + Updated the CrossWorks uIP demo to build with V1.4 of CrossWorks. + + Slight modification to the SAM7 release build configuration to correct + an include path definition. + + Updated the MPLAB PIC18 documentation to provide extra details on linker + file configuration. + +Changes between V3.0.0 and V2.6.1 - Released 23rd April, 2005 + + V3.0.0 includes many enhancements, so this history list is broken into + subsections as follows: + + API changes + New ports + Directory name changes + Kernel and miscellaneous changes changes + + - API changes + + + Each port now defines BaseType_t as the data type that is most + efficient for that architecture. The type BaseType_t is used + extensively in API calls necessitating the following changes to the + FreeRTOS API function prototypes. + + See the "New for V3.0.0" section of the FreeRTOS online + documentation for full details of API changes. + + - New ports + + + The AT91FR40008 ARM7 port contributed by John Feller is now included + in the download (thanks John!). + + The PIC18 port for the wizC/fedC compiler contributed by Marcel van + Lieshout is now included in the download (thanks Marcel!). + + The IAR port for the AVR microcontroller has been upgraded to V3.0.0 + and is now a supported port. + + - Directory name changes + + For consistency, and to allow integration of the new ports, the + following directory names have been changed. + + + The source/portable/GCC/ARM7 directory has been renamed + source/portable/GCC/ARM7_LPC2000 so it is compatible with the naming + of other GCC ARM7 ports. + + The Demo/PIC directory has been renamed Demo/PIC18_MPLAB to + accommodate the wizC/fedC PIC port. + + The demo applications for the two AVR ports no longer share the same + directory. The WinAVR demo is in the Demo/AVR_ATMega323_WinAVR + directory and the IAR port in the Demo/AVR_ATMega323_IAR directory. + + + - Kernel and miscellaneous changes changes + + See the "New for V3.0.0" section of the FreeRTOS online + documentation for more information. + + + Previously 'portmacro.h' contained some user editable definitions + relating to the user application, and some fixed definitions relating + specifically to the port being used. The application specific + definitions have been removed from 'portmacro.h' and placed inside a + new header file called 'FreeRTOSConfig.h'. 'portmacro.h' should now + never be modified by the user. A 'FreeRTOSConfig.h' is now included + in each of FreeRTOS/Demo subdirectories - as it's settings relate to + the demo application rather than being specific to the port. + + Introduced configUSE_IDLE_HOOK in idle task. + + The idle task will yield when another idle priority task is ready to + run. Previously the idle task would run to the end of its time slice + regardless. + + The idle task is now created when the scheduler is started. This + requires less stack than the previous scheme where it was created upon + creation of the first application task. + + The function usPortCheckFreeStackSpace() has been renamed + usTaskCheckFreeStackSpace() and moved from the portable layer to + tasks.c. + + Corrected spelling of portMINMAL_STACK_SIZE to portMINIMAL_STACK_SIZE. + + The portheap.c file included with the AVR port has been deleted. The + AVR demo now uses the standard heap1 sample memory allocator. + + The GCC AVR port is now build using the standard make utility. The + batch files used previously have been deleted. This means a recent + version of WinAVR is required in order to create a binary suitable for + source level debugging. + + vTaskStartScheduler() no longer takes the configUSE_PREEMPTION + constant as a parameter. Instead the constant is used directly within + tasks.c and no parameter is required. + + The header file 'FreeRTOS.h' has been created and is used to include + 'projdefs.h', 'FreeRTOSConfig.h' and 'portable.h' in the necessary + order. FreeRTOS.h can now be included in place of these other + headers. + + The header file 'errors.h' has been deleted. The definitions it + contained are now located within 'projdefs.h'. + + pvPortMalloc() now takes a size_t parameter as per the ANSI malloc(). + Previously an unsigned short was used. + + When resuming the scheduler a yield is performed if either a tick has + been missed, or a task is moved from the pending ready list into a + ready list. Previously a yield was not performed on this second + condition. + + In heap1.c an overflow check has been added to ensure the next free + byte variable does not wrap around. + + Introduced the portTASK_FUNCTION() and portTASK_FUNCTION_PROTO() + macros. + + The MPLAB PIC port now saved the TABLAT register in interrupt service + routines. + +Changes between V2.6.0 and V2.6.1 - Released Feb 22, 2005 + + This version adds support for the H8 processor. + + Other changes: + + + tskMAX_TASK_NAME_LEN removed from the task.h header and added to each + individual portmacro.h file as portMAX_TASK_NAME_LEN. This allows RAM + limited ports to allocate fewer characters to the task name. + + AVR port - Replaced the inb() and outb() functions with direct memory + access. This allows the port to be built with the 20050414 build of + WinAVR. + + GCC LPC2106 port - removed the 'static' from the definition of + vNonPreemptiveTick() to allow the demo to link when using the cooperative + scheduler. + + GCC LPC2106 port - Corrected the optimisation options in the batch files + ROM_THUMB.bat, RAM_THUMB.bat, ROM_ARM.bat and RAM_ARM.bat. The lower case + -o is replaced by an uppercase -O. + + Tasks.c - The strcpy call has been removed when copying across the task + name into the TCB. + + Updated the trace visualisation to always be 4 byte aligned so it can be + used on ARM architectures. + + There are now two tracecon executables (that convert the trace file binary + into an ASCII file). One for big endian targets and one for little endian + targets. + + Added ucTasksDeleted variable to prevent vTaskSuspendAll() being called + too often in the idle task. + + SAM7 USB driver - Replaced the duplicated RX_DATA_BK0 in the interrupt + mask with the RX_DATA_BK1. + + +Changes between V2.5.5 and V2.6.0 - Released January 16, 2005 + + + Added the API function vTaskDelayUntil(). The demo app file + Demo/Common/Minimal/flash.c has been updated to demonstrate its use. + + Added INCLUDE_vTaskDelay conditional compilation. + + Changed the name of the Demo/ARM7_AtmelSAM7S64_IAR directory to + Demo/ARM7_AT91SAM7S64_IAR for consistency. + + Modified the AT91SAM7S USB driver to allow descriptors that have + a length that is an exact multiple of the FIFO to be transmitted. + +Changes between V2.5.4 and V2.5.5 - Released January 3, 2005 + + This version adds support for the Atmel SAM7 ARM7 microcontrollers + along with the IAR development tools. + + Other changes: + + + Renamed the Demo/ARM7 directory to Demo/ARM7_LPC2106_GCC. + + Renamed the Demo/ARM7_Keil directory to Demo/ARM7_LPC2129_Keil. + + Modified the Philips ARM7 serial interrupt service routines to only + process one interrupt per call. This seems to enable the ISR to + operate more quickly. + + Removed the 'far' keyword from the Open Watcom portable layer source + files. This allows their use with V1.3 of Open Watcom. + + Minor modifications to the SDCC build files to allow their use under + Linux. Thanks to Frieder Ferlemann for this contribution. + + Small change to sTaskCreate() to allow a context switch even when + pxCreatedTask is NULL. Thanks to Kamil for this contribution. + + inline keyword removed from vTaskSwitchContext() and VTaskIncrementTick() + definitions. + +Changes between V2.5.3 and V2.5.4 - Released Dec 1, 2004 + + This is an important maintenance release. + + The function cTaskResumeAll() has been modified so it can be used safely + prior to the kernel being initialised. This was an issue as + cTaskResumeAll() is called from pvPortMalloc(). Thanks to Daniel Braun + for highlighting this issue. + +Changes between V2.5.2 and V2.5.3 - Released Nov 2, 2004 + + The critical section handling functions have been changed for the GCC ARM7 + port. Some optimisation levels use the stack differently to others. This + means the interrupt flags cannot always be stored on the stack and are + instead now stored in a variable, which is then saved as part of the + tasks context. This allows the GCC ARM7 port to be used at all + optimisation levels - including -Os. + + Other minor changes: + + + MSP430 definition of usCriticalNesting now uses the volatile qualifier. + This is probably not required but added just in case. + +Changes between V2.5.1 and V2.5.2 - Released Oct 26, 2004 + + + Added the Keil ARM7 port. + + Slight modification to comtest.c to make the delay periods more random. + This creates a better test condition. + +Changes between V2.5.0 and V2.5.1 - Released Oct 9, 2004 + + + Added the MSP430 port. + + Extra comments added to the GCC ARM7 port.c and portISR.c files. + + The memory pool allocated within heap_1.c has been placed within a + structure to ensure correct memory alignment on 32bit systems. + + Within the GCC ARM7 serial drivers an extra check is made to ensure + the post to the queue was successful if then attempting immediately + retrieve the posted character. + + Changed the name of the constant portTICKS_PER_MS to portTICK_PERIOD_MS + as the old name was misleading. + + +Changes between V2.4.2 and V2.5.0 - Released Aug 12, 2004 + + The RTOS source code download now includes three separate memory allocation + schemes - so you can choose the most appropriate for your application. + These are found in the Source/Portable/MemMang directory. The demo + application projects have also been updated to demonstrate the new schemes. + See the "Memory Management" page of the API documentation for more details. + + + Added heap_1.c, heap_2.c and heap_3.c in the Source/Portable/MemMang + directory. + + Replaced the portheap.c files for each demo application with one of the + new memory allocation files. + + Updated the portmacro.h file for each demo application to include the + constants required for the new memory allocators: portTOTAL_HEAP_SIZE and + portBYTE_ALIGNMENT. + + Added a new test to the ARM7 demo application that tests the operation + of the heap_2 memory allocator. + + +Changes between V2.4.1 and V2.4.2 - Released July 14, 2004 + + + The ARM7 port now supports THUMB mode. + + Modification to the ARM7 demo application serial port driver. + +Changes between V2.4.0 and V2.4.1 - Released July 2, 2004 + + + Rationalised the ARM7 port version of portEXIT_CRITICAL() - + improvements provided by Bill Knight. + + Made demo serial driver more complete and robust. + + +Changes between V2.4.0 and V2.3.1 - Released June 30, 2004 + + + Added the first ARM7 port - thanks to Bill Knight for the assistance + provided. + + Added extra files to the Demo/Common/Minimal directory. These are + equivalent to their Demo/Common/Full counterparts but with the + calls to the functions defined in print.c removed. + + Added TABLAT to the list of registers saved as part of a PIC18 context. + +Changes between V2.3.0 and V2.3.1 - Released June 25, 2004 + + + Changed the way the vector table is defined to be more portable. + + Corrected the definitions of SPH and SPL in portmacro.s90. + The previous definitions prevented V2.3.0 operating if the iom323.h + header file was included in portmacro.s90. + +Changes between V2.2.0 and V2.3.0 - Released June 19, 2004 + + + Added an AVR port that uses the IAR compiler. + + Explicit use of 'signed' qualifier on plain char types. + + Modified the Open Watcom project files to use 'signed' as the + default char type. + + Changed odd calculation of initial pxTopOfStack value when + portSTACK_GROWTH < 0. + + Added inline qualifier to context switch functions within task.c. + Ports that do not support the (non ANSI) inline keyword have the + inline #define'd away in their respective portmacro.h files. + +Changes between V2.1.1 and V2.2.0 - Released May 18, 2004 + + + Added Cygnal 8051 port. + + PCLATU and PCLATH are now saved as part of the PIC18 context. This + allows function pointers to be used within tasks. Thanks to Javier + Espeche for the enhancement. + + Minor changes to demo application files to reduce stack usage. + + Minor changes to prevent compiler warnings when compiling the new port. + +Changes between V2.1.0 and V2.1.1 - Released March 12, 2004 + + + Bug fix - pxCurrentTCB is now initialised before the call to + prvInitialiseTaskLists(). Previously pxCurrentTCB could be accessed + while null during the initialisation sequence. Thanks to Giuseppe + Franco for the correction. + +Changes between V2.0.0 and V2.1.0 - Released Feb 29, 2004 + + V2.1.0 has significant reworks that greatly reduce the amount of time + the kernel has interrupts disabled. The first section of modifications + listed here must be taken into account by users. The second section + are related to the kernel implementation and as such are transparent. + + Section1 : + + + The typedef TickType_t has been introduced. All delay times should + now use a variable of type TickType_t in place of the unsigned long's + used previously. API function prototypes have been updated + appropriately. + + The configuration macro USE_16_BIT_TICKS has been introduced. If set + to 1 TickType_t is defined as an unsigned short. If set to 0 + TickType_t is defined as an unsigned long. See the configuration + section of the API documentation for more details. + + The configuration macro INCLUDE_vTaskSuspendAll is now obsolete. + + vTaskResumeAll() has been renamed cTaskResumeAll() as it now returns a + value (see the API documentation). + + ulTaskGetTickCount() has been renamed xTaskGetTickCount() as the type + it returns now depends on the USE_16_BIT_TICKS definition. + + cQueueReceive() must now >never< be used from within an ISR. Use the new + cQueueReceiveFromISR() function instead. + + Section 2: + + + A mechanism has been introduced that allows a queue to be accessed by + a task and ISR simultaneously. + + A "pending ready" queue has been introduced that enables interrupts to + be processed when the scheduler is suspended. + + The list implementation has been improved to provide faster item + removal. + + The scheduler now makes use of the scheduler suspend mechanism in places + where previously interrupts were disabled. + +Changes between V1.2.6 and V2.0.0 - Released Jan 31, 2004 + + + Introduced new API functions: + vTaskPriorityGet () + vTaskPrioritySet () + vTaskSuspend () + vTaskResume () + vTaskSuspendAll () + vTaskResumeAll () + + Added conditional compilation options that allow the components of the + kernel that are unused by an application to be excluded from the build. + See the Configuration section on the WEB site for more information (on + the API pages). The macros have been added to each portmacro.h file ( + sometimes called prtmacro.h). + + Rearranged tasks.c. + + Added demo application file dynamic.c. + + Updated the PC demo application to make use of dynamic.c. + + Updated the documentation contained in the kernel header files. + + Creating a task now causes a context switch if the task being created + has a higher priority than the calling task - assuming the kernel is + running. + + vTaskDelete() now only causes a context switch if the calling task is + the task being deleted. + +Changes between V1.2.5 and V1.2.6 - Released December 31, 2003 + + Barring the change to the interrupt vector (PIC port) these are minor + enhancements. + + + The interrupt vector used for the PIC master ISR has been changed from + 0x18 to 0x08 - where it should have always been. The incorrect address + still works but probably executes a number of NOP's before getting to the + ISR. + + Changed the baud rate used by the AVR demo application to 38400. This + has an error percentage of less than one percent with an 8MHz clock. + + Raised the priority of the Rx task in demo\full\comtest.c. This only + affects the Flashlite and PC ports. This was done to prevent the Rx + buffer becoming full. + + Reverted the Flashlite COM port driver back so it does not use the DMA. + The DMA appears to miss characters under stress. The Borland Flashlite + port was also calculating a register value incorrectly resulting in the + wrong DMA source address being used. The same code worked fine when + compiling with Open Watcom. Other minor enhancements were made to the + interrupt handling. + + Modified the PIC serial Rx ISR to check for and clear overrun errors. + Overrun errors seem to prevent any further characters being received. + + The PIC demo projects now have some optimisation switched on. + + +Changes between V1.2.4 and V1.2.5 + + Small fix made to the PIC specific port.c file described below. + + + Introduced portGLOBAL_INTERRUPT_FLAG definition to test the global + interrupt flag setting. Using the two bits defined within + portINITAL_INTERRUPT_STATE was causing the w register to get clobbered + before the test was performed. + +Changes between V1.2.3 and V1.2.4 + + V1.2.4 contains a release version of the PIC18 port. + An optional exception has been included with the GPL. See the licensing + section of www.FreeRTOS.org for details. + + + The function xPortInitMinimal() has been renamed to + xSerialPortInitMinimal() and the function xPortInit() has been renamed + to xSerialPortInit(). + + The function sSerialPutChar() has been renamed cSerialPutChar() and + the function return type chaned to portCHAR. + + The integer and flop tasks now include calls to tskYIELD(), allowing + them to be used with the cooperative scheduler. + + All the demo applications now use the integer and comtest tasks when the + cooperative scheduler is being used. Previously they were only used with + the preemptive scheduler. + + Minor changes made to operation of minimal versions of comtest.c and + integer.c. + + The ATMega port definition of portCPU_CLOSK_HZ definition changed to + 8MHz base 10, previously it base 16. + + + +Changes between V1.2.2a and V1.2.3 + + The only change of any significance is to the license, which has changed + from the Open Software License to the GNU GPL. + + The zip file also contains a pre-release version of the PIC18 port. This + has not yet completed testing and as such does not constitute part of the + V1.2.3 release. It is still however covered by the GNU GPL. + + There are minor source code changes to accommodate the PIC C compiler. + These mainly involve more explicit casting. + + + sTaskCreate() has been modified slightly to make use of the + portSTACK_GROWTH macro. This is required for the PIC port where the + stack grows in the opposite direction to the other existing ports. + + prvCheckTasksWaitingTermination() has been modified slightly to bring + the decrementing of usCurrentNumberOfTasks within the critical section, + where it should have been since the creation of an eight bit port. + +Changes between V1.2.2 and V1.2.2a + + The makefile and buildcoff.bat files included with the AVR demo application + have been modified for use with the September 2003 build of WinAVR. No + source files have changed. + +Changes between V1.2.1 and V1.2.2 + + There are only minor changes here to allow the PC and Flashlite 186 ports + to use the Borland V4.52 compiler, as supplied with the Flashlite 186 + development kit. + + + Introduced a BCC directory under source\portable. This contains all the + files specific to the Borland compiler port. + + Corrected the macro naming of portMS_PER_TICK to portTICKS_PER_MS. + + Modified comtest.c to increase the rate at which the string is + transmitted and received on the serial port. The Flashlite 186 demo + app baud rate has also been increased. + + The values of the constants used in both integer.c files have been + increased to force the Borland compiler to use 32 bit values. The + Borland optimiser placed the previous values in 16 bit registers, and in + So doing invalidated the test. + +Changes between V1.2.0 and V1.2.1 + + This version includes some minor changes to the list implementation aimed + at improving the context switch time - with is now approximately 10% faster. + Changes include the removal of some null pointer assignment checks. These + were redundant where the scheduler uses the list functions, but means any + user application choosing to use the same list functions must now check + that no NULL pointers are passed as a parameter. + + The Flashlite 186 serial port driver has also been modified to use a DMA + channel for transmissions. The serial driver is fully functional but still + under development. Flashlite users may prefer to use V1.2.0 for now. + + Details: + + + Changed the baud rate for the ATMega323 serial test from 19200 to 57600. + + Use vSerialPutString() instead of single character puts in + Demo\Full\Comtest.c. This allows the use of the flashlite DMA serial + driver. Also the check variable only stops incrementing after two + consecutive failures. + + semtest.c creates four tasks, two of which operate at the idle priority. + 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 signalling an error because they have not been + scheduled enough time for each of them to count the shared variable to + the higher original value. + + The flashlite 186 serial driver now uses a DMA channel for transmissions. + + Removed the volatile modifier from the list function parameters. This was + only ever included to prevent compiler warnings. Now warnings are + removed by casting parameters where the calls are made. + + prvListGetOwnerOfNextEntry() and prvListGetOwnerOfHeadEntry() have been + removed from list.c and added as macros in list.h. + + usNumberOfItems has been added to the list structure. This removes the + need for a pointer comparison when checking if a list is empty, and so + is slightly faster. + + Removed the NULL check in vListRemove(). This makes the call faster but + necessitates any application code utilising the list implementation to + ensure NULL pointers are not passed. + + Renamed portTICKS_PER_MS definition to portMS_PER_TICK (milli seconds + per tick). This is what it always should have been. + +Changes between V1.01 and V1.2.0 + + The majority of these changes were made to accommodate the 8bit AVR port. + The scheduler workings have not changed, but some of the data types used + have been made more friendly to an eight bit environment. + + Details: + + + Changed the version numbering format. + + Added AVR port. + + Split the directory demo\common into demo\common\minimal and + demo\common\full. The files in the full directory are for systems with + a display (currently PC and Flashlite 186 demo's). The files in the + minimal directory are for systems with limited RAM and no display + (currently MegaAVR). + + Minor changes to demo application function prototypes to make more use + of 8bit data types. + + Within the scheduler itself the following functions have slightly + modified declarations to make use of 8bit data types where possible: + xQueueCreate(), + sQueueReceive(), + sQUeueReceive(), + usQueueMessageWaiting(), + sQueueSendFromISR(), + sSemaphoreTake(), + sSemaphoreGive(), + sSemaphoreGiveFromISR(), + sTaskCreate(), + sTaskMoveFromEventList(). + + Where the return type has changed the function name has also changed in + accordance with the naming convention. For example + usQueueMessageWaiting() has become ucQueueMessageWaiting(). + + The definition tskMAX_PRIORITIES has been moved from task.h to + portmacro.h and renamed portMAX_PRIORITIES. This allows different + ports to allocate a different maximum number of priorities. + + By default the trace facility is off, previously USE_TRACE_FACILITY + was defined. + + comtest.c now uses a psuedo random delay between sends. This allows for + better testing as the interrupts do not arrive at regular intervals. + + Minor change to the Flashlite serial port driver. The driver is written + to demonstrate the scheduler and is not written to be efficient. + + + +Changes between V1.00 and V1.01 + + These changes improve the ports. The scheduler itself has not changed. + + Improved context switch mechanism used when performing a context + switch from an ISR (both the tick ISR and the serial comms ISR's within + the demo application). The new mechanism is faster and uses less stack. + + The assembler file portasm.asm has been replaced by a header file + portasm.h. This includes a few assembler macro definitions. + + All saving and restoring of registers onto/off of the stack is now handled + by the compiler. This means the initial stack setup for a task has to + mimic the stack used by the compiler, which is different for debug and + release builds. + + Slightly changed the operation of the demo application, details below. + + Details: + + + portSWITCH_CONTEXT() replaced by vPortFirstContext(). + + pxPortInitialiseStack() modified to replicate the stack used by the + compiler. + + portasm.asm file removed. + + portasm.h introduced. This contains macro definitions for + portSWITCH_CONTEXT() and portFIRST_CONTEXT(). + + Context switch from ISR now uses the compiler generated interrupt + mechanism. This is done simply by calling portSWITCH_CONTEXT and leaving + the save/restore to compiler generated code. + + Calls to taskYIELD() during ISR's have been replaced by calling the + simpler and faster portSWITCH_CONTEXT(). + + The Flashlite 186 port now uses 186 instruction set (used to use 80x86 + instructions only). + + The blocking queue tasks within the demo application did not operate + quite as described. This has been corrected. + + The priority of the comtest Rx task within the demo application 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. + + Prevent the call to kbhit() in main.c for debug builds as the debugger + seems to have problems stepping over the call. This if for the PC port + only. + + + diff --git a/Quick_Start_Guide.url b/Quick_Start_Guide.url index be74fdc95..55caab7c4 100644 --- a/Quick_Start_Guide.url +++ b/Quick_Start_Guide.url @@ -1,5 +1,5 @@ -[InternetShortcut] -URL=http://www.freertos.org/FreeRTOS-quick-start-guide.html -IDList= -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/FreeRTOS-quick-start-guide.html +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/cspell.config.yaml b/cspell.config.yaml new file mode 100644 index 000000000..911ce1d8f --- /dev/null +++ b/cspell.config.yaml @@ -0,0 +1,31 @@ +--- +$schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json +version: '0.2' +# Allows things like stringLength +allowCompoundWords: true + +# Read files not to spell check from the git ignore +useGitignore: true + +# Language settings for C +languageSettings: + - caseSensitive: false + enabled: true + languageId: c + locale: "*" + +# Add a dictionary, and the path to the word list +dictionaryDefinitions: + - name: freertos-words + path: '.github/.cSpellWords.txt' + addWords: true + +dictionaries: + - freertos-words + +# Paths and files to ignore +ignorePaths: + - 'dependency' + - 'docs' + - 'ThirdParty' + - 'History.txt' diff --git a/lexicon.txt b/lexicon.txt deleted file mode 100644 index 0105b8626..000000000 --- a/lexicon.txt +++ /dev/null @@ -1,3845 +0,0 @@ -aaaa -ab -abs -accesskeyid -acclerator -ack -acks -aclk -acm -adc -adcclk -addclientauthcode -adden -addfaketaskwaitingtoreceivefromqueue -addfaketaskwaitingtosendtoqueue -addr -addvectoredexceptionhandler -adel -ades -adp -aead -aes -aesni -afer -afio -ahb -aic -aiec -ajax -aka -alpn -alt -altera -amazonrootca -amazontrust -amd -amout -ampcorea -ampm -amptask -amz -amzn -ansi -ap -apb -api -apireference -apis -apn -app -applicationexit -appnote -appropiate -aptime -apu -ar -aren't -args -armv -arp -arpqc -arraynotifed -asc -ascii -asf -asm -asn -aspr -ast -async -atmega -atmel -auth -authmode -autodetected -autonegotiation -autoreload -avr -aws -backlight -backoff -backoffalgorithm -backtrace -balternatesetting -baltimore -barry -basetime -basetype -bauddiv -baudrate -baudrateconverter -bb -bcd -bcdcdc -bcddevicel -bcdhid -bcdusbl -bclientconnected -bcountrycode -bdatainterface -bdescriptor -bdescriptortype -bdeviceclass -bdeviceprotocol -bdevicesubclass -bdirhasentry -behaviour -behavioural -bemptyfile -bendpointaddress -berkeley -bev -bf -bfunctionlength -bgce -bgnd -bhaderror -bi -bignum -binterfaceclass -binterfacenumber -binterfaceprotocol -binterfacesubclass -binterval -bio -bios -bislisten -bitmasking -bitscanreverse -bitvalue -bk -bktallowable -bkttime -ble -blenght -blength -blinkrate -blinkrates -blinky -blipping -blockq -blockqc -blocktimems -bloggedin -blox -bmasterinterface -bmattributes -bmaxpacketsize -bmcapabilities -bne -bnumconfigs -bnumdescriptors -bnumendpoints -bo -bod -bootloader -bootstrapcdn -bp -br -brasil -brdh -brdiv -brdl -brgh -brs -bsd -bsl -bslaveinterface -bsp -bss -btimer -btn -buf -buffersize -bufsize -burtc -burtcclkdiv -burtcclkselulfrco -burtcmodeem -busfault -buttonisr -bvic -bwantdhcp -bytesreceived -bytessent -bytestorecv -bytestosend -bytestring -ca -cac -cachable -calender -calloc -cas -cb -cbc -cbconfigurationvalue -cbdescriptortype -cbio -cblength -cbmattributes -cbmc -cbnuminterfaces -cbor -cbuffer -cbyte -cc -ccm -ccompare -ccount -ccs -ccv -cd -cdatastring -cdc -cec -cellularconnect -cellularconnectionloop -cellulardemo -cellulardemotask -cellularloglevel -cellulartest -cellulartesttask -centre -ceo -cer -cereg -cerrorbuffer -cert -certificateid -certificateownershiptoken -certificatetemplate -certprofile -certs -ceu -cexception -cexpectednumberofparameters -cexpectedstring -cfb -cfginitialize -cflags -cg -cgreg -ch -chacha -chachapoly -chdir -checklogin -checknullarg -checktimer -checkval -checkvalue -checon -chinese -chunked -ci -ciconfiguration -cid -ciphersuite -ciphertext -circleos -ck -cka -ckc -ckf -ckm -ckr -cktim -claro -clearpendingirq -cli -clientauthentication -clientcert -clientcertsize -clientcredential -clientcredentialmqtt -clienthello -clienttask -clienttoken -cligetoutputbuffer -clint -cliprocesscommand -clk -clkdiv -clksel -clockoffsetms -clocksource -closesession -cloudformation -cmac -cmake -cmaxpower -cmcnt -cmd -cmdlen -cmdname -cmdrx -cmds -cmdtx -cmdtype -cmessage -cmessageid -cmi -cmia -cmock -cmp -cmsdk -cmse -cmsis -cmt -cnt -co -codesigner -codewarrior -coldfire -colour -coloured -com -comfirst -comlast -comm -commandloop -commecho -commreceivecallbackthread -comms -commsfirst -commslast -commtaskthread -commtaskthreadstarted -comp -comrx -coms -comtest -comtestc -comtx -conclr -cond -conf -config -configapplication -configassert -configasserts -configbenchmark -configcheck -configclear -configclint -configclkp -configclock -configcommand -configconfigcheck -configcpu -configcreate -configecho -configenforce -configeoi -configexpected -configflash -configgenerate -confighigh -configidle -configinclude -configinitial -configinstall -configinterrupt -configinttimer -configinttimerx -configintuart -configip -configisr -configkernel -configlabel -configlibrary -configmax -configmessage -configminimal -confignetwork -confignum -configper -configperipheral -configpit -configpost -configpre -configprint -configprintf -configprio -configquery -configqueue -configrand -configred -configreg -configrun -configs -configsetup -configstack -configstream -configsupport -configsystick -configtask -configtick -configtimer -configtimers -configtotal -configudp -configuratin -configurator -configureit -configuse -configyield -conifgcreate -conifgtotal -connack -connectfunction -connectmanager -const -constantspage -contextswitch -controltask -coprocessor -copybrief -corehttp -corejson -coremqtt -corepkcs -coresntp -coretasks -corextend -correctl -couldn -countmax -countstart -coutchar -coutputbuffer -coverity -cp -cprivilegedonlyaccessarray -cprover -cpsid -cpu -cpus -cqueue -cqueuereievefromisr -cread -creadonlyarray -creadwritearray -createcertificatefromcsr -createfile -createfileforrx -createkeysandcertificate -creatething -createthread -creceivedstring -credentialprovider -cren -crend -crflash -crfmax -crgflg -crl -crls -crossstudio -crredentials -crstart -crt -crxlock -crxstring -crypotki -crypto -cryptoapi -cryptointerface -cryptoki -csamplepagefirstpart -csamplepagesecondpart -cserialputchar -cserverhost -csr -csrc -csrs -css -cstring -ctaskwokenbypost -ctaskwokenbytx -ctimer -ctopicbuffer -ctr -ctransmittedstring -ctrdrgbcontext -ctrl -ctrla -ctrlb -ctx -ctxbuffer -ctxlock -ctxstring -curbyte -currentthread -curson -cvore -cwd -cwrite -cwtotallength -cybertrust -cyclesperus -cygnal -dap -dat -datashee -datasheet -datatracker -dbe -dcdc -dclr -dco -dcr -dd -ddr -ddrb -de -deathc -debounce -debouncing -debugbreak -debugmon -december -def -defenderjsonreportaccepted -defenderstatus -defendersuccess -del -dele -democonfigaws -democonfigclient -democonfigcredentials -democonfigdemo -democonfighttp -democonfighttps -democonfigmqtt -democonfignum -democonfigpresigned -democonfigrange -democonfigroot -democonfigs -democonfigserver -democonfigthing -democonfiguse -democonfiguser -demofiles -demoiptrace -demosetup -demotask -demotimer -demultiplexing -der -des -desc -describeendpoint -describejobexecution -deserialize -deserialized -deutsche -dev -developerguide -devicepublickeyasciihex -devicepublickeyder -dfined -dflopregisters -dfreertos -dgram -dgst -dhcp -dhe -dhm -didn -diff -diffie -digicert -digitcounter -dimentions -dimitri -dir -directl -dirent -dirver -disagr -disturbe -div -dl -dlab -dly -dma -dns -dnstestnum -docomo -doctype -doen -doens -doesn -dont -dout -downloadhttpexample -downloadmultithreadedhttpexample -doxygen -dpfpu -dph -dpl -dptr -dqp -dr -drbg -drm -drx -drxvalue -dset -dsp -dspdis -dtd -dtls -dtr -dup -ealready -eawsbroker -eball -ebase -ebaud -ebbit -ebcombined -ebdont -eblocked -ebset -ebwait -ebff -ec -ecc -ecdh -ecdhe -ecdsa -echobuffer -echomultitx -echoservertaskbuffer -ecjpake -ecmd -ecp -ecparameters -ecparams -ecparamsptr -ecpoint -edbg -edk -edrx -eeprom -eequalpriority -efm -eg -egisters -eic -eidrx -eidrxsettings -eind -eint -einval -einvalid -eio -eirf -eisdir -ek -eks -elif -emac -emacaddress -emetricscollectorbadparameter -emetricscollectorcollectionfailed -emetricscollectorsuccess -empt -empted -emption -empts -emul -en -enableirq -enableit -endcode -endcond -endian -endieness -endif -enoaction -enoent -enonsecure -enotdir -enotified -enterant -entercriticalsectionstub -entrancy -entropycontext -entrytimems -enum -enums -envisionrx -envrionment -eof -eol -ep -epalstate -epfr -epint -eps -eqivalent -equalled -er -ereceivedata -erfck -erofs -errmsg -errno -errnum -erxck -esavedagentstate -esecure -eselect -esending -esentaddressforread -esentaddressforwrite -esentdata -esentstart -eserver -esp -estatus -etaskgetstate -etaskstateget -eth -etharp -ethernet -ethernetif -ethernetisr -etherpxnetif -etxck -etxhigherpriority -etxlowerpriority -etype -europe -european -eusci -eval -evb -eventcallback -eventgroup -eventqueue -evk -evnt -evt -ewavr -ewifisecurityopen -ewifisecuritywep -ewifisecuritywpa -exampleisr -exc -excep -exe -exitcriticalsectionstub -exl -expecte -expectedfirstvalue -ext -externs -exti -extit -failureprintf -fakeassertexpectfail -fakeassertgetflagandclear -faq -faqhelp -faqs -fbrg -fclk -fclose -fcpu -fcr -fcs -fd -fde -fe -february -fec -ferr -ff -ffconfigdev -ffconfigmkdir -fi -fifo -fifolevel -fifos -fih -filehandle -fileio -filesize -filteration -findfirst -findobjects -fips -firstbackoffattempt -fixme -flase -flasg -flashc -flashlite -flashtimer -fleetprovisioningdemotemplate -flexcomm -flg -flopc -fm -fmain -fmx -fn -fnnnn -foo -fopen -forcestall -fosc -fp -fpe -fpga -fpidiv -fprintf -fpu -fpscr -fr -framming -france -fre -fread -freedomstudio -freertos -freertosconfig -freertosconifg -freertosdemo -freertosipconfig -freertosipconfigdefaults -freertoskernel -freq -freqency -fromisr -fs -fsanitize -fseek -fsl -fsram -fstack -fsub -ftcpdeletefunction -ftcpworkfunction -ftell -ftpcmd -fujitsu -ful -fulfil -func -funcs -fwrite -fx -fxp -fxx -galileo -galois -gc -gcc -gcm -gcr -gdb -gen -generatekeypair -generaterandom -genqmutex -getc -getcertificatefromcsr -getcommand -getdeviceserialnumber -getfunctionlist -gethostbyname -getipaddress -getlastmonotonictestvalue -getnextmonotonictestvalue -getslotlist -getstate -getsubackstatuscodes -gettopic -gettopicstring -gf -gic -gio -giosetbit -gir -girq -girqm -github -glibc -gmon -gmtime -gnd -gnuc -googleapis -gov -gpio -gpioa -gpiob -gpioc -gpiod -gpioe -gpios -greacefully -grec -gree -grp -gsm -hal -halboardinit -hallcd -hardfault -hclk -hcomm -hcs -hed -hein -hellman -helloverifyrequest -het -hetbase -hetport -hetreg -hexstring -hfclk -hfrco -hfxo -hh -hidef -hifive -hkdf -hmac -hooknum -hooktick -hpet -hr -href -hrsh -hse -hsm -ht -htaccess -htif -htimer -htm -html -htons -http -httpbin -httpclient -httpd -httpexamplemax -httpexamples -httpmethodpaths -httpnoresponse -httpparserinternalerror -httprequestinfo -https -httpserver -httpsocket -httpsuccess -hva -hw -hwmax -hyperterminal -hz -ia -iar -iasmarm -ibe -ic -icc -iccarm -icciar -iccid -iccrx -iclk -icmp -icr -icu -idd -ide -idproductl -idvendorl -ie -iec -ier -ietf -iex -ifdef -ifetch -ifndef -iinterface -iir -il -imanufacturer -imrh -imsi -inb -inc -incase -incr -indet -inet -infos -ingroup -init -initialisation -initialise -initialised -initialises -initializerequestheaders -initirqlevels -initstructure -inputmux -int -intc -intctl -integerc -integrationtestportablemax -intel -intenac -intenas -interfal -interfer -interruptcall -interrupthandler -interrupthandlers -interruptsources -intgexpected -intit -intp -intpriorityset -intput -intq -intqhigh -intqmin -intqnum -intqtimer -intqueue -intqueuetimer -intsemmax -io -iocr -ior -iot -iotconfiguse -iotlogging -iotnetworkcredentials -ip -ipaddr -ipconfigallow -ipconfigarp -ipconfigcan -ipconfigdhcp -ipconfigdns -ipconfigdriver -ipconfigethernet -ipconfigevent -ipconfigfilter -ipconfigftp -ipconfighas -ipconfighttp -ipconfiginclude -ipconfigmax -ipconfigmaximum -ipconfignetwork -ipconfignum -ipconfigrand -ipconfigreply -ipconfigsock -ipconfigsupport -ipconfigtcp -ipconfigudp -ipconfiguse -ipinit -ipl -iproduct -iram -irda -iret -ireturned -irom -irq -irqchannelpreemptionpriority -irqchannelsubpriority -irqcr -irqhandler -irqmask -irqmd -irqn -irqs -ish -isn -iso -isr -isrcode -isrs -isrserialrx -isrserialtx -isrt -isrtriggeredtask -isset -itemlength -itesm -itimezone -itm -itmc -itteratio -itu -ivr -jan -january -javascript -jefferson -jitp -jitr -jmp -jobactiontype -jobsdemoexample -jobsexampleexecution -jobsexamplequery -jp -jquery -js -json -jsonbadparameter -jsonnotfound -jsonnullparameter -jsonsuccess -jtag -jtvic -june -juse -katy -kbhit -keil -keyboardinterrupt -keygen -keytype -khz -kib -kickstart -knowns -kw -kx -lapic -lastsynctickcount -latestversion -lathclr -lathinv -lathset -launchpad -lbme -lbpdir -lbpsel -lbytes -lcd -lcde -lcdmessage -lcdmin -lcdrs -lcdrw -lcdstring -lcharacterstoadd -lcr -ld -ldi -ldo -ldr -le -leapsecondinfo -ledflash -ledio -leds -ledtimer -len -lendofframe -lerrorfound -lerrorintask -les -letimerrepeatfree -letimerufoanone -lfilecloseresult -lfxo -lfxt -lhigherprioritytaskwoken -libatdata -libc -libgcc -libs -linux -listcurrent -listget -listis -listitem -listitems -listlist -listset -listthings -ll -llevel -llmnr -llticksperhundedthmillisecond -lm -lmessage -lmessageindex -lmessagelength -lmessagevalue -lminimumlength -localhost -logdebug -logerror -loggingthread -loginfo -logwarn -loopback -loopcounter -loopf -loopif -lowpower -lparameternumber -lparameterstringlength -lpc -lpinclude -lpit -lpuse -lqfp -lr -lregteststatus -lresult -lretries -lreturn -lreturned -lsb -lserialputstring -lsize -lsl -lsls -lsr -lstringlength -ltd -lte -ltransmitted -lu -lv -lvalue -lvi -lwindowserror -lwip -lwipapps -lwipopts -lwt -lxfo -mac -mainblinky -maincheck -maincom -maincomm -maincreate -maindebug -maindelete -maindemo -maindevice -maindigit -mainecho -mainenable -mainerror -mainfirst -mainflash -mainhigher -maini -mainindex -mainisr -mainlast -mainlcd -mainled -mainlow -mainmessage -mainno -mainpage -mainprivileged -mainqueue -mainread -mainreg -mainreset -mainrx -mainselected -mainsemaphore -mainsoftware -maintask -maintest -maintimer -maintx -mainudp -mainvalue -mainwait -mair -malloc -mallocing -mam -masterrate -matchtopic -maxcdn -maxdword -maximise -maxitems -mbanumber -mbcoherence -mbed -mbedtls -mbexpected -mbmessage -mbnumber -mcbstm -mcf -mck -mclk -mco -mcr -mcu -mcuxpresso -md -mdc -mdtm -mec -mechanims -mechansim -mem -memcheck -memcmp -memcpy -memfault -memmanage -memoryleak -memorysanitizer -mems -memset -merkle -messagebufferlocations -messagetype -metadata -metaharmoniks -mgpiopinconfigstruct -mhz -microblaze -microcontroller -microcontrollers -microsemi -microsoft -microzed -middlebox -mii -mikroc -miliseconds -min -mingw -minilistitem -minimise -minimised -minpollperiod -mips -misc -misra -mkd -mkdir -mmcr -mno -mnos -montgomery -mosquitto -mov -movs -mp -mpc -mpi -mpis -mps -mpsoc -mpu -mpudemo -mpuregionsettings -mqtt -mqttagent -mqttagentcommand -mqttagentmessagecontext -mqttbadparameter -mqttcontext -mqttdemo -mqttexamplekeep -mqttexamplemessage -mqttexamplems -mqttexampleping -mqttexampletopic -mqttgetcurrenttimefunc -mqttkeepalivetimeout -mqttserverrefused -mqttsubscribeinfo -mqttsuccess -mr -mrcc -msb -msec -msg -msgsize -msi -msp -msr -mss -msvc -mtcoverage -mtu -mtvec -muc -multithreaded -multple -mutex -mutexes -mutexstatus -mutext -mutualauthhttpexample -mvec -myinst -myreply -nabto -najay -nano -nblisten -nbns -ndhdfb -nec -negotitation -netbios -netif -netifmax -netiftx -netinterface -netmask -netstat -networkcontext -networkcredentials -nextjobexecutionchanged -ni -nic -nirq -nist -nl -nmemb -nmi -nnnn -nographic -noinline -nondet -noninfringement -nonnull -noop -nop -nops -notificationarray -notifynotified -notifynotify -notifytask -notifyuint -ns -nsc -nscfunction -nsec -nspe -nt -ntp -ntpclient -ntpdemo -nts -ntt -nullptr -num -numaker -numberofitems -numofservers -nv -nvic -nvs -nxp -oaep -ocd -oe -oer -oerr -ofb -oid -oids -ok -oled -olen -olimex -onboard -onboarding -oneshot -op -opendns -openflag -openm -openrtos -opensession -openssl -optimisation -optimise -optimised -optimiser -optimising -optionalquery -org -originatetimestamp -os -osc -oszillation -ota -otaconfigmax -otaerr -otafilecontext -otaimagestate -otaimagestateaborted -otaimagestateaccepted -otaimagestaterejected -otamqttsuccess -otaoverhttpdemoexample -otaovermqttdemoexample -otapalimagestate -otapalimagestateinvalid -otapalimagestatependingcommit -otapalimagestateunknown -otapalimagestatevalid -otapalmainstatus -otapalsuccess -ouput -outb -outerset -outform -outgoingpublishpackets -outout -outputhz -outputlogic -overapproximation -overflowcount -overlayed -overlow -ovfl -pacdata -packetid -pactopic -pake -palpnprotos -param -paramater -pargument -partest -partstall -partstled -partston -passsed -passwordsize -pasv -pathlen -pauthcodesize -pauthcontext -payloadlength -pb -pbasetime -pbclk -pbe -pbuf -pbuff -pbuffer -pbufs -pc -pca -pcaction -pcaddress -pcallbackcontext -pcap -pcapplicationhostnamehook -pcattrib -pcbuffer -pcc -pccertificate -pccertificatebuffer -pccertificateidbuffer -pccertificateownershiptoken -pcclientcertlabel -pccmdintprocesscommand -pccommand -pccommandbuffer -pccommandinput -pccommandstring -pcconnectionack -pccontentrangevalstr -pccontentstype -pccsr -pccsrbuffer -pccssitags -pccurrentdir -pcdata -pcdatasentfrominterrupt -pcdefenderresponse -pcellularcommcontext -pcellularsocketcontext -pcertfilepath -pcextracontents -pcfakestring -pcfile -pcfilebuffer -pcfilename -pcfrom -pchead -pchelpstring -pchexoutput -pchost -pchostname -pcinputstr -pcjobdocument -pcjobid -pcjobstatusreport -pck -pcks -pcl -pclabel -pclabelname -pclientcert -pclientcertlabel -pclk -pclkb -pclwipappsblockinggettxbuffer -pcmackey -pcmessage -pcmethod -pcmyreply -pcname -pcnew -pcnewdir -pcommandtorelease -pcommandtosend -pcommportevent -pcommtaskevent -pcontext -pcontextbuffer -pcoutcsrlength -pcoverflowedtask -pcownershiptokenbuffer -pcpath -pcpayload -pcprintgetnextmessage -pcprivatekey -pcprivatekeylabel -pcprivkeylabel -pcpubkeylabel -pcpublickeylabel -pcqueuegetname -pcqueuename -pcreadfrom -pcreceivedstring -pcreg -pcrestcommand -pcrootdir -pcrxbuffer -pcrxedchar -pcserver -pcservername -pcshadowname -pcsource -pcstartheaderloc -pcstatusmessage -pcstring -pcstringtoreceive -pcstringtosend -pctail -pctaskname -pcthingname -pcthingnamebuffer -pcto -pctopic -pctopicfilter -pctopicfilterstring -pctransmittedstring -pctxbuffer -pcurl -pcurldata -pcurrenttime -pcwritebuffer -pcwriteto -pd -pdata -pdc -pdcommand -pdf -pdfail -pdfalse -pdfreertos -pdigest -pdlong -pdms -pdn -pdpass -pdr -pdtrue -pe -peform -pelapsedtimems -pem -pendsv -perfrom -perh -periph -pf -pfile -pfilecontext -pfilepath -pfm -pfr -pfs -pfswe -pfunctionlist -phostname -php -phy -pic -pico -pidr -pingreq -pingresp -pio -piob -pirng -pivr -pj -pk -pkcs -pki -pkparse -pkwrite -plaformimagestate -plaintext -plaintexthttpexample -platformimagestate -pleaseconsult -plib -plic -pll -pllclk -pllclock -pllon -plls -plrng -pm -pmc -pml -pmp -pmqttagentcontext -pmqttcontext -pmsg -pmsgctx -pmu -pmutex -pnetcred -pnetctx -pnetworkcontext -pnetworkcredentials -po -podr -polarfire -pollq -pollqc -poly -porta -portaclr -portainv -portaset -portasm -portb -portbase -portcompact -portconfigure -portdisable -porte -portenter -portexit -portfreertos -portget -portisr -portlarge -portlm -portmacro -portmacros -portmax -portmedium -portno -portnum -portprivilege -portrestore -portsave -portsmall -portsoftware -portswitch -porttc -porttick -porttotal -portyield -posix -potainterfaces -powerdown -poweron -powerup -pp -pparam -pparams -ppass -ppassword -ppc -ppcmessagetodisplay -ppollperiod -ppr -pprivatekey -pprivatekeylabel -ppublishinfo -ppvcontext -ppxidletaskstackbuffer -ppxtimertaskstackbuffer -pragma -prcmd -pre -preceivedcommand -predivide -prefen -premain -prequestbuffer -prescale -prescaled -prescaler -presense -presigned -presponsedata -prev -printc -printf -printfs -prio -prioity -prioritisation -prioritised -prioritydefinitions -privatekeyclass -privatekeysize -privatekeytype -priviledged -privkey -privkeyinfo -processloop -prodh -prodl -proj -projcoverage -promiscious -prootca -properoperation -prot -proto -prototye -prs -prv -prvabortcommand -prvappendcommand -prvautoreloadtimercallback -prvbitcombinationtestmasterfunction -prvblinkytimercallback -prvblockonanonnotifiedindexed -prvblockonthenotifiedindexed -prvcallback -prvcdccommandconsoletask -prvcdcommand -prvchangeprioritywhensuspendedtask -prvcheckoptions -prvcheckothertasksarestillrunning -prvchecktask -prvchecktaskcounters -prvchecktimercallback -prvcollectdevicemetrics -prvcomtxtimercallback -prvconnectandcreatedemotasks -prvcopycommand -prvcopydatatoqueue -prvcoreatask -prvcorebtasks -prvcreatecommand -prvcreatedemofiles -prvcreatedemofilesusing -prvcreatedemofileusing -prvcreateprintsocket -prvdefenderdemotask -prvdelcommand -prvdemonstratependingfunctioncall -prvdemonstratetimerqueryfunctions -prvdemoqueuespacefunctions -prvdemotimercallback -prvdigitcountertimercallback -prvdircommand -prvdisplayipdebugstats -prvechoclientrxtask -prvechoclienttask -prvechoclienttxtask -prveventcallback -prvexceptionhandler -prvfirstregtesttask -prvflashcoroutine -prvflashtimercallback -prvfleetprovisioningtask -prvformatcommand -prvgeneratedevicemetricsreport -prvgetdisinheritpriorityaftertimeout -prvgetnextdelaytime -prvgettcbfromhandle -prvgettimems -prvhighprioritymutextask -prvhttpdemotask -prviliged -prvincomingpublish -prvinitialisehardware -prvinitialisenewqueue -prvinterrupttriggertest -prvisrautoreloadtimercallback -prvisrblocktask -prvisroneshottimercallback -prvisrtriggeredtask -prvjobsdemotask -prvkeyboardinterrupthandler -prvkeyboardinterruptsimulatortask -prvlcdtask -prvlcdtaskline -prvledtimercallback -prvledtoggletimer -prvlinkcommand -prvloggingflushbuffer -prvlowlevelinit -prvlowlevelinput -prvlowprioritymutextask -prvm -prvmaincheckothertasksarestillexecuting -prvmkdircommand -prvmqttagenttask -prvmqttdemotask -prvmqttprocessincomingpacket -prvmqttsubscribetotopic -prvmutextest -prvnonblockingreceivertask -prvnotifiedtask -prvnotifyqueuesetcontainer -prvntptask -prvobjectgeneration -prvobjectimporting -prvoldstyleprivilegedmodetask -prvoldstyleusermodetask -prvoneshottimercallback -prvpal -prvparameterechocommand -prvpendedfunction -prvperformtasksynctests -prvpingcommand -prvpingreqtimercallback -prvpublishcallback -prvqueryheapcommand -prvqueueoverwritetask -prvqueuereceivetask -prvqueuesendtask -prvqueuesendtimercallback -prvqueuesetreceivingtask -prvreadandassumecertificate -prvreadnamefield -prvreceivingtask -prvrecursivemutexblockingtask -prvrecursivemutexcontrollingtask -prvrecursivemutexpollingtask -prvregistercheck -prvregtest -prvregtesttask -prvregtesttaskentry -prvrenamecommand -prvrequesttask -prvresponsetask -prvretrievefilework -prvrunotademo -prvruntimestatscommand -prvsanitycheckcreatedsemaphore -prvsavetracefile -prvsecondregtesttask -prvsecurecallingtask -prvselectivebitstestmasterfunction -prvselectivebitstestslavefunction -prvsemaphoretaketask -prvsendcontroldata -prvsendfrontandbacktest -prvsendnextsegment -prvsendreply -prvsetandcheckregisters -prvsetuphardware -prvshadowdemotask -prvsignatureverificationfinal -prvsimpleclienttask -prvsimpleservertask -prvsimplesubscribepublishtask -prvsimplezerocopyservertask -prvsimplezerocopyudpclienttask -prvsingletasktests -prvskipnamefield -prvstartsimplemqttdemo -prvstartsimplesntpdemo -prvstartstoptracecommand -prvstatcommand -prvstatfscommand -prvstaticallyallocatedcreator -prvstaticallyallocatedtask -prvstreambufferadd -prvsubscribetodefendertopics -prvsynctask -prvtaskstatscommand -prvtasktodelete -prvtestfscommand -prvtestmastertask -prvtestmemoryregions -prvtestnotifytaskwhilesuspended -prvtesttimercallback -prvthreadsafedifferentsocketsdifferenttasks -prvthreeparameterechocommand -prvtimercallback -prvtimerquery -prvtimertesttask -prvtransactcommand -prvtransferconnect -prvtransferstart -prvtransmaskgetcommand -prvtransmasksetcommand -prvtypecommand -prvuartcommandconsoletask -prvuartrxnotificationhandler -prvudpechoclienttask -prvunlockqueue -prvupdateacceptedhandler -prvupdatedeltahandler -prvwin -prvwindowskeyboardinputthread -prvwinpcaprecvthread -prvwinpcapsendthread -prvzerocopyechoclienttask -ps -psa -psc -pscheckvariable -psel -pserver -pserverinfo -pservertime -psignature -psk -psl -pslotlist -psm -psmsettings -psmtau -psmtimer -psoc -psocket -psr -psregistrationstatus -pss -psslcontext -pstartheaderloc -pstplatformimagestate -psval -psw -pt -ptal -ptcpsocket -pth -pthingname -pthread -ptime -ptimeserver -ptimeservers -ptm -ptopicfilter -ptp -ptr -ptt -puback -pubcomp -pubin -publishtotopic -pubout -pubrec -pubrel -pucbuf -pucbuffer -puccertdata -puccertname -pucdata -pucdescription -pucethernetbuffer -pucethernetbufferpointeres -pucethernetbufferpointers -puchash -pucindex -pucinterfacename -pucmessage -pucpayloadbuffer -pucqueuestorage -pucrandom -pucresponse -pucsig -pucsignature -pucsignercert -pucsignercertificate -pucstreambufferstoragearea -pucstring -puctxbuffer -pucudppayloadbuffer -pudpcontext -pul -pulcount -puldigestlen -puldis -pullup -pullups -pulmemchecktaskrunningcounter -pulnotification -pulnotifiedvalue -pulnumber -puloutnumestablishedconnections -puloutnumudpopenports -puloutreprotlength -pulstandardperipheralregister -pulsystemperipheralregister -pultaskidarray -pultaskidarraylength -pultaskidsarray -puserdata -pusername -pusopenportsarray -pusouttcpportsarray -pusoutudpportsarray -putc -putchar -puxstackbuffer -pv -pvalue -pvargs -pvargument -pvbuffer -pvcontext -pvctx -pvincomingpublishcallbackcontext -pvitemtoqueue -pvoptionvalue -pvparam -pvparameters -pvportfree -pvportmalloc -pvrng -pvsigverifycontext -pvtaskcode -pvtaskincrementmutexheldcount -pwd -pwm -pwpr -pwr -pxaddress -pxaddresslen -pxattrs -pxbuffer -pxcallback -pxcertificatebufferlength -pxcertificatecontext -pxcertificateidbufferlength -pxclass -pxclidefinitionlistitembuffer -pxclient -pxcommand -pxcommandcontext -pxcommandinterpreter -pxcommandtoregister -pxconnectionsarray -pxcontext -pxctx -pxcurrenttcb -pxdeserializedinfo -pxdnsserveraddress -pxdptr -pxecdsacontext -pxecparams -pxecparamsptr -pxendpoint -pxexpiredtimer -pxfilesize -pxftpclient -pxfunctionlist -pxheadersdatalen -pxhigherprioritytaskwoken -pxincomingpacket -pxincomingpublishcallback -pxindex -pxinterface -pxisrfunction -pxknownmessage -pxlist -pxmbedpkcontext -pxmbedtlspkctx -pxmetrics -pxmqttcontext -pxmyinterface -pxnetif -pxnetworkbuffer -pxnetworkcontext -pxnetworkcredentials -pxnewqueue -pxnext -pxopenedinterfacehandle -pxoutcharswritten -pxoutconnectionsarray -pxoutgoingpublishpackets -pxoutlengthwritten -pxoutnetworkstats -pxoutnumestablishedconnections -pxoutnumtcpopenports -pxoutnumudpopenports -pxoutreportlength -pxoutreprotlength -pxoutwrittenlength -pxownershiptokenbufferlength -pxpacketinfo -pxpathlen -pxpkcslabelsptr -pxport -pxpublishinfo -pxqueue -pxreadhandle -pxreceivecompletedcallback -pxreportdescriptor -pxrequestheaders -pxrequestinfo -pxresponse -pxresult -pxresults -pxreturninfo -pxrng -pxrngcontext -pxsendcompletedcallback -pxsiglen -pxsigvcreds -pxslotid -pxsocket -pxstaticstreambuffer -pxstreambuffer -pxsubscriptionlist -pxtaskbuffer -pxtaskstatusarray -pxtcb -pxthingnamebufferlength -pxtickstowait -pxtimeout -pxtimer -pxtimerinstance -pxtimersettings -pxtransportinterface -pxwritehandle -py -qemu -qos -queeu -queuebuffer -queuegenericcreate -queuegenericcreatestatic -queuegenericreset -queuehandle -queuelists -queuelock -queueoverwrite -queuequeue -queueregistry -queueregistryitem -queuesemaphoretake -queueset -queuesethandle -queuesetinitial -queuesetisr -queuesetpriority -queuespacesavailable -queuestorage -queuesuspend -ra -rampz -rand -random -randomisation -randomise -randomised -randomiser -raspberrypi -ratpriorities -rb -rbar -rbr -rbuf -rc -rcc -rcvr -rcvtimeo -rdparty -readbale -readdir -readintervaltimeout -readme -readonly -readtotaltimeoutconstant -readtotaltimeoutmultiplier -realtek -reblocked -receiveloop -receivetimeout -receivetimeoutms -receivetimestamp -recmucontrolling -recmutex -recognisable -recognise -recognised -recognises -recorderdata -recv -recvfrom -recvtimeout -referenceid -referencetimestamp -reflash -reg -registerthing -regtest -reinitialise -reinitialised -rel -releasecommand -releaseudppayloadbuffer -remvove -ren -reneable -renesas -repl -repo -reportbuilderbadparameter -reportbuilderbuffertoosmall -reportbuildersuccess -reportid -reqds -reqenc -reqens -reseed -resending -resetart -resetprg -resoltion -resp -responsebuffer -responsesize -restartable -resubscribe -resubscribes -resync -resynced -resynchronise -retargets -retored -retr -rf -rfc -rgb -rhr -ri -richard -ripemd -risc -riscv -rl -rlar -rmd -rmii -rnfr -rng -rnto -ro -robotronics -rollover -rom -rootca -rootcasize -rootdelay -rootdispersion -rowley -rsa -rsaes -rsassa -rsk -rskrl -rskrx -rstop -rt -rtc -rtcc -rtcccapcomchmodecompare -rtcccntmodenormal -rtcccntpresc -rtcccnttickpresc -rtcccompbasecnt -rtcccompmatchoutactionpulse -rtccdaycomparemodemonth -rtccinedgenone -rtccprsch -rti -rtos -rtosdemo -rtp -rts -rv -rw -rx -rxbuf -rxbuffer -rxcie -rxd -rxdv -rxechar -rxed -rxen -rxend -rxevent -rxfifolevel -rxmode -rxsetup -rz -sa -safertos -sam -sama -samd -sampleapp -sampleapptask -santity -sara -sarecomtesttasksstillrunning -saveall -sbnumber -sbreceive -sbsend -sbtrigger -scalled -scanf -scf -schedulersuspend -sci -scott -scr -scrf -sct -sctlr -sdk -sdklog -sec -secretaccesskey -seedfile -seg -segfault -sel -selpll -sem -semaphorehandle -semihosting -semtest -semtestc -sendb -sendpingrequest -sendtimeout -sendtimeoutms -sendto -sep -sepearted -serialbaurate -serialised -serialisr -serialnumber -serialporttool -serialsci -serinput -serinterrupt -serput -sersource -sertx -serveraddr -serverhost -serverport -sessiontoken -setbaudratevalue -setbuf -setfaketaskpriority -setimagestate -setpollisr -setpriority -setsockopt -setupcellular -sfena -sfprld -sfr -sfsrootcag -sha -shadow -shadowname -shadownamelength -shadowstatus -shasum -shigherprioritytaskwoken -shouldinitializecontext -shouldn -shtml -sice -sifive -sigint -signalled -signatureverificationstate -signatureverificationstateptr -signingcredentialsigning -signinit -signled -sil -silabs -simon -simplelink -simpletcpechoserver -simpleudpclientandserver -simultaniously -singletasks -sizeof -sk -skt -slewrate -slibxr -smc -smclk -smp -smr -smt -snextcheckvariable -sni -snprintf -sntp -sntpclienttask -sntperrorauthfailure -sntpservernotauthenticated -sntpsuccess -sntptask -sntptimestamp -soc -sockaddr -socketauto -sockethandle -socketserrors -socklen -sof -softbank -softbaugh -somewebsite -sp -spbrg -spdx -spe -specifiedecdomain -spen -spi -spm -sprintf -spu -sr -sram -src -sren -srtp -ss -sscanf -ssi -ssitask -ssl -ssr -stabiliasation -stabilisation -stackoverflow -stacksize -stacktype -stallsent -standalone -starfield -stat -statcreate -statechanged -statfs -staticbuffersize -staticcreator -staticeventgroup -staticmax -staticqueue -staticsemaphore -staticstreambuffer -statictask -statictimer -statusmessage -stdarg -stderr -stdint -stdlib -stdout -sthreempty -stirng -stm -stor -str -strcasecmp -strcasestr -strin -stringification -strintrx -strlen -struct -structs -stxinterrupton -stylesheet -suback -sublicense -subsquent -succeds -suicidaltasks -summarise -sv -svc -svr -sw -swi -swintr -sx -synch -synchronisation -synchronise -synchronised -synchronising -sys -syscall -syscalls -syscfg -sysclk -sysinit -syst -systemcoreclock -systemgetwallclocktime -systeminit -systeminithook -systemirqhandler -systemstoreficrns -systemtick -systick -systickdelay -sz -taskbuffer -taskcode -taskdelete -taskdisable -taskenter -taskhandle -taskhasexecuted -tasknotify -taskparameters -taskpool -taskrecord -taskscheduler -taskselect -tasksstubs -taskstatus -taskyield -tbd -tbuf -tc -tcb -tcbs -tcnt -tcp -tcpechoclient -tcpip -tcpserverwork -tcpsocket -tcptestassert -tcptestbuffer -tcptestecho -tcptestechotestmodes -tcptestmax -tcptestrx -tcptesttcp -tcptesttx -td -teardown -tei -telecom -telekom -telstra -telus -temo -temt -terraterm -testcase -testcases -testloop -testrunnerafqp -testrunnerfull -testshadowname -testthingname -testtimoutms -testval -tex -tfrz -tha -thingname -thingnamelength -thr -thre -threadroutine -throwtheswitch -ths -tickless -tickrate -ticktype -tiemr -tim -timeguard -timeoutvaluems -timertest -timertimer -timeserver -tinycbor -tls -tmr -tmrdemoone -tmrhigher -tmrlower -tmrmedium -tmrtc -tmrtesthigh -tmrtimer -todo -tokenpresent -toolchain -toolset -topicbuffer -topicfilter -topicfilterlength -topiclen -topiclength -tp -tracelisttasks -traceonenter -tracetask -trafic -transmaskget -transmaskset -transportinterface -transportrecv -transportsend -transporttimeout -trc -trcena -trcrecorder -tri -triboard -tricore -tris -trmt -trng -truely -trueobject -trustzone -tscr -tskidle -tskyield -tt -ttc -ttl -twoechoclient -tx -txcomp -txd -txempty -txen -txend -txfifolevel -txpktrdy -txt -tz -uart -uartcommandconsole -uartlite -uarts -ubasetype -uc -uca -ucautoreloadtimercounters -ucbaddnsresponseh -ucbaddnsresponsei -ucbuffer -ucbufferaddresshighbyte -ucbufferaddresslowbyte -ucbufferstorage -uccommand -uccurrentoutputvalue -ucdatagar -ucdatamsr -ucdatashar -ucdatasipr -ucfifodata -uchars -ucheap -ucidentifier -ucindex -ucisrreloadtimercounter -ucisstopneededintimerzerocallback -ucline -uclisten -ucminallowablevalue -ucname -ucnextbuffertoprocess -ucnormallyemptyreceivedvalues -ucnormallyfullreceivedvalues -uconeshottimercounter -ucqos -ucqueuegetqueuetype -ucqueuestoragearea -ucreqtype -ucrequest -ucrequesttype -ucrotaskfaulttracker -ucsha -ucshadownamelength -ucsharedbuffer -ucsharedmemory -ucsharedmemoryn -ucslaveaddress -ucsrb -ucsrc -uctempbuffer -ucthingnamelength -ucxbrf -ucxbrs -udp -udpck -udpclient -udphs -uihashlen -uint -uintptr -uip -uk -ul -uladditionaloffset -ulamount -ulaverage -ulblockindex -ulblocksize -ulblockvariable -ulbufferlength -ulbytesread -ulbytesreceived -ulbytessent -ulcalculatedvalue -ulcallcount -ulcoursecyclecounter -ulcurrentversion -ulcyclecount -ulcyclecounter -ulcyclecounters -uldata -uldemosoftwaretimercounter -uldigestlength -uldirection -ulemacinputlength -ulerrorcode -ulerrorfound -uleventmask -ulexeuctioncounter -ulexitresetspinloop -ulexpectedbits -ulexpectedhighfrequencyinterrupts -ulexpectedidletime -ulfinecyclecount -ulfirstnotifiedconst -ulflags -ulflopregisters -ulfpuinterruptnesting -ulfrco -ulgetruntimecountervalue -ulglobalentrytimems -ulhighfrequencytimercounts -ulhighfrequencytimerinterrupts -ulhighfrequencytimerticks -ulinterruptmask -ulinterruptnumber -ulinterrupttriggercounter -ulipaddress -ulipaddressfound -ulledbits -ullength -ullinenumber -ulloopcounter -ulmaingetruntimecountervalue -ulmair -ulmajorreportversion -ulmaxfpuinterruptnesting -ulmaxjitter -ulmaxloop -ulmaxloopcount -ulmaxpublishcount -ulmemchecktaskrunningcount -ulmessagevalue -ulminorreportversion -ulnextrxbuffer -ulnextsubscribemessageid -ulnonblockingrxcounter -ulnonsecurecounter -ulnonsecurestartaddress -ulnotification -ulnotificationvalue -ulnotifiedvalue -uloffset -ulong -ulpacketsreceived -ulpacketssent -ulport -ulportinterruptnesting -ulprescale -ulpriority -ulprioritysetcounter -ulrangeend -ulrangestart -ulrbar -ulreaddata -ulreceivedvalue -ulrecvbytes -ulregtest -ulreloadvalue -ulreloadvalueforonehighresolutiontick -ulremoteipaddress -ulreportid -ulrestartoffset -ulreturned -ulrlar -ulruntimeoverflowcount -ulsecondnotificationvalueconst -ulsecondnotifiedconst -ulsecondnotifiedvalueconst -ulsectionlength -ulsectionlenths -ulsettononzeroindebuggertocontinue -ulsettononzerotoexitloop -ulsize -ulslotcount -ulstartingperiodms -ulstatsoverflowcount -ulstringlength -ultaskendtrace -ultaskgetidleruntimepercent -ultasknotifytake -ultasknotifytakeindexed -ultasknotifyvalueclearindexed -ultim -ultimeoutms -ultimer -ultotalframelength -ultrascale -ultx -ulvaluelen -ulvaluetosend -ulwantedbaud -umount -un -unblockes -unconfigure -unconfigured -undefine -unferenced -unicast -uninitialised -unityconfigurationguide -unityprint -unix -unk -unrecognised -unsecure -unsub -unsuback -unsuspend -unsuspends -unuseable -unusued -updatejobexecution -uploadhttpexample -upto -urandom -urc -urcevent -uri -url -urls -usagefault -usart -usarts -usb -usbat -usbbus -usbconfiguration -usbdevice -usbfifo -usbhid -usbinterface -usbmanufacturer -usbproduct -usbqueue -usbufferaddress -usbuffersize -uscheckstatus -usclockhz -usdocumentlength -userguide -usermode -usernamesize -usfrequencyhz -usidentifier -usindex -usjobidlength -usmaxjitter -usoutlength -uspacketid -uspacketidentifier -usport -usportnumber -usremoteport -usstackdepth -usstackhighwatermark -usstacksize -ustaskstacksize -uxtaskstacksize -usthingnamelength -ustopicfilterlength -ustopiclength -ustotallength -utalised -utc -utest -util -utilies -utilise -utilised -utils -utran -uvmpw -ux -uxbaseled -uxbits -uxbitsgetval -uxbitssetval -uxbufferlength -uxbytesleft -uxbytesreceived -uxbytessent -uxcreatortaskstackbuffer -uxcurrentseconds -uxerrorhasoccurred -uxeventgroupgetnumber -uxeventqueuelength -uxfreestack -uxindex -uxindextonotify -uxindextotest -uxinitialcount -uxitemsize -uxled -uxledtimer -uxlength -uxlistremove -uxloopcount -uxmaxcount -uxmessageswaiting -uxnetworkisup -uxnewpriority -uxnumbertocreate -uxpacketsreceived -uxpacketssent -uxparameternumber -uxpriority -uxqueue -uxqueuegetqueuenumber -uxqueuelength -uxqueuemessageswaiting -uxqueuemessageswaitingfromisr -uxqueuespacesavailable -uxrand -uxregtesterror -uxreturned -uxrxloops -uxrxstackbuffer -uxschedulersuspended -uxsecs -uxsemaphoregetcount -uxstackbuffer -uxstate -uxstreambufferadd -uxstringlength -uxsynchronisationbit -uxtaskgetnumberoftasks -uxtaskgetstackhighwatermark -uxtaskgetsystemstate -uxtaskgettasknumber -uxtaskpriority -uxtaskpriorityget -uxtb -uxtick -uxtxstackbuffer -uxvariabletoincrement -valdiate -valgrind -vanexampleisr -vapplicationfpusafeirqhandler -vapplicationftpreceivedhook -vapplicationgetidletaskmemory -vapplicationgettimertaskmemory -vapplicationhpettimer -vapplicationidlehook -vapplicationipnetworkeventhook -vapplicationirqhandler -vapplicationmallocfailedhook -vapplicationpingreplyhook -vapplicationsetupinterrupts -vapplicationsetuptimerinterrupt -vapplicationstackoverflowhook -vapplicationtickhook -var -vbasicwebserver -vbat -vblink -vbus -vbuttonhandlertask -vbuttonisrhandler -vcellularconnecttask -vcellulardemotask -vclearemactxbuffer -vcmp -vconfiguretimerforruntimestats -vcore -vcreatesuicidaltask -vcreatesuicidaltasks -vcreatetasks -vdd -ve -vect -vectoredhandler -vega -veh -veify -veirfy -vemacread -verifast -verifyinit -verizon -verrorchecks -veventgroupclearbitscallback -veventgroupdelete -veventgroupsetbitscallback -veventgroupsetnumber -vexternalint -vfakeassert -vfirstregistertesttask -vflopcheck -vfp -vftpreplymessage -vfulldemotickhook -vgeneratecorebinterrupt -vhandlememoryfault -vic -vinitialisetimerforintqueuetest -vinterrupton -virt -visualisation -vlcdtask -vledtimercallback -vlistinitialise -vlistinitialiseitem -vlistinsert -vlistinsertend -vlistintert -vlistintertend -vlogginginit -vloggingprintf -vlt -vlwipappsreleasetxbuffer -vmain -vmaindeleteme -vmainpoststopprocessing -vmemchecktask -vmov -vmrs -vodafone -votademotask -vpartestinitialise -vpartesttoggleled -vperformaction -vpit -vportenableinterrupt -vportexceptionsinstallhandlers -vportfree -vportgetheapstats -vporthandleinterrupt -vportsetupinterruptcontroller -vportsetuptickinterrupt -vportsetuptimerinterrupt -vportsuppressticksandsleep -vportsvchandler -vporttaskusesfpu -vporttickisr -vportyield -vportyieldfromisr -vportyieldisr -vportyieldwithinapi -vpostsleepprocessing -vpresleepprocessing -vprintdisplaymessage -vprinttask -vqueueaddtoregistry -vqueuedelete -vqueueoverwriteperiodicisrdemo -vqueuereceivewhensuspendedtask -vqueuesendwhensuspendedtask -vqueuesetaccessqueuesetfromisr -vqueuesetqueuenumber -vqueueunregisterqueue -vqueuewaitformessagerestricted -vregistercheck -vregtest -vrxfaultinjection -vsecondregistertesttask -vsemaphorecreatebinary -vsemaphoredelete -vserialputstring -vserialsendstring -vsetandcheckregisters -vsetuphighfrequencytimer -vsetuptimertest -vsimplesubscribepublishtask -vsnprintf -vstart -vstartdefenderdemo -vstartfleetprovisioningdemo -vstartjobsdemo -vstartmathtasks -vstartntptask -vstartotademo -vstartshadowdemo -vstartsimplehttpdemo -vstartsimpletcpservertasks -vstartstaticallyallocatedtasks -vstarttasknotifyarraytask -vstarttimerdemotask -vswc -vtaskcreate -vtaskcreatestatic -vtaskdelay -vtaskdelayuntil -vtaskdelete -vtaskendscheduler -vtaskgetheapstats -vtaskgetinfo -vtaskinternalsettimeoutstate -vtasklist -vtaskmissedyield -vtasknotifygivefromisr -vtaskplaceoneventlistrestricted -vtaskpriorityset -vtaskresume -vtaskresumeall -vtasksettimeoutstate -vtaskstartscheduler -vtaskstarttrace -vtasksuspend -vtasksuspendall -vtaskswitchcontext -vtaskusesdpfpu -vtaskusesfpu -vtimersettimerid -vtr -vtraceaction -vtraceenable -vtracestop -vudpcommandinterpretertask -vusbcdctask -vwritebuffertodisk -waitingtoreceive -waitingtoreceivefrom -waitingtosend -waitstate -wasn -wdt -wdtm -webmax -weierstrass -wether -wi -wifi -wifisecurity -wikipedia -winavr -winpcap -winsim -winsock -witemlength -witin -wizc -wiznet -wmaxpacketsize -wolfssl -wpa -writefile -ws -www -xa -xactionlength -xaddress -xaddresslength -xafterlinebreak -xapplicationdhcpuserhook -xaredynamicprioritytasksstillrunning -xareflopregistertestsstillrunning -xaremathstaskstillrunning -xaremessagebuffertasksstillrunning -xarequeeusettasksstillrunning -xarequeuesettasksstillrunning -xarestreambuffertasksstillrunning -xaretasknotificationarraytasksstillrunning -xarraysize -xasymmetricalgorithm -xasynchronous -xautoreload -xautoreloadtimers -xb -xbacklog -xbaseperiod -xblocktime -xblockwasaborted -xbufferlength -xburtcinitstruct -xbytesreceived -xbytessent -xbytestorecv -xc -xcb -xcdcusart -xcerthandle -xcertificatelength -xcertificateownershiptokenlength -xchecktaskbuffer -xchecktaskstack -xchecktimer -xclass -xcleansession -xclearbits -xclientaddresslength -xclientlength -xclientsocket -xcolumns -xcommand -xcommandqueue -xcomporthandle -xconnectedsocket -xconnectionsarraylength -xcontrolmessagebuffer -xcopyposition -xcorebmessagebuffers -xcount -xcreatecleansession -xcreatedtask -xcreatortasktcbbuffer -xcsrbufferlength -xcsrlength -xcurbyte -xdatalength -xdatamessagebuffers -xdb -xdefenderresponselength -xdelayticks -xdeleteresponsereceived -xdeletetaskstack -xdeltams -xdemotimer -xdestinationaddress -xdevicemetrics -xdigitcountertimer -xdirectprint -xdolisten -xdontblock -xdoremove -xe -xeb -xechoserveraddress -xemacindex -xemaclite -xend -xendpoints -xerrorcount -xerrordetected -xerrorline -xerrorstatus -xestablishmqttsession -xeventgroup -xeventgroupclearbits -xeventgroupclearbitsfromisr -xeventgroupcreate -xeventgroupcreatestatic -xeventgroupgetbits -xeventgroupgetbitsfromisr -xeventgrouphandle -xeventgroupsetbits -xeventgroupsetbitsfromisr -xeventgroupsync -xeventgroupwaitbits -xexpectedidletime -xexpectednumber -xexpectedspace -xexpectedtask -xexpectedtaskcounters -xf -xfa -xfc -xff -xfffe -xffff -xffffffff -xfffffffl -xfilenumber -xfilesize -xfirsttimerhandler -xflashrate -xflashrates -xfreeheapspace -xftpclientwork -xglobalscopecheckqueue -xglobalsubackstatus -xhashalgorithm -xhashlen -xheapregions -xheapstats -xhelpcommand -xhigherprioritytaskwoken -xhighprioritymutextask -xhighprioritytaskwoken -xhints -xhostlen -xhow -xilinx -xincrement -xindex -xinputstrlen -xinsideinterrupt -xinterface -xinterruptcontroller -xipaddressfound -xiptracevalues -xipversion -xirqrequest -xisinsideisr -xisrautoreloadtimer -xisroneshottimer -xisrstatus -xitemvalue -xkeytype -xlastchecktime -xlastcounttime -xlastexecutiontime -xlastflashtime -xlastrefreshtime -xlastwaketime -xlatcherror -xlcdqueue -xledparaemtes -xledstate -xledtimer -xlen -xlength -xlentosend -xlimitedincrementhandle -xlogging -xlogtofile -xlogtostdout -xlogtoudp -xloopcounterincrementtimemax -xm -xmaintask -xmargin -xmark -xmaxblocktime -xmaxblocktimeagain -xmaxcount -xmaxfiles -xmaximumpossiblesuppressedticks -xmdalg -xmessagebuffer -xmessagebuffercreatestatic -xmessagebufferreceive -xmessagebuffersend -xmessagebuffersendfromisr -xmessagecomplete -xmessagecompletesemaphore -xmessagelength -xmessagelengths -xmethodlen -xmode -xmoredatatofollow -xmqttsocket -xmutex -xmutexholder -xmutextodelete -xnetworkbuffer -xnetworkcontext -xnextbyte -xnextchar -xnextfreebyte -xnextlength -xnextwaketime -xnotifyarraytaskfromisr -xntppacket -xntptaskhandle -xntptaskisrunning -xnumberofleds -xnumberofsuccessfulallocations -xnumberofsuccessfulfrees -xnumbytes -xnumbytesreceived -xnumbytessenttotal -xnumreqbytes -xoktogivemutex -xoneshottimer -xopenportsarraylength -xoptionlength -xor -xosel -xp -xpar -xparameternumber -xparameterstringlength -xpathlen -xpendedticks -xpendingreadylist -xperiod -xpingreqtimer -xpingresptimer -xpkhandle -xplained -xport -xportalt -xportgetfreeheapsize -xportinit -xportinitminimal -xportinstallinterrupthandler -xportisinsideinterrupt -xportnumber -xportpendsvhandler -xportregistercinterrupthandler -xportsystickhandler -xposition -xpreparetasklists -xprintqueue -xprivatekeyhandleptr -xprivatekeylength -xprivilegedmodetaskbuffer -xprivilegedmodetaskstack -xprocessreceivedudppacket -xpublickey -xpublickeyhandleptr -xpublishcallback -xqos -xqueue -xqueueaddtoset -xqueuecreate -xqueuecreatecountingsemaphore -xqueuecreatecountingsemaphorestatic -xqueuecreatemutex -xqueuecreatemutexstatic -xqueuecreateset -xqueuecreatestatic -xqueuefromset -xqueuegenericcreate -xqueuegenericcreatestatic -xqueuegenericreset -xqueuegenericsend -xqueuegenericsendfromisr -xqueuegetmutexholder -xqueuegetmutexholderfromisr -xqueuegivefromisr -xqueuegivemutexrecursive -xqueuehandle -xqueuehandlestatic -xqueueisqueueemptyfromisr -xqueueisqueuefullfromisr -xqueueoverwrite -xqueueoverwritefromisr -xqueuepeek -xqueuepeekfromisr -xqueuereceive -xqueuereceivefromisr -xqueueregistry -xqueueremovefromset -xqueuereset -xqueueselectfromset -xqueueselectfromsetfromisr -xqueuesemaphoretake -xqueuesend -xqueuesendfromisr -xqueuesendtoback -xqueuesendtobackfromisr -xqueuesendtofront -xqueuesendtofrontfromisr -xqueueset -xqueuesetfromset -xqueuesethandlestatic -xqueuesetinner -xqueuesetouter -xqueuesettaskssatus -xqueuesizeinbytes -xqueuespacesavailable -xqueuetakemutexrecursive -xqueuetype -xrandomlength -xrc -xreadblocktime -xreceived -xreceivedbytes -xreceivelength -xrecvbuffer -xrecvloop -xregions -xregionssettings -xregtest -xregtesterror -xregteststacksize -xregteststatus -xregulatoroffidletime -xreportlength -xreportstatus -xrequest -xresponsecount -xresponsestatus -xresult -xretrytimeoutticks -xreturn -xreturned -xreturnstatus -xreturnvalue -xrow -xrtosticktimerinstance -xrunindicator -xrxaddress -xrxdescriptors -xrxtcbbuffer -xscugic -xsecondtimerhandler -xsemaphore -xsemaphorecreate -xsemaphorecreatebinary -xsemaphorecreatebinarystatic -xsemaphorecreatecounting -xsemaphorecreatecountingstatic -xsemaphorecreateeventgroupstatic -xsemaphorecreatemutex -xsemaphorecreatemutexstatic -xsemaphorecreaterecursivemutex -xsemaphorecreaterecursivemutexstatic -xsemaphoregetmutexholder -xsemaphoregetmutexholderfromisr -xsemaphoregive -xsemaphoregivefromisr -xsemaphoregiverecursive -xsemaphorehandlestatic -xsemaphoretake -xsemaphoretakefromisr -xsemaphoretakerecursive -xsendblocktime -xsenddate -xsendingtask -xsendloop -xsendnotificationfromisr -xserialportinit -xserialportinitminimal -xserialsendstring -xserver -xsession -xsessionhandle -xsetupcomplete -xsigbuffersize -xsiglen -xsignature -xsignaturelength -xsignercertificatelength -xsize -xsocket -xsocketlocal -xstacksize -xstart -xstartmargin -xstaticdeletetaskbuffer -xstaticmessagebuffers -xstaticqueue -xstaticstreambuffers -xstatus -xstreambuffer -xstreambuffercreate -xstreambuffercreatestatic -xstreambufferreceive -xstreambufferreceivecompletedfromisr -xstreambuffersendcompletedfromisr -xstringlength -xsuccessstatus -xsynceventgroup -xsynctask -xt -xtaksnotify -xtal -xtask -xtaskabortdelay -xtaskcatchupticks -xtaskcheckfortimeout -xtaskcheckfortimeoutcb -xtaskcheckfortimeoutstub -xtaskcounters -xtaskcreate -xtaskcreaterestricted -xtaskcreaterestrictedstatic -xtaskcreatestatic -xtaskdelayuntil -xtaskgetcurrenttaskhandle -xtaskgetidletaskhandle -xtaskgetschedulerstate -xtaskgettickcount -xtaskgettickcountfromisr -xtaskhandle -xtaskinfo -xtasknotify -xtasknotifyandqueryfromisr -xtasknotifyfromisr -xtasknotifytake -xtasknotifyvalueclear -xtasknotifywaitindexed -xtaskremovefromeventlist -xtaskresumeall -xtaskresumeallcallback -xtaskresumeallstub -xtasksocket -xtaskstatusarraylength -xtaskswaitingtoreceive -xtaskswaitingtosend -xtasktodelete -xtasktonotify -xtcbbuffer -xtcp -xtcpportsarraylength -xtcptestechoclientstaskparams -xtea -xtensa -xteststatus -xtickstowait -xtime -xtimeonentering -xtimeout -xtimeouts -xtimer -xtimerbuffer -xtimerchangeperiod -xtimercreate -xtimercreatestatic -xtimergettimerdaemontaskhandle -xtimerpendfunctioncall -xtimerperiod -xtimerperiodticks -xtimerresetfromisr -xtimerstart -xtimerstop -xtimertask -xtimertaskhandle -xtimetoblock -xtimetowait -xtopicfiltercontext -xtracerunning -xtransfercompletedelay -xtransfersocket -xtransmitted -xtrue -xtrueobject -xts -xttcps -xtxbuffermutex -xtxdescriptors -xtxhasended -xtxmessages -xtxtcbbuffer -xtype -xudpportsarraylength -xupdatedmessagebuffer -xurllen -xurlparser -xusb -xusermodetaskbuffer -xusermodetaskstack -xvalue -xwaitindefinitely -xwantedsize -xwolfssl -xwritebufferlen -xxd -xxx -xxxx -xxxxxx -xyieldpending -xyieldrequired -yrdkrl -yrpbrl -yyyy -yyyymmddhhmmss -zc -zer -zynq diff --git a/manifest.yml b/manifest.yml index 861fa4f75..6870992bc 100644 --- a/manifest.yml +++ b/manifest.yml @@ -1,6 +1,7 @@ name : "FreeRTOS" version: "202212.00" description: "This is the standard distribution of FreeRTOS." +license: "MIT" dependencies: - name: "FreeRTOS-Kernel" @@ -185,4 +186,16 @@ dependencies: url: "https://github.com/intel/tinycbor.git" path: "FreeRTOS-Plus/ThirdParty/tinycbor" -license: "MIT" + - name: "CMock" + version: "afa2949" + repository: + type: "git" + url: " https://github.com/ThrowTheSwitch/CMock.git" + path: "FreeRTOS/Test/CMock/CMock" + + - name: "CMock" + version: "150573c" + repository: + type: "git" + url: " https://github.com/ThrowTheSwitch/CMock.git" + path: "FreeRTOS-Plus/Test/CMock" diff --git a/tools/aws_config_offline/CertificateConfigurator.html b/tools/aws_config_offline/CertificateConfigurator.html index 25be752e9..fa07e99dc 100644 --- a/tools/aws_config_offline/CertificateConfigurator.html +++ b/tools/aws_config_offline/CertificateConfigurator.html @@ -1,4 +1,4 @@ - +